Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Sep 2013 16:31:03 +0000 (09:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Sep 2013 16:31:03 +0000 (09:31 -0700)
Pull i2c updates from Wolfram Sang:
 "Highlights:

   - OF and ACPI helpers are now included in the core, and not in
     external files anymore.  This removes dependency problems for
     modules and is cleaner, in general.
   - mv64xxx-driver gains fifo usage to support mv78230
   - imx-driver overhaul to support VF610
   - various cleanups, most notably related to devm_* and CONFIG_PM
     usage
   - driver bugfixes and smaller feature additions"

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (51 commits)
  i2c: rcar: add rcar-H2 support
  i2c: sirf: retry 3 times as sometimes we get random noack and timeout
  i2c: sirf: support reverse direction of address
  i2c: sirf: fix the typo for setting bitrate to less than 100k
  i2c: sirf: we need to wait I2C_RESET status in resume
  i2c: sirf: reset i2c controller early after we get a noack
  i2c: designware: get SDA hold time, HCNT and LCNT configuration from ACPI
  i2c: designware: make HCNT/LCNT values configurable
  i2c: mpc: cleanup clock API use
  i2c: pnx: fix error return code in i2c_pnx_probe()
  i2c: ismt: add error return code in probe()
  i2c: mv64xxx: fix typo in binding documentation
  i2c: imx: use exact SoC revision to document binding
  i2c: move ACPI helpers into the core
  i2c: move OF helpers into the core
  i2c: mv64xxx: Fix timing issue on Armada XP (errata FE-8471889)
  i2c: mv64xxx: Add I2C Transaction Generator support
  i2c: powermac: fix return path on error
  Documentation: i2c: Fix example in instantiating-devices
  i2c: tiny-usb: do not use stack as URB transfer_buffer
  ...

72 files changed:
Documentation/acpi/enumeration.txt
Documentation/devicetree/bindings/i2c/i2c-imx.txt
Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
Documentation/i2c/busses/i2c-piix4
Documentation/i2c/instantiating-devices
arch/powerpc/platforms/44x/warp.c
drivers/acpi/Kconfig
drivers/acpi/Makefile
drivers/acpi/acpi_i2c.c [deleted file]
drivers/gpu/drm/tilcdc/tilcdc_slave.c
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
drivers/gpu/host1x/drm/output.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-at91.c
drivers/i2c/busses/i2c-bfin-twi.c
drivers/i2c/busses/i2c-cbus-gpio.c
drivers/i2c/busses/i2c-cpm.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-designware-core.c
drivers/i2c/busses/i2c-designware-core.h
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-gpio.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-ismt.c
drivers/i2c/busses/i2c-mpc.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-mxs.c
drivers/i2c/busses/i2c-nomadik.c
drivers/i2c/busses/i2c-nuc900.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-octeon.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pca-platform.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-puv3.c
drivers/i2c/busses/i2c-pxa.c
drivers/i2c/busses/i2c-rcar.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/busses/i2c-s6000.c
drivers/i2c/busses/i2c-sh7760.c
drivers/i2c/busses/i2c-sh_mobile.c
drivers/i2c/busses/i2c-sirf.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/busses/i2c-tiny-usb.c
drivers/i2c/busses/i2c-versatile.c
drivers/i2c/busses/i2c-wmt.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-mux.c
drivers/i2c/i2c-smbus.c
drivers/i2c/muxes/i2c-arb-gpio-challenge.c
drivers/i2c/muxes/i2c-mux-gpio.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/i2c/muxes/i2c-mux-pinctrl.c
drivers/media/platform/exynos4-is/fimc-is-i2c.c
drivers/media/platform/exynos4-is/fimc-is.c
drivers/media/platform/exynos4-is/media-dev.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/of_i2c.c [deleted file]
drivers/staging/imx-drm/imx-tve.c
include/linux/i2c.h
include/linux/i2c/pxa-i2c.h
include/linux/of_i2c.h [deleted file]
sound/soc/fsl/imx-sgtl5000.c
sound/soc/fsl/imx-wm8962.c

index d9be7a97dff35e7b1521e709e8a29c278d3fb434..d977778b5e67b78d521fd59707d0ddcd05a3ffc3 100644 (file)
@@ -228,19 +228,9 @@ ACPI handle like:
 I2C serial bus support
 ~~~~~~~~~~~~~~~~~~~~~~
 The slaves behind I2C bus controller only need to add the ACPI IDs like
-with the platform and SPI drivers. However the I2C bus controller driver
-needs to call acpi_i2c_register_devices() after it has added the adapter.
-
-An I2C bus (controller) driver does:
-
-       ...
-       ret = i2c_add_numbered_adapter(adapter);
-       if (ret)
-               /* handle error */
-
-       of_i2c_register_devices(adapter);
-       /* Enumerate the slave devices behind this bus via ACPI */
-       acpi_i2c_register_devices(adapter);
+with the platform and SPI drivers. The I2C core automatically enumerates
+any slave devices behind the controller device once the adapter is
+registered.
 
 Below is an example of how to add ACPI support to the existing mpu3050
 input driver:
index 3614242e77321d376b9411c2f3a6168408315605..4a8513e4474049072b0bdc65ead90cab2a9ce1ef 100644 (file)
@@ -1,7 +1,10 @@
 * Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX
 
 Required properties:
-- compatible : Should be "fsl,<chip>-i2c"
+- compatible :
+  - "fsl,imx1-i2c" for I2C compatible with the one integrated on i.MX1 SoC
+  - "fsl,imx21-i2c" for I2C compatible with the one integrated on i.MX21 SoC
+  - "fsl,vf610-i2c" for I2C compatible with the one integrated on Vybrid vf610 SoC
 - reg : Should contain I2C/HS-I2C registers location and length
 - interrupts : Should contain I2C/HS-I2C interrupt
 
index 6113f9275f42074d044199145b37d20feddf279e..82e8f6f17179b9b951e3d14f17d5a8b1671990ec 100644 (file)
@@ -5,6 +5,7 @@ Required properties :
 
  - reg             : Offset and length of the register set for the device
  - compatible      : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c"
+                     or "marvell,mv78230-i2c"
  - interrupts      : The interrupt number
 
 Optional properties :
@@ -20,3 +21,12 @@ Examples:
                interrupts = <29>;
                clock-frequency = <100000>;
        };
+
+For the Armada XP:
+
+       i2c@11000 {
+               compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+               reg = <0x11000 0x100>;
+               interrupts = <29>;
+               clock-frequency = <100000>;
+       };
index a370b2047cf3025b5a0c318af15c670a76bc41e3..c097e0f020fe1d786bed67fd3ed9e06fd99f7b63 100644 (file)
@@ -73,9 +73,10 @@ this driver on those mainboards.
 The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are
 identical to the PIIX4 in I2C/SMBus support.
 
-The AMD SB700 and SP5100 chipsets implement two PIIX4-compatible SMBus
-controllers. If your BIOS initializes the secondary controller, it will
-be detected by this driver as an "Auxiliary SMBus Host Controller".
+The AMD SB700, SB800, SP5100 and Hudson-2 chipsets implement two
+PIIX4-compatible SMBus controllers. If your BIOS initializes the
+secondary controller, it will be detected by this driver as
+an "Auxiliary SMBus Host Controller".
 
 If you own Force CPCI735 motherboard or other OSB4 based systems you may need
 to change the SMBus Interrupt Select register so the SMBus controller uses
index 22182660dda762816ad4663588f9e50cb7076622..c70e7a7638d1e6e66cbddd3cf7800325560cad28 100644 (file)
@@ -19,7 +19,7 @@ i2c_board_info which is registered by calling i2c_register_board_info().
 
 Example (from omap2 h4):
 
-static struct i2c_board_info __initdata h4_i2c_board_info[] = {
+static struct i2c_board_info h4_i2c_board_info[] __initdata = {
        {
                I2C_BOARD_INFO("isp1301_omap", 0x2d),
                .irq            = OMAP_GPIO_IRQ(125),
index 4cfa49901c023f069828c5b8f50a1b5028cf69bf..534574a97ec906d72e9f15fde252dac5a36ca514 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
 #include <linux/slab.h>
 #include <linux/export.h>
 
index 3278a210c435320df0e98a9dacbab2892b180176..22327e6a7236fc367313ec5acf45016d354863d4 100644 (file)
@@ -162,12 +162,6 @@ config ACPI_DOCK
          This driver supports ACPI-controlled docking stations and removable
          drive bays such as the IBM Ultrabay and the Dell Module Bay.
 
-config ACPI_I2C
-       def_tristate I2C
-       depends on I2C
-       help
-         ACPI I2C enumeration support.
-
 config ACPI_PROCESSOR
        tristate "Processor"
        select THERMAL
index 81dbeb83bb45805de6b0f7e083ed3bb421eabca9..cdaf68b58b006fb833f104f2d5e28baa4ecaf991 100644 (file)
@@ -73,7 +73,6 @@ obj-$(CONFIG_ACPI_HED)                += hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)  += ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)                += bgrt.o
-obj-$(CONFIG_ACPI_I2C)         += acpi_i2c.o
 
 # processor has its own "processor." module_param namespace
 processor-y                    := processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
deleted file mode 100644 (file)
index a82c762..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ACPI I2C enumeration support
- *
- * Copyright (C) 2012, Intel Corporation
- * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/acpi.h>
-#include <linux/device.h>
-#include <linux/export.h>
-#include <linux/i2c.h>
-#include <linux/ioport.h>
-
-ACPI_MODULE_NAME("i2c");
-
-static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
-{
-       struct i2c_board_info *info = data;
-
-       if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
-               struct acpi_resource_i2c_serialbus *sb;
-
-               sb = &ares->data.i2c_serial_bus;
-               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
-                       info->addr = sb->slave_address;
-                       if (sb->access_mode == ACPI_I2C_10BIT_MODE)
-                               info->flags |= I2C_CLIENT_TEN;
-               }
-       } else if (info->irq < 0) {
-               struct resource r;
-
-               if (acpi_dev_resource_interrupt(ares, 0, &r))
-                       info->irq = r.start;
-       }
-
-       /* Tell the ACPI core to skip this resource */
-       return 1;
-}
-
-static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
-                                      void *data, void **return_value)
-{
-       struct i2c_adapter *adapter = data;
-       struct list_head resource_list;
-       struct i2c_board_info info;
-       struct acpi_device *adev;
-       int ret;
-
-       if (acpi_bus_get_device(handle, &adev))
-               return AE_OK;
-       if (acpi_bus_get_status(adev) || !adev->status.present)
-               return AE_OK;
-
-       memset(&info, 0, sizeof(info));
-       info.acpi_node.handle = handle;
-       info.irq = -1;
-
-       INIT_LIST_HEAD(&resource_list);
-       ret = acpi_dev_get_resources(adev, &resource_list,
-                                    acpi_i2c_add_resource, &info);
-       acpi_dev_free_resource_list(&resource_list);
-
-       if (ret < 0 || !info.addr)
-               return AE_OK;
-
-       strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
-       if (!i2c_new_device(adapter, &info)) {
-               dev_err(&adapter->dev,
-                       "failed to add I2C device %s from ACPI\n",
-                       dev_name(&adev->dev));
-       }
-
-       return AE_OK;
-}
-
-/**
- * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
- * @adapter: pointer to adapter
- *
- * Enumerate all I2C slave devices behind this adapter by walking the ACPI
- * namespace. When a device is found it will be added to the Linux device
- * model and bound to the corresponding ACPI handle.
- */
-void acpi_i2c_register_devices(struct i2c_adapter *adapter)
-{
-       acpi_handle handle;
-       acpi_status status;
-
-       handle = ACPI_HANDLE(adapter->dev.parent);
-       if (!handle)
-               return;
-
-       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
-                                    acpi_i2c_add_device, NULL,
-                                    adapter, NULL);
-       if (ACPI_FAILURE(status))
-               dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n");
-}
-EXPORT_SYMBOL_GPL(acpi_i2c_register_devices);
index dfffaf01402225b20bbbcefd97b264cad040ce28..a19f657dfa59f0efe70ea33df0bf85f82af00f0d 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/consumer.h>
 #include <drm/drm_encoder_slave.h>
index 925c7cddeff9a16e44bb99273e8ff84f784e8b62..c38b56b268ac0d8ba61a8826d13ad435f9f59fb7 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/pinctrl/pinmux.h>
index 8140fc6c34d85be1d360f54e9655ba8cdf5bab4a..137ae81ab80eb164d139742b16996bca8b8922b5 100644 (file)
@@ -9,7 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 
 #include "drm.h"
 
index dc6dea614abd68dca0e32f7d6948b9c8e40696ef..fcdd321f709ecb2f284c3afefce962a2b1a8a42c 100644 (file)
@@ -385,7 +385,7 @@ config I2C_CPM
 
 config I2C_DAVINCI
        tristate "DaVinci I2C driver"
-       depends on ARCH_DAVINCI
+       depends on ARCH_DAVINCI || ARCH_KEYSTONE
        help
          Support for TI DaVinci I2C controller driver.
 
index 6bb839b688be4f17dd0b435f46bf483e054d2071..fd059308affa2985e64142756c9176f356f0d744 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/platform_data/dma-atmel.h>
@@ -775,8 +774,6 @@ static int at91_twi_probe(struct platform_device *pdev)
                return rc;
        }
 
-       of_i2c_register_devices(&dev->adapter);
-
        dev_info(dev->dev, "AT91 i2c bus driver.\n");
        return 0;
 }
index 13ea1c29873d61f4028f48b7d8f49d7fb9a1afaa..35a473ba3d81d5afb9cb0188f2141c2dc417c737 100644 (file)
@@ -582,6 +582,7 @@ static struct i2c_algorithm bfin_twi_algorithm = {
        .functionality = bfin_twi_functionality,
 };
 
