forked from Minki/linux
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "i2c driver bugfixes (s3c2410, slave-eeprom, sh_mobile), size regression "bugfix" (i2c slave), documentation bugfix (st). Also, one documentation update (da9063), so some devicetrees can now be verified" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: sh_mobile: terminate DMA reads properly i2c: Only include slave support if selected i2c: s3c2410: fix ABBA deadlock by keeping clock prepared i2c: slave-eeprom: fix boundary check when using sysfs i2c: st: Rename clock reference to something that exists DT: i2c: Add devices handled by the da9063 MFD driver
This commit is contained in:
commit
788807d7ca
@ -31,7 +31,7 @@ i2c0: i2c@fed40000 {
|
||||
compatible = "st,comms-ssc4-i2c";
|
||||
reg = <0xfed40000 0x110>;
|
||||
interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&CLK_S_ICN_REG_0>;
|
||||
clocks = <&clk_s_a0_ls CLK_ICN_REG>;
|
||||
clock-names = "ssc";
|
||||
clock-frequency = <400000>;
|
||||
pinctrl-names = "default";
|
||||
|
@ -47,6 +47,7 @@ dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM
|
||||
dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O
|
||||
dallas,ds75 Digital Thermometer and Thermostat
|
||||
dlg,da9053 DA9053: flexible system level PMIC with multicore support
|
||||
dlg,da9063 DA9063: system PMIC for quad-core application processors
|
||||
epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
|
||||
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
|
||||
fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer
|
||||
|
@ -881,6 +881,7 @@ config I2C_XLR
|
||||
config I2C_RCAR
|
||||
tristate "Renesas R-Car I2C Controller"
|
||||
depends on ARCH_SHMOBILE || COMPILE_TEST
|
||||
select I2C_SLAVE
|
||||
help
|
||||
If you say yes to this option, support will be included for the
|
||||
R-Car I2C controller.
|
||||
|
@ -785,14 +785,16 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
|
||||
int ret;
|
||||
|
||||
pm_runtime_get_sync(&adap->dev);
|
||||
clk_prepare_enable(i2c->clk);
|
||||
ret = clk_enable(i2c->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (retry = 0; retry < adap->retries; retry++) {
|
||||
|
||||
ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
|
||||
|
||||
if (ret != -EAGAIN) {
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
clk_disable(i2c->clk);
|
||||
pm_runtime_put(&adap->dev);
|
||||
return ret;
|
||||
}
|
||||
@ -802,7 +804,7 @@ static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
clk_disable(i2c->clk);
|
||||
pm_runtime_put(&adap->dev);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
@ -1197,7 +1199,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
clk_prepare_enable(i2c->clk);
|
||||
ret = s3c24xx_i2c_init(i2c);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
clk_disable(i2c->clk);
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "I2C controller init failed\n");
|
||||
return ret;
|
||||
@ -1210,6 +1212,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
|
||||
i2c->irq = ret = platform_get_irq(pdev, 0);
|
||||
if (ret <= 0) {
|
||||
dev_err(&pdev->dev, "cannot find IRQ\n");
|
||||
clk_unprepare(i2c->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1218,6 +1221,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
if (ret != 0) {
|
||||
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
|
||||
clk_unprepare(i2c->clk);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -1225,6 +1229,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
|
||||
ret = s3c24xx_i2c_register_cpufreq(i2c);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to register cpufreq notifier\n");
|
||||
clk_unprepare(i2c->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1241,6 +1246,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
|
||||
s3c24xx_i2c_deregister_cpufreq(i2c);
|
||||
clk_unprepare(i2c->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1262,6 +1268,8 @@ static int s3c24xx_i2c_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
|
||||
|
||||
clk_unprepare(i2c->clk);
|
||||
|
||||
pm_runtime_disable(&i2c->adap.dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
@ -1293,13 +1301,16 @@ static int s3c24xx_i2c_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
if (!IS_ERR(i2c->sysreg))
|
||||
regmap_write(i2c->sysreg, EXYNOS5_SYS_I2C_CFG, i2c->sys_i2c_cfg);
|
||||
|
||||
clk_prepare_enable(i2c->clk);
|
||||
ret = clk_enable(i2c->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
s3c24xx_i2c_init(i2c);
|
||||
clk_disable_unprepare(i2c->clk);
|
||||
clk_disable(i2c->clk);
|
||||
i2c->suspended = 0;
|
||||
|
||||
return 0;
|
||||
|
@ -139,6 +139,7 @@ struct sh_mobile_i2c_data {
|
||||
int pos;
|
||||
int sr;
|
||||
bool send_stop;
|
||||
bool stop_after_dma;
|
||||
|
||||
struct resource *res;
|
||||
struct dma_chan *dma_tx;
|
||||
@ -407,7 +408,7 @@ static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd)
|
||||
|
||||
if (pd->pos == pd->msg->len) {
|
||||
/* Send stop if we haven't yet (DMA case) */
|
||||
if (pd->send_stop && (iic_rd(pd, ICCR) & ICCR_BBSY))
|
||||
if (pd->send_stop && pd->stop_after_dma)
|
||||
i2c_op(pd, OP_TX_STOP, 0);
|
||||
return 1;
|
||||
}
|
||||
@ -449,6 +450,13 @@ static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
|
||||
real_pos = pd->pos - 2;
|
||||
|
||||
if (pd->pos == pd->msg->len) {
|
||||
if (pd->stop_after_dma) {
|
||||
/* Simulate PIO end condition after DMA transfer */
|
||||
i2c_op(pd, OP_RX_STOP, 0);
|
||||
pd->pos++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (real_pos < 0) {
|
||||
i2c_op(pd, OP_RX_STOP, 0);
|
||||
break;
|
||||
@ -536,6 +544,7 @@ static void sh_mobile_i2c_dma_callback(void *data)
|
||||
|
||||
sh_mobile_i2c_dma_unmap(pd);
|
||||
pd->pos = pd->msg->len;
|
||||
pd->stop_after_dma = true;
|
||||
|
||||
iic_set_clr(pd, ICIC, 0, ICIC_TDMAE | ICIC_RDMAE);
|
||||
}
|
||||
@ -726,6 +735,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
|
||||
bool do_start = pd->send_stop || !i;
|
||||
msg = &msgs[i];
|
||||
pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP;
|
||||
pd->stop_after_dma = false;
|
||||
|
||||
err = start_ch(pd, msg, do_start);
|
||||
if (err)
|
||||
|
@ -2972,6 +2972,7 @@ trace:
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_smbus_xfer);
|
||||
|
||||
#if IS_ENABLED(CONFIG_I2C_SLAVE)
|
||||
int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
|
||||
{
|
||||
int ret;
|
||||
@ -3019,6 +3020,7 @@ int i2c_slave_unregister(struct i2c_client *client)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_slave_unregister);
|
||||
#endif
|
||||
|
||||
MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
|
||||
MODULE_DESCRIPTION("I2C-Bus main module");
|
||||
|
@ -74,7 +74,7 @@ static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj
|
||||
struct eeprom_data *eeprom;
|
||||
unsigned long flags;
|
||||
|
||||
if (off + count >= attr->size)
|
||||
if (off + count > attr->size)
|
||||
return -EFBIG;
|
||||
|
||||
eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
@ -92,7 +92,7 @@ static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kob
|
||||
struct eeprom_data *eeprom;
|
||||
unsigned long flags;
|
||||
|
||||
if (off + count >= attr->size)
|
||||
if (off + count > attr->size)
|
||||
return -EFBIG;
|
||||
|
||||
eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj));
|
||||
|
@ -228,7 +228,9 @@ struct i2c_client {
|
||||
struct device dev; /* the device structure */
|
||||
int irq; /* irq issued by device */
|
||||
struct list_head detected;
|
||||
#if IS_ENABLED(CONFIG_I2C_SLAVE)
|
||||
i2c_slave_cb_t slave_cb; /* callback for slave mode */
|
||||
#endif
|
||||
};
|
||||
#define to_i2c_client(d) container_of(d, struct i2c_client, dev)
|
||||
|
||||
@ -253,6 +255,7 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
|
||||
|
||||
/* I2C slave support */
|
||||
|
||||
#if IS_ENABLED(CONFIG_I2C_SLAVE)
|
||||
enum i2c_slave_event {
|
||||
I2C_SLAVE_REQ_READ_START,
|
||||
I2C_SLAVE_REQ_READ_END,
|
||||
@ -269,6 +272,7 @@ static inline int i2c_slave_event(struct i2c_client *client,
|
||||
{
|
||||
return client->slave_cb(client, event, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct i2c_board_info - template for device creation
|
||||
@ -404,8 +408,10 @@ struct i2c_algorithm {
|
||||
/* To determine what the adapter supports */
|
||||
u32 (*functionality) (struct i2c_adapter *);
|
||||
|
||||
#if IS_ENABLED(CONFIG_I2C_SLAVE)
|
||||
int (*reg_slave)(struct i2c_client *client);
|
||||
int (*unreg_slave)(struct i2c_client *client);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user