Commit 98f486f1 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:
 - new drivers: Kontron PLD, Wondermedia VT
 - mv64xxx driver gained sun4i support and a bigger cleanup
 - duplicate driver 'intel-mid' removed
 - added generic device tree binding for sda holding time (and
   designware driver already uses it)
 - we tried to allow driver probing with only device tree and no i2c
   ids, but I had to revert it because of side effects.  Needs some
   rethinking.
 - driver bugfixes, cleanups...

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (34 commits)
  i2c-designware: use div_u64 to fix link
  i2c: Kontron PLD i2c bus driver
  i2c: iop3xxx: fix build failure after waitqueue changes
  i2c-designware: make SDA hold time configurable
  i2c: mv64xxx: Set bus frequency to 100kHz if clock-frequency is not provided
  i2c: imx: allow autoloading on dt ids
  i2c: mv64xxx: Fix transfer error code
  i2c: i801: SMBus patch for Intel Coleto Creek DeviceIDs
  i2c: omap: correct usage of the interrupt enable register
  i2c-pxa: prepare clock before use
  Revert "i2c: core: make it possible to match a pure device tree driver"
  i2c: nomadik: allocate adapter number dynamically
  i2c: nomadik: support elder Nomadiks
  i2c: mv64xxx: Add Allwinner sun4i compatible
  i2c: mv64xxx: make the registers offset configurable
  i2c: mv64xxx: Add macros to access parts of registers
  i2c: vt8500: Add support for I2C bus on Wondermedia SoCs
  i2c: designware: fix race between subsequent xfers
  i2c: bfin-twi: Read and write the FIFO in loop
  i2c: core: make it possible to match a pure device tree driver
  ...
