Browse Source

Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

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
  ...
Linus Torvalds 12 years ago
parent
commit
00341b5301
72 changed files with 1060 additions and 610 deletions
  1. 3 13
      Documentation/acpi/enumeration.txt
  2. 4 1
      Documentation/devicetree/bindings/i2c/i2c-imx.txt
  3. 10 0
      Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
  4. 4 3
      Documentation/i2c/busses/i2c-piix4
  5. 1 1
      Documentation/i2c/instantiating-devices
  6. 0 1
      arch/powerpc/platforms/44x/warp.c
  7. 0 6
      drivers/acpi/Kconfig
  8. 0 1
      drivers/acpi/Makefile
  9. 0 103
      drivers/acpi/acpi_i2c.c
  10. 0 1
      drivers/gpu/drm/tilcdc/tilcdc_slave.c
  11. 0 1
      drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
  12. 1 1
      drivers/gpu/host1x/drm/output.c
  13. 1 1
      drivers/i2c/busses/Kconfig
  14. 0 3
      drivers/i2c/busses/i2c-at91.c
  15. 11 5
      drivers/i2c/busses/i2c-bfin-twi.c
  16. 3 2
      drivers/i2c/busses/i2c-cbus-gpio.c
  17. 0 6
      drivers/i2c/busses/i2c-cpm.c
  18. 1 5
      drivers/i2c/busses/i2c-davinci.c
  19. 25 0
      drivers/i2c/busses/i2c-designware-core.c
  20. 12 0
      drivers/i2c/busses/i2c-designware-core.h
  21. 40 6
      drivers/i2c/busses/i2c-designware-platdrv.c
  22. 3 6
      drivers/i2c/busses/i2c-gpio.c
  23. 0 2
      drivers/i2c/busses/i2c-i801.c
  24. 0 4
      drivers/i2c/busses/i2c-ibm_iic.c
  25. 169 59
      drivers/i2c/busses/i2c-imx.c
  26. 1 0
      drivers/i2c/busses/i2c-ismt.c
  27. 35 9
      drivers/i2c/busses/i2c-mpc.c
  28. 193 14
      drivers/i2c/busses/i2c-mv64xxx.c
  29. 82 34
      drivers/i2c/busses/i2c-mxs.c
  30. 1 4
      drivers/i2c/busses/i2c-nomadik.c
  31. 1 1
      drivers/i2c/busses/i2c-nuc900.c
  32. 3 9
      drivers/i2c/busses/i2c-ocores.c
  33. 0 3
      drivers/i2c/busses/i2c-octeon.c
  34. 5 22
      drivers/i2c/busses/i2c-omap.c
  35. 1 1
      drivers/i2c/busses/i2c-pca-platform.c
  36. 31 10
      drivers/i2c/busses/i2c-piix4.c
  37. 3 5
      drivers/i2c/busses/i2c-pnx.c
  38. 8 6
      drivers/i2c/busses/i2c-powermac.c
  39. 1 1
      drivers/i2c/busses/i2c-puv3.c
  40. 65 5
      drivers/i2c/busses/i2c-pxa.c
  41. 34 3
      drivers/i2c/busses/i2c-rcar.c
  42. 1 3
      drivers/i2c/busses/i2c-s3c2410.c
  43. 3 2
      drivers/i2c/busses/i2c-s6000.c
  44. 1 1
      drivers/i2c/busses/i2c-sh7760.c
  45. 1 3
      drivers/i2c/busses/i2c-sh_mobile.c
  46. 26 13
      drivers/i2c/busses/i2c-sirf.c
  47. 1 6
      drivers/i2c/busses/i2c-stu300.c
  48. 0 3
      drivers/i2c/busses/i2c-tegra.c
  49. 34 15
      drivers/i2c/busses/i2c-tiny-usb.c
  50. 0 2
      drivers/i2c/busses/i2c-versatile.c
  51. 0 3
      drivers/i2c/busses/i2c-wmt.c
  52. 1 4
      drivers/i2c/busses/i2c-xiic.c
  53. 202 4
      drivers/i2c/i2c-core.c
  54. 0 3
      drivers/i2c/i2c-mux.c
  55. 1 1
      drivers/i2c/i2c-smbus.c
  56. 1 2
      drivers/i2c/muxes/i2c-arb-gpio-challenge.c
  57. 5 4
      drivers/i2c/muxes/i2c-mux-gpio.c
  58. 1 1
      drivers/i2c/muxes/i2c-mux-pca9541.c
  59. 1 1
      drivers/i2c/muxes/i2c-mux-pca954x.c
  60. 1 2
      drivers/i2c/muxes/i2c-mux-pinctrl.c
  61. 1 3
      drivers/media/platform/exynos4-is/fimc-is-i2c.c
  62. 1 1
      drivers/media/platform/exynos4-is/fimc-is.c
  63. 0 1
      drivers/media/platform/exynos4-is/media-dev.c
  64. 0 6
      drivers/of/Kconfig
  65. 0 1
      drivers/of/Makefile
  66. 0 114
      drivers/of/of_i2c.c
  67. 1 1
      drivers/staging/imx-drm/imx-tve.c
  68. 20 4
      include/linux/i2c.h
  69. 3 0
      include/linux/i2c/pxa-i2c.h
  70. 0 46
      include/linux/of_i2c.h
  71. 1 1
      sound/soc/fsl/imx-sgtl5000.c
  72. 1 1
      sound/soc/fsl/imx-wm8962.c

+ 3 - 13
Documentation/acpi/enumeration.txt

@@ -228,19 +228,9 @@ ACPI handle like:
 I2C serial bus support
 I2C serial bus support
 ~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~
 The slaves behind I2C bus controller only need to add the ACPI IDs like
 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
 Below is an example of how to add ACPI support to the existing mpu3050
 input driver:
 input driver:

+ 4 - 1
Documentation/devicetree/bindings/i2c/i2c-imx.txt

@@ -1,7 +1,10 @@
 * Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX
 * Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX
 
 
 Required properties:
 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
 - reg : Should contain I2C/HS-I2C registers location and length
 - interrupts : Should contain I2C/HS-I2C interrupt
 - interrupts : Should contain I2C/HS-I2C interrupt
 
 

+ 10 - 0
Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt

@@ -5,6 +5,7 @@ Required properties :
 
 
  - reg             : Offset and length of the register set for the device
  - reg             : Offset and length of the register set for the device
  - compatible      : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c"
  - compatible      : Should be "marvell,mv64xxx-i2c" or "allwinner,sun4i-i2c"
+                     or "marvell,mv78230-i2c"
  - interrupts      : The interrupt number
  - interrupts      : The interrupt number
 
 
 Optional properties :
 Optional properties :
@@ -20,3 +21,12 @@ Examples:
 		interrupts = <29>;
 		interrupts = <29>;
 		clock-frequency = <100000>;
 		clock-frequency = <100000>;
 	};
 	};
+
+For the Armada XP:
+
+	i2c@11000 {
+		compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c";
+		reg = <0x11000 0x100>;
+		interrupts = <29>;
+		clock-frequency = <100000>;
+	};

+ 4 - 3
Documentation/i2c/busses/i2c-piix4

@@ -73,9 +73,10 @@ this driver on those mainboards.
 The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are
 The ServerWorks Southbridges, the Intel 440MX, and the Victory66 are
 identical to the PIIX4 in I2C/SMBus support.
 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
 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
 to change the SMBus Interrupt Select register so the SMBus controller uses

+ 1 - 1
Documentation/i2c/instantiating-devices

@@ -19,7 +19,7 @@ i2c_board_info which is registered by calling i2c_register_board_info().
 
 
 Example (from omap2 h4):
 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),
 		I2C_BOARD_INFO("isp1301_omap", 0x2d),
 		.irq		= OMAP_GPIO_IRQ(125),
 		.irq		= OMAP_GPIO_IRQ(125),

+ 0 - 1
arch/powerpc/platforms/44x/warp.c

@@ -16,7 +16,6 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/export.h>
 #include <linux/export.h>
 
 

+ 0 - 6
drivers/acpi/Kconfig

@@ -162,12 +162,6 @@ config ACPI_DOCK
 	  This driver supports ACPI-controlled docking stations and removable
 	  This driver supports ACPI-controlled docking stations and removable
 	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
 	  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
 config ACPI_PROCESSOR
 	tristate "Processor"
 	tristate "Processor"
 	select THERMAL
 	select THERMAL

+ 0 - 1
drivers/acpi/Makefile

@@ -73,7 +73,6 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
-obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
 
 
 # processor has its own "processor." module_param namespace
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
 processor-y			:= processor_driver.o processor_throttling.o

+ 0 - 103
drivers/acpi/acpi_i2c.c

@@ -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);

+ 0 - 1
drivers/gpu/drm/tilcdc/tilcdc_slave.c

@@ -16,7 +16,6 @@
  */
  */
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/consumer.h>
 #include <drm/drm_encoder_slave.h>
 #include <drm/drm_encoder_slave.h>

+ 0 - 1
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c

@@ -16,7 +16,6 @@
  */
  */
 
 
 #include <linux/i2c.h>
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/pinctrl/pinmux.h>
 #include <linux/pinctrl/pinmux.h>

+ 1 - 1
drivers/gpu/host1x/drm/output.c

@@ -9,7 +9,7 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 
 
 #include "drm.h"
 #include "drm.h"
 
 

+ 1 - 1
drivers/i2c/busses/Kconfig

@@ -385,7 +385,7 @@ config I2C_CPM
 
 
 config I2C_DAVINCI
 config I2C_DAVINCI
 	tristate "DaVinci I2C driver"
 	tristate "DaVinci I2C driver"
-	depends on ARCH_DAVINCI
+	depends on ARCH_DAVINCI || ARCH_KEYSTONE
 	help
 	help
 	  Support for TI DaVinci I2C controller driver.
 	  Support for TI DaVinci I2C controller driver.
 
 

+ 0 - 3
drivers/i2c/busses/i2c-at91.c

@@ -28,7 +28,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/platform_data/dma-atmel.h>
 #include <linux/platform_data/dma-atmel.h>
@@ -775,8 +774,6 @@ static int at91_twi_probe(struct platform_device *pdev)
 		return rc;
 		return rc;
 	}
 	}
 
 
-	of_i2c_register_devices(&dev->adapter);
-
 	dev_info(dev->dev, "AT91 i2c bus driver.\n");
 	dev_info(dev->dev, "AT91 i2c bus driver.\n");
 	return 0;
 	return 0;
 }
 }

+ 11 - 5
drivers/i2c/busses/i2c-bfin-twi.c

@@ -582,6 +582,7 @@ static struct i2c_algorithm bfin_twi_algorithm = {
 	.functionality = bfin_twi_functionality,
 	.functionality = bfin_twi_functionality,
 };
 };
 
 
