Commit c2f3ba74 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:
 "A refcounting bugfix for the i2c-core, bugfixes for the generic bus
  recovery algorithm and for its omap-user, making binary file
  attributes for EEPROMs behave POSIX compliant, and a small typo fix
  while we are here"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: fix leaked device refcount on of_find_i2c_* error path
  i2c: Fix typo in i2c-bfin-twi.c
  i2c: omap: fix bus recovery setup
  i2c: core: only use set_scl for bus recovery after calling prepare_recovery
  misc: eeprom: at24: clean up at24_bin_write()
  i2c: slave eeprom: clean up sysfs bin attribute read()/write()
parents 7e884479 e3311469
...@@ -692,7 +692,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) ...@@ -692,7 +692,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, iface); platform_set_drvdata(pdev, iface);
dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, " dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Controller, "
"regs_base@%p\n", iface->regs_base); "regs_base@%p\n", iface->regs_base);
return 0; return 0;
...@@ -735,6 +735,6 @@ subsys_initcall(i2c_bfin_twi_init); ...@@ -735,6 +735,6 @@ subsys_initcall(i2c_bfin_twi_init);
module_exit(i2c_bfin_twi_exit); module_exit(i2c_bfin_twi_exit);
MODULE_AUTHOR("Bryan Wu, Sonic Zhang"); MODULE_AUTHOR("Bryan Wu, Sonic Zhang");
MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver"); MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Controller Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:i2c-bfin-twi"); MODULE_ALIAS("platform:i2c-bfin-twi");
...@@ -1247,7 +1247,14 @@ static void omap_i2c_prepare_recovery(struct i2c_adapter *adap) ...@@ -1247,7 +1247,14 @@ static void omap_i2c_prepare_recovery(struct i2c_adapter *adap)
u32 reg; u32 reg;
reg = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG); reg = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
/* enable test mode */
reg |= OMAP_I2C_SYSTEST_ST_EN; reg |= OMAP_I2C_SYSTEST_ST_EN;
/* select SDA/SCL IO mode */
reg |= 3 << OMAP_I2C_SYSTEST_TMODE_SHIFT;
/* set SCL to high-impedance state (reset value is 0) */
reg |= OMAP_I2C_SYSTEST_SCL_O;
/* set SDA to high-impedance state (reset value is 0) */
reg |= OMAP_I2C_SYSTEST_SDA_O;
omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg); omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg);
} }
...@@ -1257,7 +1264,11 @@ static void omap_i2c_unprepare_recovery(struct i2c_adapter *adap) ...@@ -1257,7 +1264,11 @@ static void omap_i2c_unprepare_recovery(struct i2c_adapter *adap)
u32 reg; u32 reg;
reg = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG); reg = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
/* restore reset values */
reg &= ~OMAP_I2C_SYSTEST_ST_EN; reg &= ~OMAP_I2C_SYSTEST_ST_EN;
reg &= ~OMAP_I2C_SYSTEST_TMODE_MASK;
reg &= ~OMAP_I2C_SYSTEST_SCL_O;
reg &= ~OMAP_I2C_SYSTEST_SDA_O;
omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg); omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, reg);
} }
......
...@@ -567,6 +567,9 @@ static int i2c_generic_recovery(struct i2c_adapter *adap) ...@@ -567,6 +567,9 @@ static int i2c_generic_recovery(struct i2c_adapter *adap)
if (bri->prepare_recovery) if (bri->prepare_recovery)
bri->prepare_recovery(adap); bri->prepare_recovery(adap);
bri->set_scl(adap, val);
ndelay(RECOVERY_NDELAY);
/* /*
* By this time SCL is high, as we need to give 9 falling-rising edges * By this time SCL is high, as we need to give 9 falling-rising edges
*/ */
...@@ -597,7 +600,6 @@ static int i2c_generic_recovery(struct i2c_adapter *adap) ...@@ -597,7 +600,6 @@ static int i2c_generic_recovery(struct i2c_adapter *adap)
int i2c_generic_scl_recovery(struct i2c_adapter *adap) int i2c_generic_scl_recovery(struct i2c_adapter *adap)
{ {
adap->bus_recovery_info->set_scl(adap, 1);
return i2c_generic_recovery(adap); return i2c_generic_recovery(adap);
} }
EXPORT_SYMBOL_GPL(i2c_generic_scl_recovery); EXPORT_SYMBOL_GPL(i2c_generic_scl_recovery);
...@@ -1338,13 +1340,17 @@ static int of_dev_node_match(struct device *dev, void *data) ...@@ -1338,13 +1340,17 @@ static int of_dev_node_match(struct device *dev, void *data)
struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
{ {
struct device *dev; struct device *dev;
struct i2c_client *client;
dev = bus_find_device(&i2c_bus_type, NULL, node, dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
of_dev_node_match);
if (!dev) if (!dev)
return NULL; return NULL;
return i2c_verify_client(dev); client = i2c_verify_client(dev);
if (!client)
put_device(dev);
return client;
} }
EXPORT_SYMBOL(of_find_i2c_device_by_node); EXPORT_SYMBOL(of_find_i2c_device_by_node);
...@@ -1352,13 +1358,17 @@ EXPORT_SYMBOL(of_find_i2c_device_by_node); ...@@ -1352,13 +1358,17 @@ EXPORT_SYMBOL(of_find_i2c_device_by_node);
struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
{ {
struct device *dev; struct device *dev;
struct i2c_adapter *adapter;
dev = bus_find_device(&i2c_bus_type, NULL, node, dev = bus_find_device(&i2c_bus_type, NULL, node, of_dev_node_match);
of_dev_node_match);
if (!dev) if (!dev)
return NULL; return NULL;
return i2c_verify_adapter(dev); adapter = i2c_verify_adapter(dev);
if (!adapter)
put_device(dev);
return adapter;
} }
EXPORT_SYMBOL(of_find_i2c_adapter_by_node); EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
#else #else
......
...@@ -80,9 +80,6 @@ static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj ...@@ -80,9 +80,6 @@ static ssize_t i2c_slave_eeprom_bin_read(struct file *filp, struct kobject *kobj
struct eeprom_data *eeprom; struct eeprom_data *eeprom;
unsigned long flags; unsigned long flags;
if (off + count > attr->size)
return -EFBIG;
eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj));
spin_lock_irqsave(&eeprom->buffer_lock, flags); spin_lock_irqsave(&eeprom->buffer_lock, flags);
...@@ -98,9 +95,6 @@ static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kob ...@@ -98,9 +95,6 @@ static ssize_t i2c_slave_eeprom_bin_write(struct file *filp, struct kobject *kob
struct eeprom_data *eeprom; struct eeprom_data *eeprom;
unsigned long flags; unsigned long flags;
if (off + count > attr->size)
return -EFBIG;
eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj)); eeprom = dev_get_drvdata(container_of(kobj, struct device, kobj));
spin_lock_irqsave(&eeprom->buffer_lock, flags); spin_lock_irqsave(&eeprom->buffer_lock, flags);
......
...@@ -438,9 +438,6 @@ static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj, ...@@ -438,9 +438,6 @@ static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj,
{ {
struct at24_data *at24; struct at24_data *at24;
if (unlikely(off >= attr->size))
return -EFBIG;
at24 = dev_get_drvdata(container_of(kobj, struct device, kobj)); at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
return at24_write(at24, buf, off, count); return at24_write(at24, buf, off, count);
} }
......
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