+#ifdef CONFIG_PM_SLEEP
 static int i2c_bfin_twi_suspend(struct device *dev)
 {
        struct bfin_twi_iface *iface = dev_get_drvdata(dev);
@@ -619,6 +620,10 @@ static int i2c_bfin_twi_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(i2c_bfin_twi_pm,
                         i2c_bfin_twi_suspend, i2c_bfin_twi_resume);
+#define I2C_BFIN_TWI_PM_OPS    (&i2c_bfin_twi_pm)
+#else
+#define I2C_BFIN_TWI_PM_OPS    NULL
+#endif
 
 static int i2c_bfin_twi_probe(struct platform_device *pdev)
 {
@@ -669,8 +674,9 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
        p_adap->timeout = 5 * HZ;
        p_adap->retries = 3;
 
-       rc = peripheral_request_list((unsigned short *)pdev->dev.platform_data,
-                                       "i2c-bfin-twi");
+       rc = peripheral_request_list(
+                       (unsigned short *)dev_get_platdata(&pdev->dev),
+                       "i2c-bfin-twi");
        if (rc) {
                dev_err(&pdev->dev, "Can't setup pin mux!\n");
                goto out_error_pin_mux;
@@ -717,7 +723,7 @@ out_error_add_adapter:
        free_irq(iface->irq, iface);
 out_error_req_irq:
 out_error_no_irq:
-       peripheral_free_list((unsigned short *)pdev->dev.platform_data);
+       peripheral_free_list((unsigned short *)dev_get_platdata(&pdev->dev));
 out_error_pin_mux:
        iounmap(iface->regs_base);
 out_error_ioremap:
@@ -733,7 +739,7 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
 
        i2c_del_adapter(&(iface->adap));
        free_irq(iface->irq, iface);
-       peripheral_free_list((unsigned short *)pdev->dev.platform_data);
+       peripheral_free_list((unsigned short *)dev_get_platdata(&pdev->dev));
        iounmap(iface->regs_base);
        kfree(iface);
 
@@ -746,7 +752,7 @@ static struct platform_driver i2c_bfin_twi_driver = {
        .driver         = {
                .name   = "i2c-bfin-twi",
                .owner  = THIS_MODULE,
-               .pm     = &i2c_bfin_twi_pm,
+               .pm     = I2C_BFIN_TWI_PM_OPS,
        },
 };
 
index 1be13ac11dc5d615050deb2e03c58d530a99fb30..2d46f13adfdfc965561db40bdeafa55f6c445978 100644 (file)
@@ -233,8 +233,9 @@ static int cbus_i2c_probe(struct platform_device *pdev)
                chost->clk_gpio = of_get_gpio(dnode, 0);
                chost->dat_gpio = of_get_gpio(dnode, 1);
                chost->sel_gpio = of_get_gpio(dnode, 2);
-       } else if (pdev->dev.platform_data) {
-               struct i2c_cbus_platform_data *pdata = pdev->dev.platform_data;
+       } else if (dev_get_platdata(&pdev->dev)) {
+               struct i2c_cbus_platform_data *pdata =
+                       dev_get_platdata(&pdev->dev);
                chost->clk_gpio = pdata->clk_gpio;
                chost->dat_gpio = pdata->dat_gpio;
                chost->sel_gpio = pdata->sel_gpio;
index 2e1f7eb55bf4a6f6d525db8548928daa39cbd1f2..b2b8aa9adc0ef24bafd93fb6c07679463d14c212 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
 #include <sysdev/fsl_soc.h>
 #include <asm/cpm.h>
 
@@ -681,11 +680,6 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
        dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
                cpm->adap.name);
 
-       /*
-        * register OF I2C devices
-        */
-       of_i2c_register_devices(&cpm->adap);
-
        return 0;
 out_shut:
        cpm_i2c_shutdown(cpm);
index fa556057d22461a9aece9de831082f50e3b44761..57473415be10b3654fa1bbbbd30215082a01a9ba 100644 (file)
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/gpio.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/i2c-davinci.h>
 
 /* ----- global defines ----------------------------------------------- */
@@ -665,7 +662,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 #endif
        dev->dev = &pdev->dev;
        dev->irq = irq->start;
-       dev->pdata = dev->dev->platform_data;
+       dev->pdata = dev_get_platdata(&dev->dev);
        platform_set_drvdata(pdev, dev);
 
        if (!dev->pdata && pdev->dev.of_node) {
@@ -728,7 +725,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failure adding adapter\n");
                goto err_unuse_clocks;
        }
-       of_i2c_register_devices(adap);
 
        return 0;
 
index ad46616de29ec8638aeb2a17c6ff231d59c57596..dbecf08399f86dd30baa7fa7b8964e2daf616bcb 100644 (file)
@@ -317,6 +317,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
                                47,     /* tLOW = 4.7 us */
                                3,      /* tf = 0.3 us */
                                0);     /* No offset */
+
+       /* Allow platforms to specify the ideal HCNT and LCNT values */
+       if (dev->ss_hcnt && dev->ss_lcnt) {
+               hcnt = dev->ss_hcnt;
+               lcnt = dev->ss_lcnt;
+       }
        dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT);
        dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
        dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
@@ -331,6 +337,11 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
                                13,     /* tLOW = 1.3 us */
                                3,      /* tf = 0.3 us */
                                0);     /* No offset */
+
+       if (dev->fs_hcnt && dev->fs_lcnt) {
+               hcnt = dev->fs_hcnt;
+               lcnt = dev->fs_lcnt;
+       }
        dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT);
        dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
        dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
@@ -416,6 +427,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
        u32 addr = msgs[dev->msg_write_idx].addr;
        u32 buf_len = dev->tx_buf_len;
        u8 *buf = dev->tx_buf;
+       bool need_restart = false;
 
        intr_mask = DW_IC_INTR_DEFAULT_MASK;
 
@@ -443,6 +455,14 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
                        /* new i2c_msg */
                        buf = msgs[dev->msg_write_idx].buf;
                        buf_len = msgs[dev->msg_write_idx].len;
+
+                       /* If both IC_EMPTYFIFO_HOLD_MASTER_EN and
+                        * IC_RESTART_EN are set, we must manually
+                        * set restart bit between messages.
+                        */
+                       if ((dev->master_cfg & DW_IC_CON_RESTART_EN) &&
+                                       (dev->msg_write_idx > 0))
+                               need_restart = true;
                }
 
                tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR);
@@ -461,6 +481,11 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
                            buf_len == 1)
                                cmd |= BIT(9);
 
+                       if (need_restart) {
+                               cmd |= BIT(10);
+                               need_restart = false;
+                       }
+
                        if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
 
                                /* avoid rx buffer overrun */
index 912aa22628664a41ed2b8975e4548085555830a4..e8a756537ed036dbabb49302bbe0eaa4ac0abfac 100644 (file)
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
  * @rx_outstanding: current master-rx elements in tx fifo
+ * @ss_hcnt: standard speed HCNT value
+ * @ss_lcnt: standard speed LCNT value
+ * @fs_hcnt: fast speed HCNT value
+ * @fs_lcnt: fast speed LCNT value
+ *
+ * HCNT and LCNT parameters can be used if the platform knows more accurate
+ * values than the one computed based only on the input clock frequency.
+ * Leave them to be %0 if not used.
  */
 struct dw_i2c_dev {
        struct device           *dev;
@@ -91,6 +99,10 @@ struct dw_i2c_dev {
        unsigned int            rx_fifo_depth;
        int                     rx_outstanding;
        u32                     sda_hold_time;
+       u16                     ss_hcnt;
+       u16                     ss_lcnt;
+       u16                     fs_hcnt;
+       u16                     fs_lcnt;
 };
 
 #define ACCESS_SWAP            0x00000001
index 4c5fadabe49df3236e479c86105d7e479aa90d79..4c1b60539a2515c34ee4df0e7c353dbd7860dc56 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
@@ -54,9 +53,33 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
 }
 
 #ifdef CONFIG_ACPI
+static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
+                              u16 *hcnt, u16 *lcnt, u32 *sda_hold)
+{
+       struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+       acpi_handle handle = ACPI_HANDLE(&pdev->dev);
+       union acpi_object *obj;
+
+       if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
+               return;
+
+       obj = (union acpi_object *)buf.pointer;
+       if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) {
+               const union acpi_object *objs = obj->package.elements;
+
+               *hcnt = (u16)objs[0].integer.value;
+               *lcnt = (u16)objs[1].integer.value;
+               if (sda_hold)
+                       *sda_hold = (u32)objs[2].integer.value;
+       }
+
+       kfree(buf.pointer);
+}
+
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
        struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+       bool fs_mode = dev->master_cfg & DW_IC_CON_SPEED_FAST;
 
        if (!ACPI_HANDLE(&pdev->dev))
                return -ENODEV;
@@ -64,6 +87,16 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        dev->adapter.nr = -1;
        dev->tx_fifo_depth = 32;
        dev->rx_fifo_depth = 32;
+
+       /*
+        * Try to get SDA hold time and *CNT values from an ACPI method if
+        * it exists for both supported speed modes.
+        */
+       dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt,
+                          fs_mode ? NULL : &dev->sda_hold_time);
+       dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
+                          fs_mode ? &dev->sda_hold_time : NULL);
+
        return 0;
 }
 
@@ -172,8 +205,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failure adding adapter\n");
                return r;
        }
-       of_i2c_register_devices(adap);
-       acpi_i2c_register_devices(adap);
 
        pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
        pm_runtime_use_autosuspend(&pdev->dev);
@@ -207,7 +238,7 @@ static const struct of_device_id dw_i2c_of_match[] = {
 MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
 #endif
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int dw_i2c_suspend(struct device *dev)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -228,9 +259,12 @@ static int dw_i2c_resume(struct device *dev)
 
        return 0;
 }
-#endif
 
 static SIMPLE_DEV_PM_OPS(dw_i2c_dev_pm_ops, dw_i2c_suspend, dw_i2c_resume);
+#define DW_I2C_DEV_PM_OPS      (&dw_i2c_dev_pm_ops)
+#else
+#define DW_I2C_DEV_PM_OPS      NULL
+#endif
 
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:i2c_designware");
@@ -242,7 +276,7 @@ static struct platform_driver dw_i2c_driver = {
                .owner  = THIS_MODULE,
                .of_match_table = of_match_ptr(dw_i2c_of_match),
                .acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
-               .pm     = &dw_i2c_dev_pm_ops,
+               .pm     = DW_I2C_DEV_PM_OPS,
        },
 };
 
index bc6e139c6e7f3f6b91e1f054c7569a5191a08b9a..bfa02c6c2ddaf01b03a9a5121c2ddcf122f9a3e2 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
 
 struct i2c_gpio_private_data {
        struct i2c_adapter adap;
@@ -137,9 +136,9 @@ static int i2c_gpio_probe(struct platform_device *pdev)
                if (ret)
                        return ret;
        } else {
-               if (!pdev->dev.platform_data)
+               if (!dev_get_platdata(&pdev->dev))
                        return -ENXIO;
-               pdata = pdev->dev.platform_data;
+               pdata = dev_get_platdata(&pdev->dev);
                sda_pin = pdata->sda_pin;
                scl_pin = pdata->scl_pin;
        }
@@ -171,7 +170,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)
                pdata->scl_pin = scl_pin;
                of_i2c_gpio_get_props(pdev->dev.of_node, pdata);
        } else {
-               memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+               memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata));
        }
 
        if (pdata->sda_is_open_drain) {
@@ -224,8 +223,6 @@ static int i2c_gpio_probe(struct platform_device *pdev)
        if (ret)
                goto err_add_bus;
 
-       of_i2c_register_devices(adap);
-
        platform_set_drvdata(pdev, priv);
 
        dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
index 4ebceed6bc6612dbbc50bd62a8e91ef97615b66d..4296d1721272bd3fa077944a63e5708000b6a4dd 100644 (file)
@@ -87,7 +87,6 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/err.h>
-#include <linux/of_i2c.h>
 
 #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
                defined CONFIG_DMI
@@ -1230,7 +1229,6 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
                goto exit_free_irq;
        }
 
-       of_i2c_register_devices(&priv->adapter);
        i801_probe_optional_slaves(priv);
        /* We ignore errors - multiplexing is optional */
        i801_add_mux(priv);
index 973f51688276cd160de29d6483e1376a3c29ea44..ff3caa0c28cdb171e8bace863f8357617485c79c 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
 
 #include "i2c-ibm_iic.h"
 
@@ -759,9 +758,6 @@ static int iic_probe(struct platform_device *ofdev)
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
-       /* Now register all the child nodes */
-       of_i2c_register_devices(adap);
-
        return 0;
 
 error_cleanup:
index e24279725d363acb594e452b53b788a10058026d..ccf46656bdad9182e2d75d6c1f3dbf42ea0c32c6 100644 (file)
@@ -30,6 +30,8 @@
  *     Copyright (C) 2007 RightHand Technologies, Inc.
  *     Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
  *
+ *     Copyright 2013 Freescale Semiconductor, Inc.
+ *
  */
 
 /** Includes *******************************************************************
@@ -50,7 +52,6 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_data/i2c-imx.h>
 
 /** Defines ********************************************************************
 /* Default value */
 #define IMX_I2C_BIT_RATE       100000  /* 100kHz */
 
-/* IMX I2C registers */
+/* IMX I2C registers:
+ * the I2C register offset is different between SoCs,
+ * to provid support for all these chips, split the
+ * register offset into a fixed base address and a
+ * variable shift value, then the full register offset
+ * will be calculated by
+ * reg_off = ( reg_base_addr << reg_shift)
+ */
 #define IMX_I2C_IADR   0x00    /* i2c slave address */
-#define IMX_I2C_IFDR   0x04    /* i2c frequency divider */
-#define IMX_I2C_I2CR   0x08    /* i2c control */
-#define IMX_I2C_I2SR   0x0C    /* i2c status */
-#define IMX_I2C_I2DR   0x10    /* i2c transfer data */
+#define IMX_I2C_IFDR   0x01    /* i2c frequency divider */
+#define IMX_I2C_I2CR   0x02    /* i2c control */
+#define IMX_I2C_I2SR   0x03    /* i2c status */
+#define IMX_I2C_I2DR   0x04    /* i2c transfer data */
+
+#define IMX_I2C_REGSHIFT       2
+#define VF610_I2C_REGSHIFT     0
 
 /* Bits of IMX I2C registers */
 #define I2SR_RXAK      0x01
 #define I2CR_IIEN      0x40
 #define I2CR_IEN       0x80
 
+/* register bits different operating codes definition:
+ * 1) I2SR: Interrupt flags clear operation differ between SoCs:
+ * - write zero to clear(w0c) INT flag on i.MX,
+ * - but write one to clear(w1c) INT flag on Vybrid.
+ * 2) I2CR: I2C module enable operation also differ between SoCs:
+ * - set I2CR_IEN bit enable the module on i.MX,
+ * - but clear I2CR_IEN bit enable the module on Vybrid.
+ */
+#define I2SR_CLR_OPCODE_W0C    0x0
+#define I2SR_CLR_OPCODE_W1C    (I2SR_IAL | I2SR_IIF)
+#define I2CR_IEN_OPCODE_0      0x0
+#define I2CR_IEN_OPCODE_1      I2CR_IEN
+
 /** Variables ******************************************************************
 *******************************************************************************/
 
  *
  * Duplicated divider values removed from list
  */
+struct imx_i2c_clk_pair {
+       u16     div;
+       u16     val;
+};
 