+#ifdef CONFIG_PM_SLEEP
 static int i2c_bfin_twi_suspend(struct device *dev)
 static int i2c_bfin_twi_suspend(struct device *dev)
 {
 {
 	struct bfin_twi_iface *iface = dev_get_drvdata(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,
 static SIMPLE_DEV_PM_OPS(i2c_bfin_twi_pm,
 			 i2c_bfin_twi_suspend, i2c_bfin_twi_resume);
 			 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)
 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->timeout = 5 * HZ;
 	p_adap->retries = 3;
 	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) {
 	if (rc) {
 		dev_err(&pdev->dev, "Can't setup pin mux!\n");
 		dev_err(&pdev->dev, "Can't setup pin mux!\n");
 		goto out_error_pin_mux;
 		goto out_error_pin_mux;
@@ -717,7 +723,7 @@ out_error_add_adapter:
 	free_irq(iface->irq, iface);
 	free_irq(iface->irq, iface);
 out_error_req_irq:
 out_error_req_irq:
 out_error_no_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:
 out_error_pin_mux:
 	iounmap(iface->regs_base);
 	iounmap(iface->regs_base);
 out_error_ioremap:
 out_error_ioremap:
@@ -733,7 +739,7 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
 
 
 	i2c_del_adapter(&(iface->adap));
 	i2c_del_adapter(&(iface->adap));
 	free_irq(iface->irq, iface);
 	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);
 	iounmap(iface->regs_base);
 	kfree(iface);
 	kfree(iface);
 
 
@@ -746,7 +752,7 @@ static struct platform_driver i2c_bfin_twi_driver = {
 	.driver		= {
 	.driver		= {
 		.name	= "i2c-bfin-twi",
 		.name	= "i2c-bfin-twi",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
-		.pm	= &i2c_bfin_twi_pm,
+		.pm	= I2C_BFIN_TWI_PM_OPS,
 	},
 	},
 };
 };
 
 

+ 3 - 2
drivers/i2c/busses/i2c-cbus-gpio.c

@@ -233,8 +233,9 @@ static int cbus_i2c_probe(struct platform_device *pdev)
 		chost->clk_gpio = of_get_gpio(dnode, 0);
 		chost->clk_gpio = of_get_gpio(dnode, 0);
 		chost->dat_gpio = of_get_gpio(dnode, 1);
 		chost->dat_gpio = of_get_gpio(dnode, 1);
 		chost->sel_gpio = of_get_gpio(dnode, 2);
 		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->clk_gpio = pdata->clk_gpio;
 		chost->dat_gpio = pdata->dat_gpio;
 		chost->dat_gpio = pdata->dat_gpio;
 		chost->sel_gpio = pdata->sel_gpio;
 		chost->sel_gpio = pdata->sel_gpio;

+ 0 - 6
drivers/i2c/busses/i2c-cpm.c

@@ -42,7 +42,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_soc.h>
 #include <asm/cpm.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",
 	dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
 		cpm->adap.name);
 		cpm->adap.name);
 
 
-	/*
-	 * register OF I2C devices
-	 */
-	of_i2c_register_devices(&cpm->adap);
-
 	return 0;
 	return 0;
 out_shut:
 out_shut:
 	cpm_i2c_shutdown(cpm);
 	cpm_i2c_shutdown(cpm);

+ 1 - 5
drivers/i2c/busses/i2c-davinci.c

@@ -38,10 +38,7 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/cpufreq.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-
-#include <mach/hardware.h>
 #include <linux/platform_data/i2c-davinci.h>
 #include <linux/platform_data/i2c-davinci.h>
 
 
 /* ----- global defines ----------------------------------------------- */
 /* ----- global defines ----------------------------------------------- */
@@ -665,7 +662,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
 #endif
 #endif
 	dev->dev = &pdev->dev;
 	dev->dev = &pdev->dev;
 	dev->irq = irq->start;
 	dev->irq = irq->start;
-	dev->pdata = dev->dev->platform_data;
+	dev->pdata = dev_get_platdata(&dev->dev);
 	platform_set_drvdata(pdev, dev);
 	platform_set_drvdata(pdev, dev);
 
 
 	if (!dev->pdata && pdev->dev.of_node) {
 	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");
 		dev_err(&pdev->dev, "failure adding adapter\n");
 		goto err_unuse_clocks;
 		goto err_unuse_clocks;
 	}
 	}
-	of_i2c_register_devices(adap);
 
 
 	return 0;
 	return 0;
 
 

+ 25 - 0
drivers/i2c/busses/i2c-designware-core.c

@@ -317,6 +317,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 				47,	/* tLOW = 4.7 us */
 				47,	/* tLOW = 4.7 us */
 				3,	/* tf = 0.3 us */
 				3,	/* tf = 0.3 us */
 				0);	/* No offset */
 				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, hcnt, DW_IC_SS_SCL_HCNT);
 	dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
 	dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
 	dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, 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 */
 				13,	/* tLOW = 1.3 us */
 				3,	/* tf = 0.3 us */
 				3,	/* tf = 0.3 us */
 				0);	/* No offset */
 				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, hcnt, DW_IC_FS_SCL_HCNT);
 	dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
 	dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
 	dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, 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 addr = msgs[dev->msg_write_idx].addr;
 	u32 buf_len = dev->tx_buf_len;
 	u32 buf_len = dev->tx_buf_len;
 	u8 *buf = dev->tx_buf;
 	u8 *buf = dev->tx_buf;
+	bool need_restart = false;
 
 
 	intr_mask = DW_IC_INTR_DEFAULT_MASK;
 	intr_mask = DW_IC_INTR_DEFAULT_MASK;
 
 
@@ -443,6 +455,14 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
 			/* new i2c_msg */
 			/* new i2c_msg */
 			buf = msgs[dev->msg_write_idx].buf;
 			buf = msgs[dev->msg_write_idx].buf;
 			buf_len = msgs[dev->msg_write_idx].len;
 			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);
 		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)
 			    buf_len == 1)
 				cmd |= BIT(9);
 				cmd |= BIT(9);
 
 
+			if (need_restart) {
+				cmd |= BIT(10);
+				need_restart = false;
+			}
+
 			if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
 			if (msgs[dev->msg_write_idx].flags & I2C_M_RD) {
 
 
 				/* avoid rx buffer overrun */
 				/* avoid rx buffer overrun */

+ 12 - 0
drivers/i2c/busses/i2c-designware-core.h

@@ -61,6 +61,14 @@
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
  * @rx_outstanding: current master-rx elements in tx 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 dw_i2c_dev {
 	struct device		*dev;
 	struct device		*dev;
@@ -91,6 +99,10 @@ struct dw_i2c_dev {
 	unsigned int		rx_fifo_depth;
 	unsigned int		rx_fifo_depth;
 	int			rx_outstanding;
 	int			rx_outstanding;
 	u32			sda_hold_time;
 	u32			sda_hold_time;
+	u16			ss_hcnt;
+	u16			ss_lcnt;
+	u16			fs_hcnt;
+	u16			fs_lcnt;
 };
 };
 
 
 #define ACCESS_SWAP		0x00000001
 #define ACCESS_SWAP		0x00000001

+ 40 - 6
drivers/i2c/busses/i2c-designware-platdrv.c

@@ -35,7 +35,6 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.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
 #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)
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
 {
 	struct dw_i2c_dev *dev = platform_get_drvdata(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))
 	if (!ACPI_HANDLE(&pdev->dev))
 		return -ENODEV;
 		return -ENODEV;
@@ -64,6 +87,16 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
 	dev->adapter.nr = -1;
 	dev->adapter.nr = -1;
 	dev->tx_fifo_depth = 32;
 	dev->tx_fifo_depth = 32;
 	dev->rx_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;
 	return 0;
 }
 }
 
 
@@ -172,8 +205,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "failure adding adapter\n");
 		dev_err(&pdev->dev, "failure adding adapter\n");
 		return r;
 		return r;
 	}
 	}
-	of_i2c_register_devices(adap);
-	acpi_i2c_register_devices(adap);
 
 
 	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
 	pm_runtime_use_autosuspend(&pdev->dev);
 	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);
 MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
 #endif
 #endif
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int dw_i2c_suspend(struct device *dev)
 static int dw_i2c_suspend(struct device *dev)
 {
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct platform_device *pdev = to_platform_device(dev);
@@ -228,9 +259,12 @@ static int dw_i2c_resume(struct device *dev)
 
 
 	return 0;
 	return 0;
 }
 }
-#endif
 
 
 static SIMPLE_DEV_PM_OPS(dw_i2c_dev_pm_ops, dw_i2c_suspend, dw_i2c_resume);
 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 */
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:i2c_designware");
 MODULE_ALIAS("platform:i2c_designware");
@@ -242,7 +276,7 @@ static struct platform_driver dw_i2c_driver = {
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 		.of_match_table = of_match_ptr(dw_i2c_of_match),
 		.of_match_table = of_match_ptr(dw_i2c_of_match),
 		.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
 		.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
-		.pm	= &dw_i2c_dev_pm_ops,
+		.pm	= DW_I2C_DEV_PM_OPS,
 	},
 	},
 };
 };
 
 

+ 3 - 6
drivers/i2c/busses/i2c-gpio.c

@@ -16,7 +16,6 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
 
 
 struct i2c_gpio_private_data {
 struct i2c_gpio_private_data {
 	struct i2c_adapter adap;
 	struct i2c_adapter adap;
@@ -137,9 +136,9 @@ static int i2c_gpio_probe(struct platform_device *pdev)
 		if (ret)
 		if (ret)
 			return ret;
 			return ret;
 	} else {
 	} else {
-		if (!pdev->dev.platform_data)
+		if (!dev_get_platdata(&pdev->dev))
 			return -ENXIO;
 			return -ENXIO;
-		pdata = pdev->dev.platform_data;
+		pdata = dev_get_platdata(&pdev->dev);
 		sda_pin = pdata->sda_pin;
 		sda_pin = pdata->sda_pin;
 		scl_pin = pdata->scl_pin;
 		scl_pin = pdata->scl_pin;
 	}
 	}
@@ -171,7 +170,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)
 		pdata->scl_pin = scl_pin;
 		pdata->scl_pin = scl_pin;
 		of_i2c_gpio_get_props(pdev->dev.of_node, pdata);
 		of_i2c_gpio_get_props(pdev->dev.of_node, pdata);
 	} else {
 	} else {
-		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+		memcpy(pdata, dev_get_platdata(&pdev->dev), sizeof(*pdata));
 	}
 	}
 
 
 	if (pdata->sda_is_open_drain) {
 	if (pdata->sda_is_open_drain) {
@@ -224,8 +223,6 @@ static int i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 	if (ret)
 		goto err_add_bus;
 		goto err_add_bus;
 
 
-	of_i2c_register_devices(adap);
-
 	platform_set_drvdata(pdev, priv);
 	platform_set_drvdata(pdev, priv);
 
 
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
 	dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",

+ 0 - 2
drivers/i2c/busses/i2c-i801.c

@@ -87,7 +87,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <linux/err.h>
 #include <linux/err.h>
-#include <linux/of_i2c.h>
 
 
 #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
 #if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
 		defined CONFIG_DMI
 		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;
 		goto exit_free_irq;
 	}
 	}
 
 
-	of_i2c_register_devices(&priv->adapter);
 	i801_probe_optional_slaves(priv);
 	i801_probe_optional_slaves(priv);
 	/* We ignore errors - multiplexing is optional */
 	/* We ignore errors - multiplexing is optional */
 	i801_add_mux(priv);
 	i801_add_mux(priv);

+ 0 - 4
drivers/i2c/busses/i2c-ibm_iic.c

@@ -42,7 +42,6 @@
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
 
 
 #include "i2c-ibm_iic.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_info(&ofdev->dev, "using %s mode\n",
 		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 		 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
 
-	/* Now register all the child nodes */
-	of_i2c_register_devices(adap);
-
 	return 0;
 	return 0;
 
 
 error_cleanup:
 error_cleanup:

+ 169 - 59
drivers/i2c/busses/i2c-imx.c

@@ -30,6 +30,8 @@
  *	Copyright (C) 2007 RightHand Technologies, Inc.
  *	Copyright (C) 2007 RightHand Technologies, Inc.
  *	Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
  *	Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
  *
  *
+ *	Copyright 2013 Freescale Semiconductor, Inc.
+ *
  */
  */
 
 
 /** Includes *******************************************************************
 /** Includes *******************************************************************
@@ -50,7 +52,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_data/i2c-imx.h>
 #include <linux/platform_data/i2c-imx.h>
 
 
 /** Defines ********************************************************************
 /** Defines ********************************************************************
@@ -62,12 +63,22 @@
 /* Default value */
 /* Default value */
 #define IMX_I2C_BIT_RATE	100000	/* 100kHz */
 #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_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 */
 /* Bits of IMX I2C registers */
 #define I2SR_RXAK	0x01
 #define I2SR_RXAK	0x01
@@ -84,6 +95,19 @@
 #define I2CR_IIEN	0x40
 #define I2CR_IIEN	0x40
 #define I2CR_IEN	0x80
 #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 ******************************************************************
 /** Variables ******************************************************************
 *******************************************************************************/
 *******************************************************************************/
 
 
@@ -95,8 +119,12 @@
  *
  *
  * Duplicated divider values removed from list
  * 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 },
 	{ 22,	0x20 }, { 24,	0x21 }, { 26,	0x22 }, { 28,	0x23 },
 	{ 30,	0x00 },	{ 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
 	{ 30,	0x00 },	{ 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
 	{ 42,	0x03 }, { 44,	0x27 },	{ 48,	0x28 }, { 52,	0x05 },
 	{ 42,	0x03 }, { 44,	0x27 },	{ 48,	0x28 }, { 52,	0x05 },
@@ -112,9 +140,38 @@ static u16 __initdata i2c_clk_div[50][2] = {
 	{ 3072,	0x1E }, { 3840,	0x1F }
 	{ 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 {
 enum imx_i2c_type {
 	IMX1_I2C,
 	IMX1_I2C,
 	IMX21_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 {
 struct imx_i2c_struct {
@@ -126,16 +183,46 @@ struct imx_i2c_struct {
 	unsigned int 		disable_delay;
 	unsigned int 		disable_delay;
 	int			stopped;
 	int			stopped;
 	unsigned int		ifdr; /* IMX_I2C_IFDR */
 	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[] = {
 static struct platform_device_id imx_i2c_devtype[] = {
 	{
 	{
 		.name = "imx1-i2c",
 		.name = "imx1-i2c",
-		.driver_data = IMX1_I2C,
+		.driver_data = (kernel_ulong_t)&imx1_i2c_hwdata,
 	}, {
 	}, {
 		.name = "imx21-i2c",
 		.name = "imx21-i2c",
-		.driver_data = IMX21_I2C,
+		.driver_data = (kernel_ulong_t)&imx21_i2c_hwdata,
 	}, {
 	}, {
 		/* sentinel */
 		/* sentinel */
 	}
 	}
@@ -143,15 +230,28 @@ static struct platform_device_id imx_i2c_devtype[] = {
 MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
 MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
 
 
 static const struct of_device_id i2c_imx_dt_ids[] = {
 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 */ }
 	{ /* sentinel */ }
 };
 };
 MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
 MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
 
 
 static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
 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 ***************************************
 /** 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__);
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
 
 	while (1) {
 	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))
 		if (for_busy && (temp & I2SR_IBB))
 			break;
 			break;
 		if (!for_busy && !(temp & I2SR_IBB))
 		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)
 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__);
 		dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__);
 		return -EIO;  /* No ACK */
 		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__);
 	dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 
 
 	clk_prepare_enable(i2c_imx->clk);
 	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 */
 	/* 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 */
 	/* Wait controller to be stable */
 	udelay(50);
 	udelay(50);
 
 
 	/* Start I2C transaction */
 	/* Start I2C transaction */
-	temp = readb(i2c_imx->base + IMX_I2C_I2CR);
+	temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR);
 	temp |= I2CR_MSTA;
 	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);
 	result = i2c_imx_bus_busy(i2c_imx, 1);
 	if (result)
 	if (result)
 		return result;
 		return result;
 	i2c_imx->stopped = 0;
 	i2c_imx->stopped = 0;
 
 
 	temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK;
 	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;
 	return result;
 }
 }
 
 
@@ -242,9 +342,9 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 	if (!i2c_imx->stopped) {
 	if (!i2c_imx->stopped) {
 		/* Stop I2C transaction */
 		/* Stop I2C transaction */
 		dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
 		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);
 		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)) {
 	if (is_imx1_i2c(i2c_imx)) {
 		/*
 		/*
@@ -260,13 +360,15 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
 	}
 	}
 
 
 	/* Disable I2C controller */
 	/* 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);
 	clk_disable_unprepare(i2c_imx->clk);
 }
 }
 
 
 static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
 static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
 							unsigned int rate)
 							unsigned int rate)
 {
 {
+	struct imx_i2c_clk_pair *i2c_clk_div = i2c_imx->hwdata->clk_div;
 	unsigned int i2c_clk_rate;
 	unsigned int i2c_clk_rate;
 	unsigned int div;
 	unsigned int div;
 	int i;
 	int i;
@@ -274,15 +376,15 @@ static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
 	/* Divider value calculation */
 	/* Divider value calculation */
 	i2c_clk_rate = clk_get_rate(i2c_imx->clk);
 	i2c_clk_rate = clk_get_rate(i2c_imx->clk);
 	div = (i2c_clk_rate + rate - 1) / rate;
 	div = (i2c_clk_rate + rate - 1) / rate;
-	if (div < i2c_clk_div[0][0])
+	if (div < i2c_clk_div[0].div)
 		i = 0;
 		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
 	else
-		for (i = 0; i2c_clk_div[i][0] < div; i++);
+		for (i = 0; i2c_clk_div[i].div < div; i++);
 
 
 	/* Store divider value */
 	/* Store divider value */
-	i2c_imx->ifdr = i2c_clk_div[i][1];
+	i2c_imx->ifdr = i2c_clk_div[i].val;
 
 
 	/*
 	/*
 	 * There dummy delay is calculated.
 	 * 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
 	 * This delay is used in I2C bus disable function
 	 * to fix chip hardware bug.
 	 * 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);
 		+ (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2);
 
 
 	/* dev_dbg() can't be used, because adapter is not yet registered */
 	/* 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",
 	dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
 		__func__, i2c_clk_rate, div);
 		__func__, i2c_clk_rate, div);
 	dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
 	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
 #endif
 }
 }
 
 
@@ -307,12 +409,13 @@ static irqreturn_t i2c_imx_isr(int irq, void *dev_id)
 	struct imx_i2c_struct *i2c_imx = dev_id;
 	struct imx_i2c_struct *i2c_imx = dev_id;
 	unsigned int temp;
 	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) {
 	if (temp & I2SR_IIF) {
 		/* save status register */
 		/* save status register */
 		i2c_imx->i2csr = temp;
 		i2c_imx->i2csr = temp;
 		temp &= ~I2SR_IIF;
 		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);
 		wake_up(&i2c_imx->queue);
 		return IRQ_HANDLED;
 		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);
 		__func__, msgs->addr << 1);
 
 
 	/* write slave address */
 	/* 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);
 	result = i2c_imx_trx_complete(i2c_imx);
 	if (result)
 	if (result)
 		return 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,
 		dev_dbg(&i2c_imx->adapter.dev,
 			"<%s> write byte: B%d=0x%X\n",
 			"<%s> write byte: B%d=0x%X\n",
 			__func__, i, msgs->buf[i]);
 			__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);
 		result = i2c_imx_trx_complete(i2c_imx);
 		if (result)
 		if (result)
 			return 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);
 		__func__, (msgs->addr << 1) | 0x01);
 
 
 	/* write slave address */
 	/* 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);
 	result = i2c_imx_trx_complete(i2c_imx);
 	if (result)
 	if (result)
 		return 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__);
 	dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__);
 
 
 	/* setup bus to read data */
 	/* 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;
 	temp &= ~I2CR_MTX;
 	if (msgs->len - 1)
 	if (msgs->len - 1)
 		temp &= ~I2CR_TXAK;
 		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__);
 	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 */
 			   controller from generating another clock cycle */
 			dev_dbg(&i2c_imx->adapter.dev,
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> clear MSTA\n", __func__);
 				"<%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);
 			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_bus_busy(i2c_imx, 0);
 			i2c_imx->stopped = 1;
 			i2c_imx->stopped = 1;
 		} else if (i == (msgs->len - 2)) {
 		} else if (i == (msgs->len - 2)) {
 			dev_dbg(&i2c_imx->adapter.dev,
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> set TXAK\n", __func__);
 				"<%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;
 			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,
 		dev_dbg(&i2c_imx->adapter.dev,
 			"<%s> read byte: B%d=0x%X\n",
 			"<%s> read byte: B%d=0x%X\n",
 			__func__, i, msgs->buf[i]);
 			__func__, i, msgs->buf[i]);
@@ -432,9 +535,9 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 		if (i) {
 		if (i) {
 			dev_dbg(&i2c_imx->adapter.dev,
 			dev_dbg(&i2c_imx->adapter.dev,
 				"<%s> repeated start\n", __func__);
 				"<%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;
 			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);
 			result =  i2c_imx_bus_busy(i2c_imx, 1);
 			if (result)
 			if (result)
 				goto fail0;
 				goto fail0;
@@ -443,13 +546,13 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
 			"<%s> transfer message: %d\n", __func__, i);
 			"<%s> transfer message: %d\n", __func__, i);
 		/* write/read data */
 		/* write/read data */
 #ifdef CONFIG_I2C_DEBUG_BUS
 #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, "
 		dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, "
 			"MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
 			"MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__,
 			(temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
 			(temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0),
 			(temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
 			(temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0),
 			(temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 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,
 		dev_dbg(&i2c_imx->adapter.dev,
 			"<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
 			"<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, "
 			"IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__,
 			"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);
 							   &pdev->dev);
 	struct imx_i2c_struct *i2c_imx;
 	struct imx_i2c_struct *i2c_imx;
 	struct resource *res;
 	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;
 	void __iomem *base;
 	int irq, ret;
 	int irq, ret;
 	u32 bitrate;
 	u32 bitrate;
@@ -518,8 +621,10 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	if (of_id)
 	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 */
 	/* Setup i2c_imx driver structure */
 	strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
 	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);
 		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 */
 	/* Request IRQ */
 	ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
 	ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
 				pdev->name, i2c_imx);
 				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);
 	i2c_imx_set_clk(i2c_imx, bitrate);
 
 
 	/* Set up chip registers to defaults */
 	/* 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 */
 	/* Add I2C adapter */
 	ret = i2c_add_numbered_adapter(&i2c_imx->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;
 		return ret;
 	}
 	}
 
 
-	of_i2c_register_devices(&i2c_imx->adapter);
-
 	/* Set up platform driver data */
 	/* Set up platform driver data */
 	platform_set_drvdata(pdev, i2c_imx);
 	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, "claimed irq %d\n", irq);
 	dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",
 	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);
 	i2c_del_adapter(&i2c_imx->adapter);
 
 
 	/* setup chip registers to defaults */
 	/* 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;
 	return 0;
 }
 }

+ 1 - 0
drivers/i2c/busses/i2c-ismt.c

@@ -879,6 +879,7 @@ ismt_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 						 DMA_BIT_MASK(32)) != 0)) {
 						 DMA_BIT_MASK(32)) != 0)) {
 			dev_err(&pdev->dev, "pci_set_dma_mask fail %p\n",
 			dev_err(&pdev->dev, "pci_set_dma_mask fail %p\n",
 				pdev);
 				pdev);
+			err = -ENODEV;
 			goto fail;
 			goto fail;
 		}
 		}
 	}
 	}

+ 35 - 9
drivers/i2c/busses/i2c-mpc.c

@@ -18,9 +18,9 @@
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/fsl_devices.h>
 #include <linux/fsl_devices.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
@@ -64,9 +64,10 @@ struct mpc_i2c {
 	struct i2c_adapter adap;
 	struct i2c_adapter adap;
 	int irq;
 	int irq;
 	u32 real_clk;
 	u32 real_clk;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u8 fdr, dfsrr;
 	u8 fdr, dfsrr;
 #endif
 #endif
+	struct clk *clk_per;
 };
 };
 
 
 struct mpc_i2c_divider {
 struct mpc_i2c_divider {
@@ -609,7 +610,6 @@ static const struct i2c_algorithm mpc_algo = {
 
 
 static struct i2c_adapter mpc_ops = {
 static struct i2c_adapter mpc_ops = {
 	.owner = THIS_MODULE,
 	.owner = THIS_MODULE,
-	.name = "MPC adapter",
 	.algo = &mpc_algo,
 	.algo = &mpc_algo,
 	.timeout = HZ,
 	.timeout = HZ,
 };
 };
@@ -623,6 +623,9 @@ static int fsl_i2c_probe(struct platform_device *op)
 	u32 clock = MPC_I2C_CLOCK_LEGACY;
 	u32 clock = MPC_I2C_CLOCK_LEGACY;
 	int result = 0;
 	int result = 0;
 	int plen;
 	int plen;
+	struct resource res;
+	struct clk *clk;
+	int err;
 
 
 	match = of_match_device(mpc_i2c_of_match, &op->dev);
 	match = of_match_device(mpc_i2c_of_match, &op->dev);
 	if (!match)
 	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)) {
 	if (of_get_property(op->dev.of_node, "fsl,preserve-clocking", NULL)) {
 		clock = MPC_I2C_CLOCK_PRESERVE;
 		clock = MPC_I2C_CLOCK_PRESERVE;
 	} else {
 	} else {
@@ -682,6 +700,9 @@ static int fsl_i2c_probe(struct platform_device *op)
 	platform_set_drvdata(op, i2c);
 	platform_set_drvdata(op, i2c);
 
 
 	i2c->adap = mpc_ops;
 	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_set_adapdata(&i2c->adap, i2c);
 	i2c->adap.dev.parent = &op->dev;
 	i2c->adap.dev.parent = &op->dev;
 	i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
 	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");
 		dev_err(i2c->dev, "failed to add adapter\n");
 		goto fail_add;
 		goto fail_add;
 	}
 	}
-	of_i2c_register_devices(&i2c->adap);
 
 
 	return result;
 	return result;
 
 
  fail_add:
  fail_add:
+	if (i2c->clk_per)
+		clk_disable_unprepare(i2c->clk_per);
 	free_irq(i2c->irq, i2c);
 	free_irq(i2c->irq, i2c);
  fail_request:
  fail_request:
 	irq_dispose_mapping(i2c->irq);
 	irq_dispose_mapping(i2c->irq);
@@ -711,6 +733,9 @@ static int fsl_i2c_remove(struct platform_device *op)
 
 
 	i2c_del_adapter(&i2c->adap);
 	i2c_del_adapter(&i2c->adap);
 
 
+	if (i2c->clk_per)
+		clk_disable_unprepare(i2c->clk_per);
+
 	if (i2c->irq)
 	if (i2c->irq)
 		free_irq(i2c->irq, i2c);
 		free_irq(i2c->irq, i2c);
 
 
@@ -720,7 +745,7 @@ static int fsl_i2c_remove(struct platform_device *op)
 	return 0;
 	return 0;
 };
 };
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int mpc_i2c_suspend(struct device *dev)
 static int mpc_i2c_suspend(struct device *dev)
 {
 {
 	struct mpc_i2c *i2c = dev_get_drvdata(dev);
 	struct mpc_i2c *i2c = dev_get_drvdata(dev);
@@ -741,7 +766,10 @@ static int mpc_i2c_resume(struct device *dev)
 	return 0;
 	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
 #endif
 
 
 static const struct mpc_i2c_data mpc_i2c_data_512x = {
 static const struct mpc_i2c_data mpc_i2c_data_512x = {
@@ -788,9 +816,7 @@ static struct platform_driver mpc_i2c_driver = {
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,
 		.name = DRV_NAME,
 		.name = DRV_NAME,
 		.of_match_table = mpc_i2c_of_match,
 		.of_match_table = mpc_i2c_of_match,
-#ifdef CONFIG_PM
-		.pm = &mpc_i2c_pm_ops,
-#endif
+		.pm = MPC_I2C_PM_OPS,
 	},
 	},
 };
 };
 
 

+ 193 - 14
drivers/i2c/busses/i2c-mv64xxx.c

@@ -21,9 +21,9 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_irq.h>
-#include <linux/of_i2c.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 
 
 #define MV64XXX_I2C_ADDR_ADDR(val)			((val & 0x7f) << 1)
 #define MV64XXX_I2C_ADDR_ADDR(val)			((val & 0x7f) << 1)
 #define MV64XXX_I2C_BAUD_DIV_N(val)			(val & 0x7)
 #define MV64XXX_I2C_BAUD_DIV_N(val)			(val & 0x7)
@@ -55,6 +55,32 @@
 #define	MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK	0xe8
 #define	MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK	0xe8
 #define	MV64XXX_I2C_STATUS_NO_STATUS			0xf8
 #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 */
 /* Driver states */
 enum {
 enum {
 	MV64XXX_I2C_STATE_INVALID,
 	MV64XXX_I2C_STATE_INVALID,
@@ -71,14 +97,17 @@ enum {
 enum {
 enum {
 	MV64XXX_I2C_ACTION_INVALID,
 	MV64XXX_I2C_ACTION_INVALID,
 	MV64XXX_I2C_ACTION_CONTINUE,
 	MV64XXX_I2C_ACTION_CONTINUE,
+	MV64XXX_I2C_ACTION_OFFLOAD_SEND_START,
 	MV64XXX_I2C_ACTION_SEND_START,
 	MV64XXX_I2C_ACTION_SEND_START,
 	MV64XXX_I2C_ACTION_SEND_RESTART,
 	MV64XXX_I2C_ACTION_SEND_RESTART,
+	MV64XXX_I2C_ACTION_OFFLOAD_RESTART,
 	MV64XXX_I2C_ACTION_SEND_ADDR_1,
 	MV64XXX_I2C_ACTION_SEND_ADDR_1,
 	MV64XXX_I2C_ACTION_SEND_ADDR_2,
 	MV64XXX_I2C_ACTION_SEND_ADDR_2,
 	MV64XXX_I2C_ACTION_SEND_DATA,
 	MV64XXX_I2C_ACTION_SEND_DATA,
 	MV64XXX_I2C_ACTION_RCV_DATA,
 	MV64XXX_I2C_ACTION_RCV_DATA,
 	MV64XXX_I2C_ACTION_RCV_DATA_STOP,
 	MV64XXX_I2C_ACTION_RCV_DATA_STOP,
 	MV64XXX_I2C_ACTION_SEND_STOP,
 	MV64XXX_I2C_ACTION_SEND_STOP,
+	MV64XXX_I2C_ACTION_OFFLOAD_SEND_STOP,
 };
 };
 
 
 struct mv64xxx_i2c_regs {
 struct mv64xxx_i2c_regs {
@@ -117,6 +146,9 @@ struct mv64xxx_i2c_data {
 	spinlock_t		lock;
 	spinlock_t		lock;
 	struct i2c_msg		*msg;
 	struct i2c_msg		*msg;
 	struct i2c_adapter	adapter;
 	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 = {
 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
 static void
 mv64xxx_i2c_hw_init(struct mv64xxx_i2c_data *drv_data)
 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(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),
 	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);
 		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;
 		drv_data->rc = -ENXIO;
 		break;
 		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:
 	default:
 		dev_err(&drv_data->adapter.dev,
 		dev_err(&drv_data->adapter.dev,
 			"mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, "
 			"mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, "
@@ -299,19 +421,29 @@ static void
 mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 {
 {
 	switch(drv_data->action) {
 	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:
 	case MV64XXX_I2C_ACTION_SEND_RESTART:
 		/* We should only get here if we have further messages */
 		/* We should only get here if we have further messages */
 		BUG_ON(drv_data->num_msgs == 0);
 		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->msgs++;
 		drv_data->num_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
 		 * 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);
 			drv_data->reg_base + drv_data->reg_offsets.control);
 		break;
 		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:
 	case MV64XXX_I2C_ACTION_SEND_START:
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
 			drv_data->reg_base + drv_data->reg_offsets.control);
 			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,
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
 			drv_data->reg_base + drv_data->reg_offsets.control);
 			drv_data->reg_base + drv_data->reg_offsets.control);
 		drv_data->block = 0;
 		drv_data->block = 0;
+		if (drv_data->errata_delay)
+			udelay(5);
+
 		wake_up(&drv_data->waitq);
 		wake_up(&drv_data->waitq);
 		break;
 		break;
 
 
@@ -375,6 +516,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 			"mv64xxx_i2c_do_action: Invalid action: %d\n",
 			"mv64xxx_i2c_do_action: Invalid action: %d\n",
 			drv_data->action);
 			drv_data->action);
 		drv_data->rc = -EIO;
 		drv_data->rc = -EIO;
+
 		/* FALLTHRU */
 		/* FALLTHRU */
 	case MV64XXX_I2C_ACTION_SEND_STOP:
 	case MV64XXX_I2C_ACTION_SEND_STOP:
 		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
 		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;
 		drv_data->block = 0;
 		wake_up(&drv_data->waitq);
 		wake_up(&drv_data->waitq);
 		break;
 		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;
 	irqreturn_t	rc = IRQ_NONE;
 
 
 	spin_lock_irqsave(&drv_data->lock, flags);
 	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) &
 	while (readl(drv_data->reg_base + drv_data->reg_offsets.control) &
 						MV64XXX_I2C_REG_CONTROL_IFLG) {
 						MV64XXX_I2C_REG_CONTROL_IFLG) {
 		status = readl(drv_data->reg_base + drv_data->reg_offsets.status);
 		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;
 	unsigned long	flags;
 
 
 	spin_lock_irqsave(&drv_data->lock, 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->send_stop = is_last;
 	drv_data->block = 1;
 	drv_data->block = 1;
 	mv64xxx_i2c_do_action(drv_data);
 	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[] = {
 static const struct of_device_id mv64xxx_i2c_of_match_table[] = {
 	{ .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
 	{ .compatible = "allwinner,sun4i-i2c", .data = &mv64xxx_i2c_regs_sun4i},
 	{ .compatible = "marvell,mv64xxx-i2c", .data = &mv64xxx_i2c_regs_mv64xxx},
 	{ .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);
 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));
 	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:
 out:
 	return rc;
 	return rc;
 #endif
 #endif
@@ -618,7 +798,7 @@ static int
 mv64xxx_i2c_probe(struct platform_device *pd)
 mv64xxx_i2c_probe(struct platform_device *pd)
 {
 {
 	struct mv64xxx_i2c_data		*drv_data;
 	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;
 	struct resource	*r;
 	int	rc;
 	int	rc;
 
 
@@ -654,6 +834,7 @@ mv64xxx_i2c_probe(struct platform_device *pd)
 		drv_data->freq_n = pdata->freq_n;
 		drv_data->freq_n = pdata->freq_n;
 		drv_data->irq = platform_get_irq(pd, 0);
 		drv_data->irq = platform_get_irq(pd, 0);
 		drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
 		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));
 		memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
 	} else if (pd->dev.of_node) {
 	} else if (pd->dev.of_node) {
 		rc = mv64xxx_of_config(drv_data, &pd->dev);
 		rc = mv64xxx_of_config(drv_data, &pd->dev);
@@ -689,8 +870,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
 		goto exit_free_irq;
 		goto exit_free_irq;
 	}
 	}
 
 
-	of_i2c_register_devices(&drv_data->adapter);
-
 	return 0;
 	return 0;
 
 
 exit_free_irq:
 exit_free_irq:

+ 82 - 34
drivers/i2c/busses/i2c-mxs.c

@@ -27,7 +27,6 @@
 #include <linux/stmp_device.h>
 #include <linux/stmp_device.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
 #include <linux/dmaengine.h>
 
 
@@ -114,18 +113,21 @@ struct mxs_i2c_dev {
 
 
 	uint32_t timing0;
 	uint32_t timing0;
 	uint32_t timing1;
 	uint32_t timing1;
+	uint32_t timing2;
 
 
 	/* DMA support components */
 	/* DMA support components */
-	struct dma_chan         	*dmach;
+	struct dma_chan			*dmach;
 	uint32_t			pio_data[2];
 	uint32_t			pio_data[2];
 	uint32_t			addr_data;
 	uint32_t			addr_data;
 	struct scatterlist		sg_io[2];
 	struct scatterlist		sg_io[2];
 	bool				dma_read;
 	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
 	 * 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->timing0, i2c->regs + MXS_I2C_TIMING0);
 	writel(i2c->timing1, i2c->regs + MXS_I2C_TIMING1);
 	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);
 	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)
 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)
 				int stop)
 {
 {
 	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
 	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
-	int ret;
+	int ret, err;
 	int flags;
 	int flags;
 
 
 	flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
 	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;
 	i2c->cmd_err = 0;
 	if (0) {	/* disable PIO mode until a proper fix is made */
 	if (0) {	/* disable PIO mode until a proper fix is made */
 		ret = mxs_i2c_pio_setup_xfer(adap, msg, flags);
 		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 {
 	} else {
 		INIT_COMPLETION(i2c->cmd_complete);
 		INIT_COMPLETION(i2c->cmd_complete);
 		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
 		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:
 timeout:
 	dev_dbg(i2c->dev, "Timeout!\n");
 	dev_dbg(i2c->dev, "Timeout!\n");
 	mxs_i2c_dma_finish(i2c);
 	mxs_i2c_dma_finish(i2c);
-	mxs_i2c_reset(i2c);
+	ret = mxs_i2c_reset(i2c);
+	if (ret)
+		return ret;
+
 	return -ETIMEDOUT;
 	return -ETIMEDOUT;
 }
 }
 
 
@@ -577,41 +587,79 @@ static const struct i2c_algorithm mxs_i2c_algo = {
 	.functionality = mxs_i2c_func,
 	.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;
 	const uint32_t clk = 24000000;
-	uint32_t base;
+	uint32_t divider;
 	uint16_t high_count, low_count, rcv_count, xmit_count;
 	uint16_t high_count, low_count, rcv_count, xmit_count;
+	uint32_t bus_free, leadin;
 	struct device *dev = i2c->dev;
 	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->timing0 = (high_count << 16) | rcv_count;
 	i2c->timing1 = (low_count << 16) | xmit_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)
 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);
 	platform_set_drvdata(pdev, i2c);
 
 
 	/* Do reset to enforce correct startup after pinmuxing */
 	/* Do reset to enforce correct startup after pinmuxing */
-	mxs_i2c_reset(i2c);
+	err = mxs_i2c_reset(i2c);
+	if (err)
+		return err;
 
 
 	adap = &i2c->adapter;
 	adap = &i2c->adapter;
 	strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
 	strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
@@ -701,8 +751,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
 		return err;
 		return err;
 	}
 	}
 
 
-	of_i2c_register_devices(adap);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 4
drivers/i2c/busses/i2c-nomadik.c

@@ -24,7 +24,6 @@
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_data/i2c-nomadik.h>
 #include <linux/platform_data/i2c-nomadik.h>
 #include <linux/of.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/consumer.h>
 
 
 #define DRIVER_NAME "nmk-i2c"
 #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)
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
 {
 	int ret = 0;
 	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 device_node *np = adev->dev.of_node;
 	struct nmk_i2c_dev	*dev;
 	struct nmk_i2c_dev	*dev;
 	struct i2c_adapter *adap;
 	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;
 		goto err_add_adap;
 	}
 	}
 
 
