Commit 00341b53 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 45d9a222 b720423a
...@@ -228,19 +228,9 @@ ACPI handle like: ...@@ -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 with the platform and SPI drivers. The I2C core automatically enumerates
needs to call acpi_i2c_register_devices() after it has added the adapter. any slave devices behind the controller device once the adapter is
registered.
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);
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:
......
* 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
......
...@@ -5,6 +5,7 @@ Required properties : ...@@ -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: ...@@ -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>;
};
...@@ -73,9 +73,10 @@ this driver on those mainboards. ...@@ -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 The AMD SB700, SB800, SP5100 and Hudson-2 chipsets implement two
controllers. If your BIOS initializes the secondary controller, it will PIIX4-compatible SMBus controllers. If your BIOS initializes the
be detected by this driver as an "Auxiliary SMBus Host Controller". 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
......
...@@ -19,7 +19,7 @@ i2c_board_info which is registered by calling i2c_register_board_info(). ...@@ -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),
......
...@@ -16,7 +16,6 @@ ...@@ -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>
......
...@@ -162,12 +162,6 @@ config ACPI_DOCK ...@@ -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
......
...@@ -73,7 +73,6 @@ obj-$(CONFIG_ACPI_HED) += hed.o ...@@ -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
......
/*
* 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);
...@@ -16,7 +16,6 @@ ...@@ -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>
......
...@@ -16,7 +16,6 @@ ...@@ -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>
......
...@@ -9,7 +9,7 @@ ...@@ -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"
......
...@@ -385,7 +385,7 @@ config I2C_CPM ...@@ -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.
......
...@@ -28,7 +28,6 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -582,6 +582,7 @@ static struct i2c_algorithm bfin_twi_algorithm = { ...@@ -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) ...@@ -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) ...@@ -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, rc = peripheral_request_list(
"i2c-bfin-twi"); (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 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) ...@@ -717,7 +723,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
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) ...@@ -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 = { ...@@ -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,
}, },
}; };
......
...@@ -233,8 +233,9 @@ static int cbus_i2c_probe(struct platform_device *pdev) ...@@ -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) { } else if (dev_get_platdata(&pdev->dev)) {
struct i2c_cbus_platform_data *pdata = pdev->dev.platform_data; 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;
......
...@@ -42,7 +42,6 @@ ...@@ -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) ...@@ -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);
......
...@@ -38,10 +38,7 @@ ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -317,6 +317,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 */
......
...@@ -61,6 +61,14 @@ ...@@ -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 { ...@@ -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
......
...@@ -35,7 +35,6 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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[] = { ...@@ -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) ...@@ -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 = { ...@@ -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,
}, },
}; };
......
...@@ -16,7 +16,6 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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",
......
...@@ -87,7 +87,6 @@ ...@@ -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) ...@@ -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);
......
...@@ -42,7 +42,6 @@ ...@@ -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) ...@@ -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:
......
This diff is collapsed.
...@@ -879,6 +879,7 @@ ismt_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -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;
} }
} }
......
...@@ -18,9 +18,9 @@ ...@@ -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 { ...@@ -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 = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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,
.pm = &mpc_i2c_pm_ops,
#endif
}, },
}; };
......
This diff is collapsed.
...@@ -27,7 +27,6 @@ ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) if (ret) {
mxs_i2c_reset(i2c); 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, ...@@ -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 = { ...@@ -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) { divider = DIV_ROUND_UP(clk, speed);
dev_warn(dev, "Speed too high (%d Hz), using 540 kHz\n", speed);
speed = 540000; if (divider < 25) {
} else if (speed < 12000) { /*
dev_warn(dev, "Speed too low (%d Hz), using 12 kHz\n", speed); * limit the divider, so that min(low_count, high_count)
speed = 12000; * 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 * The I2C spec specifies the following timing data:
* algorithm available, it was derived by using the scope and fiddling * standard mode fast mode Bitfield name
* with constants until the result observed on the scope was good enough * tLOW (SCL LOW period) 4700 ns 1300 ns
* for 20kHz, 50kHz, 100kHz, 200kHz, 300kHz and 400kHz. It should be * tHIGH (SCL HIGH period) 4000 ns 600 ns
* possible to assume the algorithm works for other frequencies as well. * 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 * The hardware (of the i.MX28 at least) seems to add 2 additional
* possible to configure completely arbitrary frequency for the I2C bus * clock cycles to the low_count and 7 cycles to the high_count.
* clock. * This is compensated for by subtracting the respective constants
* from the values written to the timing registers.
*/ */
base = ((clk / speed) - 38) / 2; if (speed > 100000) {
high_count = base + 3; /* fast mode */
low_count = base - 3; low_count = DIV_ROUND_CLOSEST(divider * 13, (13 + 6));
rcv_count = (high_count * 3) / 4; high_count = DIV_ROUND_CLOSEST(divider * 6, (13 + 6));
xmit_count = low_count / 4; 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) ...@@ -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) ...@@ -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;
} }
......
...@@ -24,7 +24,6 @@ ...@@ -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, ...@@ -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) ...@@ -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;
......
...@@ -525,7 +525,7 @@ static int nuc900_i2c_probe(struct platform_device *pdev) ...@@ -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;
......
...@@ -24,7 +24,6 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -15,7 +15,6 @@ ...@@ -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) ...@@ -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:
......
...@@ -38,12 +38,10 @@ ...@@ -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 { ...@@ -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, ...@@ -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_read_reg(dev, OMAP_I2C_CON_REG);
w |= OMAP_I2C_CON_STP; w |= OMAP_I2C_CON_STP;
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); 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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -136,7 +136,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev) ...@@ -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;
......
...@@ -231,11 +231,11 @@ static int piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) {
dev->revision < 0x40) { if (dev->revision < 0x40) {
retval = piix4_setup_aux(dev, id, 0x58); retval = piix4_setup_aux(dev, id, 0x58);
if (retval > 0) { } else {
/* Try to add the aux adapter if it exists, /* SB800 added aux bus too */
* piix4_add_adapter will clean up if this fails */ retval = piix4_setup_sb800(dev, id, 1);
piix4_add_adapter(dev, retval, &piix4_aux_adapter);
} }
} }
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;
} }
......
...@@ -23,7 +23,6 @@ ...@@ -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 = { ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -398,7 +398,7 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap, ...@@ -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) ...@@ -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 /* Use custom child registration due to Apple device-tree funkyness */
* 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 = {
......
...@@ -245,7 +245,7 @@ static int puv3_i2c_remove(struct platform_device *pdev) ...@@ -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;
......
...@@ -31,7 +31,6 @@ ...@@ -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); ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -101,6 +101,11 @@ enum { ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, ...@@ -287,7 +306,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
/* /*
* 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 = { ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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);
......
...@@ -36,7 +36,6 @@ ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -290,8 +290,9 @@ static int s6i2c_probe(struct platform_device *dev) ...@@ -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) { if (dev_get_platdata(&dev->dev)) {
struct s6_i2c_platform_data *pdata = dev->dev.platform_data; 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;
} }
......
...@@ -437,7 +437,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev) ...@@ -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;
......
...@@ -27,7 +27,6 @@ ...@@ -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) ...@@ -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) ...@@ -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:
......
...@@ -12,7 +12,6 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 siic->err_status ? -EAGAIN : 0;
return ret;
} }
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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -17,7 +17,6 @@ ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -25,7 +25,6 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -54,12 +54,16 @@ static int usb_write(struct i2c_adapter *adapter, int cmd, ...@@ -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) ...@@ -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) ...@@ -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); dev_dbg(&adapter->dev, " status = %d\n", *pstatus);
if (status == STATUS_ADDRESS_NAK) if (*pstatus == STATUS_ADDRESS_NAK) {
return -EREMOTEIO; 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)) != if (!pfunc || usb_read(adapter, CMD_GET_FUNC, 0, 0, pfunc,
sizeof(func)) { 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 */
......
...@@ -16,7 +16,6 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -21,7 +21,6 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -40,7 +40,6 @@ ...@@ -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) ...@@ -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) ...@@ -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:
......
...@@ -23,7 +23,11 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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);
......
...@@ -25,7 +25,6 @@ ...@@ -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, ...@@ -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);
......
...@@ -137,7 +137,7 @@ static irqreturn_t smbalert_irq(int irq, void *d) ...@@ -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;
......
...@@ -21,7 +21,6 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -16,7 +16,6 @@ ...@@ -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) ...@@ -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 } else {
memcpy(&mux->data, pdev->dev.platform_data, sizeof(mux->data)); 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
......
...@@ -324,7 +324,7 @@ static int pca9541_probe(struct i2c_client *client, ...@@ -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;
......
...@@ -185,7 +185,7 @@ static int pca954x_probe(struct i2c_client *client, ...@@ -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;
......
...@@ -20,7 +20,6 @@ ...@@ -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) ...@@ -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)
......
...@@ -12,7 +12,7 @@ ...@@ -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) ...@@ -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;
} }
......
...@@ -21,7 +21,7 @@ ...@@ -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>
......
...@@ -20,7 +20,6 @@ ...@@ -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>
......
...@@ -48,12 +48,6 @@ config OF_IRQ ...@@ -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
......
...@@ -3,7 +3,6 @@ obj-$(CONFIG_OF_FLATTREE) += fdt.o ...@@ -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
......
/*
* 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");
...@@ -21,7 +21,7 @@ ...@@ -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>
......
...@@ -447,11 +447,13 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) ...@@ -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) ...@@ -542,10 +544,24 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
#endif /* I2C */ #endif /* I2C */
#if IS_ENABLED(CONFIG_ACPI_I2C) #if IS_ENABLED(CONFIG_OF)
extern void acpi_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 #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 */
...@@ -67,6 +67,9 @@ struct i2c_pxa_platform_data { ...@@ -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);
......
/*
* 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 */
...@@ -13,7 +13,7 @@ ...@@ -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>
......
...@@ -15,7 +15,7 @@ ...@@ -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>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment