linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2
@ 2015-10-01 11:20 Andy Shevchenko
  2015-10-01 11:20 ` [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning Andy Shevchenko
                   ` (8 more replies)
  0 siblings, 9 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko

There is a board in the wild, i.e. Intel Galileo Gen2, that has ACPI enumerated
devices behind I2C bus.

This patch series dedicated to enable those devices. Meanwhile it also changes
I2C core to cope with ACPI 6.0 specification (patch 1/8).

The MFD framework is also updated to cope with interesting implementation of
the cell descriptions under ACPI MFD (patch 2/8).

The patches 7 and 8 are pretty independent, though they don't make much sense
without previous ones applied.

Srinivas, it would be nice to see your tag (ideally Tested-by) to be sure we
don't break ISH stuff.

Rafael, can you Ack / comment on patch 2 (and maybe 1)?

Since it touches multiple subsystems someone needs to create an immutable
branch. I don't actually know whose subsystem better here. Lee, Wolfram?

Apparently we would like to get ACKs / comments from the rest.

Tested on the actual Intel Galileo Gen2 by Ismo (gpio expanders) and me (at24).

Changelog v2:
- append tags
- re-make patch 3 (suggested by Lee)
- improve patch 8 (suggested by Thierry)

Andy Shevchenko (7):
  mfd: core: redo ACPI matching of the children devices
  mfd: intel_quark_i2c_gpio: load gpio driver first
  mfd: intel_quark_i2c_gpio: support devices behind i2c bus
  gpio: pca953x: store driver_data for future use
  gpio: pca953x: support ACPI devices found on Galileo Gen2
  at24: enable ACPI device found on Galileo Gen2
  pwm-pca9685: enable ACPI device found on Galileo Gen2

Mika Westerberg (1):
  i2c / ACPI: Rework I2C device scanning

 Documentation/acpi/enumeration.txt | 11 +++--
 drivers/gpio/gpio-pca953x.c        | 36 +++++++++++++----
 drivers/i2c/i2c-core.c             | 82 +++++++++++++++++++++++++++-----------
 drivers/mfd/intel_quark_i2c_gpio.c | 33 ++++++++++-----
 drivers/mfd/mfd-core.c             | 52 ++++++++++++++++--------
 drivers/misc/eeprom/at24.c         | 22 ++++++++--
 drivers/pwm/Kconfig                |  2 +-
 drivers/pwm/pwm-pca9685.c          | 20 ++++++++--
 include/linux/mfd/core.h           | 10 ++++-
 9 files changed, 199 insertions(+), 69 deletions(-)

-- 
2.5.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-05 13:47   ` Rafael J. Wysocki
  2015-10-01 11:20 ` [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices Andy Shevchenko
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Mika Westerberg, Andy Shevchenko

From: Mika Westerberg <mika.westerberg@linux.intel.com>

The way we currently scan I2C devices behind an I2C host controller does not
work in cases where the I2C device in question is not declared directly below
the host controller ACPI node.

This is perfectly legal according the ACPI 6.0 specification and some existing
systems are doing this.

To be able to enumerate all devices which are connected to a certain I2C host
controller we need to rework the current I2C scanning routine a bit. Instead of
scanning directly below the host controller we scan the whole ACPI namespace
for present devices with valid I2cSerialBus() connection pointing to the host
controller in question.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/i2c/i2c-core.c | 82 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 59 insertions(+), 23 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a732107..24e516e 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -99,27 +99,40 @@ struct gsb_buffer {
 	};
 } __packed;
 
-static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
+struct acpi_i2c_lookup {
+	struct i2c_board_info *info;
+	acpi_handle adapter_handle;
+	acpi_handle device_handle;
+};
+
+static int acpi_i2c_find_address(struct acpi_resource *ares, void *data)
 {
-	struct i2c_board_info *info = data;
+	struct acpi_i2c_lookup *lookup = data;
+	struct i2c_board_info *info = lookup->info;
+	struct acpi_resource_i2c_serialbus *sb;
+	acpi_handle adapter_handle;
+	acpi_status status;
 
-	if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
-		struct acpi_resource_i2c_serialbus *sb;
+	if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+		return 1;
 
-		sb = &ares->data.i2c_serial_bus;
-		if (!info->addr && sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
-			info->addr = sb->slave_address;
-			if (sb->access_mode == ACPI_I2C_10BIT_MODE)
-				info->flags |= I2C_CLIENT_TEN;
-		}
-	} else if (!info->irq) {
-		struct resource r;
+	sb = &ares->data.i2c_serial_bus;
+	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
+		return 1;
 
-		if (acpi_dev_resource_interrupt(ares, 0, &r))
-			info->irq = r.start;
+	/*
+	 * Extract the ResourceSource and make sure that the handle matches
+	 * with the I2C adapter handle.
+	 */
+	status = acpi_get_handle(lookup->device_handle,
+				 sb->resource_source.string_ptr,
+				 &adapter_handle);
+	if (ACPI_SUCCESS(status) && adapter_handle == lookup->adapter_handle) {
+		info->addr = sb->slave_address;
+		if (sb->access_mode == ACPI_I2C_10BIT_MODE)
+			info->flags |= I2C_CLIENT_TEN;
 	}
 
-	/* Tell the ACPI core to skip this resource */
 	return 1;
 }
 
@@ -128,6 +141,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
 {
 	struct i2c_adapter *adapter = data;
 	struct list_head resource_list;
+	struct acpi_i2c_lookup lookup;
+	struct resource_entry *entry;
 	struct i2c_board_info info;
 	struct acpi_device *adev;
 	int ret;
@@ -140,14 +155,37 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
 	memset(&info, 0, sizeof(info));
 	info.fwnode = acpi_fwnode_handle(adev);
 
+	memset(&lookup, 0, sizeof(lookup));
+	lookup.adapter_handle = ACPI_HANDLE(adapter->dev.parent);
+	lookup.device_handle = handle;
+	lookup.info = &info;
+
+	/*
+	 * Look up for I2cSerialBus resource with ResourceSource that
+	 * matches with this adapter.
+	 */
 	INIT_LIST_HEAD(&resource_list);
 	ret = acpi_dev_get_resources(adev, &resource_list,
-				     acpi_i2c_add_resource, &info);
+				     acpi_i2c_find_address, &lookup);
 	acpi_dev_free_resource_list(&resource_list);
 
 	if (ret < 0 || !info.addr)
 		return AE_OK;
 