-static u16 __initdata i2c_clk_div[50][2] = {
+static struct imx_i2c_clk_pair imx_i2c_clk_div[] = {
        { 22,   0x20 }, { 24,   0x21 }, { 26,   0x22 }, { 28,   0x23 },
        { 30,   0x00 }, { 32,   0x24 }, { 36,   0x25 }, { 40,   0x26 },
        { 42,   0x03 }, { 44,   0x27 }, { 48,   0x28 }, { 52,   0x05 },
@@ -112,9 +140,38 @@ static u16 __initdata i2c_clk_div[50][2] = {
        { 3072, 0x1E }, { 3840, 0x1F }
 };
 
+/* Vybrid VF610 clock divider, register value pairs */
+static struct imx_i2c_clk_pair vf610_i2c_clk_div[] = {
+       { 20,   0x00 }, { 22,   0x01 }, { 24,   0x02 }, { 26,   0x03 },
+       { 28,   0x04 }, { 30,   0x05 }, { 32,   0x09 }, { 34,   0x06 },
+       { 36,   0x0A }, { 40,   0x07 }, { 44,   0x0C }, { 48,   0x0D },
+       { 52,   0x43 }, { 56,   0x0E }, { 60,   0x45 }, { 64,   0x12 },
+       { 68,   0x0F }, { 72,   0x13 }, { 80,   0x14 }, { 88,   0x15 },
+       { 96,   0x19 }, { 104,  0x16 }, { 112,  0x1A }, { 128,  0x17 },
+       { 136,  0x4F }, { 144,  0x1C }, { 160,  0x1D }, { 176,  0x55 },
+       { 192,  0x1E }, { 208,  0x56 }, { 224,  0x22 }, { 228,  0x24 },
+       { 240,  0x1F }, { 256,  0x23 }, { 288,  0x5C }, { 320,  0x25 },
+       { 384,  0x26 }, { 448,  0x2A }, { 480,  0x27 }, { 512,  0x2B },
+       { 576,  0x2C }, { 640,  0x2D }, { 768,  0x31 }, { 896,  0x32 },
+       { 960,  0x2F }, { 1024, 0x33 }, { 1152, 0x34 }, { 1280, 0x35 },
+       { 1536, 0x36 }, { 1792, 0x3A }, { 1920, 0x37 }, { 2048, 0x3B },
+       { 2304, 0x3C }, { 2560, 0x3D }, { 3072, 0x3E }, { 3584, 0x7A },
+       { 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E },
+};
+
 enum imx_i2c_type {
        IMX1_I2C,
        IMX21_I2C,
+       VF610_I2C,
+};
+
+struct imx_i2c_hwdata {
+       enum imx_i2c_type       devtype;
+       unsigned                regshift;
+       struct imx_i2c_clk_pair *clk_div;
+       unsigned                ndivs;
+       unsigned                i2sr_clr_opcode;
+       unsigned                i2cr_ien_opcode;
 };
 
 struct imx_i2c_struct {
@@ -126,16 +183,46 @@ struct imx_i2c_struct {
        unsigned int            disable_delay;
        int                     stopped;
        unsigned int            ifdr; /* IMX_I2C_IFDR */
-       enum imx_i2c_type       devtype;
+       const struct imx_i2c_hwdata     *hwdata;
+};
+
+static const struct imx_i2c_hwdata imx1_i2c_hwdata  = {
+       .devtype                = IMX1_I2C,
+       .regshift               = IMX_I2C_REGSHIFT,
+       .clk_div                = imx_i2c_clk_div,
+       .ndivs                  = ARRAY_SIZE(imx_i2c_clk_div),
+       .i2sr_clr_opcode        = I2SR_CLR_OPCODE_W0C,
+       .i2cr_ien_opcode        = I2CR_IEN_OPCODE_1,
+
+};
+
+static const struct imx_i2c_hwdata imx21_i2c_hwdata  = {
+       .devtype                = IMX21_I2C,
+       .regshift               = IMX_I2C_REGSHIFT,
+       .clk_div                = imx_i2c_clk_div,
+       .ndivs                  = ARRAY_SIZE(imx_i2c_clk_div),
+       .i2sr_clr_opcode        = I2SR_CLR_OPCODE_W0C,
+       .i2cr_ien_opcode        = I2CR_IEN_OPCODE_1,
+
+};
+
+static struct imx_i2c_hwdata vf610_i2c_hwdata = {
+       .devtype                = VF610_I2C,
+       .regshift               = VF610_I2C_REGSHIFT,
+       .clk_div                = vf610_i2c_clk_div,
+       .ndivs                  = ARRAY_SIZE(vf610_i2c_clk_div),
+       .i2sr_clr_opcode        = I2SR_CLR_OPCODE_W1C,
+       .i2cr_ien_opcode        = I2CR_IEN_OPCODE_0,
+
 };
 
 static struct platform_device_id imx_i2c_devtype[] = {
        {
                .name = "imx1-i2c",
-               .driver_data = IMX1_I2C,
+               .driver_data = (kernel_ulong_t)&imx1_i2c_hwdata,
        }, {
                .name = "imx21-i2c",
-               .driver_data = IMX21_I2C,
+               .driver_data = (kernel_ulong_t)&imx21_i2c_hwdata,
        }, {
                /* sentinel */
        }
@@ -143,15 +230,28 @@ static struct platform_device_id imx_i2c_devtype[] = {
 MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
 
 static const struct of_device_id i2c_imx_dt_ids[] = {
-       { .compatible = "fsl,imx1-i2c", .data = &imx_i2c_devtype[IMX1_I2C], },
-       { .compatible = "fsl,imx21-i2c", .data = &imx_i2c_devtype[IMX21_I2C], },
+       { .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
+       { .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
+       { .compatible = "fsl,vf610-i2c", .data = &vf610_i2c_hwdata, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
 
 static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
 {
-       return i2c_imx->devtype == IMX1_I2C;
+       return i2c_imx->hwdata->devtype == IMX1_I2C;
+}
+
+static inline void imx_i2c_write_reg(unsigned int val,
+               struct imx_i2c_struct *i2c_imx, unsigned int reg)
+{
+       writeb(val, i2c_imx->base + (reg << i2c_imx->hwdata->regshift));
+}
+
+static inline unsigned char imx_i2c_read_reg(struct imx_i2c_struct *i2c_imx,
+               unsigned int reg)
+{
+       return readb(i2c_imx->base + (reg << i2c_imx->hwdata->regshift));
 }
 
 /** Functions for IMX I2C adapter driver ***************************************
@@ -165,7 +265,7 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
        while (1) {
-               temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
                if (for_busy && (temp & I2SR_IBB))
                        break;
                if (!for_busy && !(temp & I2SR_IBB))
@@ -196,7 +296,7 @@ static int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx)
 
 static int i2c_imx_acked(struct imx_i2c_struct *i2c_imx)
 {
-       if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) {
+       if (imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR) & I2SR_RXAK) {
                dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
                return -EIO;  /* No ACK */
        }
@@ -213,25 +313,25 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
        dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
        clk_prepare_enable(i2c_imx->clk);
-       writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
+       imx_i2c_write_reg(i2c_imx->ifdr, i2c_imx, IMX_I2C_IFDR);
        /* Enable I2C controller */
-       writeb(0, i2c_imx->base + IMX_I2C_I2SR);
-       writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR);
+       imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
+       imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode, i2c_imx, IMX_I2C_I2CR);
 
        /* Wait controller to be stable */
        udelay(50);
 
        /* Start I2C transaction */
-       temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
        temp |= I2CR_MSTA;
-       writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        result = i2c_imx_bus_busy(i2c_imx, 1);
        if (result)
                return result;
        i2c_imx->stopped = 0;
 
        temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
-       writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        return result;
 }
 
@@ -242,9 +342,9 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
        if (!i2c_imx->stopped) {
                /* Stop I2C transaction */
                dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
-               temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                temp &= ~(I2CR_MSTA | I2CR_MTX);
-               writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+               imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        }
        if (is_imx1_i2c(i2c_imx)) {
                /*
@@ -260,13 +360,15 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
        }
 
        /* Disable I2C controller */
-       writeb(0, i2c_imx->base + IMX_I2C_I2CR);
+       temp = i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
+       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
        clk_disable_unprepare(i2c_imx->clk);
 }
 
 static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
                                                        unsigned int rate)
 {
+       struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
        unsigned int i2c_clk_rate;
        unsigned int div;
        int i;
@@ -274,15 +376,15 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
        /* Divider value calculation */
        i2c_clk_rate = clk_get_rate(i2c_imx->clk);
        div = (i2c_clk_rate + rate - 1) / rate;
-       if (div < i2c_clk_div[0][0])
+       if (div < i2c_clk_div[0].div)
                i = 0;
-       else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0])
-               i = ARRAY_SIZE(i2c_clk_div) - 1;
+       else if (div > i2c_clk_div[i2c_imx->hwdata->ndivs - 1].div)
+               i = i2c_imx->hwdata->ndivs - 1;
        else
-               for (i = 0; i2c_clk_div[i][0] < div; i++);
+               for (i = 0; i2c_clk_div[i].div < div; i++);
 
        /* Store divider value */
-       i2c_imx->ifdr = i2c_clk_div[i][1];
+       i2c_imx->ifdr = i2c_clk_div[i].val;
 
        /*
         * There dummy delay is calculated.
@@ -290,7 +392,7 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
         * This delay is used in I2C bus disable function
         * to fix chip hardware bug.
         */
-       i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0]
+       i2c_imx->disable_delay = (500000U * i2c_clk_div[i].div
                + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
 
        /* dev_dbg() can't be used, because adapter is not yet registered */
@@ -298,7 +400,7 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
        dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
                __func__, i2c_clk_rate, div);
        dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
-               __func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
+               __func__, i2c_clk_div[i].val, i2c_clk_div[i].div);
 #endif
 }
 
@@ -307,12 +409,13 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
        struct imx_i2c_struct *i2c_imx = dev_id;
        unsigned int temp;
 
-       temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
        if (temp & I2SR_IIF) {
                /* save status register */
                i2c_imx->i2csr = temp;
                temp &= ~I2SR_IIF;
-               writeb(temp, i2c_imx->base + IMX_I2C_I2SR);
+               temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF);
+               imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR);
                wake_up(&i2c_imx->queue);
                return IRQ_HANDLED;
        }
@@ -328,7 +431,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
                __func__, msgs->addr << 1);
 
        /* write slave address */
-       writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR);
+       imx_i2c_write_reg(msgs->addr << 1, i2c_imx, IMX_I2C_I2DR);
        result = i2c_imx_trx_complete(i2c_imx);
        if (result)
                return result;
@@ -342,7 +445,7 @@ static int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
                dev_dbg(&i2c_imx->adapter.dev,
                        "<%s> write byte: B%d=0x%X\n",
                        __func__, i, msgs->buf[i]);
-               writeb(msgs->buf[i], i2c_imx->base + IMX_I2C_I2DR);
+               imx_i2c_write_reg(msgs->buf[i], i2c_imx, IMX_I2C_I2DR);
                result = i2c_imx_trx_complete(i2c_imx);
                if (result)
                        return result;
@@ -363,7 +466,7 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
                __func__, (msgs->addr << 1) | 0x01);
 
        /* write slave address */
-       writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR);
+       imx_i2c_write_reg((msgs->addr << 1) | 0x01, i2c_imx, IMX_I2C_I2DR);
        result = i2c_imx_trx_complete(i2c_imx);
        if (result)
                return result;
@@ -374,12 +477,12 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
        dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);
 
        /* setup bus to read data */
-       temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
        temp &= ~I2CR_MTX;
        if (msgs->len - 1)
                temp &= ~I2CR_TXAK;
-       writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
-       readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */
+       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
+       imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR); /* dummy read */
 
        dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__);
 
@@ -393,19 +496,19 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs)
                           controller from generating another clock cycle */
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> clear MSTA\n", __func__);
-                       temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+                       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                        temp &= ~(I2CR_MSTA | I2CR_MTX);
-                       writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+                       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                        i2c_imx_bus_busy(i2c_imx, 0);
                        i2c_imx->stopped = 1;
                } else if (i == (msgs->len - 2)) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> set TXAK\n", __func__);
-                       temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+                       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                        temp |= I2CR_TXAK;
-                       writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+                       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                }
-               msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR);
+               msgs->buf[i] = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2DR);
                dev_dbg(&i2c_imx->adapter.dev,
                        "<%s> read byte: B%d=0x%X\n",
                        __func__, i, msgs->buf[i]);
@@ -432,9 +535,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
                if (i) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> repeated start\n", __func__);
-                       temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+                       temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                        temp |= I2CR_RSTA;
-                       writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
+                       imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR);
                        result =  i2c_imx_bus_busy(i2c_imx, 1);
                        if (result)
                                goto fail0;
@@ -443,13 +546,13 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
                        "<%s> transfer message: %d\n", __func__, i);
                /* write/read data */
 #ifdef CONFIG_I2C_DEBUG_BUS
-               temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
                dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, "
                        "MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
                        (temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
                        (temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
                        (temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0));
-               temp = readb(i2c_imx->base + IMX_I2C_I2SR);
+               temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2SR);
                dev_dbg(&i2c_imx->adapter.dev,
                        "<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
                        "IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__,
@@ -492,7 +595,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
                                                           &pdev->dev);
        struct imx_i2c_struct *i2c_imx;
        struct resource *res;
-       struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
+       struct imxi2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
        void __iomem *base;
        int irq, ret;
        u32 bitrate;
@@ -518,8 +621,10 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
        }
 
        if (of_id)
-               pdev->id_entry = of_id->data;
-       i2c_imx->devtype = pdev->id_entry->driver_data;
+               i2c_imx->hwdata = of_id->data;
+       else
+               i2c_imx->hwdata = (struct imx_i2c_hwdata *)
+                               platform_get_device_id(pdev)->driver_data;
 
        /* Setup i2c_imx driver structure */
        strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
@@ -537,6 +642,11 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
                return PTR_ERR(i2c_imx->clk);
        }
 
+       ret = clk_prepare_enable(i2c_imx->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "can't enable I2C clock\n");
+               return ret;
+       }
        /* Request IRQ */
        ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
                                pdev->name, i2c_imx);
@@ -560,8 +670,9 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
        i2c_imx_set_clk(i2c_imx, bitrate);
 
        /* Set up chip registers to defaults */
-       writeb(0, i2c_imx->base + IMX_I2C_I2CR);
-       writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+       imx_i2c_write_reg(i2c_imx->hwdata->i2cr_ien_opcode ^ I2CR_IEN,
+                       i2c_imx, IMX_I2C_I2CR);
+       imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
 
        /* Add I2C adapter */
        ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
@@ -570,10 +681,9 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
                return ret;
        }
 
-       of_i2c_register_devices(&i2c_imx->adapter);
-
        /* Set up platform driver data */
        platform_set_drvdata(pdev, i2c_imx);
+       clk_disable_unprepare(i2c_imx->clk);
 
        dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", irq);
        dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",
@@ -596,10 +706,10 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
        i2c_del_adapter(&i2c_imx->adapter);
 
        /* setup chip registers to defaults */
-       writeb(0, i2c_imx->base + IMX_I2C_IADR);
-       writeb(0, i2c_imx->base + IMX_I2C_IFDR);
-       writeb(0, i2c_imx->base + IMX_I2C_I2CR);
-       writeb(0, i2c_imx->base + IMX_I2C_I2SR);
+       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IADR);
+       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_IFDR);
+       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2CR);
+       imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR);
 
        return 0;
 }
index cd82eb44e4c436a68a9b51ad99e8778a83a7dd56..8ed79a086f858012b0f22b291834a5fb357d075c 100644 (file)
@@ -879,6 +879,7 @@ ismt_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                                                 DMA_BIT_MASK(32)) != 0)) {
                        dev_err(&pdev->dev, "pci_set_dma_mask fail %p\n",
                                pdev);
+                       err = -ENODEV;
                        goto fail;
                }
        }
index 7607dc0619184eaa4100c7edbb8590525df5d2f3..b80c76888cabe28c39954a96b53bb61d38d0a154 100644 (file)
@@ -18,9 +18,9 @@
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
 #include <linux/slab.h>
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/fsl_devices.h>
 #include <linux/i2c.h>
@@ -64,9 +64,10 @@ struct mpc_i2c {
        struct i2c_adapter adap;
        int irq;
        u32 real_clk;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
        u8 fdr, dfsrr;
 #endif
+       struct clk *clk_per;
 };
 
 struct mpc_i2c_divider {
@@ -609,7 +610,6 @@ static const struct i2c_algorithm mpc_algo = {
 
 static struct i2c_adapter mpc_ops = {
        .owner = THIS_MODULE,
-       .name = "MPC adapter",
        .algo = &mpc_algo,
        .timeout = HZ,
 };
@@ -623,6 +623,9 @@ static int fsl_i2c_probe(struct platform_device *op)
        u32 clock = MPC_I2C_CLOCK_LEGACY;
        int result = 0;
        int plen;
+       struct resource res;
+       struct clk *clk;
+       int err;
 
        match = of_match_device(mpc_i2c_of_match, &op->dev);
        if (!match)
@@ -653,6 +656,21 @@ static int fsl_i2c_probe(struct platform_device *op)
                }
        }
 
