Commit 331c3425 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Wolfram Sang

i2c: do not enable fall back to Host Notify by default

Falling back unconditionally to HostNotify as primary client's interrupt
breaks some drivers which alter their functionality depending on whether
interrupt is present or not, so let's introduce a board flag telling I2C
core explicitly if we want wired interrupt or HostNotify-based one:
I2C_CLIENT_HOST_NOTIFY.

For DT-based systems we introduce "host-notify" property that we convert
to I2C_CLIENT_HOST_NOTIFY board flag.
Tested-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
Acked-by: default avatarPali Rohár <pali.rohar@gmail.com>
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 30f939fe
...@@ -62,6 +62,9 @@ wants to support one of the below features, it should adapt the bindings below. ...@@ -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 "irq" and "wakeup" names are recognized by I2C core, other names are
left to individual drivers. left to individual drivers.
- host-notify
device uses SMBus host notify protocol instead of interrupt line.
- multi-master - multi-master
states that there is another master active on this bus. The OS can use 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 this information to adapt power management to keep the arbitration awake
...@@ -81,6 +84,11 @@ Binding may contain optional "interrupts" property, describing interrupts ...@@ -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 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. 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" 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 interrupt for the device. If "wakeup" interrupt name is not present in the
binding, then primary interrupt will be used as wakeup interrupt. binding, then primary interrupt will be used as wakeup interrupt.
...@@ -931,7 +931,10 @@ static int i2c_device_probe(struct device *dev) ...@@ -931,7 +931,10 @@ static int i2c_device_probe(struct device *dev)
if (!client->irq) { if (!client->irq) {
int irq = -ENOENT; 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"); irq = of_irq_get_byname(dev->of_node, "irq");
if (irq == -EINVAL || irq == -ENODATA) if (irq == -EINVAL || irq == -ENODATA)
irq = of_irq_get(dev->of_node, 0); irq = of_irq_get(dev->of_node, 0);
...@@ -940,14 +943,7 @@ static int i2c_device_probe(struct device *dev) ...@@ -940,14 +943,7 @@ static int i2c_device_probe(struct device *dev)
} }
if (irq == -EPROBE_DEFER) if (irq == -EPROBE_DEFER)
return irq; 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) if (irq < 0)
irq = 0; irq = 0;
...@@ -1716,6 +1712,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap, ...@@ -1716,6 +1712,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
info.of_node = of_node_get(node); info.of_node = of_node_get(node);
info.archdata = &dev_ad; 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)) if (of_get_property(node, "wakeup-source", NULL))
info.flags |= I2C_CLIENT_WAKE; info.flags |= I2C_CLIENT_WAKE;
......
...@@ -665,6 +665,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter) ...@@ -665,6 +665,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
/* Must equal I2C_M_TEN below */ /* Must equal I2C_M_TEN below */
#define I2C_CLIENT_SLAVE 0x20 /* we are the slave */ #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_WAKE 0x80 /* for board_info; true iff can wake */
#define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */ #define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */
/* Must match I2C_M_STOP|IGNORE_NAK */ /* Must match I2C_M_STOP|IGNORE_NAK */
......
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