提交 d7d3d841 编写于 作者: L 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:
 "A set of 'usual' driver bugfixes for the I2C subsystem"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: rcar: disable runtime PM correctly in slave mode
  i2c: designware: Keep pm_runtime_enable/_disable calls in sync
  i2c: designware: fix IO timeout issue for AMD controller
  i2c: imx: init bus recovery info before adding i2c adapter
  i2c: do not use 0x in front of %pa
  i2c: davinci: Increase module clock frequency
  i2c: mv64xxx: The n clockdiv factor is 0 based on sunxi SoCs
  i2c: rk3x: populate correct variable for sda_falling_time
...@@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) ...@@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
* d is always 6 on Keystone I2C controller * d is always 6 on Keystone I2C controller
*/ */
/* get minimum of 7 MHz clock, but max of 12 MHz */ /*
psc = (input_clock / 7000000) - 1; * Both Davinci and current Keystone User Guides recommend a value
* between 7MHz and 12MHz. In reality 7MHz module clock doesn't
* always produce enough margin between SDA and SCL transitions.
* Measurements show that the higher the module clock is, the
* bigger is the margin, providing more reliable communication.
* So we better target for 12MHz.
*/
psc = (input_clock / 12000000) - 1;
if ((input_clock / (psc + 1)) > 12000000) if ((input_clock / (psc + 1)) > 12000000)
psc++; /* better to run under spec than over */ psc++; /* better to run under spec than over */
d = (psc >= 2) ? 5 : 7 - psc; d = (psc >= 2) ? 5 : 7 - psc;
......
...@@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) ...@@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
tx_aborted: tx_aborted:
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
complete(&dev->cmd_complete); complete(&dev->cmd_complete);
else if (unlikely(dev->accessor_flags & ACCESS_INTR_MASK)) {
/* workaround to trigger pending interrupt */
stat = dw_readl(dev, DW_IC_INTR_MASK);
i2c_dw_disable_int(dev);
dw_writel(dev, stat, DW_IC_INTR_MASK);
}
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -111,6 +111,7 @@ struct dw_i2c_dev { ...@@ -111,6 +111,7 @@ struct dw_i2c_dev {
#define ACCESS_SWAP 0x00000001 #define ACCESS_SWAP 0x00000001
#define ACCESS_16BIT 0x00000002 #define ACCESS_16BIT 0x00000002
#define ACCESS_INTR_MASK 0x00000004
extern int i2c_dw_init(struct dw_i2c_dev *dev); extern int i2c_dw_init(struct dw_i2c_dev *dev);
extern void i2c_dw_disable(struct dw_i2c_dev *dev); extern void i2c_dw_disable(struct dw_i2c_dev *dev);
......
...@@ -93,6 +93,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], ...@@ -93,6 +93,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
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);
const struct acpi_device_id *id;
dev->adapter.nr = -1; dev->adapter.nr = -1;
dev->tx_fifo_depth = 32; dev->tx_fifo_depth = 32;
...@@ -106,6 +107,10 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev) ...@@ -106,6 +107,10 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
&dev->sda_hold_time); &dev->sda_hold_time);
id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
if (id && id->driver_data)
dev->accessor_flags |= (u32)id->driver_data;
return 0; return 0;
} }
...@@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = { ...@@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
{ "INT3433", 0 }, { "INT3433", 0 },
{ "80860F41", 0 }, { "80860F41", 0 },
{ "808622C1", 0 }, { "808622C1", 0 },
{ "AMD0010", 0 }, { "AMD0010", ACCESS_INTR_MASK },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match); MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
...@@ -240,12 +245,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) ...@@ -240,12 +245,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
} }
r = i2c_dw_probe(dev); r = i2c_dw_probe(dev);
if (r) { if (r && !dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return r;
}
return 0; return r;
} }
static int dw_i2c_plat_remove(struct platform_device *pdev) static int dw_i2c_plat_remove(struct platform_device *pdev)
...@@ -260,7 +263,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev) ...@@ -260,7 +263,8 @@ static int dw_i2c_plat_remove(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_sync(&pdev->dev); pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); if (!dev->pm_runtime_disabled)
pm_runtime_disable(&pdev->dev);
return 0; return 0;
} }
......
...@@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
i2c_imx, IMX_I2C_I2CR); i2c_imx, IMX_I2C_I2CR);
imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR); imx_i2c_write_reg(i2c_imx->hwdata->i2sr_clr_opcode, i2c_imx, IMX_I2C_I2SR);
i2c_imx_init_recovery_info(i2c_imx, pdev);
/* Add I2C adapter */ /* Add I2C adapter */
ret = i2c_add_numbered_adapter(&i2c_imx->adapter); ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
if (ret < 0) { if (ret < 0) {
...@@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev) ...@@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
goto clk_disable; goto clk_disable;
} }
i2c_imx_init_recovery_info(i2c_imx, pdev);
/* Set up platform driver data */ /* Set up platform driver data */
platform_set_drvdata(pdev, i2c_imx); platform_set_drvdata(pdev, i2c_imx);
clk_disable_unprepare(i2c_imx->clk); clk_disable_unprepare(i2c_imx->clk);
......
...@@ -146,6 +146,8 @@ struct mv64xxx_i2c_data { ...@@ -146,6 +146,8 @@ struct mv64xxx_i2c_data {
bool errata_delay; bool errata_delay;
struct reset_control *rstc; struct reset_control *rstc;
bool irq_clear_inverted; bool irq_clear_inverted;
/* Clk div is 2 to the power n, not 2 to the power n + 1 */
bool clk_n_base_0;
}; };
static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = { static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
...@@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table); ...@@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
#ifdef CONFIG_OF #ifdef CONFIG_OF
#ifdef CONFIG_HAVE_CLK #ifdef CONFIG_HAVE_CLK
static int static int
mv64xxx_calc_freq(const int tclk, const int n, const int m) mv64xxx_calc_freq(struct mv64xxx_i2c_data *drv_data,
const int tclk, const int n, const int m)
{ {
return tclk / (10 * (m + 1) * (2 << n)); if (drv_data->clk_n_base_0)
return tclk / (10 * (m + 1) * (1 << n));
else
return tclk / (10 * (m + 1) * (2 << n));
} }
static bool static bool
mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n, mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
u32 *best_m) const u32 req_freq, const u32 tclk)
{ {
int freq, delta, best_delta = INT_MAX; int freq, delta, best_delta = INT_MAX;
int m, n; int m, n;
for (n = 0; n <= 7; n++) for (n = 0; n <= 7; n++)
for (m = 0; m <= 15; m++) { for (m = 0; m <= 15; m++) {
freq = mv64xxx_calc_freq(tclk, n, m); freq = mv64xxx_calc_freq(drv_data, tclk, n, m);
delta = req_freq - freq; delta = req_freq - freq;
if (delta >= 0 && delta < best_delta) { if (delta >= 0 && delta < best_delta) {
*best_m = m; drv_data->freq_m = m;
*best_n = n; drv_data->freq_n = n;
best_delta = delta; best_delta = delta;
} }
if (best_delta == 0) if (best_delta == 0)
...@@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, ...@@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
if (of_property_read_u32(np, "clock-frequency", &bus_freq)) if (of_property_read_u32(np, "clock-frequency", &bus_freq))
bus_freq = 100000; /* 100kHz by default */ bus_freq = 100000; /* 100kHz by default */
if (!mv64xxx_find_baud_factors(bus_freq, tclk, if (of_device_is_compatible(np, "allwinner,sun4i-a10-i2c") ||
&drv_data->freq_n, &drv_data->freq_m)) { of_device_is_compatible(np, "allwinner,sun6i-a31-i2c"))
drv_data->clk_n_base_0 = true;
if (!mv64xxx_find_baud_factors(drv_data, bus_freq, tclk)) {
rc = -EINVAL; rc = -EINVAL;
goto out; goto out;
} }
......
...@@ -576,7 +576,7 @@ static int rcar_reg_slave(struct i2c_client *slave) ...@@ -576,7 +576,7 @@ static int rcar_reg_slave(struct i2c_client *slave)
if (slave->flags & I2C_CLIENT_TEN) if (slave->flags & I2C_CLIENT_TEN)
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
pm_runtime_forbid(rcar_i2c_priv_to_dev(priv)); pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));
priv->slave = slave; priv->slave = slave;
rcar_i2c_write(priv, ICSAR, slave->addr); rcar_i2c_write(priv, ICSAR, slave->addr);
...@@ -598,7 +598,7 @@ static int rcar_unreg_slave(struct i2c_client *slave) ...@@ -598,7 +598,7 @@ static int rcar_unreg_slave(struct i2c_client *slave)
priv->slave = NULL; priv->slave = NULL;
pm_runtime_allow(rcar_i2c_priv_to_dev(priv)); pm_runtime_put(rcar_i2c_priv_to_dev(priv));
return 0; return 0;
} }
......
...@@ -908,7 +908,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev) ...@@ -908,7 +908,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
&i2c->scl_fall_ns)) &i2c->scl_fall_ns))
i2c->scl_fall_ns = 300; i2c->scl_fall_ns = 300;
if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns", if (of_property_read_u32(pdev->dev.of_node, "i2c-sda-falling-time-ns",
&i2c->scl_fall_ns)) &i2c->sda_fall_ns))
i2c->sda_fall_ns = i2c->scl_fall_ns; i2c->sda_fall_ns = i2c->scl_fall_ns;
strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name)); strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
......
...@@ -822,7 +822,7 @@ static int st_i2c_probe(struct platform_device *pdev) ...@@ -822,7 +822,7 @@ static int st_i2c_probe(struct platform_device *pdev)
adap = &i2c_dev->adap; adap = &i2c_dev->adap;
i2c_set_adapdata(adap, i2c_dev); i2c_set_adapdata(adap, i2c_dev);
snprintf(adap->name, sizeof(adap->name), "ST I2C(0x%pa)", &res->start); snprintf(adap->name, sizeof(adap->name), "ST I2C(%pa)", &res->start);
adap->owner = THIS_MODULE; adap->owner = THIS_MODULE;
adap->timeout = 2 * HZ; adap->timeout = 2 * HZ;
adap->retries = 0; adap->retries = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册