+       /*
+        * enable clock for the I2C peripheral (non fatal),
+        * keep a reference upon successful allocation
+        */
+       clk = devm_clk_get(&op->dev, NULL);
+       if (!IS_ERR(clk)) {
+               err = clk_prepare_enable(clk);
+               if (err) {
+                       dev_err(&op->dev, "failed to enable clock\n");
+                       goto fail_request;
+               } else {
+                       i2c->clk_per = clk;
+               }
+       }
+
        if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) {
                clock = MPC_I2C_CLOCK_PRESERVE;
        } else {
@@ -682,6 +700,9 @@ static int fsl_i2c_probe(struct platform_device *op)
        platform_set_drvdata(op, i2c);
 
        i2c->adap = mpc_ops;
+       of_address_to_resource(op->dev.of_node, 0, &res);
+       scnprintf(i2c->adap.name, sizeof(i2c->adap.name),
+                 "MPC adapter at 0x%llx", (unsigned long long)res.start);
        i2c_set_adapdata(&i2c->adap, i2c);
        i2c->adap.dev.parent = &op->dev;
        i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
@@ -691,11 +712,12 @@ static int fsl_i2c_probe(struct platform_device *op)
                dev_err(i2c->dev, "failed to add adapter\n");
                goto fail_add;
        }
-       of_i2c_register_devices(&i2c->adap);
 
        return result;
 
  fail_add:
+       if (i2c->clk_per)
+               clk_disable_unprepare(i2c->clk_per);
        free_irq(i2c->irq, i2c);
  fail_request:
        irq_dispose_mapping(i2c->irq);
@@ -711,6 +733,9 @@ static int fsl_i2c_remove(struct platform_device *op)
 
        i2c_del_adapter(&i2c->adap);
 
+       if (i2c->clk_per)
+               clk_disable_unprepare(i2c->clk_per);
+
        if (i2c->irq)
                free_irq(i2c->irq, i2c);
 
@@ -720,7 +745,7 @@ static int fsl_i2c_remove(struct platform_device *op)
        return 0;
 };
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int mpc_i2c_suspend(struct device *dev)
 {
        struct mpc_i2c *i2c = dev_get_drvdata(dev);
@@ -741,7 +766,10 @@ static int mpc_i2c_resume(struct device *dev)
        return 0;
 }
 
-SIMPLE_DEV_PM_OPS(mpc_i2c_pm_ops, mpc_i2c_suspend, mpc_i2c_resume);
+static SIMPLE_DEV_PM_OPS(mpc_i2c_pm_ops, mpc_i2c_suspend, mpc_i2c_resume);
+#define MPC_I2C_PM_OPS (&mpc_i2c_pm_ops)
+#else
+#define MPC_I2C_PM_OPS NULL
 #endif
 
 static const struct mpc_i2c_data mpc_i2c_data_512x = {
@@ -788,9 +816,7 @@ static struct platform_driver mpc_i2c_driver = {
                .owner = THIS_MODULE,
                .name = DRV_NAME,
                .of_match_table = mpc_i2c_of_match,
-#ifdef CONFIG_PM
-               .pm = &mpc_i2c_pm_ops,
-#endif
+               .pm = MPC_I2C_PM_OPS,
        },
 };
 
index b1f42bf409638f166f592eba381ac9848dccb46a..7f3a4744349476f941a4500c9edc6a65a6da0fe2 100644 (file)
@@ -21,9 +21,9 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
-#include <linux/of_i2c.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 #define MV64XXX_I2C_ADDR_ADDR(val)                     ((val & 0x7f) << 1)
 #define MV64XXX_I2C_BAUD_DIV_N(val)                    (val & 0x7)
 #define        MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK        0xe8
 #define        MV64XXX_I2C_STATUS_NO_STATUS                    0xf8
 
+/* Register defines (I2C bridge) */
+#define        MV64XXX_I2C_REG_TX_DATA_LO                      0xc0
+#define        MV64XXX_I2C_REG_TX_DATA_HI                      0xc4
+#define        MV64XXX_I2C_REG_RX_DATA_LO                      0xc8
+#define        MV64XXX_I2C_REG_RX_DATA_HI                      0xcc
+#define        MV64XXX_I2C_REG_BRIDGE_CONTROL                  0xd0
+#define        MV64XXX_I2C_REG_BRIDGE_STATUS                   0xd4
+#define        MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE               0xd8
+#define        MV64XXX_I2C_REG_BRIDGE_INTR_MASK                0xdC
+#define        MV64XXX_I2C_REG_BRIDGE_TIMING                   0xe0
+
+/* Bridge Control values */
+#define        MV64XXX_I2C_BRIDGE_CONTROL_WR                   0x00000001
+#define        MV64XXX_I2C_BRIDGE_CONTROL_RD                   0x00000002
+#define        MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT           2
+#define        MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT             0x00001000
+#define        MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT        13
+#define        MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT        16
+#define        MV64XXX_I2C_BRIDGE_CONTROL_ENABLE               0x00080000
+
+/* Bridge Status values */
+#define        MV64XXX_I2C_BRIDGE_STATUS_ERROR                 0x00000001
+#define        MV64XXX_I2C_STATUS_OFFLOAD_ERROR                0xf0000001
+#define        MV64XXX_I2C_STATUS_OFFLOAD_OK                   0xf0000000
+
+
 /* Driver states */
 enum {
        MV64XXX_I2C_STATE_INVALID,
@@ -71,14 +97,17 @@ enum {
 enum {
        MV64XXX_I2C_ACTION_INVALID,
        MV64XXX_I2C_ACTION_CONTINUE,
+       MV64XXX_I2C_ACTION_OFFLOAD_SEND_START,
        MV64XXX_I2C_ACTION_SEND_START,
        MV64XXX_I2C_ACTION_SEND_RESTART,
+       MV64XXX_I2C_ACTION_OFFLOAD_RESTART,
        MV64XXX_I2C_ACTION_SEND_ADDR_1,
        MV64XXX_I2C_ACTION_SEND_ADDR_2,
        MV64XXX_I2C_ACTION_SEND_DATA,
        MV64XXX_I2C_ACTION_RCV_DATA,
        MV64XXX_I2C_ACTION_RCV_DATA_STOP,
        MV64XXX_I2C_ACTION_SEND_STOP,
+       MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP,
 };
 
 struct mv64xxx_i2c_regs {
@@ -117,6 +146,9 @@ struct mv64xxx_i2c_data {
        spinlock_t              lock;
        struct i2c_msg          *msg;
        struct i2c_adapter      adapter;
+       bool                    offload_enabled;
+/* 5us delay in order to avoid repeated start timing violation */
+       bool                    errata_delay;
 };
 
 static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -165,6 +197,77 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
        }
 }
 
+static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data)
+{
+       unsigned long data_reg_hi = 0;
+       unsigned long data_reg_lo = 0;
+       unsigned long ctrl_reg;
+       struct i2c_msg *msg = drv_data->msgs;
+
+       drv_data->msg = msg;
+       drv_data->byte_posn = 0;
+       drv_data->bytes_left = msg->len;
+       drv_data->aborting = 0;
+       drv_data->rc = 0;
+       /* Only regular transactions can be offloaded */
+       if ((msg->flags & ~(I2C_M_TEN | I2C_M_RD)) != 0)
+               return -EINVAL;
+
+       /* Only 1-8 byte transfers can be offloaded */
+       if (msg->len < 1 || msg->len > 8)
+               return -EINVAL;
+
+       /* Build transaction */
+       ctrl_reg = MV64XXX_I2C_BRIDGE_CONTROL_ENABLE |
+                  (msg->addr << MV64XXX_I2C_BRIDGE_CONTROL_ADDR_SHIFT);
+
+       if ((msg->flags & I2C_M_TEN) != 0)
+               ctrl_reg |=  MV64XXX_I2C_BRIDGE_CONTROL_ADDR_EXT;
+
+       if ((msg->flags & I2C_M_RD) == 0) {
+               u8 local_buf[8] = { 0 };
+
+               memcpy(local_buf, msg->buf, msg->len);
+               data_reg_lo = cpu_to_le32(*((u32 *)local_buf));
+               data_reg_hi = cpu_to_le32(*((u32 *)(local_buf+4)));
+
+               ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_WR |
+                   (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_TX_SIZE_SHIFT;
+
+               writel_relaxed(data_reg_lo,
+                       drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_LO);
+               writel_relaxed(data_reg_hi,
+                       drv_data->reg_base + MV64XXX_I2C_REG_TX_DATA_HI);
+
+       } else {
+               ctrl_reg |= MV64XXX_I2C_BRIDGE_CONTROL_RD |
+                   (msg->len - 1) << MV64XXX_I2C_BRIDGE_CONTROL_RX_SIZE_SHIFT;
+       }
+
+       /* Execute transaction */
+       writel(ctrl_reg, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL);
+
+       return 0;
+}
+
+static void
+mv64xxx_i2c_update_offload_data(struct mv64xxx_i2c_data *drv_data)
+{
+       struct i2c_msg *msg = drv_data->msg;
+
+       if (msg->flags & I2C_M_RD) {
+               u32 data_reg_lo = readl(drv_data->reg_base +
+                               MV64XXX_I2C_REG_RX_DATA_LO);
+               u32 data_reg_hi = readl(drv_data->reg_base +
+                               MV64XXX_I2C_REG_RX_DATA_HI);
+               u8 local_buf[8] = { 0 };
+
+               *((u32 *)local_buf) = le32_to_cpu(data_reg_lo);
+               *((u32 *)(local_buf+4)) = le32_to_cpu(data_reg_hi);
+               memcpy(msg->buf, local_buf, msg->len);
+       }
+
+}
 /*
  *****************************************************************************
  *
@@ -177,6 +280,15 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
 static void
 mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
 {
+       if (drv_data->offload_enabled) {
+               writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_CONTROL);
+               writel(0, drv_data->reg_base + MV64XXX_I2C_REG_BRIDGE_TIMING);
+               writel(0, drv_data->reg_base +
+                       MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE);
+               writel(0, drv_data->reg_base +
+                       MV64XXX_I2C_REG_BRIDGE_INTR_MASK);
+       }
+
        writel(0, drv_data->reg_base + drv_data->reg_offsets.soft_reset);
        writel(MV64XXX_I2C_BAUD_DIV_M(drv_data->freq_m) | MV64XXX_I2C_BAUD_DIV_N(drv_data->freq_n),
                drv_data->reg_base + drv_data->reg_offsets.clock);
@@ -283,6 +395,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
                drv_data->rc = -ENXIO;
                break;
 
+       case MV64XXX_I2C_STATUS_OFFLOAD_OK:
+               if (drv_data->send_stop || drv_data->aborting) {
+                       drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP;
+                       drv_data->state = MV64XXX_I2C_STATE_IDLE;
+               } else {
+                       drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_RESTART;
+                       drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_RESTART;
+               }
+               break;
+
        default:
                dev_err(&drv_data->adapter.dev,
                        "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, "
@@ -299,19 +421,29 @@ static void
 mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 {
        switch(drv_data->action) {
+       case MV64XXX_I2C_ACTION_OFFLOAD_RESTART:
+               mv64xxx_i2c_update_offload_data(drv_data);
+               writel(0, drv_data->reg_base +  MV64XXX_I2C_REG_BRIDGE_CONTROL);
+               writel(0, drv_data->reg_base +
+                       MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE);
+               /* FALLTHRU */
        case MV64XXX_I2C_ACTION_SEND_RESTART:
                /* We should only get here if we have further messages */
                BUG_ON(drv_data->num_msgs == 0);
 
-               drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
-               writel(drv_data->cntl_bits,
-                       drv_data->reg_base + drv_data->reg_offsets.control);
-
                drv_data->msgs++;
                drv_data->num_msgs--;
+               if (!(drv_data->offload_enabled &&
+                               mv64xxx_i2c_offload_msg(drv_data))) {
+                       drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
+                       writel(drv_data->cntl_bits,
+                       drv_data->reg_base + drv_data->reg_offsets.control);
 
-               /* Setup for the next message */
-               mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
+                       /* Setup for the next message */
+                       mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
+               }
+               if (drv_data->errata_delay)
+                       udelay(5);
 
                /*
                 * We're never at the start of the message here, and by this
@@ -326,6 +458,12 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                        drv_data->reg_base + drv_data->reg_offsets.control);
                break;
 
+       case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START:
+               if (!mv64xxx_i2c_offload_msg(drv_data))
+                       break;
+               else
+                       drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
+               /* FALLTHRU */
        case MV64XXX_I2C_ACTION_SEND_START:
                writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
                        drv_data->reg_base + drv_data->reg_offsets.control);
@@ -366,6 +504,9 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
                        drv_data->reg_base + drv_data->reg_offsets.control);
                drv_data->block = 0;
+               if (drv_data->errata_delay)
+                       udelay(5);
+
                wake_up(&drv_data->waitq);
                break;
 
@@ -375,6 +516,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                        "mv64xxx_i2c_do_action: Invalid action: %d\n",
                        drv_data->action);
                drv_data->rc = -EIO;
+
                /* FALLTHRU */
        case MV64XXX_I2C_ACTION_SEND_STOP:
                drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
@@ -383,6 +525,15 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
                drv_data->block = 0;
                wake_up(&drv_data->waitq);
                break;
+
+       case MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP:
+               mv64xxx_i2c_update_offload_data(drv_data);
+               writel(0, drv_data->reg_base +  MV64XXX_I2C_REG_BRIDGE_CONTROL);
+               writel(0, drv_data->reg_base +
+                       MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE);
+               drv_data->block = 0;
+               wake_up(&drv_data->waitq);
+               break;
        }
 }
 
@@ -395,6 +546,21 @@ mv64xxx_i2c_intr(int irq, void *dev_id)
        irqreturn_t     rc = IRQ_NONE;
 
        spin_lock_irqsave(&drv_data->lock, flags);
