diff mbox

ACPI / LPSS: Work around wrong sdio _ADR 0 entry on some byt/cht devices

Message ID 20161225102148.7706-1-hdegoede@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Hans de Goede Dec. 25, 2016, 10:21 a.m. UTC
The firmware on some cherrytrail devices wrongly adds _ADR 0 to their
entry describing the 80860F14 uid "2" sd-controller.

I believe the firmware writers intended this as a sdio function address,
but it is in the wrong place for this, so it gets interpreted as a pci
address, causing the node describing the sd-controller used for the
sdio-wifi to get seen as a firmware_node for the pci host bridge, rather
then being stand-alone device.

This commit adds a byt_sdio_setup function which detects this scenario
and removes the wrong firmware_node link from the pci host bridge, which
fixes acpi_create_platform_device returning NULL, leading to non-working
sdio-wifi.

BugLink: https://github.com/hadess/rtl8723bs/issues/80
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/acpi/acpi_lpss.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Rafael J. Wysocki Dec. 25, 2016, 11:25 p.m. UTC | #1
CC Mika and Andy.

Plus I don't think -stable is going to take your patches directly.

On Sun, Dec 25, 2016 at 11:21 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> The firmware on some cherrytrail devices wrongly adds _ADR 0 to their
> entry describing the 80860F14 uid "2" sd-controller.
>
> I believe the firmware writers intended this as a sdio function address,
> but it is in the wrong place for this, so it gets interpreted as a pci
> address, causing the node describing the sd-controller used for the
> sdio-wifi to get seen as a firmware_node for the pci host bridge, rather
> then being stand-alone device.
>
> This commit adds a byt_sdio_setup function which detects this scenario
> and removes the wrong firmware_node link from the pci host bridge, which
> fixes acpi_create_platform_device returning NULL, leading to non-working
> sdio-wifi.
>
> BugLink: https://github.com/hadess/rtl8723bs/issues/80
> Cc: stable@vger.kernel.org
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  drivers/acpi/acpi_lpss.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>
> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
> index 373657f..df9cc66 100644
> --- a/drivers/acpi/acpi_lpss.c
> +++ b/drivers/acpi/acpi_lpss.c
> @@ -84,6 +84,7 @@ static const struct lpss_device_desc lpss_dma_desc = {
>  };
>
>  struct lpss_private_data {
> +       struct acpi_device *adev;
>         void __iomem *mmio_base;
>         resource_size_t mmio_size;
>         unsigned int fixed_clk_rate;
> @@ -154,6 +155,33 @@ static void byt_i2c_setup(struct lpss_private_data *pdata)
>         writel(0, pdata->mmio_base + LPSS_I2C_ENABLE);
>  }
>
> +static void byt_sdio_setup(struct lpss_private_data *pdata)
> +{
> +       unsigned long long adr;
> +       acpi_status status;
> +       struct device *dev;
> +
> +       /*
> +        * Some firmware has a broken _ADR 0 enter for the 80860F14:2
> +        * device, which causes it to get seen as the firmware_node
> +        * for the pci host bridge, rather then a stand alone device.
> +        *
> +        * Check if this is the case, and if it is remove the link.
> +        */
> +       if (strcmp(acpi_device_uid(pdata->adev), "2") != 0)
> +               return;
> +
> +       status = acpi_evaluate_integer(pdata->adev->handle, "_ADR", NULL, &adr);
> +       if (ACPI_FAILURE(status) || adr != 0)
> +               return;
> +
> +       dev = acpi_get_first_physical_node(pdata->adev);
> +       if (!dev)
> +               return;
> +
> +       acpi_unbind_one(dev);
> +}
> +
>  static const struct lpss_device_desc lpt_dev_desc = {
>         .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR,
>         .prv_offset = 0x800,
> @@ -217,6 +245,7 @@ static const struct lpss_device_desc byt_spi_dev_desc = {
>
>  static const struct lpss_device_desc byt_sdio_dev_desc = {
>         .flags = LPSS_CLK,
> +       .setup = byt_sdio_setup,
>  };
>
>  static const struct lpss_device_desc byt_i2c_dev_desc = {
> @@ -425,6 +454,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
>                 goto err_out;
>         }
>
> +       pdata->adev = adev;
>         pdata->dev_desc = dev_desc;
>
>         if (dev_desc->setup)
> --
> 2.9.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Hans de Goede Dec. 26, 2016, 10:48 a.m. UTC | #2
Hi,

On 26-12-16 00:25, Rafael J. Wysocki wrote:
> CC Mika and Andy.
>
> Plus I don't think -stable is going to take your patches directly.

Not sure what you mean with this remark? According to:

Documentation/stable_kernel_rules.txt

Option 1
********

To have the patch automatically included in the stable tree, add the tag

.. code-block:: none

      Cc: stable@vger.kernel.org

in the sign-off area. Once the patch is merged it will be applied to
the stable tree without anything else needing to be done by the author
or subsystem maintainer.


So yes, it won't get merged until it has been merged into Linus'
tree. But AFAICT adding Cc: stable@vger.kernel.org is the right way
to indicate that a patch is a bug-fix which should be applied to
stable kernels once merged, which is my intention of adding the Cc.

Regards,

Hans



>
> On Sun, Dec 25, 2016 at 11:21 AM, Hans de Goede <hdegoede@redhat.com> wrote:
>> The firmware on some cherrytrail devices wrongly adds _ADR 0 to their
>> entry describing the 80860F14 uid "2" sd-controller.
>>
>> I believe the firmware writers intended this as a sdio function address,
>> but it is in the wrong place for this, so it gets interpreted as a pci
>> address, causing the node describing the sd-controller used for the
>> sdio-wifi to get seen as a firmware_node for the pci host bridge, rather
>> then being stand-alone device.
>>
>> This commit adds a byt_sdio_setup function which detects this scenario
>> and removes the wrong firmware_node link from the pci host bridge, which
>> fixes acpi_create_platform_device returning NULL, leading to non-working
>> sdio-wifi.
>>
>> BugLink: https://github.com/hadess/rtl8723bs/issues/80
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
>> ---
>>  drivers/acpi/acpi_lpss.c | 30 ++++++++++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>
>> diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
>> index 373657f..df9cc66 100644
>> --- a/drivers/acpi/acpi_lpss.c
>> +++ b/drivers/acpi/acpi_lpss.c
>> @@ -84,6 +84,7 @@ static const struct lpss_device_desc lpss_dma_desc = {
>>  };
>>
>>  struct lpss_private_data {
>> +       struct acpi_device *adev;
>>         void __iomem *mmio_base;
>>         resource_size_t mmio_size;
>>         unsigned int fixed_clk_rate;
>> @@ -154,6 +155,33 @@ static void byt_i2c_setup(struct lpss_private_data *pdata)
>>         writel(0, pdata->mmio_base + LPSS_I2C_ENABLE);
>>  }
>>
>> +static void byt_sdio_setup(struct lpss_private_data *pdata)
>> +{
>> +       unsigned long long adr;
>> +       acpi_status status;
>> +       struct device *dev;
>> +
>> +       /*
>> +        * Some firmware has a broken _ADR 0 enter for the 80860F14:2
>> +        * device, which causes it to get seen as the firmware_node
>> +        * for the pci host bridge, rather then a stand alone device.
>> +        *
>> +        * Check if this is the case, and if it is remove the link.
>> +        */
>> +       if (strcmp(acpi_device_uid(pdata->adev), "2") != 0)
>> +               return;
>> +
>> +       status = acpi_evaluate_integer(pdata->adev->handle, "_ADR", NULL, &adr);
>> +       if (ACPI_FAILURE(status) || adr != 0)
>> +               return;
>> +
>> +       dev = acpi_get_first_physical_node(pdata->adev);
>> +       if (!dev)
>> +               return;
>> +
>> +       acpi_unbind_one(dev);
>> +}
>> +
>>  static const struct lpss_device_desc lpt_dev_desc = {
>>         .flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR,
>>         .prv_offset = 0x800,
>> @@ -217,6 +245,7 @@ static const struct lpss_device_desc byt_spi_dev_desc = {
>>
>>  static const struct lpss_device_desc byt_sdio_dev_desc = {
>>         .flags = LPSS_CLK,
>> +       .setup = byt_sdio_setup,
>>  };
>>
>>  static const struct lpss_device_desc byt_i2c_dev_desc = {
>> @@ -425,6 +454,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
>>                 goto err_out;
>>         }
>>
>> +       pdata->adev = adev;
>>         pdata->dev_desc = dev_desc;
>>
>>         if (dev_desc->setup)
>> --
>> 2.9.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael J. Wysocki Dec. 26, 2016, 10:13 p.m. UTC | #3
On Mon, Dec 26, 2016 at 11:48 AM, Hans de Goede <hdegoede@redhat.com> wrote:
> Hi,
>
> On 26-12-16 00:25, Rafael J. Wysocki wrote:
>>
>> CC Mika and Andy.
>>
>> Plus I don't think -stable is going to take your patches directly.
>
>
> Not sure what you mean with this remark? According to:
>
> Documentation/stable_kernel_rules.txt
>
> Option 1
> ********
>
> To have the patch automatically included in the stable tree, add the tag
>
> .. code-block:: none
>
>      Cc: stable@vger.kernel.org
>
> in the sign-off area. Once the patch is merged it will be applied to
> the stable tree without anything else needing to be done by the author
> or subsystem maintainer.
>
> So yes, it won't get merged until it has been merged into Linus'
> tree. But AFAICT adding Cc: stable@vger.kernel.org is the right way
> to indicate that a patch is a bug-fix which should be applied to
> stable kernels once merged, which is my intention of adding the Cc.

Yes, you can add a CC: <stable@...> tag to indicate that the patch is
-stable material (in which case please also indicate which -stable
series you want it to go to).

No, you should not CC -stable on the patch submission.

The CC: <stable@...> tag is for the maintainer you're sending the
patch to rather than for -stable itself.

Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c
index 373657f..df9cc66 100644
--- a/drivers/acpi/acpi_lpss.c
+++ b/drivers/acpi/acpi_lpss.c
@@ -84,6 +84,7 @@  static const struct lpss_device_desc lpss_dma_desc = {
 };
 
 struct lpss_private_data {
+	struct acpi_device *adev;
 	void __iomem *mmio_base;
 	resource_size_t mmio_size;
 	unsigned int fixed_clk_rate;
@@ -154,6 +155,33 @@  static void byt_i2c_setup(struct lpss_private_data *pdata)
 	writel(0, pdata->mmio_base + LPSS_I2C_ENABLE);
 }
 
+static void byt_sdio_setup(struct lpss_private_data *pdata)
+{
+	unsigned long long adr;
+	acpi_status status;
+	struct device *dev;
+
+	/*
+	 * Some firmware has a broken _ADR 0 enter for the 80860F14:2
+	 * device, which causes it to get seen as the firmware_node
+	 * for the pci host bridge, rather then a stand alone device.
+	 *
+	 * Check if this is the case, and if it is remove the link.
+	 */
+	if (strcmp(acpi_device_uid(pdata->adev), "2") != 0)
+		return;
+
+	status = acpi_evaluate_integer(pdata->adev->handle, "_ADR", NULL, &adr);
+	if (ACPI_FAILURE(status) || adr != 0)
+		return;
+
+	dev = acpi_get_first_physical_node(pdata->adev);
+	if (!dev)
+		return;
+
+	acpi_unbind_one(dev);
+}
+
 static const struct lpss_device_desc lpt_dev_desc = {
 	.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_CLK_DIVIDER | LPSS_LTR,
 	.prv_offset = 0x800,
@@ -217,6 +245,7 @@  static const struct lpss_device_desc byt_spi_dev_desc = {
 
 static const struct lpss_device_desc byt_sdio_dev_desc = {
 	.flags = LPSS_CLK,
+	.setup = byt_sdio_setup,
 };
 
 static const struct lpss_device_desc byt_i2c_dev_desc = {
@@ -425,6 +454,7 @@  static int acpi_lpss_create_device(struct acpi_device *adev,
 		goto err_out;
 	}
 
+	pdata->adev = adev;
 	pdata->dev_desc = dev_desc;
 
 	if (dev_desc->setup)