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

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: hci_bcm: Add the Asus TF103C to the bcm_broken_irq_dmi_table

The DSDT for the Asus TF103C specifies a IOAPIC IRQ for the HCI -> host IRQ
but this is not correct. Unlike the previous entries in the table, this
time the correct GPIO to use instead is known; and the TF103C is battery
powered making runtime-pm support more important.

Extend the bcm_broken_irq_dmi_table mechanism to allow specifying the right
GPIO instead of just always disabling runtime-pm and add an entry to it for
the Asus TF103C.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Hans de Goede and committed by
Marcel Holtmann
27e8527e 5ad80cfc

+36 -8
+36 -8
drivers/bluetooth/hci_bcm.c
··· 20 20 #include <linux/regulator/consumer.h> 21 21 #include <linux/clk.h> 22 22 #include <linux/gpio/consumer.h> 23 + #include <linux/gpio/machine.h> 23 24 #include <linux/tty.h> 24 25 #include <linux/interrupt.h> 25 26 #include <linux/dmi.h> ··· 871 870 #endif 872 871 873 872 /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */ 873 + static struct gpiod_lookup_table asus_tf103c_irq_gpios = { 874 + .dev_id = "serial0-0", 875 + .table = { 876 + GPIO_LOOKUP("INT33FC:02", 17, "host-wakeup-alt", GPIO_ACTIVE_HIGH), 877 + { } 878 + }, 879 + }; 880 + 874 881 static const struct dmi_system_id bcm_broken_irq_dmi_table[] = { 882 + { 883 + .ident = "Asus TF103C", 884 + .matches = { 885 + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 886 + DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), 887 + }, 888 + .driver_data = &asus_tf103c_irq_gpios, 889 + }, 875 890 { 876 891 .ident = "Meegopad T08", 877 892 .matches = { ··· 1044 1027 1045 1028 static int bcm_get_resources(struct bcm_device *dev) 1046 1029 { 1047 - const struct dmi_system_id *dmi_id; 1030 + const struct dmi_system_id *broken_irq_dmi_id; 1031 + const char *irq_con_id = "host-wakeup"; 1048 1032 int err; 1049 1033 1050 1034 dev->name = dev_name(dev->dev); ··· 1101 1083 if (err) 1102 1084 return err; 1103 1085 1086 + broken_irq_dmi_id = dmi_first_match(bcm_broken_irq_dmi_table); 1087 + if (broken_irq_dmi_id && broken_irq_dmi_id->driver_data) { 1088 + gpiod_add_lookup_table(broken_irq_dmi_id->driver_data); 1089 + irq_con_id = "host-wakeup-alt"; 1090 + dev->irq_active_low = false; 1091 + dev->irq = 0; 1092 + } 1093 + 1104 1094 /* IRQ can be declared in ACPI table as Interrupt or GpioInt */ 1105 1095 if (dev->irq <= 0) { 1106 1096 struct gpio_desc *gpio; 1107 1097 1108 - gpio = devm_gpiod_get_optional(dev->dev, "host-wakeup", 1109 - GPIOD_IN); 1098 + gpio = devm_gpiod_get_optional(dev->dev, irq_con_id, GPIOD_IN); 1110 1099 if (IS_ERR(gpio)) 1111 1100 return PTR_ERR(gpio); 1112 1101 1113 1102 dev->irq = gpiod_to_irq(gpio); 1114 1103 } 1115 1104 1116 - dmi_id = dmi_first_match(bcm_broken_irq_dmi_table); 1117 - if (dmi_id) { 1118 - dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm\n", 1119 - dmi_id->ident); 1120 - dev->irq = 0; 1105 + if (broken_irq_dmi_id) { 1106 + if (broken_irq_dmi_id->driver_data) { 1107 + gpiod_remove_lookup_table(broken_irq_dmi_id->driver_data); 1108 + } else { 1109 + dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm\n", 1110 + broken_irq_dmi_id->ident); 1111 + dev->irq = 0; 1112 + } 1121 1113 } 1122 1114 1123 1115 dev_dbg(dev->dev, "BCM irq: %d\n", dev->irq);