diff mbox series

Bluetooth: hci_bcm: Add the Asus TF103C to the bcm_broken_irq_dmi_table

Message ID 20211231115055.115988-1-hdegoede@redhat.com
State Superseded
Headers show
Series Bluetooth: hci_bcm: Add the Asus TF103C to the bcm_broken_irq_dmi_table | expand

Commit Message

Hans de Goede Dec. 31, 2021, 11:50 a.m. UTC
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>
---
 drivers/bluetooth/hci_bcm.c | 44 ++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 8 deletions(-)

Comments

Marcel Holtmann Jan. 6, 2022, 8:27 p.m. UTC | #1
Hi Hans,

> 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>
> ---
> drivers/bluetooth/hci_bcm.c | 44 ++++++++++++++++++++++++++++++-------
> 1 file changed, 36 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
> index ef54afa29357..c6ac4aa994af 100644
> --- a/drivers/bluetooth/hci_bcm.c
> +++ b/drivers/bluetooth/hci_bcm.c
> @@ -20,6 +20,7 @@
> #include <linux/regulator/consumer.h>
> #include <linux/clk.h>
> #include <linux/gpio/consumer.h>
> +#include <linux/gpio/machine.h>
> #include <linux/tty.h>
> #include <linux/interrupt.h>
> #include <linux/dmi.h>
> @@ -870,7 +871,23 @@ static int bcm_resume(struct device *dev)
> #endif
> 
> /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
> +static struct gpiod_lookup_table asus_tf103c_irq_gpios = {
> +	.dev_id = "serial0-0",

do you need this one? I assume it could be easily enumerated as serial1-0 if you are unlucky.

> +	.table = {
> +		GPIO_LOOKUP("INT33FC:02", 17, "host-wakeup-alt", GPIO_ACTIVE_HIGH),
> +		{ }
> +	},
> +};
> +
> static const struct dmi_system_id bcm_broken_irq_dmi_table[] = {
> +	{
> +		.ident = "Asus TF103C",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
> +		},
> +		.driver_data = &asus_tf103c_irq_gpios,
> +	},
> 	{
> 		.ident = "Meegopad T08",
> 		.matches = {

Regards

Marcel
Hans de Goede Jan. 13, 2022, 3:22 p.m. UTC | #2
Hi Marcel,

Thank you for the review.

On 1/6/22 21:27, Marcel Holtmann wrote:
> Hi Hans,
> 
>> 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>
>> ---
>> drivers/bluetooth/hci_bcm.c | 44 ++++++++++++++++++++++++++++++-------
>> 1 file changed, 36 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
>> index ef54afa29357..c6ac4aa994af 100644
>> --- a/drivers/bluetooth/hci_bcm.c
>> +++ b/drivers/bluetooth/hci_bcm.c
>> @@ -20,6 +20,7 @@
>> #include <linux/regulator/consumer.h>
>> #include <linux/clk.h>
>> #include <linux/gpio/consumer.h>
>> +#include <linux/gpio/machine.h>
>> #include <linux/tty.h>
>> #include <linux/interrupt.h>
>> #include <linux/dmi.h>
>> @@ -870,7 +871,23 @@ static int bcm_resume(struct device *dev)
>> #endif
>>
>> /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
>> +static struct gpiod_lookup_table asus_tf103c_irq_gpios = {
>> +	.dev_id = "serial0-0",
> 
> do you need this one? I assume it could be easily enumerated as serial1-0 if you are unlucky.

Yes there can be multiple global gpiod_lookup_table-s registered
and the gpiolib code finds the one to use be matching this field
to the dev_name() for the device passed to gpiod_get().

I'm not worried about this getting enumerated with another dev_name(),
this is a tablet with no ways to add extra serial-bus devices and
there is only the 1 serial-bus device.

Regards,

Hans



> 
>> +	.table = {
>> +		GPIO_LOOKUP("INT33FC:02", 17, "host-wakeup-alt", GPIO_ACTIVE_HIGH),
>> +		{ }
>> +	},
>> +};
>> +
>> static const struct dmi_system_id bcm_broken_irq_dmi_table[] = {
>> +	{
>> +		.ident = "Asus TF103C",
>> +		.matches = {
>> +			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
>> +			DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
>> +		},
>> +		.driver_data = &asus_tf103c_irq_gpios,
>> +	},
>> 	{
>> 		.ident = "Meegopad T08",
>> 		.matches = {
> 
> Regards
> 
> Marcel
>
Marcel Holtmann Jan. 19, 2022, 7:39 p.m. UTC | #3
Hi Hans,

>>> 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>
>>> ---
>>> drivers/bluetooth/hci_bcm.c | 44 ++++++++++++++++++++++++++++++-------
>>> 1 file changed, 36 insertions(+), 8 deletions(-)
>>> 
>>> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
>>> index ef54afa29357..c6ac4aa994af 100644
>>> --- a/drivers/bluetooth/hci_bcm.c
>>> +++ b/drivers/bluetooth/hci_bcm.c
>>> @@ -20,6 +20,7 @@
>>> #include <linux/regulator/consumer.h>
>>> #include <linux/clk.h>
>>> #include <linux/gpio/consumer.h>
>>> +#include <linux/gpio/machine.h>
>>> #include <linux/tty.h>
>>> #include <linux/interrupt.h>
>>> #include <linux/dmi.h>
>>> @@ -870,7 +871,23 @@ static int bcm_resume(struct device *dev)
>>> #endif
>>> 
>>> /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
>>> +static struct gpiod_lookup_table asus_tf103c_irq_gpios = {
>>> +	.dev_id = "serial0-0",
>> 
>> do you need this one? I assume it could be easily enumerated as serial1-0 if you are unlucky.
> 
> Yes there can be multiple global gpiod_lookup_table-s registered
> and the gpiolib code finds the one to use be matching this field
> to the dev_name() for the device passed to gpiod_get().
> 
> I'm not worried about this getting enumerated with another dev_name(),
> this is a tablet with no ways to add extra serial-bus devices and
> there is only the 1 serial-bus device.

is there no other way to match this device?

Regards

Marcel
Hans de Goede Jan. 19, 2022, 8:32 p.m. UTC | #4
Hi Marcel,

On 1/19/22 20:39, Marcel Holtmann wrote:
> Hi Hans,
> 
>>>> 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>
>>>> ---
>>>> drivers/bluetooth/hci_bcm.c | 44 ++++++++++++++++++++++++++++++-------
>>>> 1 file changed, 36 insertions(+), 8 deletions(-)
>>>>
>>>> diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
>>>> index ef54afa29357..c6ac4aa994af 100644
>>>> --- a/drivers/bluetooth/hci_bcm.c
>>>> +++ b/drivers/bluetooth/hci_bcm.c
>>>> @@ -20,6 +20,7 @@
>>>> #include <linux/regulator/consumer.h>
>>>> #include <linux/clk.h>
>>>> #include <linux/gpio/consumer.h>
>>>> +#include <linux/gpio/machine.h>
>>>> #include <linux/tty.h>
>>>> #include <linux/interrupt.h>
>>>> #include <linux/dmi.h>
>>>> @@ -870,7 +871,23 @@ static int bcm_resume(struct device *dev)
>>>> #endif
>>>>
>>>> /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
>>>> +static struct gpiod_lookup_table asus_tf103c_irq_gpios = {
>>>> +	.dev_id = "serial0-0",
>>>
>>> do you need this one? I assume it could be easily enumerated as serial1-0 if you are unlucky.
>>
>> Yes there can be multiple global gpiod_lookup_table-s registered
>> and the gpiolib code finds the one to use be matching this field
>> to the dev_name() for the device passed to gpiod_get().
>>
>> I'm not worried about this getting enumerated with another dev_name(),
>> this is a tablet with no ways to add extra serial-bus devices and
>> there is only the 1 serial-bus device.
> 
> is there no other way to match this device?

I'm not sure what you mean ny "matching this device" ?  Since the ACPI
tables on this tablet contain the wrong GPIO, we need a gpio-lookup
table override and the gpio cores checks for a lookup table to use with
a specific struct device * based on dev_name() and only based on that,
there are no other matching options in the gpio-lookup mechanism.

Regards,

Hans
diff mbox series

Patch

diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
index ef54afa29357..c6ac4aa994af 100644
--- a/drivers/bluetooth/hci_bcm.c
+++ b/drivers/bluetooth/hci_bcm.c
@@ -20,6 +20,7 @@ 
 #include <linux/regulator/consumer.h>
 #include <linux/clk.h>
 #include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h>
 #include <linux/tty.h>
 #include <linux/interrupt.h>
 #include <linux/dmi.h>
@@ -870,7 +871,23 @@  static int bcm_resume(struct device *dev)
 #endif
 
 /* Some firmware reports an IRQ which does not work (wrong pin in fw table?) */
+static struct gpiod_lookup_table asus_tf103c_irq_gpios = {
+	.dev_id = "serial0-0",
+	.table = {
+		GPIO_LOOKUP("INT33FC:02", 17, "host-wakeup-alt", GPIO_ACTIVE_HIGH),
+		{ }
+	},
+};
+
 static const struct dmi_system_id bcm_broken_irq_dmi_table[] = {
+	{
+		.ident = "Asus TF103C",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
+		},
+		.driver_data = &asus_tf103c_irq_gpios,
+	},
 	{
 		.ident = "Meegopad T08",
 		.matches = {
@@ -1027,7 +1044,8 @@  static struct clk *bcm_get_txco(struct device *dev)
 
 static int bcm_get_resources(struct bcm_device *dev)
 {
-	const struct dmi_system_id *dmi_id;
+	const struct dmi_system_id *broken_irq_dmi_id;
+	const char *irq_con_id = "host-wakeup";
 	int err;
 
 	dev->name = dev_name(dev->dev);
@@ -1083,23 +1101,33 @@  static int bcm_get_resources(struct bcm_device *dev)
 	if (err)
 		return err;
 
+	broken_irq_dmi_id = dmi_first_match(bcm_broken_irq_dmi_table);
+	if (broken_irq_dmi_id && broken_irq_dmi_id->driver_data) {
+		gpiod_add_lookup_table(broken_irq_dmi_id->driver_data);
+		irq_con_id = "host-wakeup-alt";
+		dev->irq_active_low = false;
+		dev->irq = 0;
+	}
+
 	/* IRQ can be declared in ACPI table as Interrupt or GpioInt */
 	if (dev->irq <= 0) {
 		struct gpio_desc *gpio;
 
-		gpio = devm_gpiod_get_optional(dev->dev, "host-wakeup",
-					       GPIOD_IN);
+		gpio = devm_gpiod_get_optional(dev->dev, irq_con_id, GPIOD_IN);
 		if (IS_ERR(gpio))
 			return PTR_ERR(gpio);
 
 		dev->irq = gpiod_to_irq(gpio);
 	}
 
-	dmi_id = dmi_first_match(bcm_broken_irq_dmi_table);
-	if (dmi_id) {
-		dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm\n",
-			 dmi_id->ident);
-		dev->irq = 0;
+	if (broken_irq_dmi_id) {
+		if (broken_irq_dmi_id->driver_data) {
+			gpiod_remove_lookup_table(broken_irq_dmi_id->driver_data);
+		} else {
+			dev_info(dev->dev, "%s: Has a broken IRQ config, disabling IRQ support / runtime-pm\n",
+				 broken_irq_dmi_id->ident);
+			dev->irq = 0;
+		}
 	}
 
 	dev_dbg(dev->dev, "BCM irq: %d\n", dev->irq);