Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "Bugfixes for I2C. Mostly core this time which is a bit unusual but nothing really scary in there" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: i2c: piix4: Avoid race conditions with IMC i2c: fix spelling mistake: "insufficent" -> "insufficient" i2c: print correct device invalid address i2c: do not enable fall back to Host Notify by default i2c: fix kernel memory disclosure in dev interface
This commit is contained in:
commit
aa2797b30c
|
@ -62,6 +62,9 @@ wants to support one of the below features, it should adapt the bindings below.
|
|||
"irq" and "wakeup" names are recognized by I2C core, other names are
|
||||
left to individual drivers.
|
||||
|
||||
- host-notify
|
||||
device uses SMBus host notify protocol instead of interrupt line.
|
||||
|
||||
- multi-master
|
||||
states that there is another master active on this bus. The OS can use
|
||||
this information to adapt power management to keep the arbitration awake
|
||||
|
@ -81,6 +84,11 @@ Binding may contain optional "interrupts" property, describing interrupts
|
|||
used by the device. I2C core will assign "irq" interrupt (or the very first
|
||||
interrupt if not using interrupt names) as primary interrupt for the slave.
|
||||
|
||||
Alternatively, devices supporting SMbus Host Notify, and connected to
|
||||
adapters that support this feature, may use "host-notify" property. I2C
|
||||
core will create a virtual interrupt for Host Notify and assign it as
|
||||
primary interrupt for the slave.
|
||||
|
||||
Also, if device is marked as a wakeup source, I2C core will set up "wakeup"
|
||||
interrupt for the device. If "wakeup" interrupt name is not present in the
|
||||
binding, then primary interrupt will be used as wakeup interrupt.
|
||||
|
|
|
@ -585,10 +585,29 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
|
|||
u8 command, int size, union i2c_smbus_data *data)
|
||||
{
|
||||
struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(adap);
|
||||
unsigned short piix4_smba = adapdata->smba;
|
||||
int retries = MAX_TIMEOUT;
|
||||
int smbslvcnt;
|
||||
u8 smba_en_lo;
|
||||
u8 port;
|
||||
int retval;
|
||||
|
||||
/* Request the SMBUS semaphore, avoid conflicts with the IMC */
|
||||
smbslvcnt = inb_p(SMBSLVCNT);
|
||||
do {
|
||||
outb_p(smbslvcnt | 0x10, SMBSLVCNT);
|
||||
|
||||
/* Check the semaphore status */
|
||||
smbslvcnt = inb_p(SMBSLVCNT);
|
||||
if (smbslvcnt & 0x10)
|
||||
break;
|
||||
|
||||
usleep_range(1000, 2000);
|
||||
} while (--retries);
|
||||
/* SMBus is still owned by the IMC, we give up */
|
||||
if (!retries)
|
||||
return -EBUSY;
|
||||
|
||||
mutex_lock(&piix4_mutex_sb800);
|
||||
|
||||
outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
|
||||
|
@ -606,6 +625,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
|
|||
|
||||
mutex_unlock(&piix4_mutex_sb800);
|
||||
|
||||
/* Release the semaphore */
|
||||
outb_p(smbslvcnt | 0x20, SMBSLVCNT);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -931,7 +931,10 @@ static int i2c_device_probe(struct device *dev)
|
|||
if (!client->irq) {
|
||||
int irq = -ENOENT;
|
||||
|
||||
if (dev->of_node) {
|
||||
if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
|
||||
dev_dbg(dev, "Using Host Notify IRQ\n");
|
||||
irq = i2c_smbus_host_notify_to_irq(client);
|
||||
} else if (dev->of_node) {
|
||||
irq = of_irq_get_byname(dev->of_node, "irq");
|
||||
if (irq == -EINVAL || irq == -ENODATA)
|
||||
irq = of_irq_get(dev->of_node, 0);
|
||||
|
@ -940,14 +943,7 @@ static int i2c_device_probe(struct device *dev)
|
|||
}
|
||||
if (irq == -EPROBE_DEFER)
|
||||
return irq;
|
||||
/*
|
||||
* ACPI and OF did not find any useful IRQ, try to see
|
||||
* if Host Notify can be used.
|
||||
*/
|
||||
if (irq < 0) {
|
||||
dev_dbg(dev, "Using Host Notify IRQ\n");
|
||||
irq = i2c_smbus_host_notify_to_irq(client);
|
||||
}
|
||||
|
||||
if (irq < 0)
|
||||
irq = 0;
|
||||
|
||||
|
@ -1708,7 +1704,7 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
|
|||
|
||||
if (i2c_check_addr_validity(addr, info.flags)) {
|
||||
dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
|
||||
info.addr, node->full_name);
|
||||
addr, node->full_name);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
@ -1716,6 +1712,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
|
|||
info.of_node = of_node_get(node);
|
||||
info.archdata = &dev_ad;
|
||||
|
||||
if (of_property_read_bool(node, "host-notify"))
|
||||
info.flags |= I2C_CLIENT_HOST_NOTIFY;
|
||||
|
||||
if (of_get_property(node, "wakeup-source", NULL))
|
||||
info.flags |= I2C_CLIENT_WAKE;
|
||||
|
||||
|
@ -3633,7 +3632,7 @@ int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb)
|
|||
int ret;
|
||||
|
||||
if (!client || !slave_cb) {
|
||||
WARN(1, "insufficent data\n");
|
||||
WARN(1, "insufficient data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
|
|||
unsigned long arg)
|
||||
{
|
||||
struct i2c_smbus_ioctl_data data_arg;
|
||||
union i2c_smbus_data temp;
|
||||
union i2c_smbus_data temp = {};
|
||||
int datasize, res;
|
||||
|
||||
if (copy_from_user(&data_arg,
|
||||
|
|
|
@ -665,6 +665,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
|
|||
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
|
||||
/* Must equal I2C_M_TEN below */
|
||||
#define I2C_CLIENT_SLAVE 0x20 /* we are the slave */
|
||||
#define I2C_CLIENT_HOST_NOTIFY 0x40 /* We want to use I2C host notify */
|
||||
#define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */
|
||||
#define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */
|
||||
/* Must match I2C_M_STOP|IGNORE_NAK */
|
||||
|
|
Loading…
Reference in New Issue