+
+       if (drv_data->offload_enabled) {
+               while (readl(drv_data->reg_base +
+                               MV64XXX_I2C_REG_BRIDGE_INTR_CAUSE)) {
+                       int reg_status = readl(drv_data->reg_base +
+                                       MV64XXX_I2C_REG_BRIDGE_STATUS);
+                       if (reg_status & MV64XXX_I2C_BRIDGE_STATUS_ERROR)
+                               status = MV64XXX_I2C_STATUS_OFFLOAD_ERROR;
+                       else
+                               status = MV64XXX_I2C_STATUS_OFFLOAD_OK;
+                       mv64xxx_i2c_fsm(drv_data, status);
+                       mv64xxx_i2c_do_action(drv_data);
+                       rc = IRQ_HANDLED;
+               }
+       }
        while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
                                                MV64XXX_I2C_REG_CONTROL_IFLG) {
                status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
@@ -459,11 +625,15 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
        unsigned long   flags;
 
        spin_lock_irqsave(&drv_data->lock, flags);
-       mv64xxx_i2c_prepare_for_io(drv_data, msg);
-
-       drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
-       drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+       if (drv_data->offload_enabled) {
+               drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START;
+               drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+       } else {
+               mv64xxx_i2c_prepare_for_io(drv_data, msg);
 
+               drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
+               drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
+       }
        drv_data->send_stop = is_last;
        drv_data->block = 1;
        mv64xxx_i2c_do_action(drv_data);
@@ -521,6 +691,7 @@ static const struct i2c_algorithm mv64xxx_i2c_algo = {
 static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
        { .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
        { .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
+       { .compatible = "marvell,mv78230-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
        {}
 };
 MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
@@ -601,6 +772,15 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
 
        memcpy(&drv_data->reg_offsets, device->data, sizeof(drv_data->reg_offsets));
 
+       /*
+        * For controllers embedded in new SoCs activate the
+        * Transaction Generator support and the errata fix.
+        */
+       if (of_device_is_compatible(np, "marvell,mv78230-i2c")) {
+               drv_data->offload_enabled = true;
+               drv_data->errata_delay = true;
+       }
+
 out:
        return rc;
 #endif
@@ -618,7 +798,7 @@ static int
 mv64xxx_i2c_probe(struct platform_device *pd)
 {
        struct mv64xxx_i2c_data         *drv_data;
-       struct mv64xxx_i2c_pdata        *pdata = pd->dev.platform_data;
+       struct mv64xxx_i2c_pdata        *pdata = dev_get_platdata(&pd->dev);
        struct resource *r;
        int     rc;
 
@@ -654,6 +834,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
                drv_data->freq_n = pdata->freq_n;
                drv_data->irq = platform_get_irq(pd, 0);
                drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
+               drv_data->offload_enabled = false;
                memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
        } else if (pd->dev.of_node) {
                rc = mv64xxx_of_config(drv_data, &pd->dev);
@@ -689,8 +870,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
                goto exit_free_irq;
        }
 
-       of_i2c_register_devices(&drv_data->adapter);
-
        return 0;
 
 exit_free_irq:
index e2e9a0dade9665ec0d89598754c5734d2480c09c..f4a01675fa71b4a18ac2b35714425be363442528 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/stmp_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 
@@ -114,18 +113,21 @@ struct mxs_i2c_dev {
 
        uint32_t timing0;
        uint32_t timing1;
+       uint32_t timing2;
 
        /* DMA support components */
-       struct dma_chan                 *dmach;
+       struct dma_chan                 *dmach;
        uint32_t                        pio_data[2];
        uint32_t                        addr_data;
        struct scatterlist              sg_io[2];
        bool                            dma_read;
 };
 
-static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
+static int mxs_i2c_reset(struct mxs_i2c_dev *i2c)
 {
-       stmp_reset_block(i2c->regs);
+       int ret = stmp_reset_block(i2c->regs);
+       if (ret)
+               return ret;
 
        /*
         * Configure timing for the I2C block. The I2C TIMING2 register has to
@@ -136,9 +138,11 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
         */
        writel(i2c->timing0, i2c->regs + MXS_I2C_TIMING0);
        writel(i2c->timing1, i2c->regs + MXS_I2C_TIMING1);
-       writel(0x00300030, i2c->regs + MXS_I2C_TIMING2);
+       writel(i2c->timing2, i2c->regs + MXS_I2C_TIMING2);
 
        writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
+
+       return 0;
 }
 
 static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c)
@@ -475,7 +479,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
                                int stop)
 {
        struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
-       int ret;
+       int ret, err;
        int flags;
 
        flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
@@ -495,8 +499,11 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
        i2c->cmd_err = 0;
        if (0) {        /* disable PIO mode until a proper fix is made */
                ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);
-               if (ret)
-                       mxs_i2c_reset(i2c);
+               if (ret) {
+                       err = mxs_i2c_reset(i2c);
+                       if (err)
+                               return err;
+               }
        } else {
                INIT_COMPLETION(i2c->cmd_complete);
                ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
@@ -527,7 +534,10 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
 timeout:
        dev_dbg(i2c->dev, "Timeout!\n");
        mxs_i2c_dma_finish(i2c);
-       mxs_i2c_reset(i2c);
+       ret = mxs_i2c_reset(i2c);
+       if (ret)
+               return ret;
+
        return -ETIMEDOUT;
 }
 
@@ -577,41 +587,79 @@ static const struct i2c_algorithm mxs_i2c_algo = {
        .functionality = mxs_i2c_func,
 };
 
-static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed)
+static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, uint32_t speed)
 {
-       /* The I2C block clock run at 24MHz */
+       /* The I2C block clock runs at 24MHz */
        const uint32_t clk = 24000000;
-       uint32_t base;
+       uint32_t divider;
        uint16_t high_count, low_count, rcv_count, xmit_count;
+       uint32_t bus_free, leadin;
        struct device *dev = i2c->dev;
 
-       if (speed > 540000) {
-               dev_warn(dev, "Speed too high (%d Hz), using 540 kHz\n", speed);
-               speed = 540000;
-       } else if (speed < 12000) {
-               dev_warn(dev, "Speed too low (%d Hz), using 12 kHz\n", speed);
-               speed = 12000;
+       divider = DIV_ROUND_UP(clk, speed);
+
+       if (divider < 25) {
+               /*
+                * limit the divider, so that min(low_count, high_count)
+                * is >= 1
+                */
+               divider = 25;
+               dev_warn(dev,
+                       "Speed too high (%u.%03u kHz), using %u.%03u kHz\n",
+                       speed / 1000, speed % 1000,
+                       clk / divider / 1000, clk / divider % 1000);
+       } else if (divider > 1897) {
+               /*
+                * limit the divider, so that max(low_count, high_count)
+                * cannot exceed 1023
+                */
+               divider = 1897;
+               dev_warn(dev,
+                       "Speed too low (%u.%03u kHz), using %u.%03u kHz\n",
+                       speed / 1000, speed % 1000,
+                       clk / divider / 1000, clk / divider % 1000);
        }
 
        /*
-        * The timing derivation algorithm. There is no documentation for this
-        * algorithm available, it was derived by using the scope and fiddling
-        * with constants until the result observed on the scope was good enough
-        * for 20kHz, 50kHz, 100kHz, 200kHz, 300kHz and 400kHz. It should be
-        * possible to assume the algorithm works for other frequencies as well.
+        * The I2C spec specifies the following timing data:
+        *                          standard mode  fast mode Bitfield name
+        * tLOW (SCL LOW period)     4700 ns        1300 ns
+        * tHIGH (SCL HIGH period)   4000 ns         600 ns
+        * tSU;DAT (data setup time)  250 ns         100 ns
+        * tHD;STA (START hold time) 4000 ns         600 ns
+        * tBUF (bus free time)      4700 ns        1300 ns
         *
-        * Note it was necessary to cap the frequency on both ends as it's not
-        * possible to configure completely arbitrary frequency for the I2C bus
-        * clock.
+        * The hardware (of the i.MX28 at least) seems to add 2 additional
+        * clock cycles to the low_count and 7 cycles to the high_count.
+        * This is compensated for by subtracting the respective constants
+        * from the values written to the timing registers.
         */
-       base = ((clk / speed) - 38) / 2;
-       high_count = base + 3;
-       low_count = base - 3;
-       rcv_count = (high_count * 3) / 4;
-       xmit_count = low_count / 4;
+       if (speed > 100000) {
+               /* fast mode */
+               low_count = DIV_ROUND_CLOSEST(divider * 13, (13 + 6));
+               high_count = DIV_ROUND_CLOSEST(divider * 6, (13 + 6));
+               leadin = DIV_ROUND_UP(600 * (clk / 1000000), 1000);
+               bus_free = DIV_ROUND_UP(1300 * (clk / 1000000), 1000);
+       } else {
+               /* normal mode */
+               low_count = DIV_ROUND_CLOSEST(divider * 47, (47 + 40));
+               high_count = DIV_ROUND_CLOSEST(divider * 40, (47 + 40));
+               leadin = DIV_ROUND_UP(4700 * (clk / 1000000), 1000);
+               bus_free = DIV_ROUND_UP(4700 * (clk / 1000000), 1000);
+       }
+       rcv_count = high_count * 3 / 8;
+       xmit_count = low_count * 3 / 8;
+
+       dev_dbg(dev,
+               "speed=%u(actual %u) divider=%u low=%u high=%u xmit=%u rcv=%u leadin=%u bus_free=%u\n",
+               speed, clk / divider, divider, low_count, high_count,
+               xmit_count, rcv_count, leadin, bus_free);
 
+       low_count -= 2;
+       high_count -= 7;
        i2c->timing0 = (high_count << 16) | rcv_count;
        i2c->timing1 = (low_count << 16) | xmit_count;
+       i2c->timing2 = (bus_free << 16 | leadin);
 }
 
 static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
@@ -683,7 +731,9 @@ static int mxs_i2c_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, i2c);
 
        /* Do reset to enforce correct startup after pinmuxing */
-       mxs_i2c_reset(i2c);
+       err = mxs_i2c_reset(i2c);
+       if (err)
+               return err;
 
        adap = &i2c->adapter;
        strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
@@ -701,8 +751,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
                return err;
        }
 
-       of_i2c_register_devices(adap);
-
        return 0;
 }
 
index 512dfe609706a562922986b040a8bda753d82126..8bf9ac01301a5cb6fb2042808f3fdc23b3e5002b 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/pm_runtime.h>
 #include <linux/platform_data/i2c-nomadik.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 #include <linux/pinctrl/consumer.h>
 
 #define DRIVER_NAME "nmk-i2c"
@@ -943,7 +942,7 @@ static void nmk_i2c_of_probe(struct device_node *np,
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
        int ret = 0;
-       struct nmk_i2c_controller *pdata = adev->dev.platform_data;
+       struct nmk_i2c_controller *pdata = dev_get_platdata(&adev->dev);
        struct device_node *np = adev->dev.of_node;
        struct nmk_i2c_dev      *dev;
        struct i2c_adapter *adap;
@@ -1045,8 +1044,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
                goto err_add_adap;
        }
 
-       of_i2c_register_devices(adap);
-
        pm_runtime_put(&adev->dev);
 
        return 0;
index 865ee350adb363cea47f624eb4c2bb909a3b5624..36394d737faf388998b7da4b015bbea134e85709 100644 (file)
@@ -525,7 +525,7 @@ static int nuc900_i2c_probe(struct platform_device *pdev)
        struct resource *res;
        int ret;
 
-       pdata = pdev->dev.platform_data;
+       pdata = dev_get_platdata(&pdev->dev);
        if (!pdata) {
                dev_err(&pdev->dev, "no platform data\n");
                return -EINVAL;
index 0e1f8245e768d91c9fe2c58639607b952b804c57..c61f37a10a074e30f2c3c1e368a602a85e7301b9 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/i2c-ocores.h>
 #include <linux/slab.h>
 #include <linux/io.h>
-#include <linux/of_i2c.h>
 #include <linux/log2.h>
 
 struct ocores_i2c {
@@ -353,10 +352,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        int ret;
        int i;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENODEV;
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
                return irq;
@@ -365,11 +360,12 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        if (!i2c)
                return -ENOMEM;
 
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        i2c->base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(i2c->base))
                return PTR_ERR(i2c->base);
 
-       pdata = pdev->dev.platform_data;
+       pdata = dev_get_platdata(&pdev->dev);
        if (pdata) {
                i2c->reg_shift = pdata->reg_shift;
                i2c->reg_io_width = pdata->reg_io_width;
@@ -435,8 +431,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        if (pdata) {
                for (i = 0; i < pdata->num_devices; i++)
                        i2c_new_device(&i2c->adap, pdata->devices + i);
-       } else {
-               of_i2c_register_devices(&i2c->adap);
        }
 
        return 0;
@@ -456,7 +450,7 @@ static int ocores_i2c_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ocores_i2c_suspend(struct device *dev)
 {
        struct ocores_i2c *i2c = dev_get_drvdata(dev);
index 956fe320f313d84c4a0371c32d858192ad7742f1..b929ba271b4705714f846fa07aae3d9116fcada3 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -599,8 +598,6 @@ static int octeon_i2c_probe(struct platform_device *pdev)
        }
        dev_info(i2c->dev, "version %s\n", DRV_VERSION);
 
-       of_i2c_register_devices(&i2c->adap);
-
        return 0;
 
 out:
index 142b694d1c60a1ca528860a03b45c1a913dcb145..6d8308d5dc4e915c4584e2d5d9b3e5690882a2b9 100644 (file)
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/i2c-omap.h>
 #include <linux/pm_runtime.h>
-#include <linux/pinctrl/consumer.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2           0x20
@@ -216,8 +214,6 @@ struct omap_i2c_dev {
        u16                     syscstate;
        u16                     westate;
        u16                     errata;
-
-       struct pinctrl          *pins;
 };
 
 static const u8 reg_map_ip_v1[] = {
@@ -618,11 +614,10 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
        if (dev->cmd_err & OMAP_I2C_STAT_NACK) {
                if (msg->flags & I2C_M_IGNORE_NAK)
                        return 0;
-               if (stop) {
-                       w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
-                       w |= OMAP_I2C_CON_STP;
-                       omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
-               }
+
+               w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG);
+               w |= OMAP_I2C_CON_STP;
+               omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w);
                return -EREMOTEIO;
        }
        return -EIO;
@@ -1079,7 +1074,7 @@ omap_i2c_probe(struct platform_device *pdev)
        struct i2c_adapter      *adap;
        struct resource         *mem;
        const struct omap_i2c_bus_platform_data *pdata =
-               pdev->dev.platform_data;
+               dev_get_platdata(&pdev->dev);
        struct device_node      *node = pdev->dev.of_node;
        const struct of_device_id *match;
        int irq;
@@ -1120,16 +1115,6 @@ omap_i2c_probe(struct platform_device *pdev)
                dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
        }
 
-       dev->pins = devm_pinctrl_get_select_default(&pdev->dev);
-       if (IS_ERR(dev->pins)) {
-               if (PTR_ERR(dev->pins) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-
-               dev_warn(&pdev->dev, "did not get pins for i2c error: %li\n",
-                        PTR_ERR(dev->pins));
-               dev->pins = NULL;
-       }
-
        dev->dev = &pdev->dev;
        dev->irq = irq;
 
@@ -1245,8 +1230,6 @@ omap_i2c_probe(struct platform_device *pdev)
        dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n", adap->nr,
                 major, minor, dev->speed);
 
-       of_i2c_register_devices(adap);
-
        pm_runtime_mark_last_busy(dev->dev);
        pm_runtime_put_autosuspend(dev->dev);
 
index aa00df14e30b1a0114be4396b931ce4a32b523d9..39e2755e3f257c09bd1edd76371130fd8df0ceda 100644 (file)
@@ -136,7 +136,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
        struct i2c_pca_pf_data *i2c;
        struct resource *res;
        struct i2c_pca9564_pf_platform_data *platform_data =
-                               pdev->dev.platform_data;
+                               dev_get_platdata(&pdev->dev);
        int ret = 0;
        int irq;
 
index d05ad590af29b5163e0920a8d7868a31d8ec0529..a028617b8f13c37a4a8371264a149ba7f6d44540 100644 (file)
@@ -231,11 +231,11 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,
 }
 
 static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