-	of_i2c_register_devices(adap);
-
 	pm_runtime_put(&adev->dev);
 	pm_runtime_put(&adev->dev);
 
 
 	return 0;
 	return 0;

+ 1 - 1
drivers/i2c/busses/i2c-nuc900.c

@@ -525,7 +525,7 @@ static int nuc900_i2c_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct resource *res;
 	int ret;
 	int ret;
 
 
-	pdata = pdev->dev.platform_data;
+	pdata = dev_get_platdata(&pdev->dev);
 	if (!pdata) {
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data\n");
 		dev_err(&pdev->dev, "no platform data\n");
 		return -EINVAL;
 		return -EINVAL;

+ 3 - 9
drivers/i2c/busses/i2c-ocores.c

@@ -24,7 +24,6 @@
 #include <linux/i2c-ocores.h>
 #include <linux/i2c-ocores.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/io.h>
-#include <linux/of_i2c.h>
 #include <linux/log2.h>
 #include <linux/log2.h>
 
 
 struct ocores_i2c {
 struct ocores_i2c {
@@ -353,10 +352,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
 	int ret;
 	int ret;
 	int i;
 	int i;
 
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENODEV;
-
 	irq = platform_get_irq(pdev, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 	if (irq < 0)
 		return irq;
 		return irq;
@@ -365,11 +360,12 @@ static int ocores_i2c_probe(struct platform_device *pdev)
 	if (!i2c)
 	if (!i2c)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	i2c->base = devm_ioremap_resource(&pdev->dev, res);
 	i2c->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(i2c->base))
 	if (IS_ERR(i2c->base))
 		return PTR_ERR(i2c->base);
 		return PTR_ERR(i2c->base);
 
 
-	pdata = pdev->dev.platform_data;
+	pdata = dev_get_platdata(&pdev->dev);
 	if (pdata) {
 	if (pdata) {
 		i2c->reg_shift = pdata->reg_shift;
 		i2c->reg_shift = pdata->reg_shift;
 		i2c->reg_io_width = pdata->reg_io_width;
 		i2c->reg_io_width = pdata->reg_io_width;
@@ -435,8 +431,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
 	if (pdata) {
 	if (pdata) {
 		for (i = 0; i < pdata->num_devices; i++)
 		for (i = 0; i < pdata->num_devices; i++)
 			i2c_new_device(&i2c->adap, pdata->devices + i);
 			i2c_new_device(&i2c->adap, pdata->devices + i);
-	} else {
-		of_i2c_register_devices(&i2c->adap);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -456,7 +450,7 @@ static int ocores_i2c_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ocores_i2c_suspend(struct device *dev)
 static int ocores_i2c_suspend(struct device *dev)
 {
 {
 	struct ocores_i2c *i2c = dev_get_drvdata(dev);
 	struct ocores_i2c *i2c = dev_get_drvdata(dev);

+ 0 - 3
drivers/i2c/busses/i2c-octeon.c

@@ -15,7 +15,6 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/sched.h>
 #include <linux/slab.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);
 	dev_info(i2c->dev, "version %s\n", DRV_VERSION);
 
 
-	of_i2c_register_devices(&i2c->adap);
-
 	return 0;
 	return 0;
 
 
 out:
 out:

+ 5 - 22
drivers/i2c/busses/i2c-omap.c

@@ -38,12 +38,10 @@
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/i2c-omap.h>
 #include <linux/i2c-omap.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
-#include <linux/pinctrl/consumer.h>
 
 
 /* I2C controller revisions */
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2		0x20
 #define OMAP_I2C_OMAP1_REV_2		0x20
@@ -216,8 +214,6 @@ struct omap_i2c_dev {
 	u16			syscstate;
 	u16			syscstate;
 	u16			westate;
 	u16			westate;
 	u16			errata;
 	u16			errata;
-
-	struct pinctrl		*pins;
 };
 };
 
 
 static const u8 reg_map_ip_v1[] = {
 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 (dev->cmd_err & OMAP_I2C_STAT_NACK) {
 		if (msg->flags & I2C_M_IGNORE_NAK)
 		if (msg->flags & I2C_M_IGNORE_NAK)
 			return 0;
 			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 -EREMOTEIO;
 	}
 	}
 	return -EIO;
 	return -EIO;
@@ -1079,7 +1074,7 @@ omap_i2c_probe(struct platform_device *pdev)
 	struct i2c_adapter	*adap;
 	struct i2c_adapter	*adap;
 	struct resource		*mem;
 	struct resource		*mem;
 	const struct omap_i2c_bus_platform_data *pdata =
 	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;
 	struct device_node	*node = pdev->dev.of_node;
 	const struct of_device_id *match;
 	const struct of_device_id *match;
 	int irq;
 	int irq;
@@ -1120,16 +1115,6 @@ omap_i2c_probe(struct platform_device *pdev)
 		dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
 		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->dev = &pdev->dev;
 	dev->irq = irq;
 	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,
 	dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n", adap->nr,
 		 major, minor, dev->speed);
 		 major, minor, dev->speed);
 
 
-	of_i2c_register_devices(adap);
-
 	pm_runtime_mark_last_busy(dev->dev);
 	pm_runtime_mark_last_busy(dev->dev);
 	pm_runtime_put_autosuspend(dev->dev);
 	pm_runtime_put_autosuspend(dev->dev);
 
 

+ 1 - 1
drivers/i2c/busses/i2c-pca-platform.c

@@ -136,7 +136,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
 	struct i2c_pca_pf_data *i2c;
 	struct i2c_pca_pf_data *i2c;
 	struct resource *res;
 	struct resource *res;
 	struct i2c_pca9564_pf_platform_data *platform_data =
 	struct i2c_pca9564_pf_platform_data *platform_data =
-				pdev->dev.platform_data;
+				dev_get_platdata(&pdev->dev);
 	int ret = 0;
 	int ret = 0;
 	int irq;
 	int irq;
 
 

+ 31 - 10
drivers/i2c/busses/i2c-piix4.c

@@ -231,11 +231,11 @@ static int piix4_setup(struct pci_dev *PIIX4_dev,
 }
 }
 
 
 static int piix4_setup_sb800(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 piix4_smba;
 	unsigned short smba_idx = 0xcd6;
 	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 */
 	/* SB800 and later SMBus does not support forcing address */
 	if (force || force_addr) {
 	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 */
 	/* Determine the address of the SMBus areas */
+	smb_en = (aux) ? 0x28 : 0x2c;
+
 	if (!request_region(smba_idx, 2, "smba_idx")) {
 	if (!request_region(smba_idx, 2, "smba_idx")) {
 		dev_err(&PIIX4_dev->dev, "SMBus base address index region "
 		dev_err(&PIIX4_dev->dev, "SMBus base address index region "
 			"0x%x already in use!\n", smba_idx);
 			"0x%x already in use!\n", smba_idx);
@@ -272,6 +274,13 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
 		return -EBUSY;
 		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 */
 	/* Request the SMBus I2C bus config region */
 	if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
 	if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) {
 		dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region "
 		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->revision >= 0x40) ||
 	    dev->vendor == PCI_VENDOR_ID_AMD)
 	    dev->vendor == PCI_VENDOR_ID_AMD)
 		/* base address location etc changed in SB800 */
 		/* base address location etc changed in SB800 */
-		retval = piix4_setup_sb800(dev, id);
+		retval = piix4_setup_sb800(dev, id, 0);
 	else
 	else
 		retval = piix4_setup(dev, id);
 		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;
 		return retval;
 
 
 	/* Check for auxiliary SMBus on some AMD chipsets */
 	/* Check for auxiliary SMBus on some AMD chipsets */
+	retval = -ENODEV;
+
 	if (dev->vendor == PCI_VENDOR_ID_ATI &&
 	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;
 	return 0;
 }
 }
 
 

+ 3 - 5
drivers/i2c/busses/i2c-pnx.c

@@ -23,7 +23,6 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 
 
 #define I2C_PNX_TIMEOUT_DEFAULT		10 /* msec */
 #define I2C_PNX_TIMEOUT_DEFAULT		10 /* msec */
 #define I2C_PNX_SPEED_KHZ_DEFAULT	100
 #define I2C_PNX_SPEED_KHZ_DEFAULT	100
@@ -595,7 +594,7 @@ static struct i2c_algorithm pnx_algorithm = {
 	.functionality = i2c_pnx_func,
 	.functionality = i2c_pnx_func,
 };
 };
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int i2c_pnx_controller_suspend(struct device *dev)
 static int i2c_pnx_controller_suspend(struct device *dev)
 {
 {
 	struct i2c_pnx_algo_data *alg_data = dev_get_drvdata(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);
 	alg_data->irq = platform_get_irq(pdev, 0);
 	if (alg_data->irq < 0) {
 	if (alg_data->irq < 0) {
 		dev_err(&pdev->dev, "Failed to get IRQ from platform resource\n");
 		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,
 	ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
 			0, pdev->name, alg_data);
 			0, pdev->name, alg_data);
@@ -741,8 +741,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
 		goto out_irq;
 		goto out_irq;
 	}
 	}
 
 
-	of_i2c_register_devices(&alg_data->adapter);
-
 	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
 	dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
 		alg_data->adapter.name, res->start, alg_data->irq);
 		alg_data->adapter.name, res->start, alg_data->irq);
 
 

+ 8 - 6
drivers/i2c/busses/i2c-powermac.c

@@ -398,7 +398,7 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap,
 
 
 static int i2c_powermac_probe(struct platform_device *dev)
 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 device_node *parent = NULL;
 	struct i2c_adapter *adapter;
 	struct i2c_adapter *adapter;
 	const char *basename;
 	const char *basename;
@@ -440,22 +440,24 @@ static int i2c_powermac_probe(struct platform_device *dev)
 	adapter->algo = &i2c_powermac_algorithm;
 	adapter->algo = &i2c_powermac_algorithm;
 	i2c_set_adapdata(adapter, bus);
 	i2c_set_adapdata(adapter, bus);
 	adapter->dev.parent = &dev->dev;
 	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);
 	rc = i2c_add_adapter(adapter);
 	if (rc) {
 	if (rc) {
 		printk(KERN_ERR "i2c-powermac: Adapter %s registration "
 		printk(KERN_ERR "i2c-powermac: Adapter %s registration "
 		       "failed\n", adapter->name);
 		       "failed\n", adapter->name);
 		memset(adapter, 0, sizeof(*adapter));
 		memset(adapter, 0, sizeof(*adapter));
+		return rc;
 	}
 	}
 
 
 	printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
 	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);
 	i2c_powermac_register_devices(adapter, bus);
 
 
