Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
This commit is contained in:
@@ -564,7 +564,7 @@ config I2C_STU300
|
||||
|
||||
config I2C_VERSATILE
|
||||
tristate "ARM Versatile/Realview I2C bus support"
|
||||
depends on ARCH_VERSATILE || ARCH_REALVIEW
|
||||
depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
|
||||
select I2C_ALGOBIT
|
||||
help
|
||||
Say yes if you want to support the I2C serial bus on ARMs Versatile
|
||||
|
@@ -146,10 +146,10 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
|
||||
"<%s> I2C Interrupted\n", __func__);
|
||||
return -EINTR;
|
||||
}
|
||||
if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
|
||||
if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
|
||||
dev_dbg(&i2c_imx->adapter.dev,
|
||||
"<%s> I2C bus is busy\n", __func__);
|
||||
return -EIO;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
schedule();
|
||||
}
|
||||
@@ -444,6 +444,8 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
|
||||
result = i2c_imx_read(i2c_imx, &msgs[i]);
|
||||
else
|
||||
result = i2c_imx_write(i2c_imx, &msgs[i]);
|
||||
if (result)
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
fail0:
|
||||
|
@@ -447,7 +447,7 @@ static struct i2c_adapter octeon_i2c_ops = {
|
||||
/**
|
||||
* octeon_i2c_setclock - Calculate and set clock divisors.
|
||||
*/
|
||||
static int __init octeon_i2c_setclock(struct octeon_i2c *i2c)
|
||||
static int __devinit octeon_i2c_setclock(struct octeon_i2c *i2c)
|
||||
{
|
||||
int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff;
|
||||
int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000;
|
||||
@@ -490,7 +490,7 @@ static int __init octeon_i2c_setclock(struct octeon_i2c *i2c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
|
||||
static int __devinit octeon_i2c_initlowlevel(struct octeon_i2c *i2c)
|
||||
{
|
||||
u8 status;
|
||||
int tries;
|
||||
|
@@ -903,6 +903,11 @@ omap_i2c_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, dev);
|
||||
|
||||
if (cpu_is_omap7xx())
|
||||
dev->reg_shift = 1;
|
||||
else
|
||||
dev->reg_shift = 2;
|
||||
|
||||
if ((r = omap_i2c_get_clocks(dev)) != 0)
|
||||
goto err_iounmap;
|
||||
|
||||
@@ -926,11 +931,6 @@ omap_i2c_probe(struct platform_device *pdev)
|
||||
dev->b_hw = 1; /* Enable hardware fixes */
|
||||
}
|
||||
|
||||
if (cpu_is_omap7xx())
|
||||
dev->reg_shift = 1;
|
||||
else
|
||||
dev->reg_shift = 2;
|
||||
|
||||
/* reset ASAP, clearing any IRQs */
|
||||
omap_i2c_init(dev);
|
||||
|
||||
|
@@ -173,6 +173,9 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
|
||||
/* We still have something to talk about... */
|
||||
val = *alg_data->mif.buf++;
|
||||
|
||||
if (alg_data->mif.len == 1)
|
||||
val |= stop_bit;
|
||||
|
||||
alg_data->mif.len--;
|
||||
iowrite32(val, I2C_REG_TX(alg_data));
|
||||
|
||||
@@ -246,6 +249,9 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
|
||||
__func__);
|
||||
|
||||
if (alg_data->mif.len == 1) {
|
||||
/* Last byte, do not acknowledge next rcv. */
|
||||
val |= stop_bit;
|
||||
|
||||
/*
|
||||
* Enable interrupt RFDAIE (data in Rx fifo),
|
||||
* and disable DRMIE (need data for Tx)
|
||||
@@ -633,6 +639,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
|
||||
*/
|
||||
|
||||
tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
|
||||
if (tmp > 0x3FF)
|
||||
tmp = 0x3FF;
|
||||
iowrite32(tmp, I2C_REG_CKH(alg_data));
|
||||
iowrite32(tmp, I2C_REG_CKL(alg_data));
|
||||
|
||||
|
@@ -498,7 +498,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
|
||||
int i = 0;
|
||||
|
||||
/* Locate the apropriate clock setting */
|
||||
while (i < ARRAY_SIZE(stu300_clktable) &&
|
||||
while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
|
||||
stu300_clktable[i].rate < clkrate)
|
||||
i++;
|
||||
|
||||
|
@@ -40,12 +40,11 @@
|
||||
#include "i2c-core.h"
|
||||
|
||||
|
||||
/* core_lock protects i2c_adapter_idr, userspace_devices, and guarantees
|
||||
/* core_lock protects i2c_adapter_idr, and guarantees
|
||||
that device detection, deletion of detected devices, and attach_adapter
|
||||
and detach_adapter calls are serialized */
|
||||
static DEFINE_MUTEX(core_lock);
|
||||
static DEFINE_IDR(i2c_adapter_idr);
|
||||
static LIST_HEAD(userspace_devices);
|
||||
|
||||
static struct device_type i2c_client_type;
|
||||
static int i2c_check_addr(struct i2c_adapter *adapter, int addr);
|
||||
@@ -117,8 +116,10 @@ static int i2c_device_probe(struct device *dev)
|
||||
dev_dbg(dev, "probe\n");
|
||||
|
||||
status = driver->probe(client, i2c_match_id(driver->id_table, client));
|
||||
if (status)
|
||||
if (status) {
|
||||
client->driver = NULL;
|
||||
i2c_set_clientdata(client, NULL);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -139,8 +140,10 @@ static int i2c_device_remove(struct device *dev)
|
||||
dev->driver = NULL;
|
||||
status = 0;
|
||||
}
|
||||
if (status == 0)
|
||||
if (status == 0) {
|
||||
client->driver = NULL;
|
||||
i2c_set_clientdata(client, NULL);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -538,9 +541,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
|
||||
return -EEXIST;
|
||||
|
||||
/* Keep track of the added device */
|
||||
mutex_lock(&core_lock);
|
||||
list_add_tail(&client->detected, &userspace_devices);
|
||||
mutex_unlock(&core_lock);
|
||||
i2c_lock_adapter(adap);
|
||||
list_add_tail(&client->detected, &adap->userspace_clients);
|
||||
i2c_unlock_adapter(adap);
|
||||
dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
|
||||
info.type, info.addr);
|
||||
|
||||
@@ -579,9 +582,10 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
/* Make sure the device was added through sysfs */
|
||||
res = -ENOENT;
|
||||
mutex_lock(&core_lock);
|
||||
list_for_each_entry_safe(client, next, &userspace_devices, detected) {
|
||||
if (client->addr == addr && client->adapter == adap) {
|
||||
i2c_lock_adapter(adap);
|
||||
list_for_each_entry_safe(client, next, &adap->userspace_clients,
|
||||
detected) {
|
||||
if (client->addr == addr) {
|
||||
dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
|
||||
"delete_device", client->name, client->addr);
|
||||
|
||||
@@ -591,7 +595,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&core_lock);
|
||||
i2c_unlock_adapter(adap);
|
||||
|
||||
if (res < 0)
|
||||
dev_err(dev, "%s: Can't find device in list\n",
|
||||
@@ -673,6 +677,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
|
||||
}
|
||||
|
||||
rt_mutex_init(&adap->bus_lock);
|
||||
INIT_LIST_HEAD(&adap->userspace_clients);
|
||||
|
||||
/* Set default timeout to 1 second if not already set */
|
||||
if (adap->timeout == 0)
|
||||
@@ -875,14 +880,15 @@ int i2c_del_adapter(struct i2c_adapter *adap)
|
||||
return res;
|
||||
|
||||
/* Remove devices instantiated from sysfs */
|
||||
list_for_each_entry_safe(client, next, &userspace_devices, detected) {
|
||||
if (client->adapter == adap) {
|
||||
dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
|
||||
client->name, client->addr);
|
||||
list_del(&client->detected);
|
||||
i2c_unregister_device(client);
|
||||
}
|
||||
i2c_lock_adapter(adap);
|
||||
list_for_each_entry_safe(client, next, &adap->userspace_clients,
|
||||
detected) {
|
||||
dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
|
||||
client->addr);
|
||||
list_del(&client->detected);
|
||||
i2c_unregister_device(client);
|
||||
}
|
||||
i2c_unlock_adapter(adap);
|
||||
|
||||
/* Detach any active clients. This can't fail, thus we do not
|
||||
checking the returned value. */
|
||||
@@ -1260,12 +1266,23 @@ static int i2c_detect_address(struct i2c_client *temp_client,
|
||||
return 0;
|
||||
|
||||
/* Make sure there is something at this address */
|
||||
if (i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
|
||||
return 0;
|
||||
if (addr == 0x73 && (adapter->class & I2C_CLASS_HWMON)) {
|
||||
/* Special probe for FSC hwmon chips */
|
||||
union i2c_smbus_data dummy;
|
||||
|
||||
/* Prevent 24RF08 corruption */
|
||||
if ((addr & ~0x0f) == 0x50)
|
||||
i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL);
|
||||
if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_READ, 0,
|
||||
I2C_SMBUS_BYTE_DATA, &dummy) < 0)
|
||||
return 0;
|
||||
} else {
|
||||
if (i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
|
||||
I2C_SMBUS_QUICK, NULL) < 0)
|
||||
return 0;
|
||||
|
||||
/* Prevent 24RF08 corruption */
|
||||
if ((addr & ~0x0f) == 0x50)
|
||||
i2c_smbus_xfer(adapter, addr, 0, I2C_SMBUS_WRITE, 0,
|
||||
I2C_SMBUS_QUICK, NULL);
|
||||
}
|
||||
|
||||
/* Finally call the custom detection function */
|
||||
memset(&info, 0, sizeof(struct i2c_board_info));
|
||||
|
Reference in New Issue
Block a user