-                            const struct pci_device_id *id)
+                            const struct pci_device_id *id, u8 aux)
 {
        unsigned short piix4_smba;
        unsigned short smba_idx = 0xcd6;
-       u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c;
+       u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en;
 
        /* SB800 and later SMBus does not support forcing address */
        if (force || force_addr) {
@@ -245,6 +245,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
        }
 
        /* Determine the address of the SMBus areas */
+       smb_en = (aux) ? 0x28 : 0x2c;
+
        if (!request_region(smba_idx, 2, "smba_idx")) {
                dev_err(&PIIX4_dev->dev, "SMBus base address index region "
                        "0x%x already in use!\n", smba_idx);
@@ -272,6 +274,13 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
                return -EBUSY;
        }
 
+       /* Aux SMBus does not support IRQ information */
+       if (aux) {
+               dev_info(&PIIX4_dev->dev,
+                        "SMBus Host Controller at 0x%x\n", piix4_smba);
+               return piix4_smba;
+       }
+
        /* Request the SMBus I2C bus config region */
        if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
                dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
@@ -597,7 +606,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
             dev->revision >= 0x40) ||
            dev->vendor == PCI_VENDOR_ID_AMD)
                /* base address location etc changed in SB800 */
-               retval = piix4_setup_sb800(dev, id);
+               retval = piix4_setup_sb800(dev, id, 0);
        else
                retval = piix4_setup(dev, id);
 
@@ -611,17 +620,29 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
                return retval;
 
        /* Check for auxiliary SMBus on some AMD chipsets */
+       retval = -ENODEV;
+
        if (dev->vendor == PCI_VENDOR_ID_ATI &&
-           dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
-           dev->revision < 0x40) {
-               retval = piix4_setup_aux(dev, id, 0x58);
-               if (retval > 0) {
-                       /* Try to add the aux adapter if it exists,
-                        * piix4_add_adapter will clean up if this fails */
-                       piix4_add_adapter(dev, retval, &piix4_aux_adapter);
+           dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) {
+               if (dev->revision < 0x40) {
+                       retval = piix4_setup_aux(dev, id, 0x58);
+               } else {
+                       /* SB800 added aux bus too */
+                       retval = piix4_setup_sb800(dev, id, 1);
                }
        }
 
+       if (dev->vendor == PCI_VENDOR_ID_AMD &&
+           dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) {
+               retval = piix4_setup_sb800(dev, id, 1);
+       }
+
+       if (retval > 0) {
+               /* Try to add the aux adapter if it exists,
+                * piix4_add_adapter will clean up if this fails */
+               piix4_add_adapter(dev, retval, &piix4_aux_adapter);
+       }
+
        return 0;
 }
 
index 5f39c6d8117a063b41406f589ccb722d85f4b9c9..1a9ea25f23142847e1ea57cbd53cdb39cff34322 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 
 #define I2C_PNX_TIMEOUT_DEFAULT                10 /* msec */
 #define I2C_PNX_SPEED_KHZ_DEFAULT      100
@@ -595,7 +594,7 @@ static struct i2c_algorithm pnx_algorithm = {
        .functionality = i2c_pnx_func,
 };
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int i2c_pnx_controller_suspend(struct device *dev)
 {
        struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(dev);
@@ -727,7 +726,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
        alg_data->irq = platform_get_irq(pdev, 0);
        if (alg_data->irq < 0) {
                dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n");
-               goto out_irq;
+               ret = alg_data->irq;
+               goto out_clock;
        }
        ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
                        0, pdev->name, alg_data);
@@ -741,8 +741,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
                goto out_irq;
        }
 
-       of_i2c_register_devices(&alg_data->adapter);
-
        dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
                alg_data->adapter.name, res->start, alg_data->irq);
 
index 8dc90da1e6e657b6f0ca58d91bba9dda6c29a7e7..37e8cfad625b9c87101d7dd9916d5cb7787d84ae 100644 (file)
@@ -398,7 +398,7 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap,
 
 static int i2c_powermac_probe(struct platform_device *dev)
 {
-       struct pmac_i2c_bus *bus = dev->dev.platform_data;
+       struct pmac_i2c_bus *bus = dev_get_platdata(&dev->dev);
        struct device_node *parent = NULL;
        struct i2c_adapter *adapter;
        const char *basename;
@@ -440,22 +440,24 @@ static int i2c_powermac_probe(struct platform_device *dev)
        adapter->algo = &i2c_powermac_algorithm;
        i2c_set_adapdata(adapter, bus);
        adapter->dev.parent = &dev->dev;
-       adapter->dev.of_node = dev->dev.of_node;
+
+       /* Clear of_node to skip automatic registration of i2c child nodes */
+       adapter->dev.of_node = NULL;
        rc = i2c_add_adapter(adapter);
        if (rc) {
                printk(KERN_ERR "i2c-powermac: Adapter %s registration "
                       "failed\n", adapter->name);
                memset(adapter, 0, sizeof(*adapter));
+               return rc;
        }
 
        printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
 
-       /* Cannot use of_i2c_register_devices() due to Apple device-tree
-        * funkyness
-        */
+       /* Use custom child registration due to Apple device-tree funkyness */
+       adapter->dev.of_node = dev->dev.of_node;
        i2c_powermac_register_devices(adapter, bus);
 
-       return rc;
+       return 0;
 }
 
 static struct platform_driver i2c_powermac_driver = {
index 37a84c87c5fdd3fe31df3007afe959be7f98c289..ac80199885bef383c1a394ffbdbff335ab529b5d 100644 (file)
@@ -245,7 +245,7 @@ static int puv3_i2c_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int puv3_i2c_suspend(struct device *dev)
 {
        int poll_count;
index fbafed29fb8153ba404c27c8ec5183a4e82520ff..bbe6dfbc5c05da4917ad0d295f2c32659ce29dfc 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/i2c-pxa.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/clk.h>
@@ -110,6 +109,8 @@ MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
 #define ICR_SADIE      (1 << 13)          /* slave address detected int enable */
 #define ICR_UR         (1 << 14)          /* unit reset */
 #define ICR_FM         (1 << 15)          /* fast mode */
+#define ICR_HS         (1 << 16)          /* High Speed mode */
+#define ICR_GPIOEN     (1 << 19)          /* enable GPIO mode for SCL in HS */
 
 #define ISR_RWM                (1 << 0)           /* read/write mode */
 #define ISR_ACKNAK     (1 << 1)           /* ack/nak status */
@@ -155,6 +156,10 @@ struct pxa_i2c {
        int                     irq;
        unsigned int            use_pio :1;
        unsigned int            fast_mode :1;
+       unsigned int            high_mode:1;
+       unsigned char           master_code;
+       unsigned long           rate;
+       bool                    highmode_enter;
 };
 
 #define _IBMR(i2c)     ((i2c)->reg_ibmr)
@@ -459,6 +464,7 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 
        /* set control register values */
        writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
+       writel(readl(_ICR(i2c)) | (i2c->high_mode ? ICR_HS : 0), _ICR(i2c));
 
 #ifdef CONFIG_I2C_PXA_SLAVE
        dev_info(&i2c->adap.dev, "Enabling slave mode\n");
@@ -680,6 +686,34 @@ static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
        return 0;
 }
 
+/*
+ * PXA I2C send master code
+ * 1. Load master code to IDBR and send it.
+ *    Note for HS mode, set ICR [GPIOEN].
+ * 2. Wait until win arbitration.
+ */
+static int i2c_pxa_send_mastercode(struct pxa_i2c *i2c)
+{
+       u32 icr;
+       long timeout;
+
+       spin_lock_irq(&i2c->lock);
+       i2c->highmode_enter = true;
+       writel(i2c->master_code, _IDBR(i2c));
+
+       icr = readl(_ICR(i2c)) & ~(ICR_STOP | ICR_ALDIE);
+       icr |= ICR_GPIOEN | ICR_START | ICR_TB | ICR_ITEIE;
+       writel(icr, _ICR(i2c));
+
+       spin_unlock_irq(&i2c->lock);
+       timeout = wait_event_timeout(i2c->wait,
+                       i2c->highmode_enter == false, HZ * 1);
+
+       i2c->highmode_enter = false;
+
+       return (timeout == 0) ? I2C_RETRY : 0;
+}
+
 static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
                               struct i2c_msg *msg, int num)
 {
@@ -743,6 +777,14 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
                goto out;
        }
 
+       if (i2c->high_mode) {
+               ret = i2c_pxa_send_mastercode(i2c);
+               if (ret) {
+                       dev_err(&i2c->adap.dev, "i2c_pxa_send_mastercode timeout\n");
+                       goto out;
+                       }
+       }
+
        spin_lock_irq(&i2c->lock);
 
        i2c->msg = msg;
@@ -990,11 +1032,14 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
                        i2c_pxa_slave_txempty(i2c, isr);
                if (isr & ISR_IRF)
                        i2c_pxa_slave_rxfull(i2c, isr);
-       } else if (i2c->msg) {
+       } else if (i2c->msg && (!i2c->highmode_enter)) {
                if (isr & ISR_ITE)
                        i2c_pxa_irq_txempty(i2c, isr);
                if (isr & ISR_IRF)
                        i2c_pxa_irq_rxfull(i2c, isr);
+       } else if ((isr & ISR_ITE) && i2c->highmode_enter) {
+               i2c->highmode_enter = false;
+               wake_up(&i2c->wait);
        } else {
                i2c_pxa_scream_blue_murder(i2c, "spurious irq");
        }