-	return rc;
+	return 0;
 }
 }
 
 
 static struct platform_driver i2c_powermac_driver = {
 static struct platform_driver i2c_powermac_driver = {

+ 1 - 1
drivers/i2c/busses/i2c-puv3.c

@@ -245,7 +245,7 @@ static int puv3_i2c_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int puv3_i2c_suspend(struct device *dev)
 static int puv3_i2c_suspend(struct device *dev)
 {
 {
 	int poll_count;
 	int poll_count;

+ 65 - 5
drivers/i2c/busses/i2c-pxa.c

@@ -31,7 +31,6 @@
 #include <linux/i2c-pxa.h>
 #include <linux/i2c-pxa.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/clk.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_SADIE	(1 << 13)	   /* slave address detected int enable */
 #define ICR_UR		(1 << 14)	   /* unit reset */
 #define ICR_UR		(1 << 14)	   /* unit reset */
 #define ICR_FM		(1 << 15)	   /* fast mode */
 #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_RWM		(1 << 0)	   /* read/write mode */
 #define ISR_ACKNAK	(1 << 1)	   /* ack/nak status */
 #define ISR_ACKNAK	(1 << 1)	   /* ack/nak status */
@@ -155,6 +156,10 @@ struct pxa_i2c {
 	int			irq;
 	int			irq;
 	unsigned int		use_pio :1;
 	unsigned int		use_pio :1;
 	unsigned int		fast_mode :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)
 #define _IBMR(i2c)	((i2c)->reg_ibmr)
@@ -459,6 +464,7 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
 
 
 	/* set control register values */
 	/* set control register values */
 	writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
 	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
 #ifdef CONFIG_I2C_PXA_SLAVE
 	dev_info(&i2c->adap.dev, "Enabling slave mode\n");
 	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;
 	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,
 static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
 			       struct i2c_msg *msg, int num)
 			       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;
 		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);
 	spin_lock_irq(&i2c->lock);
 
 
 	i2c->msg = msg;
 	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);
 			i2c_pxa_slave_txempty(i2c, isr);
 		if (isr & ISR_IRF)
 		if (isr & ISR_IRF)
 			i2c_pxa_slave_rxfull(i2c, isr);
 			i2c_pxa_slave_rxfull(i2c, isr);
-	} else if (i2c->msg) {
+	} else if (i2c->msg && (!i2c->highmode_enter)) {
 		if (isr & ISR_ITE)
 		if (isr & ISR_ITE)
 			i2c_pxa_irq_txempty(i2c, isr);
 			i2c_pxa_irq_txempty(i2c, isr);
 		if (isr & ISR_IRF)
 		if (isr & ISR_IRF)
 			i2c_pxa_irq_rxfull(i2c, isr);
 			i2c_pxa_irq_rxfull(i2c, isr);
+	} else if ((isr & ISR_ITE) && i2c->highmode_enter) {
+		i2c->highmode_enter = false;
+		wake_up(&i2c->wait);
 	} else {
 	} else {
 		i2c_pxa_scream_blue_murder(i2c, "spurious irq");
 		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,
 			       struct pxa_i2c *i2c,
 			       enum pxa_i2c_types *i2c_types)
 			       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);
 	const struct platform_device_id *id = platform_get_device_id(pdev);
 
 
 	*i2c_types = id->driver_data;
 	*i2c_types = id->driver_data;
 	if (plat) {
 	if (plat) {
 		i2c->use_pio = plat->use_pio;
 		i2c->use_pio = plat->use_pio;
 		i2c->fast_mode = plat->fast_mode;
 		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;
 	return 0;
 }
 }
 
 
 static int i2c_pxa_probe(struct platform_device *dev)
 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;
 	enum pxa_i2c_types i2c_type;
 	struct pxa_i2c *i2c;
 	struct pxa_i2c *i2c;
 	struct resource *res = NULL;
 	struct resource *res = NULL;
