Re: [linux-yocto] [PATCH 13/29] mfd: core: redo ACPI matching of the children devices
[[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
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