@@ -1072,20 +1117,25 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
                               struct pxa_i2c *i2c,
                               enum pxa_i2c_types *i2c_types)
 {
-       struct i2c_pxa_platform_data *plat = pdev->dev.platform_data;
+       struct i2c_pxa_platform_data *plat = dev_get_platdata(&pdev->dev);
        const struct platform_device_id *id = platform_get_device_id(pdev);
 
        *i2c_types = id->driver_data;
        if (plat) {
                i2c->use_pio = plat->use_pio;
                i2c->fast_mode = plat->fast_mode;
+               i2c->high_mode = plat->high_mode;
+               i2c->master_code = plat->master_code;
+               if (!i2c->master_code)
+                       i2c->master_code = 0xe;
+               i2c->rate = plat->rate;
        }
        return 0;
 }
 
 static int i2c_pxa_probe(struct platform_device *dev)
 {
-       struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
+       struct i2c_pxa_platform_data *plat = dev_get_platdata(&dev->dev);
        enum pxa_i2c_types i2c_type;
        struct pxa_i2c *i2c;
        struct resource *res = NULL;
@@ -1151,6 +1201,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
        i2c->irq = irq;
 
        i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
+       i2c->highmode_enter = false;
 
        if (plat) {
 #ifdef CONFIG_I2C_PXA_SLAVE
@@ -1160,6 +1211,16 @@ static int i2c_pxa_probe(struct platform_device *dev)
                i2c->adap.class = plat->class;
        }
 
+       if (i2c->high_mode) {
+               if (i2c->rate) {
+                       clk_set_rate(i2c->clk, i2c->rate);
+                       pr_info("i2c: <%s> set rate to %ld\n",
+                               i2c->adap.name, clk_get_rate(i2c->clk));
+               } else
+                       pr_warn("i2c: <%s> clock rate not set\n",
+                               i2c->adap.name);
+       }
+
        clk_prepare_enable(i2c->clk);
 
        if (i2c->use_pio) {
@@ -1185,7 +1246,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
                printk(KERN_INFO "I2C: Failed to add bus\n");
                goto eadapt;
        }
-       of_i2c_register_devices(&i2c->adap);
 
        platform_set_drvdata(dev, i2c);
 
index 0fc585861610dd484fae778a729733df5e61c5d8..d2fe11da5e82a43cdc80c9fc9446aeb1e7c7fa0b 100644 (file)
@@ -101,6 +101,11 @@ enum {
 #define ID_ARBLOST     (1 << 3)
 #define ID_NACK                (1 << 4)
 
+enum rcar_i2c_type {
+       I2C_RCAR_H1,
+       I2C_RCAR_H2,
+};
+
 struct rcar_i2c_priv {
        void __iomem *io;
        struct i2c_adapter adap;
@@ -113,6 +118,7 @@ struct rcar_i2c_priv {
        int irq;
        u32 icccr;
        u32 flags;
+       enum rcar_i2c_type      devtype;
 };
 
 #define rcar_i2c_priv_to_dev(p)                ((p)->adap.dev.parent)
@@ -224,12 +230,25 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
        u32 scgd, cdf;
        u32 round, ick;
        u32 scl;
+       u32 cdf_width;
 
        if (!clkp) {
                dev_err(dev, "there is no peripheral_clk\n");
                return -EIO;
        }
 
+       switch (priv->devtype) {
+       case I2C_RCAR_H1:
+               cdf_width = 2;
+               break;
+       case I2C_RCAR_H2:
+               cdf_width = 3;
+               break;
+       default:
+               dev_err(dev, "device type error\n");
+               return -EIO;
+       }
+
        /*
         * calculate SCL clock
         * see
@@ -245,7 +264,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
         * clkp : peripheral_clk
         * F[]  : integer up-valuation
         */
-       for (cdf = 0; cdf < 4; cdf++) {
+       for (cdf = 0; cdf < (1 << cdf_width); cdf++) {
                ick = clk_get_rate(clkp) / (1 + cdf);
                if (ick < 20000000)
                        goto ick_find;
@@ -287,7 +306,7 @@ scgd_find:
        /*
         * keep icccr value
         */
-       priv->icccr = (scgd << 2 | cdf);
+       priv->icccr = (scgd << (cdf_width) | cdf);
 
        return 0;
 }
@@ -615,7 +634,7 @@ static const struct i2c_algorithm rcar_i2c_algo = {
 
 static int rcar_i2c_probe(struct platform_device *pdev)
 {
-       struct i2c_rcar_platform_data *pdata = pdev->dev.platform_data;
+       struct i2c_rcar_platform_data *pdata = dev_get_platdata(&pdev->dev);
        struct rcar_i2c_priv *priv;
        struct i2c_adapter *adap;
        struct resource *res;
@@ -632,6 +651,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
        bus_speed = 100000; /* default 100 kHz */
        if (pdata && pdata->bus_speed)
                bus_speed = pdata->bus_speed;
+
+       priv->devtype = platform_get_device_id(pdev)->driver_data;
+
        ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
        if (ret < 0)
                return ret;
@@ -686,6 +708,14 @@ static int rcar_i2c_remove(struct platform_device *pdev)
        return 0;
 }
 
+static struct platform_device_id rcar_i2c_id_table[] = {
+       { "i2c-rcar",           I2C_RCAR_H1 },
+       { "i2c-rcar_h1",        I2C_RCAR_H1 },
+       { "i2c-rcar_h2",        I2C_RCAR_H2 },
+       {},
+};
+MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table);
+
 static struct platform_driver rcar_i2c_driver = {
        .driver = {
                .name   = "i2c-rcar",
@@ -693,6 +723,7 @@ static struct platform_driver rcar_i2c_driver = {
        },
        .probe          = rcar_i2c_probe,
        .remove         = rcar_i2c_remove,
+       .id_table       = rcar_i2c_id_table,
 };
 
 module_platform_driver(rcar_i2c_driver);
index cab1c91b75a3a8e300057ef2aaf3e98b6af999d4..3535f3c0f7b43233b09123c89b4727fc302cba3b 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/io.h>
-#include <linux/of_i2c.h>
 #include <linux/of_gpio.h>
 #include <linux/pinctrl/consumer.h>
 
@@ -1033,7 +1032,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
        int ret;
 
        if (!pdev->dev.of_node) {
-               pdata = pdev->dev.platform_data;
+               pdata = dev_get_platdata(&pdev->dev);
                if (!pdata) {
                        dev_err(&pdev->dev, "no platform data\n");
                        return -EINVAL;
@@ -1154,7 +1153,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
-       of_i2c_register_devices(&i2c->adap);
        platform_set_drvdata(pdev, i2c);
 
        pm_runtime_enable(&pdev->dev);
index 7c1ca5aca08807f4510c0f0b6a79a8db41147fb7..dd186a03768431df0a4869c2b55c4e7687e7a4a1 100644 (file)
@@ -290,8 +290,9 @@ static int s6i2c_probe(struct platform_device *dev)
 
        clock = 0;
        bus_num = -1;
-       if (dev->dev.platform_data) {
-               struct s6_i2c_platform_data *pdata = dev->dev.platform_data;
+       if (dev_get_platdata(&dev->dev)) {
+               struct s6_i2c_platform_data *pdata =
+                       dev_get_platdata(&dev->dev);
                bus_num = pdata->bus_num;
                clock = pdata->clock;
        }
index 5351a2f349127919785bc9a58f11256466861fad..5e8f136e233f79d5205a5ef65038474721154b16 100644 (file)
@@ -437,7 +437,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
        struct cami2c *id;
        int ret;
 
-       pd = pdev->dev.platform_data;
+       pd = dev_get_platdata(&pdev->dev);
        if (!pd) {
                dev_err(&pdev->dev, "no platform_data!\n");
                ret = -ENODEV;
index debf745c0268f897d984d21391eed39efbd626fe..55110ddbed1ff4163d48acf20da36b58e2ee2e43 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
@@ -658,7 +657,7 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
 
 static int sh_mobile_i2c_probe(struct platform_device *dev)
 {
-       struct i2c_sh_mobile_platform_data *pdata = dev->dev.platform_data;
+       struct i2c_sh_mobile_platform_data *pdata = dev_get_platdata(&dev->dev);
        struct sh_mobile_i2c_data *pd;
        struct i2c_adapter *adap;
        struct resource *res;
@@ -758,7 +757,6 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
                 "I2C adapter %d with bus speed %lu Hz (L/H=%x/%x)\n",
                 adap->nr, pd->bus_speed, pd->iccl, pd->icch);
 
-       of_i2c_register_devices(adap);
        return 0;
 
  err_all:
index a63c7d50683676f5e01969573ffce373b3ce578f..6784f7f527a432396c1ff49faca4382a81a2fc4d 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
@@ -65,6 +64,8 @@
 #define SIRFSOC_I2C_START              BIT(7)
 
 #define SIRFSOC_I2C_DEFAULT_SPEED 100000
+#define SIRFSOC_I2C_ERR_NOACK      1
+#define SIRFSOC_I2C_ERR_TIMEOUT    2
 
 struct sirfsoc_i2c {
        void __iomem *base;
@@ -143,14 +144,24 @@ static irqreturn_t i2c_sirfsoc_irq(int irq, void *dev_id)
 
        if (i2c_stat & SIRFSOC_I2C_STAT_ERR) {
                /* Error conditions */
-               siic->err_status = 1;
+               siic->err_status = SIRFSOC_I2C_ERR_NOACK;
                writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS);
 
                if (i2c_stat & SIRFSOC_I2C_STAT_NACK)
-                       dev_err(&siic->adapter.dev, "ACK not received\n");
+                       dev_dbg(&siic->adapter.dev, "ACK not received\n");
                else
                        dev_err(&siic->adapter.dev, "I2C error\n");
 
+               /*
+                * Due to hardware ANOMALY, we need to reset I2C earlier after
+                * we get NOACK while accessing non-existing clients, otherwise
+                * we will get errors even we access existing clients later
+                */
+               writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET,
+                               siic->base + SIRFSOC_I2C_CTRL);
+               while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
+                       cpu_relax();
+
                complete(&siic->done);
        } else if (i2c_stat & SIRFSOC_I2C_STAT_CMD_DONE) {
                /* CMD buffer execution complete */
@@ -183,6 +194,10 @@ static void i2c_sirfsoc_set_address(struct sirfsoc_i2c *siic,
        if (msg->flags & I2C_M_RD)
                addr |= 1;
 
+       /* Reverse direction bit */
+       if (msg->flags & I2C_M_REV_DIR_ADDR)
+               addr ^= 1;
+
        writel(addr, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
 }
 
@@ -191,7 +206,6 @@ static int i2c_sirfsoc_xfer_msg(struct sirfsoc_i2c *siic, struct i2c_msg *msg)
        u32 regval = readl(siic->base + SIRFSOC_I2C_CTRL);
        /* timeout waiting for the xfer to finish or fail */
        int timeout = msecs_to_jiffies((msg->len + 1) * 50);
-       int ret = 0;
 
        i2c_sirfsoc_set_address(siic, msg);
 
@@ -200,7 +214,7 @@ static int i2c_sirfsoc_xfer_msg(struct sirfsoc_i2c *siic, struct i2c_msg *msg)
        i2c_sirfsoc_queue_cmd(siic);
 
        if (wait_for_completion_timeout(&siic->done, timeout) == 0) {
-               siic->err_status = 1;
+               siic->err_status = SIRFSOC_I2C_ERR_TIMEOUT;
                dev_err(&siic->adapter.dev, "Transfer timeout\n");
        }
 
@@ -208,16 +222,14 @@ static int i2c_sirfsoc_xfer_msg(struct sirfsoc_i2c *siic, struct i2c_msg *msg)
                siic->base + SIRFSOC_I2C_CTRL);
        writel(0, siic->base + SIRFSOC_I2C_CMD_START);
 
-       if (siic->err_status) {
+       /* i2c control doesn't response, reset it */
+       if (siic->err_status == SIRFSOC_I2C_ERR_TIMEOUT) {
                writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET,
                        siic->base + SIRFSOC_I2C_CTRL);
                while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
                        cpu_relax();
-
-               ret = -EIO;
        }
-
-       return ret;
+       return siic->err_status ? -EAGAIN : 0;
 }
 
 static u32 i2c_sirfsoc_func(struct i2c_adapter *adap)
@@ -321,6 +333,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 
        adap->algo = &i2c_sirfsoc_algo;
        adap->algo_data = siic;
+       adap->retries = 3;
 
        adap->dev.of_node = pdev->dev.of_node;
        adap->dev.parent = &pdev->dev;
@@ -348,7 +361,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 
        if (bitrate < 100000)
                regval =
-                       (2 * ctrl_speed) / (2 * bitrate * 11);
+                       (2 * ctrl_speed) / (bitrate * 11);
        else
                regval = ctrl_speed / (bitrate * 5);
 
@@ -366,8 +379,6 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 
        clk_disable(clk);
 
-       of_i2c_register_devices(adap);
-
        dev_info(&pdev->dev, " I2C adapter ready to operate\n");
 
        return 0;
@@ -416,6 +427,8 @@ static int i2c_sirfsoc_resume(struct device *dev)
 
        clk_enable(siic->clk);
        writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
+       while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
+               cpu_relax();
        writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE,
                siic->base + SIRFSOC_I2C_CTRL);
        writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL);
index d1a6b204af00856748b67e7d42253ebb7c849e3f..f8f6f2e552db29e344b41f4e42d0cbc1ac9fc000 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 
 /* the name of this kernel module */
 #define NAME "stu300"
@@ -884,9 +883,6 @@ stu300_probe(struct platform_device *pdev)
 
        dev->pdev = pdev;
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENOENT;
-
        dev->virtbase = devm_ioremap_resource(&pdev->dev, res);
        dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
                "base %p\n", bus_nr, dev->virtbase);
@@ -936,12 +932,11 @@ stu300_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dev);
        dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n",
                 dev->virtbase, dev->irq);
-       of_i2c_register_devices(adap);
 
        return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int stu300_suspend(struct device *device)
 {
        struct stu300_dev *dev = dev_get_drvdata(device);
index 9aa1b60f7fdd86581e2f694d96a2834e0ecad055..c457cb447c66bdf51911339853b561c273c06082 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
 #include <linux/module.h>
 #include <linux/clk/tegra.h>
@@ -802,8 +801,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
                return ret;
        }
 
-       of_i2c_register_devices(&i2c_dev->adapter);
-
        return 0;
 }
 
index 05106368d405d21c1f4aae261394f25ea7b29d7b..e7d3b755af3bb3771359fcb4110310a8d6359a90 100644 (file)
@@ -54,12 +54,16 @@ static int usb_write(struct i2c_adapter *adapter, int cmd,
 
 static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 {
-       unsigned char status;
+       unsigned char *pstatus;
        struct i2c_msg *pmsg;
-       int i;
+       int i, ret;
 
        dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
 
+       pstatus = kmalloc(sizeof(*pstatus), GFP_KERNEL);
+       if (!pstatus)
+               return -ENOMEM;
+
        for (i = 0 ; i < num ; i++) {
                int cmd = CMD_I2C_IO;
 
@@ -84,7 +88,8 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
                                     pmsg->buf, pmsg->len) != pmsg->len) {
                                dev_err(&adapter->dev,
                                        "failure reading data\n");
-                               return -EREMOTEIO;
+                               ret = -EREMOTEIO;
+                               goto out;
                        }
                } else {
                        /* write data */
@@ -93,36 +98,50 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
                                      pmsg->buf, pmsg->len) != pmsg->len) {
                                dev_err(&adapter->dev,
                                        "failure writing data\n");
-                               return -EREMOTEIO;
+                               ret = -EREMOTEIO;
+                               goto out;
                        }
                }
 
                /* read status */
-               if (usb_read(adapter, CMD_GET_STATUS, 0, 0, &status, 1) != 1) {
+               if (usb_read(adapter, CMD_GET_STATUS, 0, 0, pstatus, 1) != 1) {
                        dev_err(&adapter->dev, "failure reading status\n");
-                       return -EREMOTEIO;
+                       ret = -EREMOTEIO;
+                       goto out;
                }
 
-               dev_dbg(&adapter->dev, "  status = %d\n", status);
-               if (status == STATUS_ADDRESS_NAK)
-                       return -EREMOTEIO;
+               dev_dbg(&adapter->dev, "  status = %d\n", *pstatus);
+               if (*pstatus == STATUS_ADDRESS_NAK) {
+                       ret = -EREMOTEIO;
+                       goto out;
+               }
        }
 
-       return i;
+       ret = i;
+out:
+       kfree(pstatus);
+       return ret;
 }
 
 static u32 usb_func(struct i2c_adapter *adapter)
 {
-       __le32 func;
+       __le32 *pfunc;
+       u32 ret;
+
+       pfunc = kmalloc(sizeof(*pfunc), GFP_KERNEL);
 
        /* get functionality from adapter */
-       if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
-           sizeof(func)) {
+       if (!pfunc || usb_read(adapter, CMD_GET_FUNC, 0, 0, pfunc,
+                              sizeof(*pfunc)) != sizeof(*pfunc)) {
                dev_err(&adapter->dev, "failure reading functionality\n");
-               return 0;
+               ret = 0;
+               goto out;
        }
 
-       return le32_to_cpu(func);
+       ret = le32_to_cpup(pfunc);
+out:
+       kfree(pfunc);
+       return ret;
 }
 
 /* This is the actual algorithm we define */
index f3a8790a07e8fed578c3665c85ab9c085a6101dd..6bb3a89a440f09484082b66fd4b68bda6d439ff7 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/io.h>
-#include <linux/of_i2c.h>
 
 #define I2C_CONTROL    0x00
 #define I2C_CONTROLS   0x00
@@ -108,7 +107,6 @@ static int i2c_versatile_probe(struct platform_device *dev)
        ret = i2c_bit_add_numbered_bus(&i2c->adap);
        if (ret >= 0) {
                platform_set_drvdata(dev, i2c);
-               of_i2c_register_devices(&i2c->adap);
                return 0;
        }
 
index baaa7d15b73e03b265617e276ef8733a68159d8b..c65da3d913a03d11ed13d62c17d7dffb3fb097bf 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/of_i2c.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 
@@ -439,8 +438,6 @@ static int wmt_i2c_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, i2c_dev);
 
-       of_i2c_register_devices(adap);
-
        return 0;
 }
 
index 3d0f0520c1b44718c9fe6f7f2bd3da90f74d0dcf..4c8b368d463b7c77517fb3ed314e4234bd6dafbc 100644 (file)
@@ -40,7 +40,6 @@
 #include <linux/i2c-xiic.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 
 #define DRIVER_NAME "xiic-i2c"
 
@@ -703,7 +702,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
        if (irq < 0)
                goto resource_missing;
 
-       pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
+       pdata = (struct xiic_i2c_platform_data *)dev_get_platdata(&pdev->dev);
 
        i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
        if (!i2c)
@@ -752,8 +751,6 @@ static int xiic_i2c_probe(struct platform_device *pdev)
                        i2c_new_device(&i2c->adap, pdata->devices + i);
        }
 
-       of_i2c_register_devices(&i2c->adap);
-
        return 0;
 
 add_adapter_failed:
index f32ca293ae0e30674a436afb4bc431cdb743de28..29d3f045a2bfbc688beeb79f888cb72d10c3bcd2 100644 (file)
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
    Jean Delvare <khali@linux-fr.org>
    Mux support by Rodolfo Giometti <giometti@enneenne.com> and
-   Michael Lawnick <michael.lawnick.ext@nsn.com> */
+   Michael Lawnick <michael.lawnick.ext@nsn.com>
+   OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
+   (based on a previous patch from Jon Smirl <jonsmirl@gmail.com>) and
+   (c) 2013  Wolfram Sang <wsa@the-dreams.de>
+ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -35,7 +39,9 @@
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/irqflags.h>
@@ -954,6 +960,194 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
        up_read(&__i2c_board_lock);
 }
 