@@ -1151,6 +1201,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
 	i2c->irq = irq;
 	i2c->irq = irq;
 
 
 	i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
 	i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
+	i2c->highmode_enter = false;
 
 
 	if (plat) {
 	if (plat) {
 #ifdef CONFIG_I2C_PXA_SLAVE
 #ifdef CONFIG_I2C_PXA_SLAVE
@@ -1160,6 +1211,16 @@ static int i2c_pxa_probe(struct platform_device *dev)
 		i2c->adap.class = plat->class;
 		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);
 	clk_prepare_enable(i2c->clk);
 
 
 	if (i2c->use_pio) {
 	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");
 		printk(KERN_INFO "I2C: Failed to add bus\n");
 		goto eadapt;
 		goto eadapt;
 	}
 	}
-	of_i2c_register_devices(&i2c->adap);
 
 
 	platform_set_drvdata(dev, i2c);
 	platform_set_drvdata(dev, i2c);
 
 

+ 34 - 3
drivers/i2c/busses/i2c-rcar.c

@@ -101,6 +101,11 @@ enum {
 #define ID_ARBLOST	(1 << 3)
 #define ID_ARBLOST	(1 << 3)
 #define ID_NACK		(1 << 4)
 #define ID_NACK		(1 << 4)
 
 
+enum rcar_i2c_type {
+	I2C_RCAR_H1,
+	I2C_RCAR_H2,
+};
+
 struct rcar_i2c_priv {
 struct rcar_i2c_priv {
 	void __iomem *io;
 	void __iomem *io;
 	struct i2c_adapter adap;
 	struct i2c_adapter adap;
@@ -113,6 +118,7 @@ struct rcar_i2c_priv {
 	int irq;
 	int irq;
 	u32 icccr;
 	u32 icccr;
 	u32 flags;
 	u32 flags;
+	enum rcar_i2c_type	devtype;
 };
 };
 
 
 #define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
 #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 scgd, cdf;
 	u32 round, ick;
 	u32 round, ick;
 	u32 scl;
 	u32 scl;
+	u32 cdf_width;
 
 
 	if (!clkp) {
 	if (!clkp) {
 		dev_err(dev, "there is no peripheral_clk\n");
 		dev_err(dev, "there is no peripheral_clk\n");
 		return -EIO;
 		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
 	 * calculate SCL clock
 	 * see
 	 * see
@@ -245,7 +264,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
 	 * clkp : peripheral_clk
 	 * clkp : peripheral_clk
 	 * F[]  : integer up-valuation
 	 * 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);
 		ick = clk_get_rate(clkp) / (1 + cdf);
 		if (ick < 20000000)
 		if (ick < 20000000)
 			goto ick_find;
 			goto ick_find;
@@ -287,7 +306,7 @@ scgd_find:
 	/*
 	/*
 	 * keep icccr value
 	 * keep icccr value
 	 */
 	 */
-	priv->icccr = (scgd << 2 | cdf);
+	priv->icccr = (scgd << (cdf_width) | cdf);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -615,7 +634,7 @@ static const struct i2c_algorithm rcar_i2c_algo = {
 
 
 static int rcar_i2c_probe(struct platform_device *pdev)
 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 rcar_i2c_priv *priv;
 	struct i2c_adapter *adap;
 	struct i2c_adapter *adap;
 	struct resource *res;
 	struct resource *res;
@@ -632,6 +651,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
 	bus_speed = 100000; /* default 100 kHz */
 	bus_speed = 100000; /* default 100 kHz */
 	if (pdata && pdata->bus_speed)
 	if (pdata && pdata->bus_speed)
 		bus_speed = 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);
 	ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
@@ -686,6 +708,14 @@ static int rcar_i2c_remove(struct platform_device *pdev)
 	return 0;
 	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 = {
 static struct platform_driver rcar_i2c_driver = {
 	.driver	= {
 	.driver	= {
 		.name	= "i2c-rcar",
 		.name	= "i2c-rcar",
@@ -693,6 +723,7 @@ static struct platform_driver rcar_i2c_driver = {
 	},
 	},
 	.probe		= rcar_i2c_probe,
 	.probe		= rcar_i2c_probe,
 	.remove		= rcar_i2c_remove,
 	.remove		= rcar_i2c_remove,
+	.id_table	= rcar_i2c_id_table,
 };
 };
 
 
 module_platform_driver(rcar_i2c_driver);
 module_platform_driver(rcar_i2c_driver);

+ 1 - 3
drivers/i2c/busses/i2c-s3c2410.c

@@ -36,7 +36,6 @@
 #include <linux/cpufreq.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/io.h>
-#include <linux/of_i2c.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/consumer.h>
 
 
@@ -1033,7 +1032,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 	int ret;
 	int ret;
 
 
 	if (!pdev->dev.of_node) {
 	if (!pdev->dev.of_node) {
-		pdata = pdev->dev.platform_data;
+		pdata = dev_get_platdata(&pdev->dev);
 		if (!pdata) {
 		if (!pdata) {
 			dev_err(&pdev->dev, "no platform data\n");
 			dev_err(&pdev->dev, "no platform data\n");
 			return -EINVAL;
 			return -EINVAL;
@@ -1154,7 +1153,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	of_i2c_register_devices(&i2c->adap);
 	platform_set_drvdata(pdev, i2c);
 	platform_set_drvdata(pdev, i2c);
 
 
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);

+ 3 - 2
drivers/i2c/busses/i2c-s6000.c

@@ -290,8 +290,9 @@ static int s6i2c_probe(struct platform_device *dev)
 
 
 	clock = 0;
 	clock = 0;
 	bus_num = -1;
 	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;
 		bus_num = pdata->bus_num;
 		clock = pdata->clock;
 		clock = pdata->clock;
 	}
 	}

+ 1 - 1
drivers/i2c/busses/i2c-sh7760.c

@@ -437,7 +437,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
 	struct cami2c *id;
 	struct cami2c *id;
 	int ret;
 	int ret;
 
 
-	pd = pdev->dev.platform_data;
+	pd = dev_get_platdata(&pdev->dev);
 	if (!pd) {
 	if (!pd) {
 		dev_err(&pdev->dev, "no platform_data!\n");
 		dev_err(&pdev->dev, "no platform_data!\n");
 		ret = -ENODEV;
 		ret = -ENODEV;

+ 1 - 3
drivers/i2c/busses/i2c-sh_mobile.c

@@ -27,7 +27,6 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 #include <linux/clk.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)
 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 sh_mobile_i2c_data *pd;
 	struct i2c_adapter *adap;
 	struct i2c_adapter *adap;
 	struct resource *res;
 	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",
 		 "I2C adapter %d with bus speed %lu Hz (L/H=%x/%x)\n",
 		 adap->nr, pd->bus_speed, pd->iccl, pd->icch);
 		 adap->nr, pd->bus_speed, pd->iccl, pd->icch);
 
 
-	of_i2c_register_devices(adap);
 	return 0;
 	return 0;
 
 
  err_all:
  err_all:

+ 26 - 13
drivers/i2c/busses/i2c-sirf.c

@@ -12,7 +12,6 @@
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c.h>
-#include <linux/of_i2c.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/io.h>
@@ -65,6 +64,8 @@
 #define SIRFSOC_I2C_START		BIT(7)
 #define SIRFSOC_I2C_START		BIT(7)
 
 
 #define SIRFSOC_I2C_DEFAULT_SPEED 100000
 #define SIRFSOC_I2C_DEFAULT_SPEED 100000
+#define SIRFSOC_I2C_ERR_NOACK      1
+#define SIRFSOC_I2C_ERR_TIMEOUT    2
 
 
 struct sirfsoc_i2c {
 struct sirfsoc_i2c {
 	void __iomem *base;
 	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) {
 	if (i2c_stat & SIRFSOC_I2C_STAT_ERR) {
 		/* Error conditions */
 		/* Error conditions */
-		siic->err_status = 1;
+		siic->err_status = SIRFSOC_I2C_ERR_NOACK;
 		writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS);
 		writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS);
 
 
 		if (i2c_stat & SIRFSOC_I2C_STAT_NACK)
 		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
 		else
 			dev_err(&siic->adapter.dev, "I2C error\n");
 			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);
 		complete(&siic->done);
 	} else if (i2c_stat & SIRFSOC_I2C_STAT_CMD_DONE) {
 	} else if (i2c_stat & SIRFSOC_I2C_STAT_CMD_DONE) {
 		/* CMD buffer execution complete */
 		/* CMD buffer execution complete */
@@ -183,6 +194,10 @@ static void i2c_sirfsoc_set_address(struct sirfsoc_i2c *siic,
 	if (msg->flags & I2C_M_RD)
 	if (msg->flags & I2C_M_RD)
 		addr |= 1;
 		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++));
 	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);
 	u32 regval = readl(siic->base + SIRFSOC_I2C_CTRL);
 	/* timeout waiting for the xfer to finish or fail */
 	/* timeout waiting for the xfer to finish or fail */
 	int timeout = msecs_to_jiffies((msg->len + 1) * 50);
 	int timeout = msecs_to_jiffies((msg->len + 1) * 50);
-	int ret = 0;
 
 
 	i2c_sirfsoc_set_address(siic, msg);
 	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);
 	i2c_sirfsoc_queue_cmd(siic);
 
 
 	if (wait_for_completion_timeout(&siic->done, timeout) == 0) {
 	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");
 		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);
 		siic->base + SIRFSOC_I2C_CTRL);
 	writel(0, siic->base + SIRFSOC_I2C_CMD_START);
 	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,
 		writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET,
 			siic->base + SIRFSOC_I2C_CTRL);
 			siic->base + SIRFSOC_I2C_CTRL);
 		while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
 		while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
 			cpu_relax();
 			cpu_relax();
