aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2017-01-04 23:57:22 -0500
committerWolfram Sang <wsa@the-dreams.de>2017-01-12 14:06:15 -0500
commit331c34255293cd02d395b7097008b509ba89e60e (patch)
tree90c079b378ecb58eaa9dac6341ae9c776bc97019
parent30f939feaeee23e21391cfc7b484f012eb189c3c (diff)
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: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Acked-by: Pali Rohár <pali.rohar@gmail.com> Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c.txt8
-rw-r--r--drivers/i2c/i2c-core.c17
-rw-r--r--include/linux/i2c.h1
3 files changed, 17 insertions, 9 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt
index 5fa691e6f638..cee9d5055fa2 100644
--- a/Documentation/devicetree/bindings/i2c/i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c.txt
@@ -62,6 +62,9 @@ wants to support one of the below features, it should adapt the bindings below.
62 "irq" and "wakeup" names are recognized by I2C core, other names are 62 "irq" and "wakeup" names are recognized by I2C core, other names are
63 left to individual drivers. 63 left to individual drivers.
64 64
65- host-notify
66 device uses SMBus host notify protocol instead of interrupt line.
67
65- multi-master 68- multi-master
66 states that there is another master active on this bus. The OS can use 69 states that there is another master active on this bus. The OS can use
67 this information to adapt power management to keep the arbitration awake 70 this information to adapt power management to keep the arbitration awake
@@ -81,6 +84,11 @@ Binding may contain optional "interrupts" property, describing interrupts
81used by the device. I2C core will assign "irq" interrupt (or the very first 84used by the device. I2C core will assign "irq" interrupt (or the very first
82interrupt if not using interrupt names) as primary interrupt for the slave. 85interrupt if not using interrupt names) as primary interrupt for the slave.
83 86
87Alternatively, devices supporting SMbus Host Notify, and connected to
88adapters that support this feature, may use "host-notify" property. I2C
89core will create a virtual interrupt for Host Notify and assign it as
90primary interrupt for the slave.
91
84Also, if device is marked as a wakeup source, I2C core will set up "wakeup" 92Also, if device is marked as a wakeup source, I2C core will set up "wakeup"
85interrupt for the device. If "wakeup" interrupt name is not present in the 93interrupt for the device. If "wakeup" interrupt name is not present in the
86binding, then primary interrupt will be used as wakeup interrupt. 94binding, then primary interrupt will be used as wakeup interrupt.
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index cf9e396d7702..7b117240f1ea 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -931,7 +931,10 @@ static int i2c_device_probe(struct device *dev)
931 if (!client->irq) { 931 if (!client->irq) {
932 int irq = -ENOENT; 932 int irq = -ENOENT;
933 933
934 if (dev->of_node) { 934 if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
935 dev_dbg(dev, "Using Host Notify IRQ\n");
936 irq = i2c_smbus_host_notify_to_irq(client);
937 } else if (dev->of_node) {
935 irq = of_irq_get_byname(dev->of_node, "irq"); 938 irq = of_irq_get_byname(dev->of_node, "irq");
936 if (irq == -EINVAL || irq == -ENODATA) 939 if (irq == -EINVAL || irq == -ENODATA)
937 irq = of_irq_get(dev->of_node, 0); 940 irq = of_irq_get(dev->of_node, 0);
@@ -940,14 +943,7 @@ static int i2c_device_probe(struct device *dev)
940 } 943 }
941 if (irq == -EPROBE_DEFER) 944 if (irq == -EPROBE_DEFER)
942 return irq; 945 return irq;
943 /* 946
944 * ACPI and OF did not find any useful IRQ, try to see
945 * if Host Notify can be used.
946 */
947 if (irq < 0) {
948 dev_dbg(dev, "Using Host Notify IRQ\n");
949 irq = i2c_smbus_host_notify_to_irq(client);
950 }
951 if (irq < 0) 947 if (irq < 0)
952 irq = 0; 948 irq = 0;
953 949
@@ -1716,6 +1712,9 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
1716 info.of_node = of_node_get(node); 1712 info.of_node = of_node_get(node);
1717 info.archdata = &dev_ad; 1713 info.archdata = &dev_ad;
1718 1714
1715 if (of_property_read_bool(node, "host-notify"))
1716 info.flags |= I2C_CLIENT_HOST_NOTIFY;
1717
1719 if (of_get_property(node, "wakeup-source", NULL)) 1718 if (of_get_property(node, "wakeup-source", NULL))
1720 info.flags |= I2C_CLIENT_WAKE; 1719 info.flags |= I2C_CLIENT_WAKE;
1721 1720
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index b2109c522dec..4b45ec46161f 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -665,6 +665,7 @@ i2c_unlock_adapter(struct i2c_adapter *adapter)
665#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ 665#define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
666 /* Must equal I2C_M_TEN below */ 666 /* Must equal I2C_M_TEN below */
667#define I2C_CLIENT_SLAVE 0x20 /* we are the slave */ 667#define I2C_CLIENT_SLAVE 0x20 /* we are the slave */
668#define I2C_CLIENT_HOST_NOTIFY 0x40 /* We want to use I2C host notify */
668#define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */ 669#define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */
669#define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */ 670#define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */
670 /* Must match I2C_M_STOP|IGNORE_NAK */ 671 /* Must match I2C_M_STOP|IGNORE_NAK */