parents 84cbd722 97191d73
......@@ -10,6 +10,10 @@ Recommended properties :
- clock-frequency : desired I2C bus clock frequency in Hz.
Optional properties :
- i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds.
This option is only supported in hardware blocks version 1.11a or newer.
Example :
i2c@f0000 {
......@@ -20,3 +24,14 @@ Example :
interrupts = <11>;
clock-frequency = <400000>;
};
i2c@1120000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0x1120000 0x1000>;
interrupt-parent = <&ictl>;
interrupts = <12 1>;
clock-frequency = <400000>;
i2c-sda-hold-time-ns = <300>;
};
......@@ -6,7 +6,11 @@ Required properties :
- reg : Offset and length of the register set for the device
- compatible : Should be "marvell,mv64xxx-i2c"
- interrupts : The interrupt number
- clock-frequency : Desired I2C bus clock frequency in Hz.
Optional properties :
- clock-frequency : Desired I2C bus clock frequency in Hz. If not set the
default frequency is 100kHz
Examples:
......
* Wondermedia I2C Controller
Required properties :
- compatible : should be "wm,wm8505-i2c"
- reg : Offset and length of the register set for the device
- interrupts : <IRQ> where IRQ is the interrupt number
- clocks : phandle to the I2C clock source
Optional properties :
- clock-frequency : desired I2C bus clock frequency in Hz.
Valid values are 100000 and 400000.
Default to 100000 if not specified, or invalid value.
Example :
i2c_0: i2c@d8280000 {
compatible = "wm,wm8505-i2c";
reg = <0xd8280000 0x1000>;
interrupts = <19>;
clocks = <&clki2c0>;
clock-frequency = <400000>;
};
......@@ -24,6 +24,7 @@ Supported adapters:
* Intel Lynx Point-LP (PCH)
* Intel Avoton (SOC)
* Intel Wellsburg (PCH)
* Intel Coleto Creek (PCH)
Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller
......
......@@ -1301,6 +1301,7 @@ S: Maintained
F: arch/arm/mach-vt8500/
F: drivers/clocksource/vt8500_timer.c
F: drivers/gpio/gpio-vt8500.c
F: drivers/i2c/busses/i2c-wmt.c
F: drivers/mmc/host/wmt-sdmmc.c
F: drivers/pwm/pwm-vt8500.c
F: drivers/rtc/rtc-vt8500.c
......
......@@ -45,19 +45,19 @@ ethernet@FE100000 {
};
i2c0: i2c@FF120000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c1: i2c@FF121000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c2: i2c@FF122000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c3: i2c@FF123000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c4: i2c@FF124000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
leds {
......
......@@ -45,19 +45,19 @@ ethernet@FE100000 {
};
i2c0: i2c@FF120000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c1: i2c@FF121000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c2: i2c@FF122000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c3: i2c@FF123000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
i2c4: i2c@FF124000 {
sda-hold-time = <432>;
i2c-sda-hold-time-ns = <432>;
};
leds {
......
......@@ -108,6 +108,7 @@ config I2C_I801
Lynx Point-LP (PCH)
Avoton (SOC)
Wellsburg (PCH)
Coleto Creek (PCH)
This driver can also be built as a module. If so, the module
will be called i2c-i801.
......@@ -475,16 +476,6 @@ config I2C_IMX
This driver can also be built as a module. If so, the module
will be called i2c-imx.
config I2C_INTEL_MID
tristate "Intel Moorestown/Medfield Platform I2C controller"
depends on PCI
help
Say Y here if you have an Intel Moorestown/Medfield platform I2C
controller.
This support is also available as a module. If so, the module
will be called i2c-intel-mid.
config I2C_IOP3XX
tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX
......@@ -495,6 +486,16 @@ config I2C_IOP3XX
This driver can also be built as a module. If so, the module
will be called i2c-iop3xx.
config I2C_KEMPLD
tristate "Kontron COM I2C Controller"
depends on MFD_KEMPLD
help
This enables support for the I2C bus interface on some Kontron ETX
and COMexpress (ETXexpress) modules.
This driver can also be built as a module. If so, the module
will be called i2c-kempld.
config I2C_MPC
tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
depends on PPC
......@@ -508,10 +509,11 @@ config I2C_MPC
config I2C_MV64XXX
tristate "Marvell mv64xxx I2C Controller"
depends on (MV64X60 || PLAT_ORION)
depends on (MV64X60 || PLAT_ORION || ARCH_SUNXI)
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Marvell 64xxx line of host bridges.
This driver is also used for Allwinner SoCs I2C controllers.
This driver can also be built as a module. If so, the module
will be called i2c-mv64xxx.
......@@ -725,6 +727,16 @@ config I2C_VERSATILE
This driver can also be built as a module. If so, the module
will be called i2c-versatile.
config I2C_WMT
tristate "Wondermedia WM8xxx SoC I2C bus support"
depends on ARCH_VT8500
help
Say yes if you want to support the I2C bus on Wondermedia 8xxx-series
SoCs.
This driver can also be built as a module. If so, the module will be
called i2c-wmt.
config I2C_OCTEON
tristate "Cavium OCTEON I2C bus support"
depends on CPU_CAVIUM_OCTEON
......
......@@ -46,8 +46,8 @@ obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
obj-$(CONFIG_I2C_IMX) += i2c-imx.o
obj-$(CONFIG_I2C_INTEL_MID) += i2c-intel-mid.o
obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_MXS) += i2c-mxs.o
......@@ -71,6 +71,7 @@ obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
obj-$(CONFIG_I2C_WMT) += i2c-wmt.o
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
obj-$(CONFIG_I2C_XLR) += i2c-xlr.o
......
......@@ -39,33 +39,40 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,
unsigned short mast_stat = read_MASTER_STAT(iface);
if (twi_int_status & XMTSERV) {
if (iface->writeNum <= 0) {
/* start receive immediately after complete sending in
* combine mode.
*/
if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) | MDIR);
else if (iface->manual_stop)
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) | STOP);
else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
iface->cur_msg + 1 < iface->msg_num) {
if (iface->pmsg[iface->cur_msg + 1].flags &
I2C_M_RD)
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) |
MDIR);
else
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) &
~MDIR);
}
}
/* Transmit next data */
if (iface->writeNum > 0) {
while (iface->writeNum > 0 &&
(read_FIFO_STAT(iface) & XMTSTAT) != XMT_FULL) {
SSYNC();
write_XMT_DATA8(iface, *(iface->transPtr++));
iface->writeNum--;
}
/* start receive immediately after complete sending in
* combine mode.
*/
else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) | MDIR);
else if (iface->manual_stop)
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) | STOP);
else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
iface->cur_msg + 1 < iface->msg_num) {
if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) | MDIR);
else
write_MASTER_CTL(iface,
read_MASTER_CTL(iface) & ~MDIR);
}
}
if (twi_int_status & RCVSERV) {
if (iface->readNum > 0) {
while (iface->readNum > 0 &&
(read_FIFO_STAT(iface) & RCVSTAT)) {
/* Receive next data */
*(iface->transPtr) = read_RCV_DATA8(iface);
if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
......
......@@ -654,7 +654,7 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
cpm->ofdev = ofdev;
dev_set_drvdata(&ofdev->dev, cpm);
platform_set_drvdata(ofdev, cpm);
cpm->adap = cpm_ops;
i2c_set_adapdata(&cpm->adap, cpm);
......@@ -697,7 +697,7 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
static int cpm_i2c_remove(struct platform_device *ofdev)
{
struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
struct cpm_i2c *cpm = platform_get_drvdata(ofdev);
i2c_del_adapter(&cpm->adap);
......
......@@ -646,13 +646,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
struct resource *mem, *irq;
int r;
/* NOTE: driver uses the static register mapping */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
dev_err(&pdev->dev, "no irq resource?\n");
......@@ -697,6 +690,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
return -ENODEV;
clk_prepare_enable(dev->clk);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dev->base)) {
r = PTR_ERR(dev->base);
......
......@@ -67,9 +67,12 @@
#define DW_IC_STATUS 0x70
#define DW_IC_TXFLR 0x74
#define DW_IC_RXFLR 0x78
#define DW_IC_SDA_HOLD 0x7c
#define DW_IC_TX_ABRT_SOURCE 0x80
#define DW_IC_ENABLE_STATUS 0x9c
#define DW_IC_COMP_PARAM_1 0xf4
#define DW_IC_COMP_VERSION 0xf8
#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A
#define DW_IC_COMP_TYPE 0xfc
#define DW_IC_COMP_TYPE_VALUE 0x44570140
......@@ -332,6 +335,16 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
/* Configure SDA Hold Time if required */
if (dev->sda_hold_time) {
reg = dw_readl(dev, DW_IC_COMP_VERSION);
if (reg >= DW_IC_SDA_HOLD_MIN_VERS)
dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
else
dev_warn(dev->dev,
"Hardware too old to adjust SDA hold time.");
}
/* Configure Tx/Rx FIFO threshold levels */
dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL);
dw_writel(dev, 0, DW_IC_RX_TL);
......@@ -580,14 +593,23 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
i2c_dw_xfer_init(dev);
/* wait for tx to complete */
ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ);
ret = wait_for_completion_timeout(&dev->cmd_complete, HZ);
if (ret == 0) {
dev_err(dev->dev, "controller timed out\n");
/* i2c_dw_init implicitly disables the adapter */
i2c_dw_init(dev);
ret = -ETIMEDOUT;
goto done;
} else if (ret < 0)
goto done;
}
/*
* We must disable the adapter before unlocking the &dev->lock mutex
* below. Otherwise the hardware might continue generating interrupts
* which in turn causes a race condition with the following transfer.
* Needs some more investigation if the additional interrupts are
* a hardware bug or this driver doesn't handle them correctly yet.
*/
__i2c_dw_enable(dev, false);
if (dev->msg_err) {
ret = dev->msg_err;
......@@ -596,8 +618,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
/* no error */
if (likely(!dev->cmd_err)) {
/* Disable the adapter */
__i2c_dw_enable(dev, false);
ret = num;
goto done;
}
......
......@@ -90,6 +90,7 @@ struct dw_i2c_dev {
unsigned int tx_fifo_depth;
unsigned int rx_fifo_depth;
int rx_outstanding;
u32 sda_hold_time;
};
#define ACCESS_SWAP 0x00000001
......
......@@ -34,6 +34,7 @@
#include <linux/sched.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_i2c.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
......@@ -87,13 +88,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
struct resource *mem;
int irq, r;
/* NOTE: driver uses the static register mapping */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
return -EINVAL;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
......@@ -104,6 +98,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dev->base))
return PTR_ERR(dev->base);
......@@ -121,6 +116,16 @@ static int dw_i2c_probe(struct platform_device *pdev)
return PTR_ERR(dev->clk);
clk_prepare_enable(dev->clk);
if (pdev->dev.of_node) {
u32 ht = 0;
u32 ic_clk = dev->get_clk_rate_khz(dev);
of_property_read_u32(pdev->dev.of_node,
"i2c-sda-hold-time-ns", &ht);
dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
1000000);
}
dev->functionality =
I2C_FUNC_I2C |
I2C_FUNC_10BIT_ADDR |
......
......@@ -58,6 +58,7 @@
Wellsburg (PCH) MS 0x8d7d 32 hard yes yes yes
Wellsburg (PCH) MS 0x8d7e 32 hard yes yes yes
Wellsburg (PCH) MS 0x8d7f 32 hard yes yes yes
Coleto Creek (PCH) 0x23b0 32 hard yes yes yes
Features supported by this driver:
Software PEC no
......@@ -169,6 +170,7 @@
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
#define PCI_DEVICE_ID_INTEL_AVOTON_SMBUS 0x1f3c
#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330
#define PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS 0x23b0
#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22
#define PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS 0x8d22
......@@ -817,6 +819,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS0) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS1) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SMBUS_MS2) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COLETOCREEK_SMBUS) },
{ 0, }
};
......
......@@ -705,7 +705,7 @@ static int iic_probe(struct platform_device *ofdev)
return -ENOMEM;
}
dev_set_drvdata(&ofdev->dev, dev);
platform_set_drvdata(ofdev, dev);
dev->vaddr = of_iomap(np, 0);
if (dev->vaddr == NULL) {
......@@ -782,7 +782,7 @@ static int iic_probe(struct platform_device *ofdev)
*/
static int iic_remove(struct platform_device *ofdev)
{
struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
struct ibm_iic_private *dev = platform_get_drvdata(ofdev);
i2c_del_adapter(&dev->adap);
......
......@@ -51,7 +51,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_i2c.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_data/i2c-imx.h>
/** Defines ********************************************************************
......@@ -148,6 +147,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
{ .compatible = "fsl,imx21-i2c", .data = &imx_i2c_devtype[IMX21_I2C], },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);
static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
{
......@@ -493,24 +493,19 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
struct imx_i2c_struct *i2c_imx;
struct resource *res;
struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
struct pinctrl *pinctrl;
void __iomem *base;
int irq, ret;
u32 bitrate;
dev_dbg(&pdev->dev, "<%s>\n", __func__);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "can't get device resources\n");
return -ENOENT;
}
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "can't get irq number\n");
return -ENOENT;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
......@@ -535,12 +530,6 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
i2c_imx->adapter.dev.of_node = pdev->dev.of_node;
i2c_imx->base = base;
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl)) {
dev_err(&pdev->dev, "can't get/select pinctrl\n");
return PTR_ERR(pinctrl);
}
/* Get I2C clock */
i2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c_imx->clk)) {
......
This diff is collapsed.
......@@ -176,7 +176,7 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap,
interrupted = wait_event_interruptible_timeout (
iop3xx_adap->waitq,
(done = compare( sr = iop3xx_i2c_get_srstat(iop3xx_adap) ,flags )),
1 * HZ;
1 * HZ
);
if ((rc = iop3xx_i2c_error(sr)) < 0) {
*status = sr;
......
This diff is collapsed.
......@@ -679,7 +679,7 @@ static int fsl_i2c_probe(struct platform_device *op)
}
dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
dev_set_drvdata(&op->dev, i2c);
platform_set_drvdata(op, i2c);
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
......@@ -707,7 +707,7 @@ static int fsl_i2c_probe(struct platform_device *op)
static int fsl_i2c_remove(struct platform_device *op)
{
struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);
struct mpc_i2c *i2c = platform_get_drvdata(op);
i2c_del_adapter(&i2c->adap);
......
This diff is collapsed.
......@@ -24,7 +24,6 @@
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/io.h>
#include <linux/pinctrl/consumer.h>
#include <linux/stmp_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
......@@ -638,15 +637,10 @@ static int mxs_i2c_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct mxs_i2c_dev *i2c;
struct i2c_adapter *adap;
struct pinctrl *pinctrl;
struct resource *res;
resource_size_t res_size;
int err, irq;
pinctrl = devm_pinctrl_get_select_default(dev);
if (IS_ERR(pinctrl))
return PTR_ERR(pinctrl);
i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
......
......@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/amba/bus.h>
#include <linux/atomic.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
......@@ -106,6 +105,16 @@
/* maximum threshold value */
#define MAX_I2C_FIFO_THRESHOLD 15
/**
* struct i2c_vendor_data - per-vendor variations
* @has_mtdws: variant has the MTDWS bit
* @fifodepth: variant FIFO depth
*/
struct i2c_vendor_data {
bool has_mtdws;
u32 fifodepth;
};
enum i2c_status {
I2C_NOP,
I2C_ON_GOING,
......@@ -138,6 +147,7 @@ struct i2c_nmk_client {
/**
* struct nmk_i2c_dev - private data structure of the controller.
* @vendor: vendor data for this variant.
* @adev: parent amba device.
* @adap: corresponding I2C adapter.
* @irq: interrupt line for the controller.
......@@ -151,6 +161,7 @@ struct i2c_nmk_client {
* @busy: Busy doing transfer.
*/
struct nmk_i2c_dev {
struct i2c_vendor_data *vendor;
struct amba_device *adev;
struct i2c_adapter adap;
int irq;
......@@ -422,7 +433,7 @@ static int read_i2c(struct nmk_i2c_dev *dev, u16 flags)
irq_mask = (I2C_IT_RXFNF | I2C_IT_RXFF |
I2C_IT_MAL | I2C_IT_BERR);
if (dev->stop)
if (dev->stop || !dev->vendor->has_mtdws)
irq_mask |= I2C_IT_MTD;
else
irq_mask |= I2C_IT_MTDWS;
......@@ -502,7 +513,7 @@ static int write_i2c(struct nmk_i2c_dev *dev, u16 flags)
* set the MTDWS bit (Master Transaction Done Without Stop)
* to start repeated start operation
*/
if (dev->stop)
if (dev->stop || !dev->vendor->has_mtdws)
irq_mask |= I2C_IT_MTD;
else
irq_mask |= I2C_IT_MTDWS;
......@@ -929,8 +940,6 @@ static void nmk_i2c_of_probe(struct device_node *np,
pdata->sm = I2C_FREQ_MODE_FAST;
}
static atomic_t adapter_id = ATOMIC_INIT(0);
static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
......@@ -938,6 +947,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
struct device_node *np = adev->dev.of_node;
struct nmk_i2c_dev *dev;
struct i2c_adapter *adap;
struct i2c_vendor_data *vendor = id->data;
u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
if (!pdata) {
if (np) {
......@@ -954,12 +965,25 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
pdata = &u8500_i2c;
}
if (pdata->tft > max_fifo_threshold) {
dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
pdata->tft, max_fifo_threshold);
pdata->tft = max_fifo_threshold;
}
if (pdata->rft > max_fifo_threshold) {
dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n",
pdata->rft, max_fifo_threshold);
pdata->rft = max_fifo_threshold;
}
dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
if (!dev) {
dev_err(&adev->dev, "cannot allocate memory\n");
ret = -ENOMEM;
goto err_no_mem;
}
dev->vendor = vendor;
dev->busy = false;
dev->adev = adev;
amba_set_drvdata(adev, dev);
......@@ -999,10 +1023,8 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
adap->algo = &nmk_i2c_algo;
adap->timeout = msecs_to_jiffies(pdata->timeout);
adap->nr = atomic_read(&adapter_id);
snprintf(adap->name, sizeof(adap->name),
"Nomadik I2C%d at %pR", adap->nr, &adev->res);
atomic_inc(&adapter_id);
"Nomadik I2C at %pR", &adev->res);
/* fetch the controller configuration from machine */
dev->cfg.clk_freq = pdata->clk_freq;
......@@ -1017,7 +1039,7 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
"initialize %s on virtual base %p\n",
adap->name, dev->virtbase);
ret = i2c_add_numbered_adapter(adap);
ret = i2c_add_adapter(adap);
if (ret) {
dev_err(&adev->dev, "failed to add adapter\n");
goto err_add_adap;
......@@ -1064,14 +1086,26 @@ static int nmk_i2c_remove(struct amba_device *adev)
return 0;
}
static struct i2c_vendor_data vendor_stn8815 = {
.has_mtdws = false,
.fifodepth = 16, /* Guessed from TFTR/RFTR = 7 */
};
static struct i2c_vendor_data vendor_db8500 = {
.has_mtdws = true,
.fifodepth = 32, /* Guessed from TFTR/RFTR = 15 */
};
static struct amba_id nmk_i2c_ids[] = {
{
.id = 0x00180024,
.mask = 0x00ffffff,
.data = &vendor_stn8815,
},
{
.id = 0x00380024,
.mask = 0x00ffffff,
.data = &vendor_db8500,
},
{},
};
......
......@@ -180,6 +180,8 @@ enum {
#define I2C_OMAP_ERRATA_I207 (1 << 0)
#define I2C_OMAP_ERRATA_I462 (1 << 1)
#define OMAP_I2C_IP_V2_INTERRUPTS_MASK 0x6FFF
struct omap_i2c_dev {
spinlock_t lock; /* IRQ synchronization */
struct device *dev;
......@@ -193,6 +195,7 @@ struct omap_i2c_dev {
long latency);
u32 speed; /* Speed of bus in kHz */
u32 flags;
u16 scheme;
u16 cmd_err;
u8 *buf;
u8 *regs;
......@@ -1082,14 +1085,7 @@ omap_i2c_probe(struct platform_device *pdev)
int irq;
int r;
u32 rev;
u16 minor, major, scheme;
/* NOTE: driver uses the static register mapping */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
u16 minor, major;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
......@@ -1103,6 +1099,7 @@ omap_i2c_probe(struct platform_device *pdev)
return -ENOMEM;
}
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dev->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dev->base))
return PTR_ERR(dev->base);
......@@ -1159,8 +1156,8 @@ omap_i2c_probe(struct platform_device *pdev)
*/
rev = __raw_readw(dev->base + 0x04);
scheme = OMAP_I2C_SCHEME(rev);
switch (scheme) {
dev->scheme = OMAP_I2C_SCHEME(rev);
switch (dev->scheme) {
case OMAP_I2C_SCHEME_0:
dev->regs = (u8 *)reg_map_ip_v1;
dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG);
......@@ -1289,7 +1286,11 @@ static int omap_i2c_runtime_suspend(struct device *dev)
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
if (_dev->scheme == OMAP_I2C_SCHEME_0)
omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
else
omap_i2c_write_reg(_dev, OMAP_I2C_IP_V2_IRQENABLE_CLR,
OMAP_I2C_IP_V2_INTERRUPTS_MASK);
if (_dev->rev < OMAP_I2C_OMAP1_REV_2) {
omap_i2c_read_reg(_dev, OMAP_I2C_IV_REG); /* Read clears */
......
......@@ -1160,7 +1160,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
i2c->adap.class = plat->class;
}
clk_enable(i2c->clk);
clk_prepare_enable(i2c->clk);
if (i2c->use_pio) {
i2c->adap.algo = &i2c_pxa_pio_algorithm;
......@@ -1202,7 +1202,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
if (!i2c->use_pio)
free_irq(irq, i2c);
ereqirq:
clk_disable(i2c->clk);
clk_disable_unprepare(i2c->clk);
iounmap(i2c->reg_base);
eremap:
clk_put(i2c->clk);
......@@ -1221,7 +1221,7 @@ static int i2c_pxa_remove(struct platform_device *dev)
if (!i2c->use_pio)
free_irq(i2c->irq, i2c);
clk_disable(i2c->clk);
clk_disable_unprepare(i2c->clk);
clk_put(i2c->clk);
iounmap(i2c->reg_base);
......
......@@ -623,12 +623,6 @@ static int rcar_i2c_probe(struct platform_device *pdev)
u32 bus_speed;
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(dev, "no mmio resources\n");
return -ENODEV;
}
priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
if (!priv) {
dev_err(dev, "no mem for private data\n");
......@@ -642,6 +636,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->io = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->io))
return PTR_ERR(priv->io);
......
This diff is collapsed.
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