+/* OF support code */
+
+#if IS_ENABLED(CONFIG_OF)
+static void of_i2c_register_devices(struct i2c_adapter *adap)
+{
+       void *result;
+       struct device_node *node;
+
+       /* Only register child devices if the adapter has a node pointer set */
+       if (!adap->dev.of_node)
+               return;
+
+       dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
+
+       for_each_available_child_of_node(adap->dev.of_node, node) {
+               struct i2c_board_info info = {};
+               struct dev_archdata dev_ad = {};
+               const __be32 *addr;
+               int len;
+
+               dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
+
+               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+                       dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
+                               node->full_name);
+                       continue;
+               }
+
+               addr = of_get_property(node, "reg", &len);
+               if (!addr || (len < sizeof(int))) {
+                       dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+                               node->full_name);
+                       continue;
+               }
+
+               info.addr = be32_to_cpup(addr);
+               if (info.addr > (1 << 10) - 1) {
+                       dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+                               info.addr, node->full_name);
+                       continue;
+               }
+
+               info.irq = irq_of_parse_and_map(node, 0);
+               info.of_node = of_node_get(node);
+               info.archdata = &dev_ad;
+
+               if (of_get_property(node, "wakeup-source", NULL))
+                       info.flags |= I2C_CLIENT_WAKE;
+
+               request_module("%s%s", I2C_MODULE_PREFIX, info.type);
+
+               result = i2c_new_device(adap, &info);
+               if (result == NULL) {
+                       dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+                               node->full_name);
+                       of_node_put(node);
+                       irq_dispose_mapping(info.irq);
+                       continue;
+               }
+       }
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+       return dev->of_node == data;
+}
+
+/* must call put_device() when done with returned i2c_client device */
+struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&i2c_bus_type, NULL, node,
+                                        of_dev_node_match);
+       if (!dev)
+               return NULL;
+
+       return i2c_verify_client(dev);
+}
+EXPORT_SYMBOL(of_find_i2c_device_by_node);
+
+/* must call put_device() when done with returned i2c_adapter device */
+struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+       struct device *dev;
+
+       dev = bus_find_device(&i2c_bus_type, NULL, node,
+                                        of_dev_node_match);
+       if (!dev)
+               return NULL;
+
+       return i2c_verify_adapter(dev);
+}
+EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
+#else
+static void of_i2c_register_devices(struct i2c_adapter *adap) { }
+#endif /* CONFIG_OF */
+
+/* ACPI support code */
+
+#if IS_ENABLED(CONFIG_ACPI)
+static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
+{
+       struct i2c_board_info *info = data;
+
+       if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
+               struct acpi_resource_i2c_serialbus *sb;
+
+               sb = &ares->data.i2c_serial_bus;
+               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+                       info->addr = sb->slave_address;
+                       if (sb->access_mode == ACPI_I2C_10BIT_MODE)
+                               info->flags |= I2C_CLIENT_TEN;
+               }
+       } else if (info->irq < 0) {
+               struct resource r;
+
+               if (acpi_dev_resource_interrupt(ares, 0, &r))
+                       info->irq = r.start;
+       }
+
+       /* Tell the ACPI core to skip this resource */
+       return 1;
+}
+
+static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
+                                      void *data, void **return_value)
+{
+       struct i2c_adapter *adapter = data;
+       struct list_head resource_list;
+       struct i2c_board_info info;
+       struct acpi_device *adev;
+       int ret;
+
+       if (acpi_bus_get_device(handle, &adev))
+               return AE_OK;
+       if (acpi_bus_get_status(adev) || !adev->status.present)
+               return AE_OK;
+
+       memset(&info, 0, sizeof(info));
+       info.acpi_node.handle = handle;
+       info.irq = -1;
+
+       INIT_LIST_HEAD(&resource_list);
+       ret = acpi_dev_get_resources(adev, &resource_list,
+                                    acpi_i2c_add_resource, &info);
+       acpi_dev_free_resource_list(&resource_list);
+
+       if (ret < 0 || !info.addr)
+               return AE_OK;
+
+       strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
+       if (!i2c_new_device(adapter, &info)) {
+               dev_err(&adapter->dev,
+                       "failed to add I2C device %s from ACPI\n",
+                       dev_name(&adev->dev));
+       }
+
+       return AE_OK;
+}
+
+/**
+ * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
+ * @adap: pointer to adapter
+ *
+ * Enumerate all I2C slave devices behind this adapter by walking the ACPI
+ * namespace. When a device is found it will be added to the Linux device
+ * model and bound to the corresponding ACPI handle.
+ */
+static void acpi_i2c_register_devices(struct i2c_adapter *adap)
+{
+       acpi_handle handle;
+       acpi_status status;
+
+       handle = ACPI_HANDLE(adap->dev.parent);
+       if (!handle)
+               return;
+
+       status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+                                    acpi_i2c_add_device, NULL,
+                                    adap, NULL);
+       if (ACPI_FAILURE(status))
+               dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
+}
+#else
+static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
+#endif /* CONFIG_ACPI */
+
 static int i2c_do_add_adapter(struct i2c_driver *driver,
                              struct i2c_adapter *adap)
 {
@@ -1058,6 +1252,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 
 exit_recovery:
        /* create pre-declared device nodes */
+       of_i2c_register_devices(adap);
+       acpi_i2c_register_devices(adap);
+
        if (adap->nr < __i2c_first_dynamic_bus_num)
                i2c_scan_static_board_info(adap);
 
@@ -1282,7 +1479,6 @@ void i2c_del_adapter(struct i2c_adapter *adap)
 }
 EXPORT_SYMBOL(i2c_del_adapter);
 
-
 /* ------------------------------------------------------------------------- */
 
 int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
@@ -1665,7 +1861,8 @@ static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
                err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
                                     I2C_SMBUS_BYTE, &dummy);
        else {
-               dev_warn(&adap->dev, "No suitable probing method supported\n");
+               dev_warn(&adap->dev, "No suitable probing method supported for address 0x%02X\n",
+                        addr);
                err = -EOPNOTSUPP;
        }
 
@@ -1825,7 +2022,8 @@ EXPORT_SYMBOL(i2c_get_adapter);
 
 void i2c_put_adapter(struct i2c_adapter *adap)
 {
-       module_put(adap->owner);
+       if (adap)
+               module_put(adap->owner);
 }
 EXPORT_SYMBOL(i2c_put_adapter);
 
index 7409ebb33c47df7166087f937d0d5eb91d9d70c9..797e3117bef7437ef2d6f734431a16e43acaed34 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 
 /* multiplexer per channel data */
 struct i2c_mux_priv {
@@ -185,8 +184,6 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
        dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
                 i2c_adapter_id(&priv->adap));
 
-       of_i2c_register_devices(&priv->adap);
-
        return &priv->adap;
 }
 EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
index 92cdd2323b03f3adc8a3a0303d9f51c2eca23c5f..44d4c6071c15096e19d16433092b7428c113f34f 100644 (file)
@@ -137,7 +137,7 @@ static irqreturn_t smbalert_irq(int irq, void *d)
 static int smbalert_probe(struct i2c_client *ara,
                          const struct i2c_device_id *id)
 {
-       struct i2c_smbus_alert_setup *setup = ara->dev.platform_data;
+       struct i2c_smbus_alert_setup *setup = dev_get_platdata(&ara->dev);
        struct i2c_smbus_alert *alert;
        struct i2c_adapter *adapter = ara->adapter;
        int res;
index 210b6f7b9028af89036341b02de8f7251a7ca996..74b41ae690f3e6dab7271319ed62c436ac30935a 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/i2c-mux.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
@@ -131,7 +130,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
                dev_err(dev, "Cannot find device tree node\n");
                return -ENODEV;
        }
-       if (dev->platform_data) {
+       if (dev_get_platdata(dev)) {
                dev_err(dev, "Platform data is not supported\n");
                return -EINVAL;
        }
index 5a0ce0081dce415b14cd1d40662845fb99c0f7d4..5d4a99ba743e39b21a9483ce2a15aabb41a84934 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
-#include <linux/of_i2c.h>
 #include <linux/of_gpio.h>
 
 struct gpiomux {
@@ -148,12 +147,14 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, mux);
 
-       if (!pdev->dev.platform_data) {
+       if (!dev_get_platdata(&pdev->dev)) {
                ret = i2c_mux_gpio_probe_dt(mux, pdev);
                if (ret < 0)
                        return ret;
-       } else
-               memcpy(&mux->data, pdev->dev.platform_data, sizeof(mux->data));
+       } else {
+               memcpy(&mux->data, dev_get_platdata(&pdev->dev),
+                       sizeof(mux->data));
+       }
 
        /*
         * If a GPIO chip name is provided, the GPIO pin numbers provided are
index 966a18a5d12d2397d2a43f25bcd22a65420cc5e4..c4f08ad311832ed79da7d02d6606342e696b72c1 100644 (file)
@@ -324,7 +324,7 @@ static int pca9541_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        struct i2c_adapter *adap = client->adapter;
-       struct pca954x_platform_data *pdata = client->dev.platform_data;
+       struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
        struct pca9541 *data;
        int force;
        int ret = -ENODEV;
index a531d801dbe47aa8a35461955a57e7320380e9fc..bad5b84a59850f79448b3ace9026eb671d201a37 100644 (file)
@@ -185,7 +185,7 @@ static int pca954x_probe(struct i2c_client *client,
                         const struct i2c_device_id *id)
 {
        struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
-       struct pca954x_platform_data *pdata = client->dev.platform_data;
+       struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev);
        int num, force, class;
        struct pca954x *data;
        int ret = -ENODEV;
index a43c0ce5e3d8728918afa810842292d00efdac8c..69a91732ae6561560ca6286007a10602e0e09ba4 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/i2c-mux.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/i2c-mux-pinctrl.h>
 #include <linux/platform_device.h>
@@ -145,7 +144,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 
        mux->dev = &pdev->dev;
 
-       mux->pdata = pdev->dev.platform_data;
+       mux->pdata = dev_get_platdata(&pdev->dev);
        if (!mux->pdata) {
                ret = i2c_mux_pinctrl_parse_dt(mux, pdev);
                if (ret < 0)
index 617a798d92352e30e5342253f5fcc83aa6b18a5c..9930556052141cdc6f3a0b60da7945ba9de3b7bd 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <linux/clk.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
@@ -67,8 +67,6 @@ static int fimc_is_i2c_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
        pm_runtime_enable(&i2c_adap->dev);
 
-       of_i2c_register_devices(i2c_adap);
-
        return 0;
 }
 
index 967f6a939340ea7ace2eb8826703bf713be4cd9d..2276fdc213c53dd128edb6e0f7b37b28d8654b16 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
index 19f556c5957f5661bbc5b5ccb35575d6e01b97a6..f8c66b434fd612f89b42b7d8c51cd7edb4f71d15 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
index 80e5c13b930de507424d4549e2e968636a58bbaa..78cc76053328c2c8c70bff559f5dc0f903a241df 100644 (file)
@@ -48,12 +48,6 @@ config OF_IRQ
        def_bool y
        depends on !SPARC
 
-config OF_I2C
-       def_tristate I2C
-       depends on I2C
-       help
-         OpenFirmware I2C accessors
-
 config OF_NET
        depends on NETDEVICES
        def_bool y
index 1f9c0c492ef9f57b3e39a71db1dd551ad7b55bf1..efd05102c40533100794b7d6a7626f583a1f0cdc 100644 (file)
@@ -3,7 +3,6 @@ obj-$(CONFIG_OF_FLATTREE) += fdt.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
-obj-$(CONFIG_OF_I2C)   += of_i2c.o
 obj-$(CONFIG_OF_NET)   += of_net.o
 obj-$(CONFIG_OF_SELFTEST) += selftest.o
 obj-$(CONFIG_OF_MDIO)  += of_mdio.o
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
deleted file mode 100644 (file)
index b667264..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * OF helpers for the I2C API
- *
- * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
- *
- * Based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/of.h>
-#include <linux/of_i2c.h>
-#include <linux/of_irq.h>
-#include <linux/module.h>
-
-void of_i2c_register_devices(struct i2c_adapter *adap)
-{
-       void *result;
-       struct device_node *node;
-
-       /* Only register child devices if the adapter has a node pointer set */
-       if (!adap->dev.of_node)
-               return;
-
-       dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
-
-       for_each_available_child_of_node(adap->dev.of_node, node) {
-               struct i2c_board_info info = {};
-               struct dev_archdata dev_ad = {};
-               const __be32 *addr;
-               int len;
-
-               dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
-
-               if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
-                       dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
-                               node->full_name);
-                       continue;
-               }
-
-               addr = of_get_property(node, "reg", &len);
-               if (!addr || (len < sizeof(int))) {
-                       dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
-                               node->full_name);
-                       continue;
-               }
-
-               info.addr = be32_to_cpup(addr);
-               if (info.addr > (1 << 10) - 1) {
-                       dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
-                               info.addr, node->full_name);
-                       continue;
-               }
-
-               info.irq = irq_of_parse_and_map(node, 0);
-               info.of_node = of_node_get(node);
-               info.archdata = &dev_ad;
-
-               if (of_get_property(node, "wakeup-source", NULL))
-                       info.flags |= I2C_CLIENT_WAKE;
-
-               request_module("%s%s", I2C_MODULE_PREFIX, info.type);
-
-               result = i2c_new_device(adap, &info);
-               if (result == NULL) {
-                       dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
-                               node->full_name);
-                       of_node_put(node);
-                       irq_dispose_mapping(info.irq);
-                       continue;
-               }
-       }
-}
-EXPORT_SYMBOL(of_i2c_register_devices);
-
-static int of_dev_node_match(struct device *dev, void *data)
-{
-        return dev->of_node == data;
-}
-
-/* must call put_device() when done with returned i2c_client device */
-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&i2c_bus_type, NULL, node,
-                                        of_dev_node_match);
-       if (!dev)
-               return NULL;
-
-       return i2c_verify_client(dev);
-}
-EXPORT_SYMBOL(of_find_i2c_device_by_node);
-
-/* must call put_device() when done with returned i2c_adapter device */
-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
-{
-       struct device *dev;
-
-       dev = bus_find_device(&i2c_bus_type, NULL, node,
-                                        of_dev_node_match);
-       if (!dev)
-               return NULL;
-
-       return i2c_verify_adapter(dev);
-}
-EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
-
-MODULE_LICENSE("GPL");
index 3c024b40b4f88933ccc024a32feda9e173b17fa9..33d6525cf9960c5b4a36b2114a6f9fffc9ca7711 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
index e988fa935b3c4ad22e5a6e47e8f4ccea0f0e1c3d..2ab11dc38077c89f7c60d767ed1096b909ab6039 100644 (file)
@@ -447,11 +447,13 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
 static inline struct i2c_adapter *
 i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter)
 {
+#if IS_ENABLED(I2C_MUX)
        struct device *parent = adapter->dev.parent;
 
        if (parent != NULL && parent->type == &i2c_adapter_type)
                return to_i2c_adapter(parent);
        else
+#endif
                return NULL;
 }
 
@@ -542,10 +544,24 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
 
 #endif /* I2C */
 
-#if IS_ENABLED(CONFIG_ACPI_I2C)
-extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
+#if IS_ENABLED(CONFIG_OF)
+/* must call put_device() when done with returned i2c_client device */
+extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+
+/* must call put_device() when done with returned i2c_adapter device */
+extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
+
 #else
-static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
-#endif
+
+static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
+{
+       return NULL;
+}
+
+static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+       return NULL;
+}
+#endif /* CONFIG_OF */
 
 #endif /* _LINUX_I2C_H */
index 1a9f65e6ec0f043a4e45ff58c0220db5194e737d..53aab243cbd83437e60caef39ef39502bba9f5ce 100644 (file)
@@ -67,6 +67,9 @@ struct i2c_pxa_platform_data {
        unsigned int            class;
        unsigned int            use_pio :1;
        unsigned int            fast_mode :1;
+       unsigned int            high_mode:1;
+       unsigned char           master_code;
+       unsigned long           rate;
 };
 
 extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h
deleted file mode 100644 (file)
index cfb545c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Generic I2C API implementation for PowerPC.
- *
- * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __LINUX_OF_I2C_H
-#define __LINUX_OF_I2C_H
-
-#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE)
-#include <linux/i2c.h>
-
-extern void of_i2c_register_devices(struct i2c_adapter *adap);
-
-/* must call put_device() when done with returned i2c_client device */
-extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
-
-/* must call put_device() when done with returned i2c_adapter device */
-extern struct i2c_adapter *of_find_i2c_adapter_by_node(
-                                               struct device_node *node);
-
-#else
-static inline void of_i2c_register_devices(struct i2c_adapter *adap)
-{
-       return;
-}
-
-static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
-{
-       return NULL;
-}
-
-/* must call put_device() when done with returned i2c_adapter device */
-static inline struct i2c_adapter *of_find_i2c_adapter_by_node(
-                                               struct device_node *node)
-{
-       return NULL;
-}
-#endif /* CONFIG_OF_I2C */
-
-#endif /* __LINUX_OF_I2C_H */
index 389cbfa6dca79d6100b34e64f57d6bc2514d20f8..46c5b4fdfc5298e61008032fe903c0191f886d31 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/clk.h>
 #include <sound/soc.h>
 
index 1d70e278e9154e7f21d1ba230b4f573ad5b31f95..722afe69169e904798974115292159a89a08ba18 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <linux/module.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <sound/soc.h>