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
This commit is contained in:
Коммит
d7d3d84194
|
@ -202,8 +202,15 @@ static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
|
|||
* 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)
|
||||
psc++; /* better to run under spec than over */
|
||||
d = (psc >= 2) ? 5 : 7 - psc;
|
||||
|
|
|
@ -813,6 +813,12 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
|
|||
tx_aborted:
|
||||
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err)
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ struct dw_i2c_dev {
|
|||
|
||||
#define ACCESS_SWAP 0x00000001
|
||||
#define ACCESS_16BIT 0x00000002
|
||||
#define ACCESS_INTR_MASK 0x00000004
|
||||
|
||||
extern int i2c_dw_init(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[],
|
|||
static int dw_i2c_acpi_configure(struct platform_device *pdev)
|
||||
{
|
||||
struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
|
||||
const struct acpi_device_id *id;
|
||||
|
||||
dev->adapter.nr = -1;
|
||||
dev->tx_fifo_depth = 32;
|
||||
|
@ -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,
|
||||
&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;
|
||||
}
|
||||
|
||||
|
@ -116,7 +121,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
|
|||
{ "INT3433", 0 },
|
||||
{ "80860F41", 0 },
|
||||
{ "808622C1", 0 },
|
||||
{ "AMD0010", 0 },
|
||||
{ "AMD0010", ACCESS_INTR_MASK },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
|
||||
|
@ -240,12 +245,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
r = i2c_dw_probe(dev);
|
||||
if (r) {
|
||||
if (r && !dev->pm_runtime_disabled)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
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_put_sync(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (!dev->pm_runtime_disabled)
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1119,6 +1119,8 @@ static int i2c_imx_probe(struct platform_device *pdev)
|
|||
i2c_imx, IMX_I2C_I2CR);
|
||||
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 */
|
||||
ret = i2c_add_numbered_adapter(&i2c_imx->adapter);
|
||||
if (ret < 0) {
|
||||
|
@ -1126,8 +1128,6 @@ static int i2c_imx_probe(struct platform_device *pdev)
|
|||
goto clk_disable;
|
||||
}
|
||||
|
||||
i2c_imx_init_recovery_info(i2c_imx, pdev);
|
||||
|
||||
/* Set up platform driver data */
|
||||
platform_set_drvdata(pdev, i2c_imx);
|
||||
clk_disable_unprepare(i2c_imx->clk);
|
||||
|
|
|
@ -146,6 +146,8 @@ struct mv64xxx_i2c_data {
|
|||
bool errata_delay;
|
||||
struct reset_control *rstc;
|
||||
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 = {
|
||||
|
@ -757,25 +759,29 @@ MODULE_DEVICE_TABLE(of, mv64xxx_i2c_of_match_table);
|
|||
#ifdef CONFIG_OF
|
||||
#ifdef CONFIG_HAVE_CLK
|
||||
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
|
||||
mv64xxx_find_baud_factors(const u32 req_freq, const u32 tclk, u32 *best_n,
|
||||
u32 *best_m)
|
||||
mv64xxx_find_baud_factors(struct mv64xxx_i2c_data *drv_data,
|
||||
const u32 req_freq, const u32 tclk)
|
||||
{
|
||||
int freq, delta, best_delta = INT_MAX;
|
||||
int m, n;
|
||||
|
||||
for (n = 0; n <= 7; n++)
|
||||
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;
|
||||
if (delta >= 0 && delta < best_delta) {
|
||||
*best_m = m;
|
||||
*best_n = n;
|
||||
drv_data->freq_m = m;
|
||||
drv_data->freq_n = n;
|
||||
best_delta = delta;
|
||||
}
|
||||
if (best_delta == 0)
|
||||
|
@ -813,8 +819,11 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data,
|
|||
if (of_property_read_u32(np, "clock-frequency", &bus_freq))
|
||||
bus_freq = 100000; /* 100kHz by default */
|
||||
|
||||
if (!mv64xxx_find_baud_factors(bus_freq, tclk,
|
||||
&drv_data->freq_n, &drv_data->freq_m)) {
|
||||
if (of_device_is_compatible(np, "allwinner,sun4i-a10-i2c") ||
|
||||
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;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -576,7 +576,7 @@ static int rcar_reg_slave(struct i2c_client *slave)
|
|||
if (slave->flags & I2C_CLIENT_TEN)
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
pm_runtime_forbid(rcar_i2c_priv_to_dev(priv));
|
||||
pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));
|
||||
|
||||
priv->slave = slave;
|
||||
rcar_i2c_write(priv, ICSAR, slave->addr);
|
||||
|
@ -598,7 +598,7 @@ static int rcar_unreg_slave(struct i2c_client *slave)
|
|||
|
||||
priv->slave = NULL;
|
||||
|
||||
pm_runtime_allow(rcar_i2c_priv_to_dev(priv));
|
||||
pm_runtime_put(rcar_i2c_priv_to_dev(priv));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -908,7 +908,7 @@ static int rk3x_i2c_probe(struct platform_device *pdev)
|
|||
&i2c->scl_fall_ns))
|
||||
i2c->scl_fall_ns = 300;
|
||||
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;
|
||||
|
||||
strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
|
||||
|
|
|
@ -822,7 +822,7 @@ static int st_i2c_probe(struct platform_device *pdev)
|
|||
|
||||
adap = &i2c_dev->adap;
|
||||
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->timeout = 2 * HZ;
|
||||
adap->retries = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче