Re: [linux-yocto] [PATCH 13/29] mfd: core: redo ACPI matching of the children devices

2016-02-07 Thread Paul Gortmaker
[[linux-yocto] [PATCH 13/29] mfd: core: redo ACPI matching of the children 
devices] On 05/02/2016 (Fri 06:53) Saul Wold wrote:

> From: Andy Shevchenko 
> 
> There is at least one board on the market, i.e. Intel Galileo Gen2, that uses
> _ADR to distinguish the devices under one actual device. Due to this we have 
> to
> improve the quirk in the MFD core to handle that board.
> 
> Signed-off-by: Andy Shevchenko 
> 
> Upstream-status: Submitted

Appears in linux-next an a quick investigation shows the subsystem
maintainer has buried it under a several month old merge, so we can call
this aaccepted to mainline and hence backport status too.

paul@yow-builder:~/git/linux-head$ git describe --contains 98a3be44ffa6
next-20151106~47^2~63^2~3
paul@yow-builder:~/git/linux-head$ git show next-20151106~47^2~63
commit 74b533c529f88b7ae4d607276916f9d8d44571f5
Merge: 6c20b9342478 40d8edc9bf05 1d7f833fd182 b4fe8ba7a310 7e5071199355
Author: Lee Jones 
Date:   Mon Oct 26 14:48:22 2015 +

Merge branches 'ib-extcon-mfd-4.4', 'ib-mfd-i2c-v4.4',
'ib-mfd-power-4.4', 'ib-mfd-regmap-4.4' and 'ib-mfd-regulator-4.4' into 
ibs-for-mfd-merged

paul@yow-builder:~/git/linux-head$ 

I won't bother nit-picking status fields on any other commits in the
series, other than to mention it is also OK to list commit IDs from
subsystem maintainer's queue branches if the full git://kernel.org repo
link is also given.  99% of those trees don't rebase and hence the ID
passes on to Linus as-is.

Paul.
--

