Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dmitry Torokhov and committed by
Wolfram Sang
331c3425 30f939fe

+17 -9
+8
Documentation/devicetree/bindings/i2c/i2c.txt
··· 62 62 "irq" and "wakeup" names are recognized by I2C core, other names are 63 63 left to individual drivers. 64 64 65 + - host-notify 66 + device uses SMBus host notify protocol instead of interrupt line. 67 + 65 68 - multi-master 66 69 states that there is another master active on this bus. The OS can use 67 70 this information to adapt power management to keep the arbitration awake ··· 83 80 Binding may contain optional "interrupts" property, describing interrupts 84 81 used by the device. I2C core will assign "irq" interrupt (or the very first 85 82 interrupt if not using interrupt names) as primary interrupt for the slave. 83 + 84 + Alternatively, devices supporting SMbus Host Notify, and connected to 85 + adapters that support this feature, may use "host-notify" property. I2C 86 + core will create a virtual interrupt for Host Notify and assign it as 87 + primary interrupt for the slave. 86 88 87 89 Also, if device is marked as a wakeup source, I2C core will set up "wakeup" 88 90 interrupt for the device. If "wakeup" interrupt name is not present in the
+8 -9
drivers/i2c/i2c-core.c
··· 931 931 if (!client->irq) { 932 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 938 irq = of_irq_get_byname(dev->of_node, "irq"); 936 939 if (irq == -EINVAL || irq == -ENODATA) 937 940 irq = of_irq_get(dev->of_node, 0); ··· 943 940 } 944 941 if (irq == -EPROBE_DEFER) 945 942 return irq; 946 - /* 947 - * ACPI and OF did not find any useful IRQ, try to see 948 - * if Host Notify can be used. 949 - */ 950 - if (irq < 0) { 951 - dev_dbg(dev, "Using Host Notify IRQ\n"); 952 - irq = i2c_smbus_host_notify_to_irq(client); 953 - } 943 + 954 944 if (irq < 0) 955 945 irq = 0; 956 946 ··· 1711 1715 info.addr = addr; 1712 1716 info.of_node = of_node_get(node); 1713 1717 info.archdata = &dev_ad; 1718 + 1719 + if (of_property_read_bool(node, "host-notify")) 1720 + info.flags |= I2C_CLIENT_HOST_NOTIFY; 1714 1721 1715 1722 if (of_get_property(node, "wakeup-source", NULL)) 1716 1723 info.flags |= I2C_CLIENT_WAKE;
+1
include/linux/i2c.h
··· 665 665 #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ 666 666 /* Must equal I2C_M_TEN below */ 667 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 669 #define I2C_CLIENT_WAKE 0x80 /* for board_info; true iff can wake */ 669 670 #define I2C_CLIENT_SCCB 0x9000 /* Use Omnivision SCCB protocol */ 670 671 /* Must match I2C_M_STOP|IGNORE_NAK */