Commit 077e81d5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull i2c fixes from Wolfram Sang:
 "Another bunch  of driver fixes"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: sprd: depend on COMMON_CLK to fix compile tests
  Revert "i2c: imx: Remove unused .id_table support"
  i2c: octeon: check correct size of maximum RECV_LEN packet
  i2c: tegra: Create i2c_writesl_vi() to use with VI I2C for filling TX FIFO
  i2c: bpmp-tegra: Ignore unknown I2C_M flags
  i2c: tegra: Wait for config load atomically while in ISR
parents 15cfb0f0 9ecd1d2b
...@@ -1013,6 +1013,7 @@ config I2C_SIRF ...@@ -1013,6 +1013,7 @@ config I2C_SIRF
config I2C_SPRD config I2C_SPRD
tristate "Spreadtrum I2C interface" tristate "Spreadtrum I2C interface"
depends on I2C=y && (ARCH_SPRD || COMPILE_TEST) depends on I2C=y && (ARCH_SPRD || COMPILE_TEST)
depends on COMMON_CLK
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
Spreadtrum I2C interface. Spreadtrum I2C interface.
......
...@@ -241,6 +241,19 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = { ...@@ -241,6 +241,19 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
}; };
static const struct platform_device_id imx_i2c_devtype[] = {
{
.name = "imx1-i2c",
.driver_data = (kernel_ulong_t)&imx1_i2c_hwdata,
}, {
.name = "imx21-i2c",
.driver_data = (kernel_ulong_t)&imx21_i2c_hwdata,
}, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
static const struct of_device_id i2c_imx_dt_ids[] = { static const struct of_device_id i2c_imx_dt_ids[] = {
{ .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, }, { .compatible = "fsl,imx1-i2c", .data = &imx1_i2c_hwdata, },
{ .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, }, { .compatible = "fsl,imx21-i2c", .data = &imx21_i2c_hwdata, },
...@@ -1330,7 +1343,11 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1330,7 +1343,11 @@ static int i2c_imx_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
match = device_get_match_data(&pdev->dev); match = device_get_match_data(&pdev->dev);
if (match)
i2c_imx->hwdata = match; i2c_imx->hwdata = match;
else
i2c_imx->hwdata = (struct imx_i2c_hwdata *)
platform_get_device_id(pdev)->driver_data;
/* Setup i2c_imx driver structure */ /* Setup i2c_imx driver structure */
strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name)); strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
...@@ -1498,6 +1515,7 @@ static struct platform_driver i2c_imx_driver = { ...@@ -1498,6 +1515,7 @@ static struct platform_driver i2c_imx_driver = {
.of_match_table = i2c_imx_dt_ids, .of_match_table = i2c_imx_dt_ids,
.acpi_match_table = i2c_imx_acpi_ids, .acpi_match_table = i2c_imx_acpi_ids,
}, },
.id_table = imx_i2c_devtype,
}; };
static int __init i2c_adap_imx_init(void) static int __init i2c_adap_imx_init(void)
......
...@@ -347,7 +347,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target, ...@@ -347,7 +347,7 @@ static int octeon_i2c_read(struct octeon_i2c *i2c, int target,
if (result) if (result)
return result; return result;
if (recv_len && i == 0) { if (recv_len && i == 0) {
if (data[i] > I2C_SMBUS_BLOCK_MAX + 1) if (data[i] > I2C_SMBUS_BLOCK_MAX)
return -EPROTO; return -EPROTO;
length += data[i]; length += data[i];
} }
......
...@@ -80,7 +80,7 @@ static int tegra_bpmp_xlate_flags(u16 flags, u16 *out) ...@@ -80,7 +80,7 @@ static int tegra_bpmp_xlate_flags(u16 flags, u16 *out)
flags &= ~I2C_M_RECV_LEN; flags &= ~I2C_M_RECV_LEN;
} }
return (flags != 0) ? -EINVAL : 0; return 0;
} }
/** /**
......
...@@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg) ...@@ -326,6 +326,8 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg)
/* read back register to make sure that register writes completed */ /* read back register to make sure that register writes completed */
if (reg != I2C_TX_FIFO) if (reg != I2C_TX_FIFO)
readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg)); readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
else if (i2c_dev->is_vi)
readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS));
} }
static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg) static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
...@@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data, ...@@ -339,6 +341,21 @@ static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len); writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
} }
static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
unsigned int reg, unsigned int len)
{
u32 *data32 = data;
/*
* VI I2C controller has known hardware bug where writes get stuck
* when immediate multiple writes happen to TX_FIFO register.
* Recommended software work around is to read I2C register after
* each write to TX_FIFO register to flush out the data.
*/
while (len--)
i2c_writel(i2c_dev, *data32++, reg);
}
static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data, static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
unsigned int reg, unsigned int len) unsigned int reg, unsigned int len)
{ {
...@@ -533,7 +550,7 @@ static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev, ...@@ -533,7 +550,7 @@ static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg); void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
u32 val; u32 val;
if (!i2c_dev->atomic_mode) if (!i2c_dev->atomic_mode && !in_irq())
return readl_relaxed_poll_timeout(addr, val, !(val & mask), return readl_relaxed_poll_timeout(addr, val, !(val & mask),
delay_us, timeout_us); delay_us, timeout_us);
...@@ -811,6 +828,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev) ...@@ -811,6 +828,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
i2c_dev->msg_buf_remaining = buf_remaining; i2c_dev->msg_buf_remaining = buf_remaining;
i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD; i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;
if (i2c_dev->is_vi)
i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
else
i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer); i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
buf += words_to_transfer * BYTES_PER_FIFO_WORD; buf += words_to_transfer * BYTES_PER_FIFO_WORD;
......
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