-
-		ret = -EIO;
 	}
 	}
-
-	return ret;
+	return siic->err_status ? -EAGAIN : 0;
 }
 }
 
 
 static u32 i2c_sirfsoc_func(struct i2c_adapter *adap)
 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 = &i2c_sirfsoc_algo;
 	adap->algo_data = siic;
 	adap->algo_data = siic;
+	adap->retries = 3;
 
 
 	adap->dev.of_node = pdev->dev.of_node;
 	adap->dev.of_node = pdev->dev.of_node;
 	adap->dev.parent = &pdev->dev;
 	adap->dev.parent = &pdev->dev;
@@ -348,7 +361,7 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 
 
 	if (bitrate < 100000)
 	if (bitrate < 100000)
 		regval =
 		regval =
-			(2 * ctrl_speed) / (2 * bitrate * 11);
+			(2 * ctrl_speed) / (bitrate * 11);
 	else
 	else
 		regval = ctrl_speed / (bitrate * 5);
 		regval = ctrl_speed / (bitrate * 5);
 
 
@@ -366,8 +379,6 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
 
 
 	clk_disable(clk);
 	clk_disable(clk);
 
 
-	of_i2c_register_devices(adap);
-
 	dev_info(&pdev->dev, " I2C adapter ready to operate\n");
 	dev_info(&pdev->dev, " I2C adapter ready to operate\n");
 
 
 	return 0;
 	return 0;
@@ -416,6 +427,8 @@ static int i2c_sirfsoc_resume(struct device *dev)
 
 
 	clk_enable(siic->clk);
 	clk_enable(siic->clk);
 	writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
 	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,
 	writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE,
 		siic->base + SIRFSOC_I2C_CTRL);
 		siic->base + SIRFSOC_I2C_CTRL);
 	writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL);
 	writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL);

+ 1 - 6
drivers/i2c/busses/i2c-stu300.c

@@ -17,7 +17,6 @@
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 
 
 /* the name of this kernel module */
 /* the name of this kernel module */
 #define NAME "stu300"
 #define NAME "stu300"
@@ -884,9 +883,6 @@ stu300_probe(struct platform_device *pdev)
 
 
 	dev->pdev = pdev;
 	dev->pdev = pdev;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENOENT;
-
 	dev->virtbase = devm_ioremap_resource(&pdev->dev, res);
 	dev->virtbase = devm_ioremap_resource(&pdev->dev, res);
 	dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
 	dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual "
 		"base %p\n", bus_nr, dev->virtbase);
 		"base %p\n", bus_nr, dev->virtbase);
@@ -936,12 +932,11 @@ stu300_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, dev);
 	platform_set_drvdata(pdev, dev);
 	dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n",
 	dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n",
 		 dev->virtbase, dev->irq);
 		 dev->virtbase, dev->irq);
-	of_i2c_register_devices(adap);
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int stu300_suspend(struct device *device)
 static int stu300_suspend(struct device *device)
 {
 {
 	struct stu300_dev *dev = dev_get_drvdata(device);
 	struct stu300_dev *dev = dev_get_drvdata(device);

+ 0 - 3
drivers/i2c/busses/i2c-tegra.c

@@ -25,7 +25,6 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/clk/tegra.h>
 #include <linux/clk/tegra.h>
@@ -802,8 +801,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	of_i2c_register_devices(&i2c_dev->adapter);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 34 - 15
drivers/i2c/busses/i2c-tiny-usb.c

@@ -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)
 static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
 {
 {
-	unsigned char status;
+	unsigned char *pstatus;
 	struct i2c_msg *pmsg;
 	struct i2c_msg *pmsg;
-	int i;
+	int i, ret;
 
 
 	dev_dbg(&adapter->dev, "master xfer %d messages:\n", num);
 	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++) {
 	for (i = 0 ; i < num ; i++) {
 		int cmd = CMD_I2C_IO;
 		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) {
 				     pmsg->buf, pmsg->len) != pmsg->len) {
 				dev_err(&adapter->dev,
 				dev_err(&adapter->dev,
 					"failure reading data\n");
 					"failure reading data\n");
-				return -EREMOTEIO;
+				ret = -EREMOTEIO;
+				goto out;
 			}
 			}
 		} else {
 		} else {
 			/* write data */
 			/* 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) {
 				      pmsg->buf, pmsg->len) != pmsg->len) {
 				dev_err(&adapter->dev,
 				dev_err(&adapter->dev,
 					"failure writing data\n");
 					"failure writing data\n");
-				return -EREMOTEIO;
+				ret = -EREMOTEIO;
+				goto out;
 			}
 			}
 		}
 		}
 
 
 		/* read status */
 		/* 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");
 			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)
 static u32 usb_func(struct i2c_adapter *adapter)
 {
 {
-	__le32 func;
+	__le32 *pfunc;
+	u32 ret;
+
+	pfunc = kmalloc(sizeof(*pfunc), GFP_KERNEL);
 
 
 	/* get functionality from adapter */
 	/* 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");
 		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 */
 /* This is the actual algorithm we define */

+ 0 - 2
drivers/i2c/busses/i2c-versatile.c

@@ -16,7 +16,6 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/io.h>
-#include <linux/of_i2c.h>
 
 
 #define I2C_CONTROL	0x00
 #define I2C_CONTROL	0x00
 #define I2C_CONTROLS	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);
 	ret = i2c_bit_add_numbered_bus(&i2c->adap);
 	if (ret >= 0) {
 	if (ret >= 0) {
 		platform_set_drvdata(dev, i2c);
 		platform_set_drvdata(dev, i2c);
-		of_i2c_register_devices(&i2c->adap);
 		return 0;
 		return 0;
 	}
 	}
 
 

+ 0 - 3
drivers/i2c/busses/i2c-wmt.c

@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
-#include <linux/of_i2c.h>
 #include <linux/of_irq.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.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);
 	platform_set_drvdata(pdev, i2c_dev);
 
 
-	of_i2c_register_devices(adap);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 4
drivers/i2c/busses/i2c-xiic.c

@@ -40,7 +40,6 @@
 #include <linux/i2c-xiic.h>
 #include <linux/i2c-xiic.h>
 #include <linux/io.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
-#include <linux/of_i2c.h>
 
 
 #define DRIVER_NAME "xiic-i2c"
 #define DRIVER_NAME "xiic-i2c"
 
 
@@ -703,7 +702,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
 	if (irq < 0)
 	if (irq < 0)
 		goto resource_missing;
 		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);
 	i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
 	if (!i2c)
 	if (!i2c)