> Signed-off-by: Saul Wold 
> ---
>  Documentation/acpi/enumeration.txt | 11 +---
>  drivers/mfd/mfd-core.c | 52 
> ++
>  include/linux/mfd/core.h   | 10 ++--
>  3 files changed, 52 insertions(+), 21 deletions(-)
> 
> diff --git a/Documentation/acpi/enumeration.txt 
> b/Documentation/acpi/enumeration.txt
> index 15dfce7..afd34d0 100644
> --- a/Documentation/acpi/enumeration.txt
> +++ b/Documentation/acpi/enumeration.txt
> @@ -347,13 +347,18 @@ For the first case, the MFD drivers do not need to do 
> anything. The
>  resulting child platform device will have its ACPI_COMPANION() set to point
>  to the parent device.
>  
> -If the ACPI namespace has a device that we can match using an ACPI id,
> -the id should be set like:
> +If the ACPI namespace has a device that we can match using an ACPI id or ACPI
> +adr, the cell should be set like:
> +
> + static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
> + .pnpid = "XYZ0001",
> + .adr = 0,
> + };
>  
>   static struct mfd_cell my_subdevice_cell = {
>   .name = "my_subdevice",
>   /* set the resources relative to the parent */
> - .acpi_pnpid = "XYZ0001",
> + .acpi_match = &my_subdevice_cell_acpi_match,
>   };
>  
>  The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
> diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
> index 1aed3b7..ea844dc 100644
> --- a/drivers/mfd/mfd-core.c
> +++ b/drivers/mfd/mfd-core.c
> @@ -82,29 +82,49 @@ static int mfd_platform_add_cell(struct platform_device 
> *pdev,
>  static void mfd_acpi_add_device(const struct mfd_cell *cell,
>   struct platform_device *pdev)
>  {
> - struct acpi_device *parent_adev;
> + const struct mfd_cell_acpi_match *match = cell->acpi_match;
> + struct acpi_device *parent, *child;
>   struct acpi_device *adev;
>  
> - parent_adev = ACPI_COMPANION(pdev->dev.parent);
> - if (!parent_adev)
> + parent = ACPI_COMPANION(pdev->dev.parent);
> + if (!parent)
>   return;
>  
>   /*
> -  * MFD child device gets its ACPI handle either from the ACPI
> -  * device directly under the parent that matches the acpi_pnpid or
> -  * it will use the parent handle if is no acpi_pnpid is given.
> +  * MFD child device gets its ACPI handle either from the ACPI device
> +  * directly under the parent that matches the either _HID or _CID, or
> +  * _ADR or it will use the parent handle if is no ID is given.
> +  *
> +  * Note that use of _ADR is a grey area in the ACPI specification,
> +  * though Intel Galileo Gen2 is using it to distinguish the children
> +  * devices.
>*/
> - adev = parent_adev;
> - if (cell->acpi_pnpid) {
> - struct acpi_device_id ids[2] = {};
> - struct acpi_device *child_adev;
> -
> - strlcpy(ids[0].id, cell->acpi_pnpid, sizeof(ids[0].id));
> - list_for_each_entry(child_adev, &parent_adev->

[linux-yocto] [PATCH 13/29] mfd: core: redo ACPI matching of the children devices

2016-02-05 Thread Saul Wold
From: Andy Shevchenko 

There is at least one board on the market, i.e. Intel Galileo Gen2, that uses
_ADR to distinguish the devices under one actual device. Due to this we have to
improve the quirk in the MFD core to handle that board.

Signed-off-by: Andy Shevchenko 

Upstream-status: Submitted
Signed-off-by: Saul Wold 
---
 Documentation/acpi/enumeration.txt | 11 +---
 drivers/mfd/mfd-core.c | 52 ++
 include/linux/mfd/core.h   | 10 ++--
 3 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/Documentation/acpi/enumeration.txt 
b/Documentation/acpi/enumeration.txt
index 15dfce7..afd34d0 100644
--- a/Documentation/acpi/enumeration.txt
+++ b/Documentation/acpi/enumeration.txt
@@ -347,13 +347,18 @@ For the first case, the MFD drivers do not need to do 
anything. The
 resulting child platform device will have its ACPI_COMPANION() set to point
 to the parent device.
 
-If the ACPI namespace has a device that we can match using an ACPI id,
-the id should be set like:
+If the ACPI namespace has a device that we can match using an ACPI id or ACPI
+adr, the cell should be set like:
+
+   static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
+   .pnpid = "XYZ0001",
+   .adr = 0,
+   };
 
static struct mfd_cell my_subdevice_cell = {
.name = "my_subdevice",
/* set the resources relative to the parent */
-   .acpi_pnpid = "XYZ0001",
+   .acpi_match = &my_subdevice_cell_acpi_match,
};
 
 The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 1aed3b7..ea844dc 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -82,29 +82,49 @@ static int mfd_platform_add_cell(struct platform_device 
*pdev,
 static void mfd_acpi_add_device(const struct mfd_cell *cell,
struct platform_device *pdev)
 {
-   struct acpi_device *parent_adev;
+   const struct mfd_cell_acpi_match *match = cell->acpi_match;
+   struct acpi_device *parent, *child;
struct acpi_device *adev;
 
-   parent_adev = ACPI_COMPANION(pdev->dev.parent);
-   if (!parent_adev)
+   parent = ACPI_COMPANION(pdev->dev.parent);
+   if (!parent)
return;
 
/*
-* MFD child device gets its ACPI handle either from the ACPI
-* device directly under the parent that matches the acpi_pnpid or
-* it will use the parent handle if is no acpi_pnpid is given.
+* MFD child device gets its ACPI handle either from the ACPI device
+* directly under the parent that matches the either _HID or _CID, or
+* _ADR or it will use the parent handle if is no ID is given.
+*
+* Note that use of _ADR is a grey area in the ACPI specification,
+* though Intel Galileo Gen2 is using it to distinguish the children
+* devices.
 */
-   adev = parent_adev;
-   if (cell->acpi_pnpid) {
-   struct acpi_device_id ids[2] = {};
-   struct acpi_device *child_adev;
-
-   strlcpy(ids[0].id, cell->acpi_pnpid, sizeof(ids[0].id));
-   list_for_each_entry(child_adev, &parent_adev->children, node)
-   if (acpi_match_device_ids(child_adev, ids)) {
-   adev = child_adev;
-   break;
+   adev = parent;
+   if (match) {
+   if (match->pnpid) {
+   struct acpi_device_id ids[2] = {};
+
+   strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
+   list_for_each_entry(child, &parent->children, node) {
+   if (acpi_match_device_ids(child, ids)) {
+   adev = child;
+   break;
+   }
+   }
+   } else {
+   unsigned long long adr;
+   acpi_status status;
+
+   list_for_each_entry(child, &parent->children, node) {
+   status = acpi_evaluate_integer(child->handle,
+  "_ADR", NULL,
+  &adr);
+   if (ACPI_SUCCESS(status) && match->adr == adr) {
+   adev = child;
+   break;
+   }
}
+   }
}
 
ACPI_COMPANION_SET(&pdev->dev, adev);
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index a76bc10..27dac3f 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -18,6 +18,12 @@
 
 struct irq_domain;
 
+/* Matches AC