+	/* Then fill IRQ number if any */
+	ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+	if (ret < 0)
+		return AE_OK;
+
+	resource_list_for_each_entry(entry, &resource_list) {
+		if (resource_type(entry->res) == IORESOURCE_IRQ) {
+			info.irq = entry->res->start;
+			break;
+		}
+	}
+
+	acpi_dev_free_resource_list(&resource_list);
+
 	adev->power.flags.ignore_parent = true;
 	strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
 	if (!i2c_new_device(adapter, &info)) {
@@ -160,6 +198,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
 	return AE_OK;
 }
 
+#define ACPI_I2C_MAX_SCAN_DEPTH 32
+
 /**
  * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
  * @adap: pointer to adapter
@@ -170,17 +210,13 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
  */
 static void acpi_i2c_register_devices(struct i2c_adapter *adap)
 {
-	acpi_handle handle;
 	acpi_status status;
 
-	if (!adap->dev.parent)
-		return;
-
-	handle = ACPI_HANDLE(adap->dev.parent);
-	if (!handle)
+	if (!adap->dev.parent || !has_acpi_companion(adap->dev.parent))
 		return;
 
-	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+				     ACPI_I2C_MAX_SCAN_DEPTH,
 				     acpi_i2c_add_device, NULL,
 				     adap, NULL);
 	if (ACPI_FAILURE(status))
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
  2015-10-01 11:20 ` [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-01 14:54   ` Lee Jones
                     ` (2 more replies)
  2015-10-01 11:20 ` [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first Andy Shevchenko
                   ` (6 subsequent siblings)
  8 siblings, 3 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: 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 <andriy.shevchenko@linux.intel.com>
---
 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 b731b29..a91ec5a 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 c17635d..60b60dc 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 ACPI PNP id, either _HID or _CID, or ACPI _ADR */
+struct mfd_cell_acpi_match {
+	const char			*pnpid;
+	const unsigned long long	adr;
+};
+
 /*
  * This struct describes the MFD part ("cell").
  * After registration the copy of this structure will become the platform data
@@ -44,8 +50,8 @@ struct mfd_cell {
 	 */
 	const char		*of_compatible;
 
-	/* Matches ACPI PNP id, either _HID or _CID */
-	const char		*acpi_pnpid;
+	/* Matches ACPI */
+	const struct mfd_cell_acpi_match	*acpi_match;
 
 	/*
 	 * These resources can be specified relative to the parent device.
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
  2015-10-01 11:20 ` [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning Andy Shevchenko
  2015-10-01 11:20 ` [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-01 14:54   ` Lee Jones
  2015-10-01 11:20 ` [PATCH v2 4/8] mfd: intel_quark_i2c_gpio: support devices behind i2c bus Andy Shevchenko
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko

On Intel Galileo boards the GPIO expander is connected to i2c bus. Moreover it
is able to generate interrupt, but interrupt line is connected to GPIO. That's
why we have to have GPIO driver in place when we will probe i2c host with
device connected to it.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/mfd/intel_quark_i2c_gpio.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 1ce1603..958c134 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -90,19 +90,19 @@ static struct resource intel_quark_gpio_res[] = {
 
 static struct mfd_cell intel_quark_mfd_cells[] = {
 	{
-		.id = MFD_I2C_BAR,
-		.name = "i2c_designware",
-		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
-		.resources = intel_quark_i2c_res,
-		.ignore_resource_conflicts = true,
-	},
-	{
 		.id = MFD_GPIO_BAR,
 		.name = "gpio-dwapb",
 		.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
 		.resources = intel_quark_gpio_res,
 		.ignore_resource_conflicts = true,
 	},
+	{
+		.id = MFD_I2C_BAR,
+		.name = "i2c_designware",
+		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
+		.resources = intel_quark_i2c_res,
+		.ignore_resource_conflicts = true,
+	},
 };
 
 static const struct pci_device_id intel_quark_mfd_ids[] = {
@@ -248,12 +248,11 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
 
 	dev_set_drvdata(&pdev->dev, quark_mfd);
 
-	ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[MFD_I2C_BAR]);
+	ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
 	if (ret)
 		return ret;
 
-	ret = intel_quark_gpio_setup(pdev,
-				     &intel_quark_mfd_cells[MFD_GPIO_BAR]);
+	ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
 	if (ret)
 		return ret;
 
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 4/8] mfd: intel_quark_i2c_gpio: support devices behind i2c bus
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
                   ` (2 preceding siblings ...)
  2015-10-01 11:20 ` [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-01 11:20 ` [PATCH v2 5/8] gpio: pca953x: store driver_data for future use Andy Shevchenko
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko

On Intel Galileo Gen2 the GPIO expanders are connected to the i2c bus. For
those devices the ACPI table has specific parameters that refer to an actual
i2c host controller. Since MFD now copes with that specific configuration we
have to provide a necessary information how to distinguish devices in ACPI
namespace. Here the _ADR values are provided.

Acked-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/mfd/intel_quark_i2c_gpio.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
index 958c134..0421374 100644
--- a/drivers/mfd/intel_quark_i2c_gpio.c
+++ b/drivers/mfd/intel_quark_i2c_gpio.c
@@ -31,6 +31,10 @@
 #define MFD_I2C_BAR		0
 #define MFD_GPIO_BAR		1
 
+/* ACPI _ADR value to match the child node */
+#define MFD_ACPI_MATCH_GPIO	0ULL
+#define MFD_ACPI_MATCH_I2C	1ULL
+
 /* The base GPIO number under GPIOLIB framework */
 #define INTEL_QUARK_MFD_GPIO_BASE	8
 
@@ -82,16 +86,25 @@ static struct resource intel_quark_i2c_res[] = {
 	},
 };
 
+static struct mfd_cell_acpi_match intel_quark_acpi_match_i2c = {
+	.adr = MFD_ACPI_MATCH_I2C,
+};
+
 static struct resource intel_quark_gpio_res[] = {
 	[INTEL_QUARK_IORES_MEM] = {
 		.flags = IORESOURCE_MEM,
 	},
 };
 
+static struct mfd_cell_acpi_match intel_quark_acpi_match_gpio = {
+	.adr = MFD_ACPI_MATCH_GPIO,
+};
+
 static struct mfd_cell intel_quark_mfd_cells[] = {
 	{
 		.id = MFD_GPIO_BAR,
 		.name = "gpio-dwapb",
+		.acpi_match = &intel_quark_acpi_match_gpio,
 		.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
 		.resources = intel_quark_gpio_res,
 		.ignore_resource_conflicts = true,
@@ -99,6 +112,7 @@ static struct mfd_cell intel_quark_mfd_cells[] = {
 	{
 		.id = MFD_I2C_BAR,
 		.name = "i2c_designware",
+		.acpi_match = &intel_quark_acpi_match_i2c,
 		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
 		.resources = intel_quark_i2c_res,
 		.ignore_resource_conflicts = true,
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 5/8] gpio: pca953x: store driver_data for future use
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
                   ` (3 preceding siblings ...)
  2015-10-01 11:20 ` [PATCH v2 4/8] mfd: intel_quark_i2c_gpio: support devices behind i2c bus Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-05  8:56   ` Linus Walleij
  2015-10-01 11:20 ` [PATCH v2 6/8] gpio: pca953x: support ACPI devices found on Galileo Gen2 Andy Shevchenko
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko

Instead of using id->driver_data directly we copied it to the internal
structure. This will help to adapt driver for ACPI use.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-pca953x.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 50caeb1..242e244 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -42,6 +42,9 @@
 #define PCA_INT			0x0100
 #define PCA953X_TYPE		0x1000
 #define PCA957X_TYPE		0x2000
+#define PCA_TYPE_MASK		0xF000
+
+#define PCA_CHIP_TYPE(x)	((x) & PCA_TYPE_MASK)
 
 static const struct i2c_device_id pca953x_id[] = {
 	{ "pca9505", 40 | PCA953X_TYPE | PCA_INT, },
@@ -95,6 +98,7 @@ struct pca953x_chip {
 	struct gpio_chip gpio_chip;
 	const char *const *names;
 	int	chip_type;
+	unsigned long driver_data;
 };
 
 static inline struct pca953x_chip *to_pca(struct gpio_chip *gc)
@@ -517,14 +521,13 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid)
 }
 
 static int pca953x_irq_setup(struct pca953x_chip *chip,
-			     const struct i2c_device_id *id,
 			     int irq_base)
 {
 	struct i2c_client *client = chip->client;
 	int ret, i, offset = 0;
 
 	if (client->irq && irq_base != -1
-			&& (id->driver_data & PCA_INT)) {
+			&& (chip->driver_data & PCA_INT)) {
 
 		switch (chip->chip_type) {
 		case PCA953X_TYPE:
@@ -581,12 +584,11 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 
 #else /* CONFIG_GPIO_PCA953X_IRQ */
 static int pca953x_irq_setup(struct pca953x_chip *chip,
-			     const struct i2c_device_id *id,
 			     int irq_base)
 {
 	struct i2c_client *client = chip->client;
 
-	if (irq_base != -1 && (id->driver_data & PCA_INT))
+	if (irq_base != -1 && (chip->driver_data & PCA_INT))
 		dev_warn(&client->dev, "interrupt support not compiled in\n");
 
 	return 0;
@@ -673,14 +675,15 @@ static int pca953x_probe(struct i2c_client *client,
 
 	chip->client = client;
 
-	chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
+	chip->driver_data = id->driver_data;
+	chip->chip_type = PCA_CHIP_TYPE(chip->driver_data);
 
 	mutex_init(&chip->i2c_lock);
 
 	/* initialize cached registers from their original values.
 	 * we can't share this chip with another i2c master.
 	 */
-	pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
+	pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK);
 
 	if (chip->chip_type == PCA953X_TYPE)
 		ret = device_pca953x_init(chip, invert);
@@ -693,7 +696,7 @@ static int pca953x_probe(struct i2c_client *client,
 	if (ret)
 		return ret;
 
-	ret = pca953x_irq_setup(chip, id, irq_base);
+	ret = pca953x_irq_setup(chip, irq_base);
 	if (ret)
 		return ret;
 
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 6/8] gpio: pca953x: support ACPI devices found on Galileo Gen2
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
                   ` (4 preceding siblings ...)
  2015-10-01 11:20 ` [PATCH v2 5/8] gpio: pca953x: store driver_data for future use Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-05  8:59   ` Linus Walleij
  2015-10-01 11:20 ` [PATCH v2 7/8] at24: enable ACPI device " Andy Shevchenko
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko

This patch adds a support of the expandes found on Intel Galileo Gen2 board.
The platform information comes from ACPI.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/gpio/gpio-pca953x.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 242e244..0220b38 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -21,6 +21,7 @@
 #ifdef CONFIG_OF_GPIO
 #include <linux/of_platform.h>
 #endif
+#include <linux/acpi.h>
 
 #define PCA953X_INPUT		0
 #define PCA953X_OUTPUT		1
@@ -75,6 +76,12 @@ static const struct i2c_device_id pca953x_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, pca953x_id);
 
+static const struct acpi_device_id pca953x_acpi_ids[] = {
+	{ "INT3491", 16 | PCA953X_TYPE | PCA_INT, },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, pca953x_acpi_ids);
+
 #define MAX_BANK 5
 #define BANK_SZ 8
 
@@ -675,7 +682,18 @@ static int pca953x_probe(struct i2c_client *client,
 
 	chip->client = client;
 
-	chip->driver_data = id->driver_data;
+	if (id) {
+		chip->driver_data = id->driver_data;
+	} else {
+		const struct acpi_device_id *id;
+
+		id = acpi_match_device(pca953x_acpi_ids, &client->dev);
+		if (!id)
+			return -ENODEV;
+
+		chip->driver_data = id->driver_data;
+	}
+
 	chip->chip_type = PCA_CHIP_TYPE(chip->driver_data);
 
 	mutex_init(&chip->i2c_lock);
@@ -768,6 +786,7 @@ static struct i2c_driver pca953x_driver = {
 	.driver = {
 		.name	= "pca953x",
 		.of_match_table = pca953x_dt_ids,
+		.acpi_match_table = ACPI_PTR(pca953x_acpi_ids),
 	},
 	.probe		= pca953x_probe,
 	.remove		= pca953x_remove,
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 7/8] at24: enable ACPI device found on Galileo Gen2
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
                   ` (5 preceding siblings ...)
  2015-10-01 11:20 ` [PATCH v2 6/8] gpio: pca953x: support ACPI devices found on Galileo Gen2 Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-01 11:20 ` [PATCH v2 8/8] pwm-pca9685: " Andy Shevchenko
  2015-10-05  7:20 ` [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Linus Walleij
  8 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko

There is a 24c08 chip connected to i2c bus on Intel Galileo Gen2 board. Enable
it via ACPI ID INT3499.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/misc/eeprom/at24.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index c6cb7f8..ed009a3 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -21,6 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 #include <linux/of.h>
+#include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/platform_data/at24.h>
 
@@ -131,6 +132,12 @@ static const struct i2c_device_id at24_ids[] = {
 };
 MODULE_DEVICE_TABLE(i2c, at24_ids);
 
+static const struct acpi_device_id at24_acpi_ids[] = {
+	{ "INT3499", AT24_DEVICE_MAGIC(8192 / 8, 0) },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, at24_acpi_ids);
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -473,15 +480,23 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	struct at24_data *at24;
 	int err;
 	unsigned i, num_addresses;
-	kernel_ulong_t magic;
+	kernel_ulong_t magic = 0;
 
 	if (client->dev.platform_data) {
 		chip = *(struct at24_platform_data *)client->dev.platform_data;
 	} else {
-		if (!id->driver_data)
+		if (id) {
+			magic = id->driver_data;
+		} else {
+			const struct acpi_device_id *id;
+
+			id = acpi_match_device(at24_acpi_ids, &client->dev);
+			if (id)
+				magic = id->driver_data;
+		}
+		if (!magic)
 			return -ENODEV;
 
-		magic = id->driver_data;
 		chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN));
 		magic >>= AT24_SIZE_BYTELEN;
 		chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS);
@@ -661,6 +676,7 @@ static int at24_remove(struct i2c_client *client)
 static struct i2c_driver at24_driver = {
 	.driver = {
 		.name = "at24",
+		.acpi_match_table = ACPI_PTR(at24_acpi_ids),
 	},
 	.probe = at24_probe,
 	.remove = at24_remove,
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 8/8] pwm-pca9685: enable ACPI device found on Galileo Gen2
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
                   ` (6 preceding siblings ...)
  2015-10-01 11:20 ` [PATCH v2 7/8] at24: enable ACPI device " Andy Shevchenko
@ 2015-10-01 11:20 ` Andy Shevchenko
  2015-10-05  7:20 ` [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Linus Walleij
  8 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-01 11:20 UTC (permalink / raw)
  To: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel
  Cc: Andy Shevchenko, Thierry Reding

There is a chip connected to i2c bus on Intel Galileo Gen2 board. Enable it via
ACPI ID INT3492.

Cc: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/pwm/Kconfig       |  2 +-
 drivers/pwm/pwm-pca9685.c | 20 ++++++++++++++++----
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 062630a..bb114ef 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -242,7 +242,7 @@ config PWM_MXS
 
 config PWM_PCA9685
 	tristate "NXP PCA9685 PWM driver"
-	depends on OF && I2C
+	depends on I2C
 	select REGMAP_I2C
 	help
 	  Generic PWM framework driver for NXP PCA9685 LED controller.
diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
index 70448a6..117fccf 100644
--- a/drivers/pwm/pwm-pca9685.c
+++ b/drivers/pwm/pwm-pca9685.c
@@ -19,9 +19,11 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/pwm.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
@@ -297,7 +299,6 @@ static const struct regmap_config pca9685_regmap_i2c_config = {
 static int pca9685_pwm_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
-	struct device_node *np = client->dev.of_node;
 	struct pca9685 *pca;
 	int ret;
 	int mode2;
@@ -320,12 +321,12 @@ static int pca9685_pwm_probe(struct i2c_client *client,
 
 	regmap_read(pca->regmap, PCA9685_MODE2, &mode2);
 
-	if (of_property_read_bool(np, "invert"))
+	if (device_property_read_bool(&client->dev, "invert"))
 		mode2 |= MODE2_INVRT;
 	else
 		mode2 &= ~MODE2_INVRT;
 
-	if (of_property_read_bool(np, "open-drain"))
+	if (device_property_read_bool(&client->dev, "open-drain"))
 		mode2 &= ~MODE2_OUTDRV;
 	else
 		mode2 |= MODE2_OUTDRV;
@@ -363,16 +364,27 @@ static const struct i2c_device_id pca9685_id[] = {
 };
 MODULE_DEVICE_TABLE(i2c, pca9685_id);
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id pca9685_acpi_ids[] = {
+	{ "INT3492", 0 },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(acpi, pca9685_acpi_ids);
+#endif
+
+#ifdef CONFIG_OF
 static const struct of_device_id pca9685_dt_ids[] = {
 	{ .compatible = "nxp,pca9685-pwm", },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, pca9685_dt_ids);
+#endif
 
 static struct i2c_driver pca9685_i2c_driver = {
 	.driver = {
 		.name = "pca9685-pwm",
-		.of_match_table = pca9685_dt_ids,
+		.acpi_match_table = ACPI_PTR(pca9685_acpi_ids),
+		.of_match_table = of_match_ptr(pca9685_dt_ids),
 	},
 	.probe = pca9685_pwm_probe,
 	.remove = pca9685_pwm_remove,
-- 
2.5.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first
  2015-10-01 11:20 ` [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first Andy Shevchenko
@ 2015-10-01 14:54   ` Lee Jones
  2015-10-02 12:11     ` Andy Shevchenko
  0 siblings, 1 reply; 20+ messages in thread
From: Lee Jones @ 2015-10-01 14:54 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-acpi, linux-i2c, linux-gpio, Wolfram Sang, Linus Walleij,
	Rafael J . Wysocki, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel

On Thu, 01 Oct 2015, Andy Shevchenko wrote:

> On Intel Galileo boards the GPIO expander is connected to i2c bus. Moreover it
> is able to generate interrupt, but interrupt line is connected to GPIO. That's
> why we have to have GPIO driver in place when we will probe i2c host with
> device connected to it.
> 
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
>  drivers/mfd/intel_quark_i2c_gpio.c | 19 +++++++++----------
>  1 file changed, 9 insertions(+), 10 deletions(-)

Acked-by: Lee Jones <lee.jones@linaro.org>

Are there build dependancies in this set?  Or can all patches filter
through their own subsystems?

> diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
> index 1ce1603..958c134 100644
> --- a/drivers/mfd/intel_quark_i2c_gpio.c
> +++ b/drivers/mfd/intel_quark_i2c_gpio.c
> @@ -90,19 +90,19 @@ static struct resource intel_quark_gpio_res[] = {
>  
>  static struct mfd_cell intel_quark_mfd_cells[] = {
>  	{
> -		.id = MFD_I2C_BAR,
> -		.name = "i2c_designware",
> -		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
> -		.resources = intel_quark_i2c_res,
> -		.ignore_resource_conflicts = true,
> -	},
> -	{
>  		.id = MFD_GPIO_BAR,
>  		.name = "gpio-dwapb",
>  		.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
>  		.resources = intel_quark_gpio_res,
>  		.ignore_resource_conflicts = true,
>  	},
> +	{
> +		.id = MFD_I2C_BAR,
> +		.name = "i2c_designware",
> +		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
> +		.resources = intel_quark_i2c_res,
> +		.ignore_resource_conflicts = true,
> +	},
>  };
>  
>  static const struct pci_device_id intel_quark_mfd_ids[] = {
> @@ -248,12 +248,11 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
>  
>  	dev_set_drvdata(&pdev->dev, quark_mfd);
>  
> -	ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[MFD_I2C_BAR]);
> +	ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
>  	if (ret)
>  		return ret;
>  
> -	ret = intel_quark_gpio_setup(pdev,
> -				     &intel_quark_mfd_cells[MFD_GPIO_BAR]);
> +	ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
>  	if (ret)
>  		return ret;
>  

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices
  2015-10-01 11:20 ` [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices Andy Shevchenko
@ 2015-10-01 14:54   ` Lee Jones
  2015-10-01 21:59     ` Rafael J. Wysocki
  2015-10-05 14:02   ` Rafael J. Wysocki
  2015-10-13  9:21   ` Lee Jones
  2 siblings, 1 reply; 20+ messages in thread
From: Lee Jones @ 2015-10-01 14:54 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-acpi, linux-i2c, linux-gpio, Wolfram Sang, Linus Walleij,
	Rafael J . Wysocki, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel

On Thu, 01 Oct 2015, Andy Shevchenko wrote:

> 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 <andriy.shevchenko@linux.intel.com>
> ---
>  Documentation/acpi/enumeration.txt | 11 +++++---
>  drivers/mfd/mfd-core.c             | 52 ++++++++++++++++++++++++++------------
>  include/linux/mfd/core.h           | 10 ++++++--
>  3 files changed, 52 insertions(+), 21 deletions(-)

This whole patch still needs an ACPI Ack.

> diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt
> index b731b29..a91ec5a 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 c17635d..60b60dc 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 ACPI PNP id, either _HID or _CID, or ACPI _ADR */
> +struct mfd_cell_acpi_match {
> +	const char			*pnpid;
> +	const unsigned long long	adr;
> +};
> +
>  /*
>   * This struct describes the MFD part ("cell").
>   * After registration the copy of this structure will become the platform data
> @@ -44,8 +50,8 @@ struct mfd_cell {
>  	 */
>  	const char		*of_compatible;
>  
> -	/* Matches ACPI PNP id, either _HID or _CID */
> -	const char		*acpi_pnpid;
> +	/* Matches ACPI */
> +	const struct mfd_cell_acpi_match	*acpi_match;
>  
>  	/*
>  	 * These resources can be specified relative to the parent device.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices
  2015-10-01 14:54   ` Lee Jones
@ 2015-10-01 21:59     ` Rafael J. Wysocki
  0 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2015-10-01 21:59 UTC (permalink / raw)
  To: Lee Jones
  Cc: Andy Shevchenko, linux-acpi, linux-i2c, linux-gpio, Wolfram Sang,
	Linus Walleij, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel

On Thursday, October 01, 2015 03:54:36 PM Lee Jones wrote:
> On Thu, 01 Oct 2015, Andy Shevchenko wrote:
> 
> > 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 <andriy.shevchenko@linux.intel.com>
> > ---
> >  Documentation/acpi/enumeration.txt | 11 +++++---
> >  drivers/mfd/mfd-core.c             | 52 ++++++++++++++++++++++++++------------
> >  include/linux/mfd/core.h           | 10 ++++++--
> >  3 files changed, 52 insertions(+), 21 deletions(-)
> 
> This whole patch still needs an ACPI Ack.

I'll take care of it shortly.

Thanks,
Rafael


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first
  2015-10-01 14:54   ` Lee Jones
@ 2015-10-02 12:11     ` Andy Shevchenko
  0 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-02 12:11 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-acpi, linux-i2c, linux-gpio, Wolfram Sang, Linus Walleij,
	Rafael J . Wysocki, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel

On Thu, 2015-10-01 at 15:54 +0100, Lee Jones wrote:
> On Thu, 01 Oct 2015, Andy Shevchenko wrote:
> 
> > On Intel Galileo boards the GPIO expander is connected to i2c bus. 
> > Moreover it
> > is able to generate interrupt, but interrupt line is connected to 
> > GPIO. That's
> > why we have to have GPIO driver in place when we will probe i2c 
> > host with
> > device connected to it.
> > 
> > Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > ---
> >  drivers/mfd/intel_quark_i2c_gpio.c | 19 +++++++++----------
> >  1 file changed, 9 insertions(+), 10 deletions(-)
> 
> Acked-by: Lee Jones <lee.jones@linaro.org>
> 
> Are there build dependancies in this set?  Or can all patches filter
> through their own subsystems?

Practically patches 4-8 can go by their own, though it makes not much
sense since it doesn't add a value (they will be not enumerated until
patches 1-4 made an upstream).

> 
> > diff --git a/drivers/mfd/intel_quark_i2c_gpio.c 
> > b/drivers/mfd/intel_quark_i2c_gpio.c
> > index 1ce1603..958c134 100644
> > --- a/drivers/mfd/intel_quark_i2c_gpio.c
> > +++ b/drivers/mfd/intel_quark_i2c_gpio.c
> > @@ -90,19 +90,19 @@ static struct resource intel_quark_gpio_res[] = 
> > {
> >  
> >  static struct mfd_cell intel_quark_mfd_cells[] = {
> >  	{
> > -		.id = MFD_I2C_BAR,
> > -		.name = "i2c_designware",
> > -		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
> > -		.resources = intel_quark_i2c_res,
> > -		.ignore_resource_conflicts = true,
> > -	},
> > -	{
> >  		.id = MFD_GPIO_BAR,
> >  		.name = "gpio-dwapb",
> >  		.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
> >  		.resources = intel_quark_gpio_res,
> >  		.ignore_resource_conflicts = true,
> >  	},
> > +	{
> > +		.id = MFD_I2C_BAR,
> > +		.name = "i2c_designware",
> > +		.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
> > +		.resources = intel_quark_i2c_res,
> > +		.ignore_resource_conflicts = true,
> > +	},
> >  };
> >  
> >  static const struct pci_device_id intel_quark_mfd_ids[] = {
> > @@ -248,12 +248,11 @@ static int intel_quark_mfd_probe(struct 
> > pci_dev *pdev,
> >  
> >  	dev_set_drvdata(&pdev->dev, quark_mfd);
> >  
> > -	ret = intel_quark_i2c_setup(pdev, 
> > &intel_quark_mfd_cells[MFD_I2C_BAR]);
> > +	ret = intel_quark_i2c_setup(pdev, 
> > &intel_quark_mfd_cells[1]);
> >  	if (ret)
> >  		return ret;
> >  
> > -	ret = intel_quark_gpio_setup(pdev,
> > -				    
> >  &intel_quark_mfd_cells[MFD_GPIO_BAR]);
> > +	ret = intel_quark_gpio_setup(pdev, 
> > &intel_quark_mfd_cells[0]);
> >  	if (ret)
> >  		return ret;
> >  
> 

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2
  2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
                   ` (7 preceding siblings ...)
  2015-10-01 11:20 ` [PATCH v2 8/8] pwm-pca9685: " Andy Shevchenko
@ 2015-10-05  7:20 ` Linus Walleij
  2015-10-05  7:28   ` Andy Shevchenko
  8 siblings, 1 reply; 20+ messages in thread
From: Linus Walleij @ 2015-10-05  7:20 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: ACPI Devel Maling List, linux-i2c, linux-gpio, Lee Jones,
	Wolfram Sang, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel

On Thu, Oct 1, 2015 at 1:20 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> The patches 7 and 8 are pretty independent, though they don't make much sense
> without previous ones applied.

To me it seems patches 5 & 6 (GPIO patches) can be applied as-is
to my GPIO tree without any bad side effects. Is this correct?

In that case I will apply them.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2
  2015-10-05  7:20 ` [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Linus Walleij
@ 2015-10-05  7:28   ` Andy Shevchenko
  0 siblings, 0 replies; 20+ messages in thread
From: Andy Shevchenko @ 2015-10-05  7:28 UTC (permalink / raw)
  To: Linus Walleij
  Cc: ACPI Devel Maling List, linux-i2c, linux-gpio, Lee Jones,
	Wolfram Sang, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel

On Mon, 2015-10-05 at 09:20 +0200, Linus Walleij wrote:
> On Thu, Oct 1, 2015 at 1:20 PM, Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> 
> > The patches 7 and 8 are pretty independent, though they don't make 
> > much sense
> > without previous ones applied.
> 
> To me it seems patches 5 & 6 (GPIO patches) can be applied as-is
> to my GPIO tree without any bad side effects. Is this correct?

Yes, that's correct.

> 
> In that case I will apply them.
> 
> Yours,
> Linus Walleij

-- 
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 5/8] gpio: pca953x: store driver_data for future use
  2015-10-01 11:20 ` [PATCH v2 5/8] gpio: pca953x: store driver_data for future use Andy Shevchenko
@ 2015-10-05  8:56   ` Linus Walleij
  0 siblings, 0 replies; 20+ messages in thread
From: Linus Walleij @ 2015-10-05  8:56 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: ACPI Devel Maling List, linux-i2c, linux-gpio, Lee Jones,
	Wolfram Sang, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel

On Thu, Oct 1, 2015 at 1:20 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> Instead of using id->driver_data directly we copied it to the internal
> structure. This will help to adapt driver for ACPI use.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 6/8] gpio: pca953x: support ACPI devices found on Galileo Gen2
  2015-10-01 11:20 ` [PATCH v2 6/8] gpio: pca953x: support ACPI devices found on Galileo Gen2 Andy Shevchenko
@ 2015-10-05  8:59   ` Linus Walleij
  0 siblings, 0 replies; 20+ messages in thread
From: Linus Walleij @ 2015-10-05  8:59 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: ACPI Devel Maling List, linux-i2c, linux-gpio, Lee Jones,
	Wolfram Sang, Rafael J . Wysocki, Mika Westerberg, Puustinen,
	Ismo, Pandruvada, Srinivas, linux-kernel

On Thu, Oct 1, 2015 at 1:20 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:

> This patch adds a support of the expandes found on Intel Galileo Gen2 board.
> The platform information comes from ACPI.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Patch applied.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning
  2015-10-01 11:20 ` [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning Andy Shevchenko
@ 2015-10-05 13:47   ` Rafael J. Wysocki
  0 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2015-10-05 13:47 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel, Mika Westerberg

On Thursday, October 01, 2015 02:20:23 PM Andy Shevchenko wrote:
> From: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> The way we currently scan I2C devices behind an I2C host controller does not
> work in cases where the I2C device in question is not declared directly below
> the host controller ACPI node.
> 
> This is perfectly legal according the ACPI 6.0 specification and some existing
> systems are doing this.
> 
> To be able to enumerate all devices which are connected to a certain I2C host
> controller we need to rework the current I2C scanning routine a bit. Instead of
> scanning directly below the host controller we scan the whole ACPI namespace
> for present devices with valid I2cSerialBus() connection pointing to the host
> controller in question.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/i2c/i2c-core.c | 82 ++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 59 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index a732107..24e516e 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -99,27 +99,40 @@ struct gsb_buffer {
>  	};
>  } __packed;
>  
> -static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data)
> +struct acpi_i2c_lookup {
> +	struct i2c_board_info *info;
> +	acpi_handle adapter_handle;
> +	acpi_handle device_handle;
> +};
> +
> +static int acpi_i2c_find_address(struct acpi_resource *ares, void *data)
>  {
> -	struct i2c_board_info *info = data;
> +	struct acpi_i2c_lookup *lookup = data;
> +	struct i2c_board_info *info = lookup->info;
> +	struct acpi_resource_i2c_serialbus *sb;
> +	acpi_handle adapter_handle;
> +	acpi_status status;
>  
> -	if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
> -		struct acpi_resource_i2c_serialbus *sb;
> +	if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
> +		return 1;
>  
> -		sb = &ares->data.i2c_serial_bus;
> -		if (!info->addr && sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
> -			info->addr = sb->slave_address;
> -			if (sb->access_mode == ACPI_I2C_10BIT_MODE)
> -				info->flags |= I2C_CLIENT_TEN;
> -		}
> -	} else if (!info->irq) {
> -		struct resource r;
> +	sb = &ares->data.i2c_serial_bus;
> +	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
> +		return 1;
>  
> -		if (acpi_dev_resource_interrupt(ares, 0, &r))
> -			info->irq = r.start;
> +	/*
> +	 * Extract the ResourceSource and make sure that the handle matches
> +	 * with the I2C adapter handle.
> +	 */
> +	status = acpi_get_handle(lookup->device_handle,
> +				 sb->resource_source.string_ptr,
> +				 &adapter_handle);
> +	if (ACPI_SUCCESS(status) && adapter_handle == lookup->adapter_handle) {
> +		info->addr = sb->slave_address;
> +		if (sb->access_mode == ACPI_I2C_10BIT_MODE)
> +			info->flags |= I2C_CLIENT_TEN;
>  	}
>  
> -	/* Tell the ACPI core to skip this resource */
>  	return 1;
>  }
>  
> @@ -128,6 +141,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
>  {
>  	struct i2c_adapter *adapter = data;
>  	struct list_head resource_list;
> +	struct acpi_i2c_lookup lookup;
> +	struct resource_entry *entry;
>  	struct i2c_board_info info;
>  	struct acpi_device *adev;
>  	int ret;
> @@ -140,14 +155,37 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
>  	memset(&info, 0, sizeof(info));
>  	info.fwnode = acpi_fwnode_handle(adev);
>  
> +	memset(&lookup, 0, sizeof(lookup));
> +	lookup.adapter_handle = ACPI_HANDLE(adapter->dev.parent);
> +	lookup.device_handle = handle;
> +	lookup.info = &info;
> +
> +	/*
> +	 * Look up for I2cSerialBus resource with ResourceSource that
> +	 * matches with this adapter.
> +	 */
>  	INIT_LIST_HEAD(&resource_list);
>  	ret = acpi_dev_get_resources(adev, &resource_list,
> -				     acpi_i2c_add_resource, &info);
> +				     acpi_i2c_find_address, &lookup);
>  	acpi_dev_free_resource_list(&resource_list);
>  
>  	if (ret < 0 || !info.addr)
>  		return AE_OK;
>  
> +	/* Then fill IRQ number if any */
> +	ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
> +	if (ret < 0)
> +		return AE_OK;
> +
> +	resource_list_for_each_entry(entry, &resource_list) {
> +		if (resource_type(entry->res) == IORESOURCE_IRQ) {
> +			info.irq = entry->res->start;
> +			break;
> +		}
> +	}
> +
> +	acpi_dev_free_resource_list(&resource_list);
> +
>  	adev->power.flags.ignore_parent = true;
>  	strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
>  	if (!i2c_new_device(adapter, &info)) {
> @@ -160,6 +198,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
>  	return AE_OK;
>  }
>  
> +#define ACPI_I2C_MAX_SCAN_DEPTH 32
> +
>  /**
>   * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
>   * @adap: pointer to adapter
> @@ -170,17 +210,13 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
>   */
>  static void acpi_i2c_register_devices(struct i2c_adapter *adap)
>  {
> -	acpi_handle handle;
>  	acpi_status status;
>  
> -	if (!adap->dev.parent)
> -		return;
> -
> -	handle = ACPI_HANDLE(adap->dev.parent);
> -	if (!handle)
> +	if (!adap->dev.parent || !has_acpi_companion(adap->dev.parent))
>  		return;
>  
> -	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
> +				     ACPI_I2C_MAX_SCAN_DEPTH,
>  				     acpi_i2c_add_device, NULL,
>  				     adap, NULL);
>  	if (ACPI_FAILURE(status))
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices
  2015-10-01 11:20 ` [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices Andy Shevchenko
  2015-10-01 14:54   ` Lee Jones
@ 2015-10-05 14:02   ` Rafael J. Wysocki
  2015-10-13  9:21   ` Lee Jones
  2 siblings, 0 replies; 20+ messages in thread
From: Rafael J. Wysocki @ 2015-10-05 14:02 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-acpi, linux-i2c, linux-gpio, Lee Jones, Wolfram Sang,
	Linus Walleij, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel

On Thursday, October 01, 2015 02:20:24 PM Andy Shevchenko wrote:
> 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 <andriy.shevchenko@linux.intel.com>

>From the ACPI angle:

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  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 b731b29..a91ec5a 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 c17635d..60b60dc 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 ACPI PNP id, either _HID or _CID, or ACPI _ADR */
> +struct mfd_cell_acpi_match {
> +	const char			*pnpid;
> +	const unsigned long long	adr;
> +};
> +
>  /*
>   * This struct describes the MFD part ("cell").
>   * After registration the copy of this structure will become the platform data
> @@ -44,8 +50,8 @@ struct mfd_cell {
>  	 */
>  	const char		*of_compatible;
>  
> -	/* Matches ACPI PNP id, either _HID or _CID */
> -	const char		*acpi_pnpid;
> +	/* Matches ACPI */
> +	const struct mfd_cell_acpi_match	*acpi_match;
>  
>  	/*
>  	 * These resources can be specified relative to the parent device.
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices
  2015-10-01 11:20 ` [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices Andy Shevchenko
  2015-10-01 14:54   ` Lee Jones
  2015-10-05 14:02   ` Rafael J. Wysocki
@ 2015-10-13  9:21   ` Lee Jones
  2 siblings, 0 replies; 20+ messages in thread
From: Lee Jones @ 2015-10-13  9:21 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: linux-acpi, linux-i2c, linux-gpio, Wolfram Sang, Linus Walleij,
	Rafael J . Wysocki, Mika Westerberg, Puustinen, Ismo, Pandruvada,
	Srinivas, linux-kernel

On Thu, 01 Oct 2015, Andy Shevchenko wrote:

> 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 <andriy.shevchenko@linux.intel.com>
> ---
>  Documentation/acpi/enumeration.txt | 11 +++++---
>  drivers/mfd/mfd-core.c             | 52 ++++++++++++++++++++++++++------------
>  include/linux/mfd/core.h           | 10 ++++++--
>  3 files changed, 52 insertions(+), 21 deletions(-)

Acked-by: Lee Jones <lee.jones@linaro.org>

> diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt
> index b731b29..a91ec5a 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 c17635d..60b60dc 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 ACPI PNP id, either _HID or _CID, or ACPI _ADR */
> +struct mfd_cell_acpi_match {
> +	const char			*pnpid;
> +	const unsigned long long	adr;
> +};
> +
>  /*
>   * This struct describes the MFD part ("cell").
>   * After registration the copy of this structure will become the platform data
> @@ -44,8 +50,8 @@ struct mfd_cell {
>  	 */
>  	const char		*of_compatible;
>  
> -	/* Matches ACPI PNP id, either _HID or _CID */
> -	const char		*acpi_pnpid;
> +	/* Matches ACPI */
> +	const struct mfd_cell_acpi_match	*acpi_match;
>  
>  	/*
>  	 * These resources can be specified relative to the parent device.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-10-13  9:21 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-01 11:20 [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Andy Shevchenko
2015-10-01 11:20 ` [PATCH v2 1/8] i2c / ACPI: Rework I2C device scanning Andy Shevchenko
2015-10-05 13:47   ` Rafael J. Wysocki
2015-10-01 11:20 ` [PATCH v2 2/8] mfd: core: redo ACPI matching of the children devices Andy Shevchenko
2015-10-01 14:54   ` Lee Jones
2015-10-01 21:59     ` Rafael J. Wysocki
2015-10-05 14:02   ` Rafael J. Wysocki
2015-10-13  9:21   ` Lee Jones
2015-10-01 11:20 ` [PATCH v2 3/8] mfd: intel_quark_i2c_gpio: load gpio driver first Andy Shevchenko
2015-10-01 14:54   ` Lee Jones
2015-10-02 12:11     ` Andy Shevchenko
2015-10-01 11:20 ` [PATCH v2 4/8] mfd: intel_quark_i2c_gpio: support devices behind i2c bus Andy Shevchenko
2015-10-01 11:20 ` [PATCH v2 5/8] gpio: pca953x: store driver_data for future use Andy Shevchenko
2015-10-05  8:56   ` Linus Walleij
2015-10-01 11:20 ` [PATCH v2 6/8] gpio: pca953x: support ACPI devices found on Galileo Gen2 Andy Shevchenko
2015-10-05  8:59   ` Linus Walleij
2015-10-01 11:20 ` [PATCH v2 7/8] at24: enable ACPI device " Andy Shevchenko
2015-10-01 11:20 ` [PATCH v2 8/8] pwm-pca9685: " Andy Shevchenko
2015-10-05  7:20 ` [PATCH v2 0/8] enable I2C devices behind I2C bus on Gen2 Linus Walleij
2015-10-05  7:28   ` Andy Shevchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).