@@ -752,8 +751,6 @@ static int xiic_i2c_probe(struct platform_device *pdev)
 			i2c_new_device(&i2c->adap, pdata->devices + i);
 			i2c_new_device(&i2c->adap, pdata->devices + i);
 	}
 	}
 
 
-	of_i2c_register_devices(&i2c->adap);
-
 	return 0;
 	return 0;
 
 
 add_adapter_failed:
 add_adapter_failed:

+ 202 - 4
drivers/i2c/i2c-core.c

@@ -23,7 +23,11 @@
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
    SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
    Jean Delvare <khali@linux-fr.org>
    Jean Delvare <khali@linux-fr.org>
    Mux support by Rodolfo Giometti <giometti@enneenne.com> and
    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/module.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -35,7 +39,9 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/idr.h>
 #include <linux/idr.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
+#include <linux/of_irq.h>
 #include <linux/completion.h>
 #include <linux/completion.h>
 #include <linux/hardirq.h>
 #include <linux/hardirq.h>
 #include <linux/irqflags.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);
 	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,
 static int i2c_do_add_adapter(struct i2c_driver *driver,
 			      struct i2c_adapter *adap)
 			      struct i2c_adapter *adap)
 {
 {
@@ -1058,6 +1252,9 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 
 
 exit_recovery:
 exit_recovery:
 	/* create pre-declared device nodes */
 	/* create pre-declared device nodes */
+	of_i2c_register_devices(adap);
+	acpi_i2c_register_devices(adap);
+
 	if (adap->nr < __i2c_first_dynamic_bus_num)
 	if (adap->nr < __i2c_first_dynamic_bus_num)
 		i2c_scan_static_board_info(adap);
 		i2c_scan_static_board_info(adap);
 
 
@@ -1282,7 +1479,6 @@ void i2c_del_adapter(struct i2c_adapter *adap)
 }
 }
 EXPORT_SYMBOL(i2c_del_adapter);
 EXPORT_SYMBOL(i2c_del_adapter);
 
 
-
 /* ------------------------------------------------------------------------- */
 /* ------------------------------------------------------------------------- */
 
 
 int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
 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,
 		err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
 				     I2C_SMBUS_BYTE, &dummy);
 				     I2C_SMBUS_BYTE, &dummy);
 	else {
 	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;
 		err = -EOPNOTSUPP;
 	}
 	}
 
 
@@ -1825,7 +2022,8 @@ EXPORT_SYMBOL(i2c_get_adapter);
 
 
 void i2c_put_adapter(struct i2c_adapter *adap)
 void i2c_put_adapter(struct i2c_adapter *adap)
 {
 {
-	module_put(adap->owner);
+	if (adap)
+		module_put(adap->owner);
 }
 }
 EXPORT_SYMBOL(i2c_put_adapter);
 EXPORT_SYMBOL(i2c_put_adapter);
 
 

+ 0 - 3
drivers/i2c/i2c-mux.c

@@ -25,7 +25,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
 #include <linux/i2c-mux.h>
 #include <linux/of.h>
 #include <linux/of.h>
-#include <linux/of_i2c.h>
 
 
 /* multiplexer per channel data */
 /* multiplexer per channel data */
 struct i2c_mux_priv {
 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",
 	dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
 		 i2c_adapter_id(&priv->adap));
 		 i2c_adapter_id(&priv->adap));
 
 
-	of_i2c_register_devices(&priv->adap);
-
 	return &priv->adap;
 	return &priv->adap;
 }
 }
 EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
 EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);

+ 1 - 1
drivers/i2c/i2c-smbus.c

@@ -137,7 +137,7 @@ static irqreturn_t smbalert_irq(int irq, void *d)
 static int smbalert_probe(struct i2c_client *ara,
 static int smbalert_probe(struct i2c_client *ara,
 			  const struct i2c_device_id *id)
 			  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_smbus_alert *alert;
 	struct i2c_adapter *adapter = ara->adapter;
 	struct i2c_adapter *adapter = ara->adapter;
 	int res;
 	int res;

+ 1 - 2
drivers/i2c/muxes/i2c-arb-gpio-challenge.c

@@ -21,7 +21,6 @@
 #include <linux/i2c-mux.h>
 #include <linux/i2c-mux.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.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");
 		dev_err(dev, "Cannot find device tree node\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
-	if (dev->platform_data) {
+	if (dev_get_platdata(dev)) {
 		dev_err(dev, "Platform data is not supported\n");
 		dev_err(dev, "Platform data is not supported\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}

+ 5 - 4
drivers/i2c/muxes/i2c-mux-gpio.c

@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
 #include <linux/gpio.h>
-#include <linux/of_i2c.h>
 #include <linux/of_gpio.h>
 #include <linux/of_gpio.h>
 
 
 struct gpiomux {
 struct gpiomux {
@@ -148,12 +147,14 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
 
 
 	platform_set_drvdata(pdev, mux);
 	platform_set_drvdata(pdev, mux);
 
 
-	if (!pdev->dev.platform_data) {
+	if (!dev_get_platdata(&pdev->dev)) {
 		ret = i2c_mux_gpio_probe_dt(mux, pdev);
 		ret = i2c_mux_gpio_probe_dt(mux, pdev);
 		if (ret < 0)
 		if (ret < 0)
 			return ret;
 			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
 	 * If a GPIO chip name is provided, the GPIO pin numbers provided are

+ 1 - 1
drivers/i2c/muxes/i2c-mux-pca9541.c

@@ -324,7 +324,7 @@ static int pca9541_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
 	struct i2c_adapter *adap = client->adapter;
 	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;
 	struct pca9541 *data;
 	int force;
 	int force;
 	int ret = -ENODEV;
 	int ret = -ENODEV;

+ 1 - 1
drivers/i2c/muxes/i2c-mux-pca954x.c

@@ -185,7 +185,7 @@ static int pca954x_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
 	struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
 	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;
 	int num, force, class;
 	struct pca954x *data;
 	struct pca954x *data;
 	int ret = -ENODEV;
 	int ret = -ENODEV;

+ 1 - 2
drivers/i2c/muxes/i2c-mux-pinctrl.c

@@ -20,7 +20,6 @@
 #include <linux/i2c-mux.h>
 #include <linux/i2c-mux.h>
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/i2c-mux-pinctrl.h>
 #include <linux/i2c-mux-pinctrl.h>
 #include <linux/platform_device.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->dev = &pdev->dev;
 
 
-	mux->pdata = pdev->dev.platform_data;
+	mux->pdata = dev_get_platdata(&pdev->dev);
 	if (!mux->pdata) {
 	if (!mux->pdata) {
 		ret = i2c_mux_pinctrl_parse_dt(mux, pdev);
 		ret = i2c_mux_pinctrl_parse_dt(mux, pdev);
 		if (ret < 0)
 		if (ret < 0)

+ 1 - 3
drivers/media/platform/exynos4-is/fimc-is-i2c.c

@@ -12,7 +12,7 @@
 
 
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.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(&pdev->dev);
 	pm_runtime_enable(&i2c_adap->dev);
 	pm_runtime_enable(&i2c_adap->dev);
 
 
-	of_i2c_register_devices(i2c_adap);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
drivers/media/platform/exynos4-is/fimc-is.c

@@ -21,7 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/of_irq.h>
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>

+ 0 - 1
drivers/media/platform/exynos4-is/media-dev.c

@@ -20,7 +20,6 @@
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
 #include <linux/of_device.h>
 #include <linux/of_device.h>
-#include <linux/of_i2c.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_runtime.h>
 #include <linux/types.h>
 #include <linux/types.h>

+ 0 - 6
drivers/of/Kconfig

@@ -48,12 +48,6 @@ config OF_IRQ
 	def_bool y
 	def_bool y
 	depends on !SPARC
 	depends on !SPARC
 
 
-config OF_I2C
-	def_tristate I2C
-	depends on I2C
-	help
-	  OpenFirmware I2C accessors
-
 config OF_NET
 config OF_NET
 	depends on NETDEVICES
 	depends on NETDEVICES
 	def_bool y
 	def_bool y

+ 0 - 1
drivers/of/Makefile

@@ -3,7 +3,6 @@ obj-$(CONFIG_OF_FLATTREE) += fdt.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
 obj-$(CONFIG_OF_IRQ)    += irq.o
-obj-$(CONFIG_OF_I2C)	+= of_i2c.o
 obj-$(CONFIG_OF_NET)	+= of_net.o
 obj-$(CONFIG_OF_NET)	+= of_net.o
 obj-$(CONFIG_OF_SELFTEST) += selftest.o
 obj-$(CONFIG_OF_SELFTEST) += selftest.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_MDIO)	+= of_mdio.o

+ 0 - 114
drivers/of/of_i2c.c

@@ -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");

+ 1 - 1
drivers/staging/imx-drm/imx-tve.c

@@ -21,7 +21,7 @@
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/clk-provider.h>
 #include <linux/module.h>
 #include <linux/module.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/regmap.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/spinlock.h>

+ 20 - 4
include/linux/i2c.h

@@ -447,11 +447,13 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
 static inline struct i2c_adapter *
 static inline struct i2c_adapter *
 i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter)
 i2c_parent_is_i2c_adapter(const struct i2c_adapter *adapter)
 {
 {
+#if IS_ENABLED(I2C_MUX)
 	struct device *parent = adapter->dev.parent;
 	struct device *parent = adapter->dev.parent;
 
 
 	if (parent != NULL && parent->type == &i2c_adapter_type)
 	if (parent != NULL && parent->type == &i2c_adapter_type)
 		return to_i2c_adapter(parent);
 		return to_i2c_adapter(parent);
 	else
 	else
+#endif
 		return NULL;
 		return NULL;
 }
 }
 
 
@@ -542,10 +544,24 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
 
 
 #endif /* I2C */
 #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
 #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 */
 #endif /* _LINUX_I2C_H */

+ 3 - 0
include/linux/i2c/pxa-i2c.h

@@ -67,6 +67,9 @@ struct i2c_pxa_platform_data {
 	unsigned int		class;
 	unsigned int		class;
 	unsigned int		use_pio :1;
 	unsigned int		use_pio :1;
 	unsigned int		fast_mode :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);
 extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);

+ 0 - 46
include/linux/of_i2c.h

@@ -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 */

+ 1 - 1
sound/soc/fsl/imx-sgtl5000.c

@@ -13,7 +13,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <sound/soc.h>
 #include <sound/soc.h>
 
 

+ 1 - 1
sound/soc/fsl/imx-wm8962.c

@@ -15,7 +15,7 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/of_platform.h>
-#include <linux/of_i2c.h>
+#include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <sound/soc.h>
 #include <sound/soc.h>