All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C
@ 2012-11-03  7:46 Mika Westerberg
  2012-11-03  7:46 ` [PATCH 1/3] gpio / ACPI: add ACPI support Mika Westerberg
                   ` (4 more replies)
  0 siblings, 5 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-03  7:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: lenb, rafael.j.wysocki, broonie, grant.likely, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, Mika Westerberg,
	linux-acpi

Hi,

With ACPI 5 we can now describe how devices are connected to their bus
using new resources: SPISerialBus and I2CSerialBus. Also it is now possible
to add GPIO connections for the devices with the help of GpioIO and GpioInt
resources.

This series adds support for these new resources.

The series based on the ACPI 5 enumeration support patches that are available
on Rafael's linux-next branch:

	git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next	

Specifically patches from this thread:

	https://lkml.org/lkml/2012/10/31/154

Since these patches depend on the above patches on Rafael's linux-next branch
I suggest that these be merged via that branch, if there are no objections.

The series follows the Device Tree way so that it would be easy to add ACPI
support for the existing SPI and I2C drivers if one is familiar how the
corresponding DT support is done.

For GPIO we introduce a function that maps between ACPI GPIO numbers and Linux
ones - acpi_get_gpio().

SPI slave devices gets enumerated automatically if the master device has
master->dev.acpi_handle set (this is analogous to master->dev.of_mode). The
platform bus code in Rafael's branch assigns the ACPI handle to the master
device.

I2C slave devices can be enumerated by calling acpi_i2c_register_devices() in
the adapter driver.

Thanks,
Mika

Mathias Nyman (1):
  gpio / ACPI: add ACPI support

Mika Westerberg (2):
  spi / ACPI: add ACPI enumeration support
  i2c / ACPI: add ACPI enumeration support

 drivers/acpi/Kconfig        |    6 ++
 drivers/acpi/Makefile       |    1 +
 drivers/acpi/acpi_i2c.c     |  234 +++++++++++++++++++++++++++++++++++++++++++
 drivers/gpio/Kconfig        |    4 +
 drivers/gpio/Makefile       |    1 +
 drivers/gpio/gpiolib-acpi.c |   60 +++++++++++
 drivers/i2c/i2c-core.c      |    9 ++
 drivers/spi/spi.c           |  231 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/acpi_gpio.h   |   19 ++++
 include/linux/acpi_i2c.h    |   29 ++++++
 10 files changed, 593 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/acpi_i2c.c
 create mode 100644 drivers/gpio/gpiolib-acpi.c
 create mode 100644 include/linux/acpi_gpio.h
 create mode 100644 include/linux/acpi_i2c.h

-- 
1.7.10.4


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

* [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-03  7:46 [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Mika Westerberg
@ 2012-11-03  7:46 ` Mika Westerberg
  2012-11-05 11:53   ` Linus Walleij
  2012-11-08 15:55   ` Grant Likely
  2012-11-03  7:46 ` [PATCH 2/3] spi / ACPI: add ACPI enumeration support Mika Westerberg
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-03  7:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: lenb, rafael.j.wysocki, broonie, grant.likely, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, Mika Westerberg,
	linux-acpi

From: Mathias Nyman <mathias.nyman@linux.intel.com>

Add support for translating ACPI GPIO pin numbers to Linux GPIO API pins.
Needs a gpio controller driver with the acpi handler hook set.

Drivers can use acpi_get_gpio() to translate ACPI5 GpioIO and GpioInt
resources to Linux GPIO's.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/gpio/Kconfig        |    4 +++
 drivers/gpio/Makefile       |    1 +
 drivers/gpio/gpiolib-acpi.c |   60 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi_gpio.h   |   19 ++++++++++++++
 4 files changed, 84 insertions(+)
 create mode 100644 drivers/gpio/gpiolib-acpi.c
 create mode 100644 include/linux/acpi_gpio.h

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d055cee..2f1905b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -49,6 +49,10 @@ config OF_GPIO
 	def_bool y
 	depends on OF && !SPARC
 
+config ACPI_GPIO
+	def_bool y
+	depends on ACPI
+
 config DEBUG_GPIO
 	bool "Debug GPIO calls"
 	depends on DEBUG_KERNEL
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 9aeed67..5254b6d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_GPIO)	+= -DDEBUG
 
 obj-$(CONFIG_GPIOLIB)		+= gpiolib.o devres.o
 obj-$(CONFIG_OF_GPIO)		+= gpiolib-of.o
+obj-$(CONFIG_ACPI_GPIO)		+= gpiolib-acpi.o
 
 # Device drivers. Generally keep list sorted alphabetically
 obj-$(CONFIG_GPIO_GENERIC)	+= gpio-generic.o
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
new file mode 100644
index 0000000..ef56ea4
--- /dev/null
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -0,0 +1,60 @@
+/*
+ * ACPI helpers for GPIO API
+ *
+ * Copyright (C) 2012, Intel Corporation
+ * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/acpi_gpio.h>
+#include <linux/acpi.h>
+
+static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
+{
+	acpi_handle handle = data;
+	acpi_handle gc_handle;
+
+	if (!gc->dev)
+		return false;
+
+	gc_handle = gc->dev->acpi_handle;
+	if (!gc_handle)
+		return false;
+
+	return gc_handle == handle;
+}
+
+/**
+ * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API
+ * @path:	ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
+ * @pin:	ACPI GPIO pin number (0-based, controller-relative)
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or errno error value
+ */
+
+int acpi_get_gpio(char *path, int pin)
+{
+	struct gpio_chip *chip;
+	acpi_handle handle;
+	acpi_status status;
+
+	status = acpi_get_handle(NULL, path, &handle);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	chip = gpiochip_find(handle, acpi_gpiochip_find);
+	if (!chip)
+		return -ENODEV;
+
+	if (!gpio_is_valid(chip->base + pin))
+		return -EINVAL;
+
+	return chip->base + pin;
+}
+EXPORT_SYMBOL(acpi_get_gpio);
diff --git a/include/linux/acpi_gpio.h b/include/linux/acpi_gpio.h
new file mode 100644
index 0000000..e025664
--- /dev/null
+++ b/include/linux/acpi_gpio.h
@@ -0,0 +1,19 @@
+#ifndef _LINUX_ACPI_GPIO_H_
+#define _LINUX_ACPI_GPIO_H_
+
+#include <linux/errno.h>
+
+#ifdef CONFIG_ACPI_GPIO
+
+int acpi_get_gpio(char *path, int pin);
+
+#else /* CONFIG_ACPI_GPIO */
+
+static inline int acpi_get_gpio(char *path, int pin)
+{
+	return -ENODEV;
+}
+
+#endif /* CONFIG_ACPI_GPIO */
+
+#endif /* _LINUX_ACPI_GPIO_H_ */
-- 
1.7.10.4


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

* [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03  7:46 [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Mika Westerberg
  2012-11-03  7:46 ` [PATCH 1/3] gpio / ACPI: add ACPI support Mika Westerberg
@ 2012-11-03  7:46 ` Mika Westerberg
  2012-11-03 19:42   ` Bjorn Helgaas
                     ` (2 more replies)
  2012-11-03  7:46 ` [PATCH 3/3] i2c " Mika Westerberg
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-03  7:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: lenb, rafael.j.wysocki, broonie, grant.likely, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, Mika Westerberg,
	linux-acpi

ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
configure the SPI slave devices behind the SPI controller. This patch adds
support for this to the SPI core.

In addition we bind ACPI nodes to SPI devices. This makes it possible for
the slave drivers to get the ACPI handle for further configuration.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 230 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 84c2861..de22a6e 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -35,6 +35,7 @@
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
+#include <linux/acpi.h>
 
 static void spidev_release(struct device *dev)
 {
@@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
 	if (of_driver_match_device(dev, drv))
 		return 1;
 
+	/* Then try ACPI */
+	if (acpi_driver_match_device(dev, drv))
+		return 1;
+
 	if (sdrv->id_table)
 		return !!spi_match_id(sdrv->id_table, spi);
 
@@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
 static void of_register_spi_devices(struct spi_master *master) { }
 #endif
 
+#ifdef CONFIG_ACPI
+struct acpi_spi {
+	acpi_status (*callback)(struct acpi_device *, void *);
+	void *data;
+};
+
+static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
+					     void *data, void **return_value)
+{
+	struct acpi_spi *acpi_spi = data;
+	struct acpi_device *adev;
+
+	if (acpi_bus_get_device(handle, &adev))
+		return AE_OK;
+	if (acpi_bus_get_status(adev) || !adev->status.present)
+		return AE_OK;
+
+	return acpi_spi->callback(adev, acpi_spi->data);
+}
+
+static acpi_status acpi_spi_enumerate(acpi_handle handle,
+	acpi_status (*callback)(struct acpi_device *, void *), void *data)
+{
+	struct acpi_spi acpi_spi;
+
+	acpi_spi.callback = callback;
+	acpi_spi.data = data;
+
+	return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+				   acpi_spi_enumerate_device, NULL,
+				   &acpi_spi, NULL);
+}
+
+struct acpi_spi_device_info {
+	struct spi_device *spi;
+	int triggering;
+	int polarity;
+	int gsi;
+	bool valid;
+};
+
+static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
+{
+	struct acpi_spi_device_info *info = data;
+	struct acpi_resource_spi_serialbus *sb;
+	struct spi_device *spi = info->spi;
+
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
+		sb = &res->data.spi_serial_bus;
+		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
+			spi->chip_select = sb->device_selection;
+			spi->max_speed_hz = sb->connection_speed;
+
+			/* Mode (clock phase/polarity/etc. */
+			if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
+				spi->mode |= SPI_CPHA;
+			if (sb->clock_polarity == ACPI_SPI_START_HIGH)
+				spi->mode |= SPI_CPOL;
+			if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
+				spi->mode |= SPI_CS_HIGH;
+
+			/*
+			 * The info is valid once we have found the
+			 * SPISerialBus resource.
+			 */
+			info->valid = true;
+		}
+		break;
+
+	case ACPI_RESOURCE_TYPE_IRQ:
+		info->gsi = res->data.irq.interrupts[0];
+		info->triggering = res->data.irq.triggering;
+		info->polarity = res->data.irq.polarity;
+		break;
+
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		info->gsi = res->data.extended_irq.interrupts[0];
+		info->triggering = res->data.extended_irq.triggering;
+		info->polarity = res->data.extended_irq.polarity;
+		break;
+	}
+
+	return AE_OK;
+}
+
+static acpi_status acpi_spi_add_device(struct acpi_device *adev, void *data)
+{
+	struct acpi_spi_device_info info;
+	struct spi_master *master = data;
+	struct spi_device *spi;
+	acpi_status status;
+
+	spi = spi_alloc_device(master);
+	if (!spi) {
+		dev_err(&master->dev, "failed to allocate SPI device\n");
+		return AE_ERROR;
+	}
+
+	memset(&info, 0, sizeof(info));
+	info.spi = spi;
+	info.gsi = -1;
+
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_spi_add_resources, &info);
+	if (ACPI_FAILURE(status) || !info.valid)
+		goto fail_put_dev;
+
+	strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
+	if (info.gsi >= 0)
+		spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
+					     info.triggering, info.polarity);
+	request_module(spi->modalias);
+	if (spi_add_device(spi)) {
+		dev_err(&master->dev, "failed to add SPI device from ACPI\n");
+		goto fail_unregister_gsi;
+	}
+
+	return AE_OK;
+
+ fail_unregister_gsi:
+	if (info.gsi >= 0)
+		acpi_unregister_gsi(info.gsi);
+ fail_put_dev:
+	spi_dev_put(spi);
+
+	return AE_OK;
+}
+
+static void acpi_register_spi_devices(struct spi_master *master)
+{
+	acpi_status status;
+	acpi_handle handle;
+
+	handle = master->dev.acpi_handle;
+	if (!handle)
+		return;
+
+	status = acpi_spi_enumerate(handle, acpi_spi_add_device, master);
+	if (ACPI_FAILURE(status))
+		dev_warn(&master->dev, "failed to enumerate SPI slaves\n");
+}
+
+struct acpi_spi_find {
+	acpi_handle handle;
+	u16 chip_select;
+	bool found;
+};
+
+static acpi_status acpi_spi_find_child_address(struct acpi_resource *res,
+					       void *data)
+{
+	struct acpi_resource_spi_serialbus *sb;
+	struct acpi_spi_find *spi_find = data;
+
+	if (res->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+		return AE_OK;
+
+	sb = &res->data.spi_serial_bus;
+	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_SPI)
+		return AE_OK;
+
+	if (sb->device_selection == spi_find->chip_select) {
+		spi_find->found = true;
+		return AE_CTRL_TERMINATE;
+	}
+
+	return AE_OK;
+}
+
+static acpi_status acpi_spi_find_child(struct acpi_device *adev, void *data)
+{
+	struct acpi_spi_find *spi_find = data;
+	acpi_status status;
+
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_spi_find_child_address, spi_find);
+	if (ACPI_FAILURE(status) || !spi_find->found)
+		return status;
+
+	spi_find->handle = adev->handle;
+	return AE_CTRL_TERMINATE;
+}
+
+static int acpi_spi_find_device(struct device *dev, acpi_handle *handle)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct spi_master *master = spi->master;
+	struct acpi_spi_find spi_find;
+	acpi_handle parent;
+	acpi_status status;
+
+	parent = master->dev.acpi_handle;
+	if (!parent)
+		return -ENODEV;
+
+	memset(&spi_find, 0, sizeof(spi_find));
+	spi_find.chip_select = spi->chip_select;
+
+	status = acpi_spi_enumerate(parent, acpi_spi_find_child, &spi_find);
+	if (ACPI_FAILURE(status) || !spi_find.handle)
+		return -ENODEV;
+
+	*handle = spi_find.handle;
+	return 0;
+}
+
+static struct acpi_bus_type acpi_spi_bus = {
+	.bus = &spi_bus_type,
+	.find_device = acpi_spi_find_device,
+};
+
+static void acpi_spi_bus_register(void)
+{
+	register_acpi_bus_type(&acpi_spi_bus);
+}
+#else
+static inline void acpi_register_spi_devices(struct spi_master *master) {}
+static inline void acpi_spi_bus_register(void) {}
+#endif /* CONFIG_ACPI */
+
 static void spi_master_release(struct device *dev)
 {
 	struct spi_master *master;
@@ -1023,8 +1249,9 @@ int spi_register_master(struct spi_master *master)
 		spi_match_master_to_boardinfo(master, &bi->board_info);
 	mutex_unlock(&board_lock);
 
-	/* Register devices from the device tree */
+	/* Register devices from the device tree and ACPI */
 	of_register_spi_devices(master);
+	acpi_register_spi_devices(master);
 done:
 	return status;
 }
@@ -1550,6 +1777,8 @@ static int __init spi_init(void)
 	status = class_register(&spi_master_class);
 	if (status < 0)
 		goto err2;
+
+	acpi_spi_bus_register();
 	return 0;
 
 err2:
-- 
1.7.10.4

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

* [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-03  7:46 [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Mika Westerberg
  2012-11-03  7:46 ` [PATCH 1/3] gpio / ACPI: add ACPI support Mika Westerberg
  2012-11-03  7:46 ` [PATCH 2/3] spi / ACPI: add ACPI enumeration support Mika Westerberg
@ 2012-11-03  7:46 ` Mika Westerberg
  2012-11-03 21:52   ` Jean Delvare
  2012-11-08 18:58   ` Grant Likely
  2012-11-04 18:29 ` [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Linus Walleij
  2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
  4 siblings, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-03  7:46 UTC (permalink / raw)
  To: linux-kernel
  Cc: lenb, rafael.j.wysocki, broonie, grant.likely, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, Mika Westerberg,
	linux-acpi

ACPI 5 introduced I2cSerialBus resource that makes it possible to enumerate
and configure the I2C slave devices behind the I2C controller. This patch
adds helper functions to support I2C slave enumeration.

An ACPI enabled I2C controller driver only needs to call acpi_i2c_register_devices()
in order to get its slave devices enumerated, created and bound to the
corresponding ACPI handle.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/Kconfig     |    6 ++
 drivers/acpi/Makefile    |    1 +
 drivers/acpi/acpi_i2c.c  |  234 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/i2c-core.c   |    9 ++
 include/linux/acpi_i2c.h |   29 ++++++
 5 files changed, 279 insertions(+)
 create mode 100644 drivers/acpi/acpi_i2c.c
 create mode 100644 include/linux/acpi_i2c.h

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 119d58d..0300bf6 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -181,6 +181,12 @@ config ACPI_DOCK
 	  This driver supports ACPI-controlled docking stations and removable
 	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
 
+config ACPI_I2C
+	def_tristate I2C
+	depends on I2C
+	help
+	  ACPI I2C enumeration support.
+
 config ACPI_PROCESSOR
 	tristate "Processor"
 	select THERMAL
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index a7badb5..8573346 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
 obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
+obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
new file mode 100644
index 0000000..dc6997e
--- /dev/null
+++ b/drivers/acpi/acpi_i2c.c
@@ -0,0 +1,234 @@
+/*
+ * ACPI I2C enumeration support
+ *
+ * Copyright (C) 2012, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+
+struct acpi_i2c {
+	acpi_status (*callback)(struct acpi_device *, void *);
+	void *data;
+};
+
+static acpi_status acpi_i2c_enumerate_device(acpi_handle handle, u32 level,
+					     void *data, void **return_value)
+{
+	struct acpi_i2c *acpi_i2c = data;
+	struct acpi_device *adev;
+
+	if (acpi_bus_get_device(handle, &adev))
+		return AE_OK;
+	if (acpi_bus_get_status(adev) || !adev->status.present)
+		return AE_OK;
+
+	return acpi_i2c->callback(adev, acpi_i2c->data);
+}
+
+static acpi_status acpi_i2c_enumerate(acpi_handle handle,
+	acpi_status (*callback)(struct acpi_device *, void *), void *data)
+{
+	struct acpi_i2c acpi_i2c;
+
+	acpi_i2c.callback = callback;
+	acpi_i2c.data = data;
+
+	return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+				   acpi_i2c_enumerate_device, NULL,
+				   &acpi_i2c, NULL);
+}
+
+struct acpi_i2c_device_info {
+	struct i2c_board_info board;
+	int triggering;
+	int polarity;
+	int gsi;
+	bool valid;
+};
+
+static acpi_status acpi_i2c_add_resources(struct acpi_resource *res, void *data)
+{
+	struct acpi_i2c_device_info *info = data;
+	struct acpi_resource_i2c_serialbus *sb;
+
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
+		sb = &res->data.i2c_serial_bus;
+		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
+			info->board.addr = sb->slave_address;
+			if (sb->access_mode == ACPI_I2C_10BIT_MODE)
+				info->board.flags |= I2C_CLIENT_TEN;
+
+			/*
+			 * The info is valid once we have found the
+			 * I2CSerialBus resource.
+			 */
+			info->valid = true;
+		}
+		break;
+
+	case ACPI_RESOURCE_TYPE_IRQ:
+		info->gsi = res->data.irq.interrupts[0];
+		info->triggering = res->data.irq.triggering;
+		info->polarity = res->data.irq.polarity;
+		break;
+
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		info->gsi = res->data.extended_irq.interrupts[0];
+		info->triggering = res->data.extended_irq.triggering;
+		info->polarity = res->data.extended_irq.polarity;
+		break;
+	}
+
+	return AE_OK;
+}
+
+static acpi_status acpi_i2c_add_device(struct acpi_device *adev, void *data)
+{
+	struct acpi_i2c_device_info info;
+	struct i2c_adapter *adapter = data;
+	acpi_status status;
+
+	memset(&info, 0, sizeof(info));
+	info.gsi = -1;
+
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_i2c_add_resources, &info);
+	if (ACPI_FAILURE(status) || !info.valid)
+		return status;
+
+	strlcpy(info.board.type, acpi_device_hid(adev),
+		sizeof(info.board.type));
+	if (info.gsi >= 0)
+		info.board.irq = acpi_register_gsi(&adev->dev, info.gsi,
+						   info.triggering,
+						   info.polarity);
+
+	request_module("%s%s", I2C_MODULE_PREFIX, info.board.type);
+	if (!i2c_new_device(adapter, &info.board)) {
+		dev_err(&adapter->dev, "failed to add i2c device from ACPI\n");
+		if (info.gsi >= 0)
+			acpi_unregister_gsi(info.gsi);
+	}
+
+	return AE_OK;
+}
+
+/**
+ * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
+ * @adapter: pointer to adapter
+ *
+ * Enumerate all I2C slave devices behind this adapter by walking the ACPI
+ * namespace. When a device is found it will be added to the Linux device
+ * model and bound to the corresponding ACPI handle.
+ */
+void acpi_i2c_register_devices(struct i2c_adapter *adapter)
+{
+	acpi_handle handle;
+	acpi_status status;
+
+	handle = adapter->dev.acpi_handle;
+	if (!handle)
+		return;
+
+	status = acpi_i2c_enumerate(handle, acpi_i2c_add_device, adapter);
+	if (ACPI_FAILURE(status))
+		dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n");
+}
+EXPORT_SYMBOL_GPL(acpi_i2c_register_devices);
+
+struct acpi_i2c_find {
+	acpi_handle handle;
+	u16 addr;
+	bool found;
+};
+
+static acpi_status acpi_i2c_find_child_address(struct acpi_resource *res,
+					       void *data)
+{
+	struct acpi_resource_i2c_serialbus *sb;
+	struct acpi_i2c_find *i2c_find = data;
+
+	if (res->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
+		return AE_OK;
+
+	sb = &res->data.i2c_serial_bus;
+	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
+		return AE_OK;
+
+	if (sb->slave_address == i2c_find->addr) {
+		i2c_find->found = true;
+		return AE_CTRL_TERMINATE;
+	}
+
+	return AE_OK;
+}
+
+static acpi_status acpi_i2c_find_child(struct acpi_device *adev, void *data)
+{
+	struct acpi_i2c_find *i2c_find = data;
+	acpi_status status;
+
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_i2c_find_child_address, i2c_find);
+	if (ACPI_FAILURE(status) || !i2c_find->found)
+		return status;
+
+	i2c_find->handle = adev->handle;
+	return AE_CTRL_TERMINATE;
+}
+
+static int acpi_i2c_find_device(struct device *dev, acpi_handle *handle)
+{
+	struct acpi_i2c_find i2c_find;
+	struct i2c_adapter *adapter;
+	struct i2c_client *client;
+	acpi_handle parent;
+	acpi_status status;
+
+	client = i2c_verify_client(dev);
+	if (!client)
+		return -ENODEV;
+
+	adapter = client->adapter;
+	if (!adapter)
+		return -ENODEV;
+
+	parent = adapter->dev.acpi_handle;
+	if (!parent)
+		return -ENODEV;
+
+	memset(&i2c_find, 0, sizeof(i2c_find));
+	i2c_find.addr = client->addr;
+
+	status = acpi_i2c_enumerate(parent, acpi_i2c_find_child, &i2c_find);
+	if (ACPI_FAILURE(status) || !i2c_find.handle)
+		return -ENODEV;
+
+	*handle = i2c_find.handle;
+	return 0;
+}
+
+static struct acpi_bus_type acpi_i2c_bus = {
+	.bus = &i2c_bus_type,
+	.find_device = acpi_i2c_find_device,
+};
+
+void acpi_i2c_bus_register(void)
+{
+	register_acpi_bus_type(&acpi_i2c_bus);
+}
+EXPORT_SYMBOL_GPL(acpi_i2c_bus_register);
+
+void acpi_i2c_bus_unregister(void)
+{
+	unregister_acpi_bus_type(&acpi_i2c_bus);
+}
+EXPORT_SYMBOL_GPL(acpi_i2c_bus_unregister);
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a7edf98..8b9d6fb 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -39,6 +39,7 @@
 #include <linux/irqflags.h>
 #include <linux/rwsem.h>
 #include <linux/pm_runtime.h>
+#include <linux/acpi_i2c.h>
 #include <asm/uaccess.h>
 
 #include "i2c-core.h"
@@ -78,6 +79,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
 	if (of_driver_match_device(dev, drv))
 		return 1;
 
+	/* Then ACPI style match */
+	if (acpi_driver_match_device(dev, drv))
+		return 1;
+
 	driver = to_i2c_driver(drv);
 	/* match on an id table if there is one */
 	if (driver->id_table)
@@ -1298,6 +1303,8 @@ static int __init i2c_init(void)
 	retval = i2c_add_driver(&dummy_driver);
 	if (retval)
 		goto class_err;
+
+	acpi_i2c_bus_register();
 	return 0;
 
 class_err:
@@ -1311,6 +1318,8 @@ bus_err:
 
 static void __exit i2c_exit(void)
 {
+	acpi_i2c_bus_unregister();
+
 	i2c_del_driver(&dummy_driver);
 #ifdef CONFIG_I2C_COMPAT
 	class_compat_unregister(i2c_adapter_compat_class);
diff --git a/include/linux/acpi_i2c.h b/include/linux/acpi_i2c.h
new file mode 100644
index 0000000..d4482df
--- /dev/null
+++ b/include/linux/acpi_i2c.h
@@ -0,0 +1,29 @@
+/*
+ * ACPI I2C enumeration support
+ *
+ * Copyright (C) 2012, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef LINUX_ACPI_I2C_H
+#define LINUX_ACPI_I2C_H
+
+#include <linux/acpi.h>
+
+struct i2c_adapter;
+
+#if defined(CONFIG_ACPI_I2C) || defined(CONFIG_ACPI_I2C_MODULE)
+extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
+extern void acpi_i2c_bus_register(void);
+extern void acpi_i2c_bus_unregister(void);
+#else
+static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
+static inline void acpi_i2c_bus_register(void) {}
+static inline void acpi_i2c_bus_unregister(void) {}
+#endif /* CONFIG_ACPI_I2C */
+
+#endif /* LINUX_ACPI_I2C_H */
-- 
1.7.10.4

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03  7:46 ` [PATCH 2/3] spi / ACPI: add ACPI enumeration support Mika Westerberg
@ 2012-11-03 19:42   ` Bjorn Helgaas
  2012-11-03 20:13     ` Mika Westerberg
  2012-11-03 20:39     ` Rafael J. Wysocki
  2012-11-05 10:54   ` Mark Brown
  2012-11-08 18:48   ` Grant Likely
  2 siblings, 2 replies; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-03 19:42 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> configure the SPI slave devices behind the SPI controller. This patch adds
> support for this to the SPI core.
>
> In addition we bind ACPI nodes to SPI devices. This makes it possible for
> the slave drivers to get the ACPI handle for further configuration.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 230 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 84c2861..de22a6e 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -35,6 +35,7 @@
>  #include <linux/sched.h>
>  #include <linux/delay.h>
>  #include <linux/kthread.h>
> +#include <linux/acpi.h>
>
>  static void spidev_release(struct device *dev)
>  {
> @@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
>         if (of_driver_match_device(dev, drv))
>                 return 1;
>
> +       /* Then try ACPI */
> +       if (acpi_driver_match_device(dev, drv))
> +               return 1;
> +
>         if (sdrv->id_table)
>                 return !!spi_match_id(sdrv->id_table, spi);
>
> @@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
>  static void of_register_spi_devices(struct spi_master *master) { }
>  #endif
>
> +#ifdef CONFIG_ACPI
> +struct acpi_spi {
> +       acpi_status (*callback)(struct acpi_device *, void *);
> +       void *data;
> +};
> +
> +static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
> +                                            void *data, void **return_value)
> +{
> +       struct acpi_spi *acpi_spi = data;
> +       struct acpi_device *adev;
> +
> +       if (acpi_bus_get_device(handle, &adev))
> +               return AE_OK;
> +       if (acpi_bus_get_status(adev) || !adev->status.present)
> +               return AE_OK;
> +
> +       return acpi_spi->callback(adev, acpi_spi->data);
> +}
> +
> +static acpi_status acpi_spi_enumerate(acpi_handle handle,
> +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> +{
> +       struct acpi_spi acpi_spi;
> +
> +       acpi_spi.callback = callback;
> +       acpi_spi.data = data;
> +
> +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +                                  acpi_spi_enumerate_device, NULL,
> +                                  &acpi_spi, NULL);
> +}
> +
> +struct acpi_spi_device_info {
> +       struct spi_device *spi;
> +       int triggering;
> +       int polarity;
> +       int gsi;
> +       bool valid;
> +};
> +
> +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
> +{
> +       struct acpi_spi_device_info *info = data;
> +       struct acpi_resource_spi_serialbus *sb;
> +       struct spi_device *spi = info->spi;
> +
> +       switch (res->type) {
> +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> +               sb = &res->data.spi_serial_bus;
> +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
> +                       spi->chip_select = sb->device_selection;
> +                       spi->max_speed_hz = sb->connection_speed;
> +
> +                       /* Mode (clock phase/polarity/etc. */
> +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
> +                               spi->mode |= SPI_CPHA;
> +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
> +                               spi->mode |= SPI_CPOL;
> +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
> +                               spi->mode |= SPI_CS_HIGH;
> +
> +                       /*
> +                        * The info is valid once we have found the
> +                        * SPISerialBus resource.
> +                        */
> +                       info->valid = true;
> +               }
> +               break;
> +
> +       case ACPI_RESOURCE_TYPE_IRQ:
> +               info->gsi = res->data.irq.interrupts[0];
> +               info->triggering = res->data.irq.triggering;
> +               info->polarity = res->data.irq.polarity;
> +               break;
> +
> +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> +               info->gsi = res->data.extended_irq.interrupts[0];
> +               info->triggering = res->data.extended_irq.triggering;
> +               info->polarity = res->data.extended_irq.polarity;

A driver doesn't seem like the right place for _CRS parsing code.  I
think the intent of _CRS is to describe resources that need to be
coordinated across all devices, e.g., MMIO space, I/O port space, and
IRQs.  Since these resources require system-wide coordination, even
when we don't have drivers for some devices, the ACPI core should be
able to parse _CRS without needing any device-specific knowledge.

I know the Linux ACPI core doesn't parse _CRS today, but it should.
The only reason we get away with the core ignoring _CRS is because the
BIOS sets up most ACPI devices and we never change them.  If we change
any resource assignments, we have to know where all the other devices
are so we can avoid conflicts.

> +               break;
> +       }
> +
> +       return AE_OK;
> +}
> +
> +static acpi_status acpi_spi_add_device(struct acpi_device *adev, void *data)
> +{
> +       struct acpi_spi_device_info info;
> +       struct spi_master *master = data;
> +       struct spi_device *spi;
> +       acpi_status status;
> +
> +       spi = spi_alloc_device(master);
> +       if (!spi) {
> +               dev_err(&master->dev, "failed to allocate SPI device\n");
> +               return AE_ERROR;
> +       }
> +
> +       memset(&info, 0, sizeof(info));
> +       info.spi = spi;
> +       info.gsi = -1;
> +
> +       status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> +                                    acpi_spi_add_resources, &info);
> +       if (ACPI_FAILURE(status) || !info.valid)
> +               goto fail_put_dev;
> +
> +       strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
> +       if (info.gsi >= 0)
> +               spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
> +                                            info.triggering, info.polarity);
> +       request_module(spi->modalias);
> +       if (spi_add_device(spi)) {
> +               dev_err(&master->dev, "failed to add SPI device from ACPI\n");
> +               goto fail_unregister_gsi;
> +       }
> +
> +       return AE_OK;
> +
> + fail_unregister_gsi:
> +       if (info.gsi >= 0)
> +               acpi_unregister_gsi(info.gsi);
> + fail_put_dev:
> +       spi_dev_put(spi);
> +
> +       return AE_OK;
> +}
> +
> +static void acpi_register_spi_devices(struct spi_master *master)
> +{
> +       acpi_status status;
> +       acpi_handle handle;
> +
> +       handle = master->dev.acpi_handle;
> +       if (!handle)
> +               return;
> +
> +       status = acpi_spi_enumerate(handle, acpi_spi_add_device, master);

How does this work with hot-plug?  acpi_spi_enumerate() walks a
portion of the namespace.  How do we deal with changes to that part of
the namespace?  For example, what happens if this part of the
namespace gets pruned because an enclosing device is removed?  Is
there a way to discover new SPI devices if they get added?

> +       if (ACPI_FAILURE(status))
> +               dev_warn(&master->dev, "failed to enumerate SPI slaves\n");
> +}
> +
> +struct acpi_spi_find {
> +       acpi_handle handle;
> +       u16 chip_select;
> +       bool found;
> +};
> +
> +static acpi_status acpi_spi_find_child_address(struct acpi_resource *res,
> +                                              void *data)
> +{
> +       struct acpi_resource_spi_serialbus *sb;
> +       struct acpi_spi_find *spi_find = data;
> +
> +       if (res->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
> +               return AE_OK;
> +
> +       sb = &res->data.spi_serial_bus;
> +       if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_SPI)
> +               return AE_OK;
> +
> +       if (sb->device_selection == spi_find->chip_select) {
> +               spi_find->found = true;
> +               return AE_CTRL_TERMINATE;
> +       }
> +
> +       return AE_OK;
> +}
> +
> +static acpi_status acpi_spi_find_child(struct acpi_device *adev, void *data)
> +{
> +       struct acpi_spi_find *spi_find = data;
> +       acpi_status status;
> +
> +       status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> +                                    acpi_spi_find_child_address, spi_find);
> +       if (ACPI_FAILURE(status) || !spi_find->found)
> +               return status;
> +
> +       spi_find->handle = adev->handle;
> +       return AE_CTRL_TERMINATE;
> +}
> +
> +static int acpi_spi_find_device(struct device *dev, acpi_handle *handle)
> +{
> +       struct spi_device *spi = to_spi_device(dev);
> +       struct spi_master *master = spi->master;
> +       struct acpi_spi_find spi_find;
> +       acpi_handle parent;
> +       acpi_status status;
> +
> +       parent = master->dev.acpi_handle;
> +       if (!parent)
> +               return -ENODEV;
> +
> +       memset(&spi_find, 0, sizeof(spi_find));
> +       spi_find.chip_select = spi->chip_select;
> +
> +       status = acpi_spi_enumerate(parent, acpi_spi_find_child, &spi_find);
> +       if (ACPI_FAILURE(status) || !spi_find.handle)
> +               return -ENODEV;
> +
> +       *handle = spi_find.handle;
> +       return 0;
> +}
> +
> +static struct acpi_bus_type acpi_spi_bus = {
> +       .bus = &spi_bus_type,
> +       .find_device = acpi_spi_find_device,
> +};
> +
> +static void acpi_spi_bus_register(void)
> +{
> +       register_acpi_bus_type(&acpi_spi_bus);
> +}
> +#else
> +static inline void acpi_register_spi_devices(struct spi_master *master) {}
> +static inline void acpi_spi_bus_register(void) {}
> +#endif /* CONFIG_ACPI */
> +
>  static void spi_master_release(struct device *dev)
>  {
>         struct spi_master *master;
> @@ -1023,8 +1249,9 @@ int spi_register_master(struct spi_master *master)
>                 spi_match_master_to_boardinfo(master, &bi->board_info);
>         mutex_unlock(&board_lock);
>
> -       /* Register devices from the device tree */
> +       /* Register devices from the device tree and ACPI */
>         of_register_spi_devices(master);
> +       acpi_register_spi_devices(master);
>  done:
>         return status;
>  }
> @@ -1550,6 +1777,8 @@ static int __init spi_init(void)
>         status = class_register(&spi_master_class);
>         if (status < 0)
>                 goto err2;
> +
> +       acpi_spi_bus_register();
>         return 0;
>
>  err2:
> --
> 1.7.10.4
>
> --
> 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

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03 19:42   ` Bjorn Helgaas
@ 2012-11-03 20:13     ` Mika Westerberg
  2012-11-03 20:59       ` Rafael J. Wysocki
  2012-11-05 10:54       ` Mark Brown
  2012-11-03 20:39     ` Rafael J. Wysocki
  1 sibling, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-03 20:13 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
> On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> > configure the SPI slave devices behind the SPI controller. This patch adds
> > support for this to the SPI core.
> >
> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
> > the slave drivers to get the ACPI handle for further configuration.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 230 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> > index 84c2861..de22a6e 100644
> > --- a/drivers/spi/spi.c
> > +++ b/drivers/spi/spi.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/sched.h>
> >  #include <linux/delay.h>
> >  #include <linux/kthread.h>
> > +#include <linux/acpi.h>
> >
> >  static void spidev_release(struct device *dev)
> >  {
> > @@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
> >         if (of_driver_match_device(dev, drv))
> >                 return 1;
> >
> > +       /* Then try ACPI */
> > +       if (acpi_driver_match_device(dev, drv))
> > +               return 1;
> > +
> >         if (sdrv->id_table)
> >                 return !!spi_match_id(sdrv->id_table, spi);
> >
> > @@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
> >  static void of_register_spi_devices(struct spi_master *master) { }
> >  #endif
> >
> > +#ifdef CONFIG_ACPI
> > +struct acpi_spi {
> > +       acpi_status (*callback)(struct acpi_device *, void *);
> > +       void *data;
> > +};
> > +
> > +static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
> > +                                            void *data, void **return_value)
> > +{
> > +       struct acpi_spi *acpi_spi = data;
> > +       struct acpi_device *adev;
> > +
> > +       if (acpi_bus_get_device(handle, &adev))
> > +               return AE_OK;
> > +       if (acpi_bus_get_status(adev) || !adev->status.present)
> > +               return AE_OK;
> > +
> > +       return acpi_spi->callback(adev, acpi_spi->data);
> > +}
> > +
> > +static acpi_status acpi_spi_enumerate(acpi_handle handle,
> > +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> > +{
> > +       struct acpi_spi acpi_spi;
> > +
> > +       acpi_spi.callback = callback;
> > +       acpi_spi.data = data;
> > +
> > +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> > +                                  acpi_spi_enumerate_device, NULL,
> > +                                  &acpi_spi, NULL);
> > +}
> > +
> > +struct acpi_spi_device_info {
> > +       struct spi_device *spi;
> > +       int triggering;
> > +       int polarity;
> > +       int gsi;
> > +       bool valid;
> > +};
> > +
> > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
> > +{
> > +       struct acpi_spi_device_info *info = data;
> > +       struct acpi_resource_spi_serialbus *sb;
> > +       struct spi_device *spi = info->spi;
> > +
> > +       switch (res->type) {
> > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> > +               sb = &res->data.spi_serial_bus;
> > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
> > +                       spi->chip_select = sb->device_selection;
> > +                       spi->max_speed_hz = sb->connection_speed;
> > +
> > +                       /* Mode (clock phase/polarity/etc. */
> > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
> > +                               spi->mode |= SPI_CPHA;
> > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
> > +                               spi->mode |= SPI_CPOL;
> > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
> > +                               spi->mode |= SPI_CS_HIGH;
> > +
> > +                       /*
> > +                        * The info is valid once we have found the
> > +                        * SPISerialBus resource.
> > +                        */
> > +                       info->valid = true;
> > +               }
> > +               break;
> > +
> > +       case ACPI_RESOURCE_TYPE_IRQ:
> > +               info->gsi = res->data.irq.interrupts[0];
> > +               info->triggering = res->data.irq.triggering;
> > +               info->polarity = res->data.irq.polarity;
> > +               break;
> > +
> > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > +               info->gsi = res->data.extended_irq.interrupts[0];
> > +               info->triggering = res->data.extended_irq.triggering;
> > +               info->polarity = res->data.extended_irq.polarity;
> 
> A driver doesn't seem like the right place for _CRS parsing code.  I
> think the intent of _CRS is to describe resources that need to be
> coordinated across all devices, e.g., MMIO space, I/O port space, and
> IRQs.  Since these resources require system-wide coordination, even
> when we don't have drivers for some devices, the ACPI core should be
> able to parse _CRS without needing any device-specific knowledge.

I think the driver is the only one who really knows the resources it needs
in order to talk the hardware.

The purpose of the above code is to extract the resources in a suitable
form so that we can create a struct spi_device out of them automatically,
in a similar way than the Device Tree does.

There are other things which we cannot do in the generic code, such as GPIO
resources and FixedDMA resources. These should be handled by the actual
driver with the help of dev->acpi_handle IMO.

> I know the Linux ACPI core doesn't parse _CRS today, but it should.
> The only reason we get away with the core ignoring _CRS is because the
> BIOS sets up most ACPI devices and we never change them.  If we change
> any resource assignments, we have to know where all the other devices
> are so we can avoid conflicts.

I agree but these devices are typically "fixed" so that they wont be
hot-plugged (although we should prepare for such devices as well) so
basically we don't need to do change any assignments for resources.

And if the ACPI core parses the _CRS, how does it pass all the resources to
the drivers?

The idea here is to reuse the existing drivers as much as possible. That's
why we follow what Device Tree did already.

> 
> > +               break;
> > +       }
> > +
> > +       return AE_OK;
> > +}
> > +
> > +static acpi_status acpi_spi_add_device(struct acpi_device *adev, void *data)
> > +{
> > +       struct acpi_spi_device_info info;
> > +       struct spi_master *master = data;
> > +       struct spi_device *spi;
> > +       acpi_status status;
> > +
> > +       spi = spi_alloc_device(master);
> > +       if (!spi) {
> > +               dev_err(&master->dev, "failed to allocate SPI device\n");
> > +               return AE_ERROR;
> > +       }
> > +
> > +       memset(&info, 0, sizeof(info));
> > +       info.spi = spi;
> > +       info.gsi = -1;
> > +
> > +       status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> > +                                    acpi_spi_add_resources, &info);
> > +       if (ACPI_FAILURE(status) || !info.valid)
> > +               goto fail_put_dev;
> > +
> > +       strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
> > +       if (info.gsi >= 0)
> > +               spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
> > +                                            info.triggering, info.polarity);
> > +       request_module(spi->modalias);
> > +       if (spi_add_device(spi)) {
> > +               dev_err(&master->dev, "failed to add SPI device from ACPI\n");
> > +               goto fail_unregister_gsi;
> > +       }
> > +
> > +       return AE_OK;
> > +
> > + fail_unregister_gsi:
> > +       if (info.gsi >= 0)
> > +               acpi_unregister_gsi(info.gsi);
> > + fail_put_dev:
> > +       spi_dev_put(spi);
> > +
> > +       return AE_OK;
> > +}
> > +
> > +static void acpi_register_spi_devices(struct spi_master *master)
> > +{
> > +       acpi_status status;
> > +       acpi_handle handle;
> > +
> > +       handle = master->dev.acpi_handle;
> > +       if (!handle)
> > +               return;
> > +
> > +       status = acpi_spi_enumerate(handle, acpi_spi_add_device, master);
> 
> How does this work with hot-plug?  acpi_spi_enumerate() walks a
> portion of the namespace.  How do we deal with changes to that part of
> the namespace?  For example, what happens if this part of the
> namespace gets pruned because an enclosing device is removed?  Is
> there a way to discover new SPI devices if they get added?

I'm not aware that we even support SPI hot-plug in the first place (well,
I'm not sure that the SPI bus even supports such thing).

Typically SPI devices are pretty much "static", at least that is my
understanding. The platform device type ACPI support doesn't yet handle
removing of the device and same goes with this code (typically the SPI
master is based on a platform device).

Eventually we should prepare for hot-plugging the SPI master device and
delete the slave device when the master is removed.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03 19:42   ` Bjorn Helgaas
  2012-11-03 20:13     ` Mika Westerberg
@ 2012-11-03 20:39     ` Rafael J. Wysocki
  2012-11-05 16:54       ` Bjorn Helgaas
  1 sibling, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-03 20:39 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Saturday, November 03, 2012 01:42:02 PM Bjorn Helgaas wrote:
> On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> > configure the SPI slave devices behind the SPI controller. This patch adds
> > support for this to the SPI core.
> >
> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
> > the slave drivers to get the ACPI handle for further configuration.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 230 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> > index 84c2861..de22a6e 100644
> > --- a/drivers/spi/spi.c
> > +++ b/drivers/spi/spi.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/sched.h>
> >  #include <linux/delay.h>
> >  #include <linux/kthread.h>
> > +#include <linux/acpi.h>
> >
> >  static void spidev_release(struct device *dev)
> >  {
> > @@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
> >         if (of_driver_match_device(dev, drv))
> >                 return 1;
> >
> > +       /* Then try ACPI */
> > +       if (acpi_driver_match_device(dev, drv))
> > +               return 1;
> > +
> >         if (sdrv->id_table)
> >                 return !!spi_match_id(sdrv->id_table, spi);
> >
> > @@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
> >  static void of_register_spi_devices(struct spi_master *master) { }
> >  #endif
> >
> > +#ifdef CONFIG_ACPI
> > +struct acpi_spi {
> > +       acpi_status (*callback)(struct acpi_device *, void *);
> > +       void *data;
> > +};
> > +
> > +static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
> > +                                            void *data, void **return_value)
> > +{
> > +       struct acpi_spi *acpi_spi = data;
> > +       struct acpi_device *adev;
> > +
> > +       if (acpi_bus_get_device(handle, &adev))
> > +               return AE_OK;
> > +       if (acpi_bus_get_status(adev) || !adev->status.present)
> > +               return AE_OK;
> > +
> > +       return acpi_spi->callback(adev, acpi_spi->data);
> > +}
> > +
> > +static acpi_status acpi_spi_enumerate(acpi_handle handle,
> > +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> > +{
> > +       struct acpi_spi acpi_spi;
> > +
> > +       acpi_spi.callback = callback;
> > +       acpi_spi.data = data;
> > +
> > +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> > +                                  acpi_spi_enumerate_device, NULL,
> > +                                  &acpi_spi, NULL);
> > +}
> > +
> > +struct acpi_spi_device_info {
> > +       struct spi_device *spi;
> > +       int triggering;
> > +       int polarity;
> > +       int gsi;
> > +       bool valid;
> > +};
> > +
> > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
> > +{
> > +       struct acpi_spi_device_info *info = data;
> > +       struct acpi_resource_spi_serialbus *sb;
> > +       struct spi_device *spi = info->spi;
> > +
> > +       switch (res->type) {
> > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> > +               sb = &res->data.spi_serial_bus;
> > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
> > +                       spi->chip_select = sb->device_selection;
> > +                       spi->max_speed_hz = sb->connection_speed;
> > +
> > +                       /* Mode (clock phase/polarity/etc. */
> > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
> > +                               spi->mode |= SPI_CPHA;
> > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
> > +                               spi->mode |= SPI_CPOL;
> > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
> > +                               spi->mode |= SPI_CS_HIGH;
> > +
> > +                       /*
> > +                        * The info is valid once we have found the
> > +                        * SPISerialBus resource.
> > +                        */
> > +                       info->valid = true;
> > +               }
> > +               break;
> > +
> > +       case ACPI_RESOURCE_TYPE_IRQ:
> > +               info->gsi = res->data.irq.interrupts[0];
> > +               info->triggering = res->data.irq.triggering;
> > +               info->polarity = res->data.irq.polarity;
> > +               break;
> > +
> > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > +               info->gsi = res->data.extended_irq.interrupts[0];
> > +               info->triggering = res->data.extended_irq.triggering;
> > +               info->polarity = res->data.extended_irq.polarity;
> 
> A driver doesn't seem like the right place for _CRS parsing code.

This is not a driver, however. :-)

> I think the intent of _CRS is to describe resources that need to be
> coordinated across all devices, e.g., MMIO space, I/O port space, and
> IRQs.  Since these resources require system-wide coordination, even
> when we don't have drivers for some devices, the ACPI core should be
> able to parse _CRS without needing any device-specific knowledge.

Hmm.

So you would like the ACPI core to parse _CRS centrally for each device
node and create an SPI device object and run spi_add_device() to register
it whenever it finds ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI?
And analogously for I2C?

That might work too.

> I know the Linux ACPI core doesn't parse _CRS today, but it should.
> The only reason we get away with the core ignoring _CRS is because the
> BIOS sets up most ACPI devices and we never change them.  If we change
> any resource assignments, we have to know where all the other devices
> are so we can avoid conflicts.

Well, point taken.

> > +               break;
> > +       }
> > +
> > +       return AE_OK;
> > +}
> > +
> > +static acpi_status acpi_spi_add_device(struct acpi_device *adev, void *data)
> > +{
> > +       struct acpi_spi_device_info info;
> > +       struct spi_master *master = data;
> > +       struct spi_device *spi;
> > +       acpi_status status;
> > +
> > +       spi = spi_alloc_device(master);
> > +       if (!spi) {
> > +               dev_err(&master->dev, "failed to allocate SPI device\n");
> > +               return AE_ERROR;
> > +       }
> > +
> > +       memset(&info, 0, sizeof(info));
> > +       info.spi = spi;
> > +       info.gsi = -1;
> > +
> > +       status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> > +                                    acpi_spi_add_resources, &info);
> > +       if (ACPI_FAILURE(status) || !info.valid)
> > +               goto fail_put_dev;
> > +
> > +       strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
> > +       if (info.gsi >= 0)
> > +               spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
> > +                                            info.triggering, info.polarity);
> > +       request_module(spi->modalias);
> > +       if (spi_add_device(spi)) {
> > +               dev_err(&master->dev, "failed to add SPI device from ACPI\n");
> > +               goto fail_unregister_gsi;
> > +       }
> > +
> > +       return AE_OK;
> > +
> > + fail_unregister_gsi:
> > +       if (info.gsi >= 0)
> > +               acpi_unregister_gsi(info.gsi);
> > + fail_put_dev:
> > +       spi_dev_put(spi);
> > +
> > +       return AE_OK;
> > +}
> > +
> > +static void acpi_register_spi_devices(struct spi_master *master)
> > +{
> > +       acpi_status status;
> > +       acpi_handle handle;
> > +
> > +       handle = master->dev.acpi_handle;
> > +       if (!handle)
> > +               return;
> > +
> > +       status = acpi_spi_enumerate(handle, acpi_spi_add_device, master);
> 
> How does this work with hot-plug?  acpi_spi_enumerate() walks a
> portion of the namespace.  How do we deal with changes to that part of
> the namespace?  For example, what happens if this part of the
> namespace gets pruned because an enclosing device is removed?  Is
> there a way to discover new SPI devices if they get added?

Yes, there should be a way to do that eventually.  No, we don't have any
removable SPI devices described by ACPI yet, as far as I know.  So even if
we added code for that now, we wouldn't be able to test it anyway with any
real hardware until such devices become available.  I have no idea when that's
going to happen, though.

> > +       if (ACPI_FAILURE(status))
> > +               dev_warn(&master->dev, "failed to enumerate SPI slaves\n");
> > +}
> > +
> > +struct acpi_spi_find {
> > +       acpi_handle handle;
> > +       u16 chip_select;
> > +       bool found;
> > +};
> > +
> > +static acpi_status acpi_spi_find_child_address(struct acpi_resource *res,
> > +                                              void *data)
> > +{
> > +       struct acpi_resource_spi_serialbus *sb;
> > +       struct acpi_spi_find *spi_find = data;
> > +
> > +       if (res->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
> > +               return AE_OK;
> > +
> > +       sb = &res->data.spi_serial_bus;
> > +       if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_SPI)
> > +               return AE_OK;
> > +
> > +       if (sb->device_selection == spi_find->chip_select) {
> > +               spi_find->found = true;
> > +               return AE_CTRL_TERMINATE;
> > +       }
> > +
> > +       return AE_OK;
> > +}
> > +
> > +static acpi_status acpi_spi_find_child(struct acpi_device *adev, void *data)
> > +{
> > +       struct acpi_spi_find *spi_find = data;
> > +       acpi_status status;
> > +
> > +       status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> > +                                    acpi_spi_find_child_address, spi_find);
> > +       if (ACPI_FAILURE(status) || !spi_find->found)
> > +               return status;
> > +
> > +       spi_find->handle = adev->handle;
> > +       return AE_CTRL_TERMINATE;
> > +}
> > +
> > +static int acpi_spi_find_device(struct device *dev, acpi_handle *handle)
> > +{
> > +       struct spi_device *spi = to_spi_device(dev);
> > +       struct spi_master *master = spi->master;
> > +       struct acpi_spi_find spi_find;
> > +       acpi_handle parent;
> > +       acpi_status status;
> > +
> > +       parent = master->dev.acpi_handle;
> > +       if (!parent)
> > +               return -ENODEV;
> > +
> > +       memset(&spi_find, 0, sizeof(spi_find));
> > +       spi_find.chip_select = spi->chip_select;
> > +
> > +       status = acpi_spi_enumerate(parent, acpi_spi_find_child, &spi_find);
> > +       if (ACPI_FAILURE(status) || !spi_find.handle)
> > +               return -ENODEV;
> > +
> > +       *handle = spi_find.handle;
> > +       return 0;
> > +}
> > +
> > +static struct acpi_bus_type acpi_spi_bus = {
> > +       .bus = &spi_bus_type,
> > +       .find_device = acpi_spi_find_device,
> > +};
> > +
> > +static void acpi_spi_bus_register(void)
> > +{
> > +       register_acpi_bus_type(&acpi_spi_bus);
> > +}
> > +#else
> > +static inline void acpi_register_spi_devices(struct spi_master *master) {}
> > +static inline void acpi_spi_bus_register(void) {}
> > +#endif /* CONFIG_ACPI */
> > +
> >  static void spi_master_release(struct device *dev)
> >  {
> >         struct spi_master *master;
> > @@ -1023,8 +1249,9 @@ int spi_register_master(struct spi_master *master)
> >                 spi_match_master_to_boardinfo(master, &bi->board_info);
> >         mutex_unlock(&board_lock);
> >
> > -       /* Register devices from the device tree */
> > +       /* Register devices from the device tree and ACPI */
> >         of_register_spi_devices(master);
> > +       acpi_register_spi_devices(master);
> >  done:
> >         return status;
> >  }
> > @@ -1550,6 +1777,8 @@ static int __init spi_init(void)
> >         status = class_register(&spi_master_class);
> >         if (status < 0)
> >                 goto err2;
> > +
> > +       acpi_spi_bus_register();
> >         return 0;
> >
> >  err2:
> > --

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03 20:13     ` Mika Westerberg
@ 2012-11-03 20:59       ` Rafael J. Wysocki
  2012-11-05 10:31         ` Rafael J. Wysocki
  2012-11-05 10:54       ` Mark Brown
  1 sibling, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-03 20:59 UTC (permalink / raw)
  To: Mika Westerberg, Bjorn Helgaas
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
> On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
> > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> > <mika.westerberg@linux.intel.com> wrote:
> > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> > > configure the SPI slave devices behind the SPI controller. This patch adds
> > > support for this to the SPI core.
> > >
> > > In addition we bind ACPI nodes to SPI devices. This makes it possible for
> > > the slave drivers to get the ACPI handle for further configuration.
> > >
> > > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > > ---
> > >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> > >  1 file changed, 230 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> > > index 84c2861..de22a6e 100644
> > > --- a/drivers/spi/spi.c
> > > +++ b/drivers/spi/spi.c
> > > @@ -35,6 +35,7 @@
> > >  #include <linux/sched.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/kthread.h>
> > > +#include <linux/acpi.h>
> > >
> > >  static void spidev_release(struct device *dev)
> > >  {
> > > @@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
> > >         if (of_driver_match_device(dev, drv))
> > >                 return 1;
> > >
> > > +       /* Then try ACPI */
> > > +       if (acpi_driver_match_device(dev, drv))
> > > +               return 1;
> > > +
> > >         if (sdrv->id_table)
> > >                 return !!spi_match_id(sdrv->id_table, spi);
> > >
> > > @@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
> > >  static void of_register_spi_devices(struct spi_master *master) { }
> > >  #endif
> > >
> > > +#ifdef CONFIG_ACPI
> > > +struct acpi_spi {
> > > +       acpi_status (*callback)(struct acpi_device *, void *);
> > > +       void *data;
> > > +};
> > > +
> > > +static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
> > > +                                            void *data, void **return_value)
> > > +{
> > > +       struct acpi_spi *acpi_spi = data;
> > > +       struct acpi_device *adev;
> > > +
> > > +       if (acpi_bus_get_device(handle, &adev))
> > > +               return AE_OK;
> > > +       if (acpi_bus_get_status(adev) || !adev->status.present)
> > > +               return AE_OK;
> > > +
> > > +       return acpi_spi->callback(adev, acpi_spi->data);
> > > +}
> > > +
> > > +static acpi_status acpi_spi_enumerate(acpi_handle handle,
> > > +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> > > +{
> > > +       struct acpi_spi acpi_spi;
> > > +
> > > +       acpi_spi.callback = callback;
> > > +       acpi_spi.data = data;
> > > +
> > > +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> > > +                                  acpi_spi_enumerate_device, NULL,
> > > +                                  &acpi_spi, NULL);
> > > +}
> > > +
> > > +struct acpi_spi_device_info {
> > > +       struct spi_device *spi;
> > > +       int triggering;
> > > +       int polarity;
> > > +       int gsi;
> > > +       bool valid;
> > > +};
> > > +
> > > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
> > > +{
> > > +       struct acpi_spi_device_info *info = data;
> > > +       struct acpi_resource_spi_serialbus *sb;
> > > +       struct spi_device *spi = info->spi;
> > > +
> > > +       switch (res->type) {
> > > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> > > +               sb = &res->data.spi_serial_bus;
> > > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
> > > +                       spi->chip_select = sb->device_selection;
> > > +                       spi->max_speed_hz = sb->connection_speed;
> > > +
> > > +                       /* Mode (clock phase/polarity/etc. */
> > > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
> > > +                               spi->mode |= SPI_CPHA;
> > > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
> > > +                               spi->mode |= SPI_CPOL;
> > > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
> > > +                               spi->mode |= SPI_CS_HIGH;
> > > +
> > > +                       /*
> > > +                        * The info is valid once we have found the
> > > +                        * SPISerialBus resource.
> > > +                        */
> > > +                       info->valid = true;
> > > +               }
> > > +               break;
> > > +
> > > +       case ACPI_RESOURCE_TYPE_IRQ:
> > > +               info->gsi = res->data.irq.interrupts[0];
> > > +               info->triggering = res->data.irq.triggering;
> > > +               info->polarity = res->data.irq.polarity;
> > > +               break;
> > > +
> > > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > > +               info->gsi = res->data.extended_irq.interrupts[0];
> > > +               info->triggering = res->data.extended_irq.triggering;
> > > +               info->polarity = res->data.extended_irq.polarity;
> > 
> > A driver doesn't seem like the right place for _CRS parsing code.  I
> > think the intent of _CRS is to describe resources that need to be
> > coordinated across all devices, e.g., MMIO space, I/O port space, and
> > IRQs.  Since these resources require system-wide coordination, even
> > when we don't have drivers for some devices, the ACPI core should be
> > able to parse _CRS without needing any device-specific knowledge.
> 
> I think the driver is the only one who really knows the resources it needs
> in order to talk the hardware.
> 
> The purpose of the above code is to extract the resources in a suitable
> form so that we can create a struct spi_device out of them automatically,
> in a similar way than the Device Tree does.
> 
> There are other things which we cannot do in the generic code, such as GPIO
> resources and FixedDMA resources. These should be handled by the actual
> driver with the help of dev->acpi_handle IMO.
> 
> > I know the Linux ACPI core doesn't parse _CRS today, but it should.
> > The only reason we get away with the core ignoring _CRS is because the
> > BIOS sets up most ACPI devices and we never change them.  If we change
> > any resource assignments, we have to know where all the other devices
> > are so we can avoid conflicts.
> 
> I agree but these devices are typically "fixed" so that they wont be
> hot-plugged (although we should prepare for such devices as well) so
> basically we don't need to do change any assignments for resources.
> 
> And if the ACPI core parses the _CRS, how does it pass all the resources to
> the drivers?

Pretty much the same way the $subject patch does.

Instead of parsing the entire subtree below an SPI controller and trying
acpi_spi_add_device() for each device node in there, it could call
acpi_spi_add_device() whenever it finds a device of type
ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
The only problem is how to pass "master" to it.

So Bjorn, do you have any idea how we could pass the "master" pointer from the
ACPI core to acpi_spi_add_device() in a sensible way?

An alternative might be to store the information obtained from _CRS in
struct acpi_device objects created by the ACPI core while parsing the
namespace.  We do that already for things like _PRW, so we might as well do it
for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
below the SPI controller's acpi_device to extract that information.
Maybe that's the way to go?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-03  7:46 ` [PATCH 3/3] i2c " Mika Westerberg
@ 2012-11-03 21:52   ` Jean Delvare
  2012-11-04  7:23     ` Mika Westerberg
  2012-11-08 18:58   ` Grant Likely
  1 sibling, 1 reply; 127+ messages in thread
From: Jean Delvare @ 2012-11-03 21:52 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sat,  3 Nov 2012 09:46:33 +0200, Mika Westerberg wrote:
> ACPI 5 introduced I2cSerialBus resource that makes it possible to enumerate
> and configure the I2C slave devices behind the I2C controller. This patch
> adds helper functions to support I2C slave enumeration.
> 
> An ACPI enabled I2C controller driver only needs to call acpi_i2c_register_devices()
> in order to get its slave devices enumerated, created and bound to the
> corresponding ACPI handle.

I'm very happy to finally see this happen. Out of curiosity, did you
try that code with an actual ACPI implementation?

Light review below:

> 
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/acpi/Kconfig     |    6 ++
>  drivers/acpi/Makefile    |    1 +
>  drivers/acpi/acpi_i2c.c  |  234 ++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/i2c/i2c-core.c   |    9 ++
>  include/linux/acpi_i2c.h |   29 ++++++
>  5 files changed, 279 insertions(+)
>  create mode 100644 drivers/acpi/acpi_i2c.c
>  create mode 100644 include/linux/acpi_i2c.h
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 119d58d..0300bf6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -181,6 +181,12 @@ config ACPI_DOCK
>  	  This driver supports ACPI-controlled docking stations and removable
>  	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
>  
> +config ACPI_I2C
> +	def_tristate I2C
> +	depends on I2C
> +	help
> +	  ACPI I2C enumeration support.
> +
>  config ACPI_PROCESSOR
>  	tristate "Processor"
>  	select THERMAL
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index a7badb5..8573346 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -69,6 +69,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
>  obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
> +obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y			:= processor_driver.o processor_throttling.o
> diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
> new file mode 100644
> index 0000000..dc6997e
> --- /dev/null
> +++ b/drivers/acpi/acpi_i2c.c
> @@ -0,0 +1,234 @@
> +/*
> + * ACPI I2C enumeration support
> + *
> + * Copyright (C) 2012, Intel Corporation
> + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>

You also need <linux/device.h> for dev_err() etc., and <linux/err.h> for
ENODEV etc.
> +
> +struct acpi_i2c {
> +	acpi_status (*callback)(struct acpi_device *, void *);
> +	void *data;
> +};
> +
> +static acpi_status acpi_i2c_enumerate_device(acpi_handle handle, u32 level,
> +					     void *data, void **return_value)
> +{
> +	struct acpi_i2c *acpi_i2c = data;
> +	struct acpi_device *adev;
> +
> +	if (acpi_bus_get_device(handle, &adev))
> +		return AE_OK;
> +	if (acpi_bus_get_status(adev) || !adev->status.present)
> +		return AE_OK;
> +
> +	return acpi_i2c->callback(adev, acpi_i2c->data);
> +}
> +
> +static acpi_status acpi_i2c_enumerate(acpi_handle handle,
> +	acpi_status (*callback)(struct acpi_device *, void *), void *data)
> +{
> +	struct acpi_i2c acpi_i2c;
> +
> +	acpi_i2c.callback = callback;
> +	acpi_i2c.data = data;
> +
> +	return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +				   acpi_i2c_enumerate_device, NULL,
> +				   &acpi_i2c, NULL);
> +}
> +
> +struct acpi_i2c_device_info {
> +	struct i2c_board_info board;
> +	int triggering;
> +	int polarity;
> +	int gsi;
> +	bool valid;
> +};
> +
> +static acpi_status acpi_i2c_add_resources(struct acpi_resource *res, void *data)
> +{
> +	struct acpi_i2c_device_info *info = data;
> +	struct acpi_resource_i2c_serialbus *sb;
> +
> +	switch (res->type) {
> +	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> +		sb = &res->data.i2c_serial_bus;
> +		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
> +			info->board.addr = sb->slave_address;
> +			if (sb->access_mode == ACPI_I2C_10BIT_MODE)
> +				info->board.flags |= I2C_CLIENT_TEN;
> +
> +			/*
> +			 * The info is valid once we have found the
> +			 * I2CSerialBus resource.
> +			 */
> +			info->valid = true;
> +		}
> +		break;
> +
> +	case ACPI_RESOURCE_TYPE_IRQ:
> +		info->gsi = res->data.irq.interrupts[0];
> +		info->triggering = res->data.irq.triggering;
> +		info->polarity = res->data.irq.polarity;
> +		break;
> +
> +	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> +		info->gsi = res->data.extended_irq.interrupts[0];
> +		info->triggering = res->data.extended_irq.triggering;
> +		info->polarity = res->data.extended_irq.polarity;
> +		break;
> +	}
> +
> +	return AE_OK;
> +}
> +
> +static acpi_status acpi_i2c_add_device(struct acpi_device *adev, void *data)
> +{
> +	struct acpi_i2c_device_info info;
> +	struct i2c_adapter *adapter = data;
> +	acpi_status status;
> +
> +	memset(&info, 0, sizeof(info));
> +	info.gsi = -1;
> +
> +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> +				     acpi_i2c_add_resources, &info);
> +	if (ACPI_FAILURE(status) || !info.valid)
> +		return status;
> +
> +	strlcpy(info.board.type, acpi_device_hid(adev),
> +		sizeof(info.board.type));

I very much doubt the ACPI HID names will match the Linux i2c device
names. In other words you are instantiating devices no driver will want
to bind to. How do you plan to solve this issue?

> +	if (info.gsi >= 0)
> +		info.board.irq = acpi_register_gsi(&adev->dev, info.gsi,
> +						   info.triggering,
> +						   info.polarity);
> +
> +	request_module("%s%s", I2C_MODULE_PREFIX, info.board.type);
> +	if (!i2c_new_device(adapter, &info.board)) {
> +		dev_err(&adapter->dev, "failed to add i2c device from ACPI\n");
> +		if (info.gsi >= 0)
> +			acpi_unregister_gsi(info.gsi);
> +	}
> +
> +	return AE_OK;
> +}
> +
> +/**
> + * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
> + * @adapter: pointer to adapter
> + *
> + * Enumerate all I2C slave devices behind this adapter by walking the ACPI
> + * namespace. When a device is found it will be added to the Linux device
> + * model and bound to the corresponding ACPI handle.
> + */
> +void acpi_i2c_register_devices(struct i2c_adapter *adapter)
> +{
> +	acpi_handle handle;
> +	acpi_status status;
> +
> +	handle = adapter->dev.acpi_handle;
> +	if (!handle)
> +		return;
> +
> +	status = acpi_i2c_enumerate(handle, acpi_i2c_add_device, adapter);
> +	if (ACPI_FAILURE(status))
> +		dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n");
> +}
> +EXPORT_SYMBOL_GPL(acpi_i2c_register_devices);
> +
> +struct acpi_i2c_find {
> +	acpi_handle handle;
> +	u16 addr;
> +	bool found;
> +};
> +
> +static acpi_status acpi_i2c_find_child_address(struct acpi_resource *res,
> +					       void *data)
> +{
> +	struct acpi_resource_i2c_serialbus *sb;
> +	struct acpi_i2c_find *i2c_find = data;
> +
> +	if (res->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
> +		return AE_OK;
> +
> +	sb = &res->data.i2c_serial_bus;
> +	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
> +		return AE_OK;
> +
> +	if (sb->slave_address == i2c_find->addr) {
> +		i2c_find->found = true;
> +		return AE_CTRL_TERMINATE;
> +	}
> +
> +	return AE_OK;
> +}
> +
> +static acpi_status acpi_i2c_find_child(struct acpi_device *adev, void *data)
> +{
> +	struct acpi_i2c_find *i2c_find = data;
> +	acpi_status status;
> +
> +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> +				     acpi_i2c_find_child_address, i2c_find);
> +	if (ACPI_FAILURE(status) || !i2c_find->found)
> +		return status;
> +
> +	i2c_find->handle = adev->handle;
> +	return AE_CTRL_TERMINATE;
> +}
> +
> +static int acpi_i2c_find_device(struct device *dev, acpi_handle *handle)
> +{
> +	struct acpi_i2c_find i2c_find;
> +	struct i2c_adapter *adapter;
> +	struct i2c_client *client;
> +	acpi_handle parent;
> +	acpi_status status;
> +
> +	client = i2c_verify_client(dev);
> +	if (!client)
> +		return -ENODEV;
> +
> +	adapter = client->adapter;
> +	if (!adapter)
> +		return -ENODEV;
> +
> +	parent = adapter->dev.acpi_handle;
> +	if (!parent)
> +		return -ENODEV;
> +
> +	memset(&i2c_find, 0, sizeof(i2c_find));
> +	i2c_find.addr = client->addr;
> +
> +	status = acpi_i2c_enumerate(parent, acpi_i2c_find_child, &i2c_find);
> +	if (ACPI_FAILURE(status) || !i2c_find.handle)
> +		return -ENODEV;
> +
> +	*handle = i2c_find.handle;
> +	return 0;
> +}
> +
> +static struct acpi_bus_type acpi_i2c_bus = {
> +	.bus = &i2c_bus_type,
> +	.find_device = acpi_i2c_find_device,
> +};
> +
> +void acpi_i2c_bus_register(void)
> +{
> +	register_acpi_bus_type(&acpi_i2c_bus);
> +}
> +EXPORT_SYMBOL_GPL(acpi_i2c_bus_register);
> +
> +void acpi_i2c_bus_unregister(void)
> +{
> +	unregister_acpi_bus_type(&acpi_i2c_bus);
> +}
> +EXPORT_SYMBOL_GPL(acpi_i2c_bus_unregister);
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index a7edf98..8b9d6fb 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -39,6 +39,7 @@
>  #include <linux/irqflags.h>
>  #include <linux/rwsem.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/acpi_i2c.h>
>  #include <asm/uaccess.h>
>  
>  #include "i2c-core.h"
> @@ -78,6 +79,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
>  	if (of_driver_match_device(dev, drv))
>  		return 1;
>  
> +	/* Then ACPI style match */
> +	if (acpi_driver_match_device(dev, drv))
> +		return 1;
> +
>  	driver = to_i2c_driver(drv);
>  	/* match on an id table if there is one */
>  	if (driver->id_table)
> @@ -1298,6 +1303,8 @@ static int __init i2c_init(void)
>  	retval = i2c_add_driver(&dummy_driver);
>  	if (retval)
>  		goto class_err;
> +
> +	acpi_i2c_bus_register();
>  	return 0;
>  
>  class_err:
> @@ -1311,6 +1318,8 @@ bus_err:
>  
>  static void __exit i2c_exit(void)
>  {
> +	acpi_i2c_bus_unregister();
> +
>  	i2c_del_driver(&dummy_driver);
>  #ifdef CONFIG_I2C_COMPAT
>  	class_compat_unregister(i2c_adapter_compat_class);
> diff --git a/include/linux/acpi_i2c.h b/include/linux/acpi_i2c.h
> new file mode 100644
> index 0000000..d4482df
> --- /dev/null
> +++ b/include/linux/acpi_i2c.h
> @@ -0,0 +1,29 @@
> +/*
> + * ACPI I2C enumeration support
> + *
> + * Copyright (C) 2012, Intel Corporation
> + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef LINUX_ACPI_I2C_H
> +#define LINUX_ACPI_I2C_H
> +
> +#include <linux/acpi.h>

What for?

> +struct i2c_adapter;
> +
> +#if defined(CONFIG_ACPI_I2C) || defined(CONFIG_ACPI_I2C_MODULE)
> +extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
> +extern void acpi_i2c_bus_register(void);
> +extern void acpi_i2c_bus_unregister(void);
> +#else
> +static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
> +static inline void acpi_i2c_bus_register(void) {}
> +static inline void acpi_i2c_bus_unregister(void) {}
> +#endif /* CONFIG_ACPI_I2C */
> +
> +#endif /* LINUX_ACPI_I2C_H */


-- 
Jean Delvare

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

* Re: [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-03 21:52   ` Jean Delvare
@ 2012-11-04  7:23     ` Mika Westerberg
  2012-11-04  8:50       ` Jean Delvare
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-04  7:23 UTC (permalink / raw)
  To: Jean Delvare
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sat, Nov 03, 2012 at 10:52:46PM +0100, Jean Delvare wrote:
> On Sat,  3 Nov 2012 09:46:33 +0200, Mika Westerberg wrote:
> > ACPI 5 introduced I2cSerialBus resource that makes it possible to enumerate
> > and configure the I2C slave devices behind the I2C controller. This patch
> > adds helper functions to support I2C slave enumeration.
> > 
> > An ACPI enabled I2C controller driver only needs to call acpi_i2c_register_devices()
> > in order to get its slave devices enumerated, created and bound to the
> > corresponding ACPI handle.
> 
> I'm very happy to finally see this happen. Out of curiosity, did you
> try that code with an actual ACPI implementation?

Yes, it was tested on a real hardware with ACPI 5 support.

> 
> Light review below:
> 
> > 
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/acpi/Kconfig     |    6 ++
> >  drivers/acpi/Makefile    |    1 +
> >  drivers/acpi/acpi_i2c.c  |  234 ++++++++++++++++++++++++++++++++++++++++++++++
> >  drivers/i2c/i2c-core.c   |    9 ++
> >  include/linux/acpi_i2c.h |   29 ++++++
> >  5 files changed, 279 insertions(+)
> >  create mode 100644 drivers/acpi/acpi_i2c.c
> >  create mode 100644 include/linux/acpi_i2c.h
> > 
> > diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> > index 119d58d..0300bf6 100644
> > --- a/drivers/acpi/Kconfig
> > +++ b/drivers/acpi/Kconfig
> > @@ -181,6 +181,12 @@ config ACPI_DOCK
> >  	  This driver supports ACPI-controlled docking stations and removable
> >  	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
> >  
> > +config ACPI_I2C
> > +	def_tristate I2C
> > +	depends on I2C
> > +	help
> > +	  ACPI I2C enumeration support.
> > +
> >  config ACPI_PROCESSOR
> >  	tristate "Processor"
> >  	select THERMAL
> > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> > index a7badb5..8573346 100644
> > --- a/drivers/acpi/Makefile
> > +++ b/drivers/acpi/Makefile
> > @@ -69,6 +69,7 @@ obj-$(CONFIG_ACPI_HED)		+= hed.o
> >  obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
> >  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
> >  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
> > +obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
> >  
> >  # processor has its own "processor." module_param namespace
> >  processor-y			:= processor_driver.o processor_throttling.o
> > diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
> > new file mode 100644
> > index 0000000..dc6997e
> > --- /dev/null
> > +++ b/drivers/acpi/acpi_i2c.c
> > @@ -0,0 +1,234 @@
> > +/*
> > + * ACPI I2C enumeration support
> > + *
> > + * Copyright (C) 2012, Intel Corporation
> > + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> 
> You also need <linux/device.h> for dev_err() etc., and <linux/err.h> for
> ENODEV etc.

I think <acpi.h> already includes <device.h> but I'll double check. At
least this compiles without those headers in place :)

> > +
> > +struct acpi_i2c {
> > +	acpi_status (*callback)(struct acpi_device *, void *);
> > +	void *data;
> > +};
> > +
> > +static acpi_status acpi_i2c_enumerate_device(acpi_handle handle, u32 level,
> > +					     void *data, void **return_value)
> > +{
> > +	struct acpi_i2c *acpi_i2c = data;
> > +	struct acpi_device *adev;
> > +
> > +	if (acpi_bus_get_device(handle, &adev))
> > +		return AE_OK;
> > +	if (acpi_bus_get_status(adev) || !adev->status.present)
> > +		return AE_OK;
> > +
> > +	return acpi_i2c->callback(adev, acpi_i2c->data);
> > +}
> > +
> > +static acpi_status acpi_i2c_enumerate(acpi_handle handle,
> > +	acpi_status (*callback)(struct acpi_device *, void *), void *data)
> > +{
> > +	struct acpi_i2c acpi_i2c;
> > +
> > +	acpi_i2c.callback = callback;
> > +	acpi_i2c.data = data;
> > +
> > +	return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> > +				   acpi_i2c_enumerate_device, NULL,
> > +				   &acpi_i2c, NULL);
> > +}
> > +
> > +struct acpi_i2c_device_info {
> > +	struct i2c_board_info board;
> > +	int triggering;
> > +	int polarity;
> > +	int gsi;
> > +	bool valid;
> > +};
> > +
> > +static acpi_status acpi_i2c_add_resources(struct acpi_resource *res, void *data)
> > +{
> > +	struct acpi_i2c_device_info *info = data;
> > +	struct acpi_resource_i2c_serialbus *sb;
> > +
> > +	switch (res->type) {
> > +	case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> > +		sb = &res->data.i2c_serial_bus;
> > +		if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) {
> > +			info->board.addr = sb->slave_address;
> > +			if (sb->access_mode == ACPI_I2C_10BIT_MODE)
> > +				info->board.flags |= I2C_CLIENT_TEN;
> > +
> > +			/*
> > +			 * The info is valid once we have found the
> > +			 * I2CSerialBus resource.
> > +			 */
> > +			info->valid = true;
> > +		}
> > +		break;
> > +
> > +	case ACPI_RESOURCE_TYPE_IRQ:
> > +		info->gsi = res->data.irq.interrupts[0];
> > +		info->triggering = res->data.irq.triggering;
> > +		info->polarity = res->data.irq.polarity;
> > +		break;
> > +
> > +	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > +		info->gsi = res->data.extended_irq.interrupts[0];
> > +		info->triggering = res->data.extended_irq.triggering;
> > +		info->polarity = res->data.extended_irq.polarity;
> > +		break;
> > +	}
> > +
> > +	return AE_OK;
> > +}
> > +
> > +static acpi_status acpi_i2c_add_device(struct acpi_device *adev, void *data)
> > +{
> > +	struct acpi_i2c_device_info info;
> > +	struct i2c_adapter *adapter = data;
> > +	acpi_status status;
> > +
> > +	memset(&info, 0, sizeof(info));
> > +	info.gsi = -1;
> > +
> > +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> > +				     acpi_i2c_add_resources, &info);
> > +	if (ACPI_FAILURE(status) || !info.valid)
> > +		return status;
> > +
> > +	strlcpy(info.board.type, acpi_device_hid(adev),
> > +		sizeof(info.board.type));
> 
> I very much doubt the ACPI HID names will match the Linux i2c device
> names. In other words you are instantiating devices no driver will want
> to bind to. How do you plan to solve this issue?

We use ACPI IDs (_HID, _CID) for matching in a similar way than the Device
Tree does. Typicaly you add following code to the existing I2C driver:

#ifdef CONFIG_ACPI
static struct acpi_device_id mydrv_acpi_match[] = {
	{ "CHRGR00", 0 },
	...
	{ }
};
MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match);
#endif

static struct i2c_driver mydrv = {
	.driver = {
		.acpi_match_table = ACPI_PTR(mydrv_acpi_match),
	},
	...
};

in order to get the driver matched to the device. If the driver needs to
perform some ACPI specific things, like call _DSM method - it gets the ACPI
handle from dev->acpi_handle (analoguous to Device Tree dev->of_node).

The same thing applies to platform and SPI busses as well.

> > +	if (info.gsi >= 0)
> > +		info.board.irq = acpi_register_gsi(&adev->dev, info.gsi,
> > +						   info.triggering,
> > +						   info.polarity);
> > +
> > +	request_module("%s%s", I2C_MODULE_PREFIX, info.board.type);
> > +	if (!i2c_new_device(adapter, &info.board)) {
> > +		dev_err(&adapter->dev, "failed to add i2c device from ACPI\n");
> > +		if (info.gsi >= 0)
> > +			acpi_unregister_gsi(info.gsi);
> > +	}
> > +
> > +	return AE_OK;
> > +}
> > +
> > +/**
> > + * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter
> > + * @adapter: pointer to adapter
> > + *
> > + * Enumerate all I2C slave devices behind this adapter by walking the ACPI
> > + * namespace. When a device is found it will be added to the Linux device
> > + * model and bound to the corresponding ACPI handle.
> > + */
> > +void acpi_i2c_register_devices(struct i2c_adapter *adapter)
> > +{
> > +	acpi_handle handle;
> > +	acpi_status status;
> > +
> > +	handle = adapter->dev.acpi_handle;
> > +	if (!handle)
> > +		return;
> > +
> > +	status = acpi_i2c_enumerate(handle, acpi_i2c_add_device, adapter);
> > +	if (ACPI_FAILURE(status))
> > +		dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n");
> > +}
> > +EXPORT_SYMBOL_GPL(acpi_i2c_register_devices);
> > +
> > +struct acpi_i2c_find {
> > +	acpi_handle handle;
> > +	u16 addr;
> > +	bool found;
> > +};
> > +
> > +static acpi_status acpi_i2c_find_child_address(struct acpi_resource *res,
> > +					       void *data)
> > +{
> > +	struct acpi_resource_i2c_serialbus *sb;
> > +	struct acpi_i2c_find *i2c_find = data;
> > +
> > +	if (res->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
> > +		return AE_OK;
> > +
> > +	sb = &res->data.i2c_serial_bus;
> > +	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
> > +		return AE_OK;
> > +
> > +	if (sb->slave_address == i2c_find->addr) {
> > +		i2c_find->found = true;
> > +		return AE_CTRL_TERMINATE;
> > +	}
> > +
> > +	return AE_OK;
> > +}
> > +
> > +static acpi_status acpi_i2c_find_child(struct acpi_device *adev, void *data)
> > +{
> > +	struct acpi_i2c_find *i2c_find = data;
> > +	acpi_status status;
> > +
> > +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> > +				     acpi_i2c_find_child_address, i2c_find);
> > +	if (ACPI_FAILURE(status) || !i2c_find->found)
> > +		return status;
> > +
> > +	i2c_find->handle = adev->handle;
> > +	return AE_CTRL_TERMINATE;
> > +}
> > +
> > +static int acpi_i2c_find_device(struct device *dev, acpi_handle *handle)
> > +{
> > +	struct acpi_i2c_find i2c_find;
> > +	struct i2c_adapter *adapter;
> > +	struct i2c_client *client;
> > +	acpi_handle parent;
> > +	acpi_status status;
> > +
> > +	client = i2c_verify_client(dev);
> > +	if (!client)
> > +		return -ENODEV;
> > +
> > +	adapter = client->adapter;
> > +	if (!adapter)
> > +		return -ENODEV;
> > +
> > +	parent = adapter->dev.acpi_handle;
> > +	if (!parent)
> > +		return -ENODEV;
> > +
> > +	memset(&i2c_find, 0, sizeof(i2c_find));
> > +	i2c_find.addr = client->addr;
> > +
> > +	status = acpi_i2c_enumerate(parent, acpi_i2c_find_child, &i2c_find);
> > +	if (ACPI_FAILURE(status) || !i2c_find.handle)
> > +		return -ENODEV;
> > +
> > +	*handle = i2c_find.handle;
> > +	return 0;
> > +}
> > +
> > +static struct acpi_bus_type acpi_i2c_bus = {
> > +	.bus = &i2c_bus_type,
> > +	.find_device = acpi_i2c_find_device,
> > +};
> > +
> > +void acpi_i2c_bus_register(void)
> > +{
> > +	register_acpi_bus_type(&acpi_i2c_bus);
> > +}
> > +EXPORT_SYMBOL_GPL(acpi_i2c_bus_register);
> > +
> > +void acpi_i2c_bus_unregister(void)
> > +{
> > +	unregister_acpi_bus_type(&acpi_i2c_bus);
> > +}
> > +EXPORT_SYMBOL_GPL(acpi_i2c_bus_unregister);
> > diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> > index a7edf98..8b9d6fb 100644
> > --- a/drivers/i2c/i2c-core.c
> > +++ b/drivers/i2c/i2c-core.c
> > @@ -39,6 +39,7 @@
> >  #include <linux/irqflags.h>
> >  #include <linux/rwsem.h>
> >  #include <linux/pm_runtime.h>
> > +#include <linux/acpi_i2c.h>
> >  #include <asm/uaccess.h>
> >  
> >  #include "i2c-core.h"
> > @@ -78,6 +79,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
> >  	if (of_driver_match_device(dev, drv))
> >  		return 1;
> >  
> > +	/* Then ACPI style match */
> > +	if (acpi_driver_match_device(dev, drv))
> > +		return 1;
> > +
> >  	driver = to_i2c_driver(drv);
> >  	/* match on an id table if there is one */
> >  	if (driver->id_table)
> > @@ -1298,6 +1303,8 @@ static int __init i2c_init(void)
> >  	retval = i2c_add_driver(&dummy_driver);
> >  	if (retval)
> >  		goto class_err;
> > +
> > +	acpi_i2c_bus_register();
> >  	return 0;
> >  
> >  class_err:
> > @@ -1311,6 +1318,8 @@ bus_err:
> >  
> >  static void __exit i2c_exit(void)
> >  {
> > +	acpi_i2c_bus_unregister();
> > +
> >  	i2c_del_driver(&dummy_driver);
> >  #ifdef CONFIG_I2C_COMPAT
> >  	class_compat_unregister(i2c_adapter_compat_class);
> > diff --git a/include/linux/acpi_i2c.h b/include/linux/acpi_i2c.h
> > new file mode 100644
> > index 0000000..d4482df
> > --- /dev/null
> > +++ b/include/linux/acpi_i2c.h
> > @@ -0,0 +1,29 @@
> > +/*
> > + * ACPI I2C enumeration support
> > + *
> > + * Copyright (C) 2012, Intel Corporation
> > + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#ifndef LINUX_ACPI_I2C_H
> > +#define LINUX_ACPI_I2C_H
> > +
> > +#include <linux/acpi.h>
> 
> What for?

No reason, I'll remove that.

> 
> > +struct i2c_adapter;
> > +
> > +#if defined(CONFIG_ACPI_I2C) || defined(CONFIG_ACPI_I2C_MODULE)
> > +extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
> > +extern void acpi_i2c_bus_register(void);
> > +extern void acpi_i2c_bus_unregister(void);
> > +#else
> > +static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
> > +static inline void acpi_i2c_bus_register(void) {}
> > +static inline void acpi_i2c_bus_unregister(void) {}
> > +#endif /* CONFIG_ACPI_I2C */
> > +
> > +#endif /* LINUX_ACPI_I2C_H */
> 
> 
> -- 
> Jean Delvare

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

* Re: [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-04  7:23     ` Mika Westerberg
@ 2012-11-04  8:50       ` Jean Delvare
  2012-11-04 10:50         ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Jean Delvare @ 2012-11-04  8:50 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sun, 4 Nov 2012 09:23:17 +0200, Mika Westerberg wrote:
> On Sat, Nov 03, 2012 at 10:52:46PM +0100, Jean Delvare wrote:
> > On Sat,  3 Nov 2012 09:46:33 +0200, Mika Westerberg wrote:
> > > --- /dev/null
> > > +++ b/drivers/acpi/acpi_i2c.c
> > > @@ -0,0 +1,234 @@
> > > +/*
> > > + * ACPI I2C enumeration support
> > > + *
> > > + * Copyright (C) 2012, Intel Corporation
> > > + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License version 2 as
> > > + * published by the Free Software Foundation.
> > > + */
> > > +
> > > +#include <linux/acpi.h>
> > > +#include <linux/i2c.h>
> > > +#include <linux/module.h>
> > 
> > You also need <linux/device.h> for dev_err() etc., and <linux/err.h> for
> > ENODEV etc.
> 
> I think <acpi.h> already includes <device.h> but I'll double check. At
> least this compiles without those headers in place :)

That's not really the point. You never know which header inclusions
will be removed from other header files in the future, so you should
include what you need explicitly. This avoids future build breakages as
well as build breakages on other architectures.

> > > (...)
> > > +static acpi_status acpi_i2c_add_device(struct acpi_device *adev, void *data)
> > > +{
> > > +	struct acpi_i2c_device_info info;
> > > +	struct i2c_adapter *adapter = data;
> > > +	acpi_status status;
> > > +
> > > +	memset(&info, 0, sizeof(info));
> > > +	info.gsi = -1;
> > > +
> > > +	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
> > > +				     acpi_i2c_add_resources, &info);
> > > +	if (ACPI_FAILURE(status) || !info.valid)
> > > +		return status;
> > > +
> > > +	strlcpy(info.board.type, acpi_device_hid(adev),
> > > +		sizeof(info.board.type));
> > 
> > I very much doubt the ACPI HID names will match the Linux i2c device
> > names. In other words you are instantiating devices no driver will want
> > to bind to. How do you plan to solve this issue?
> 
> We use ACPI IDs (_HID, _CID) for matching in a similar way than the Device
> Tree does. Typicaly you add following code to the existing I2C driver:
> 
> #ifdef CONFIG_ACPI
> static struct acpi_device_id mydrv_acpi_match[] = {
> 	{ "CHRGR00", 0 },
> 	...
> 	{ }
> };
> MODULE_DEVICE_TABLE(acpi, mydrv_acpi_match);
> #endif
> 
> static struct i2c_driver mydrv = {
> 	.driver = {
> 		.acpi_match_table = ACPI_PTR(mydrv_acpi_match),
> 	},
> 	...
> };
> 
> in order to get the driver matched to the device. If the driver needs to
> perform some ACPI specific things, like call _DSM method - it gets the ACPI
> handle from dev->acpi_handle (analoguous to Device Tree dev->of_node).
> 
> The same thing applies to platform and SPI busses as well.

OK, very nice, that should work just fine :)

Thanks,
-- 
Jean Delvare

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

* Re: [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-04  8:50       ` Jean Delvare
@ 2012-11-04 10:50         ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-04 10:50 UTC (permalink / raw)
  To: Jean Delvare
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sun, Nov 04, 2012 at 09:50:31AM +0100, Jean Delvare wrote:
> On Sun, 4 Nov 2012 09:23:17 +0200, Mika Westerberg wrote:
> > On Sat, Nov 03, 2012 at 10:52:46PM +0100, Jean Delvare wrote:
> > > On Sat,  3 Nov 2012 09:46:33 +0200, Mika Westerberg wrote:
> > > > --- /dev/null
> > > > +++ b/drivers/acpi/acpi_i2c.c
> > > > @@ -0,0 +1,234 @@
> > > > +/*
> > > > + * ACPI I2C enumeration support
> > > > + *
> > > > + * Copyright (C) 2012, Intel Corporation
> > > > + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> > > > + *
> > > > + * This program is free software; you can redistribute it and/or modify
> > > > + * it under the terms of the GNU General Public License version 2 as
> > > > + * published by the Free Software Foundation.
> > > > + */
> > > > +
> > > > +#include <linux/acpi.h>
> > > > +#include <linux/i2c.h>
> > > > +#include <linux/module.h>
> > > 
> > > You also need <linux/device.h> for dev_err() etc., and <linux/err.h> for
> > > ENODEV etc.
> > 
> > I think <acpi.h> already includes <device.h> but I'll double check. At
> > least this compiles without those headers in place :)
> 
> That's not really the point. You never know which header inclusions
> will be removed from other header files in the future, so you should
> include what you need explicitly. This avoids future build breakages as
> well as build breakages on other architectures.

Right. I've actually seen this problem few times before. I added the
inclusion of <devide.h> and <err.h> to the file.

Thanks.

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

* Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C
  2012-11-03  7:46 [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Mika Westerberg
                   ` (2 preceding siblings ...)
  2012-11-03  7:46 ` [PATCH 3/3] i2c " Mika Westerberg
@ 2012-11-04 18:29 ` Linus Walleij
  2012-11-05  9:23   ` Mika Westerberg
  2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
  4 siblings, 1 reply; 127+ messages in thread
From: Linus Walleij @ 2012-11-04 18:29 UTC (permalink / raw)
  To: Mika Westerberg, Grant Likely
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Sat, Nov 3, 2012 at 8:46 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> With ACPI 5 we can now describe how devices are connected to their bus
> using new resources: SPISerialBus and I2CSerialBus. Also it is now possible
> to add GPIO connections for the devices with the help of GpioIO and GpioInt
> resources.
>
> This series adds support for these new resources.

I would very much like Grant to review and merge these patches, since he
is way more familiar with these concepts than me, but I'll have a quick
glance for syntax and semantics...

Yours,
Linus Walleij

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

* Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C
  2012-11-04 18:29 ` [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Linus Walleij
@ 2012-11-05  9:23   ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05  9:23 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Grant Likely, linux-kernel, lenb, rafael.j.wysocki, broonie,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sun, Nov 04, 2012 at 07:29:10PM +0100, Linus Walleij wrote:
> On Sat, Nov 3, 2012 at 8:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> 
> > With ACPI 5 we can now describe how devices are connected to their bus
> > using new resources: SPISerialBus and I2CSerialBus. Also it is now possible
> > to add GPIO connections for the devices with the help of GpioIO and GpioInt
> > resources.
> >
> > This series adds support for these new resources.
> 
> I would very much like Grant to review and merge these patches, since he
> is way more familiar with these concepts than me, but I'll have a quick
> glance for syntax and semantics...

That sounds good, thanks!

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03 20:59       ` Rafael J. Wysocki
@ 2012-11-05 10:31         ` Rafael J. Wysocki
  2012-11-05 10:56           ` Mika Westerberg
  2012-11-05 16:54           ` Bjorn Helgaas
  0 siblings, 2 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-05 10:31 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Saturday, November 03, 2012 09:59:28 PM Rafael J. Wysocki wrote:
> On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
> > On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
> > > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> > > <mika.westerberg@linux.intel.com> wrote:
> > > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> > > > configure the SPI slave devices behind the SPI controller. This patch adds
> > > > support for this to the SPI core.
[...]
> > And if the ACPI core parses the _CRS, how does it pass all the resources to
> > the drivers?
> 
> Pretty much the same way the $subject patch does.
> 
> Instead of parsing the entire subtree below an SPI controller and trying
> acpi_spi_add_device() for each device node in there, it could call
> acpi_spi_add_device() whenever it finds a device of type
> ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
> The only problem is how to pass "master" to it.
> 
> So Bjorn, do you have any idea how we could pass the "master" pointer from the
> ACPI core to acpi_spi_add_device() in a sensible way?
> 
> An alternative might be to store the information obtained from _CRS in
> struct acpi_device objects created by the ACPI core while parsing the
> namespace.  We do that already for things like _PRW, so we might as well do it
> for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
> below the SPI controller's acpi_device to extract that information.
> Maybe that's the way to go?

The general idea is to move the _CRS parsing routine from acpi_platform.c
to scan.c and make it attach resource objects to struct acpi_device.

I'm thinking about adding a list head to struct acpi_device pointing to a
list of entries like:

struct resource_list_entry {
	struct list_head node;
	struct resource *resources;
	unsigned int count;
};

where "resources" is an array of resources (e.g. interrupts) in the given
entry and count is the size of that array.

That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.
I think adding it would allow us to make acpi_create_platform_device(),
acpi_spi_add_resources() and acpi_i2c_add_resources() more straightforward (and
remove some code duplication between the last two routines).

In addition to that, I'd add an entry containing serial bus information, if
applicable, for the given struct acpi_device, something like:

union acpi_resource_serial_bus {
	struct acpi_resource_common_serialbus;
	struct acpi_resource_spi_serialbus;
	struct acpi_resource_i2c_serialbus;
	struct acpi_resource_uart_serialbus;
};

struct acpi_device {
	...
	union acpi_resource_serial_bus *serial;
	...
};

Then, things like acpi_spi_add_resources() and acpi_i2c_add_resources() would
be able to use struct acpi_device objects directly without running any AML.

That could be done on top of the current series and I'm going to prepare a patch
for that in the next few days if I find some time between the LCE sessions.

Thanks,
Rafael


--- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03 20:13     ` Mika Westerberg
  2012-11-03 20:59       ` Rafael J. Wysocki
@ 2012-11-05 10:54       ` Mark Brown
  1 sibling, 0 replies; 127+ messages in thread
From: Mark Brown @ 2012-11-05 10:54 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Sat, Nov 03, 2012 at 10:13:10PM +0200, Mika Westerberg wrote:
> On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:

> > > +       case ACPI_RESOURCE_TYPE_IRQ:
> > > +               info->gsi = res->data.irq.interrupts[0];
> > > +               info->triggering = res->data.irq.triggering;
> > > +               info->polarity = res->data.irq.polarity;
> > > +               break;

> > > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > > +               info->gsi = res->data.extended_irq.interrupts[0];
> > > +               info->triggering = res->data.extended_irq.triggering;
> > > +               info->polarity = res->data.extended_irq.polarity;

> > A driver doesn't seem like the right place for _CRS parsing code.  I
> > think the intent of _CRS is to describe resources that need to be
> > coordinated across all devices, e.g., MMIO space, I/O port space, and
> > IRQs.  Since these resources require system-wide coordination, even
> > when we don't have drivers for some devices, the ACPI core should be
> > able to parse _CRS without needing any device-specific knowledge.

> I think the driver is the only one who really knows the resources it needs
> in order to talk the hardware.

Generic SPI drivers expect the subsystem to supply them with an
interrupt number; if there is a single interrupt it seems reasonable for
the generic code to continue to do that for them when they're
instantiated from ACPI.  On the other hand if there are muliple
interrupts it should probably give up and punt to the driver.

> The purpose of the above code is to extract the resources in a suitable
> form so that we can create a struct spi_device out of them automatically,
> in a similar way than the Device Tree does.

Definitely agreed.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03  7:46 ` [PATCH 2/3] spi / ACPI: add ACPI enumeration support Mika Westerberg
  2012-11-03 19:42   ` Bjorn Helgaas
@ 2012-11-05 10:54   ` Mark Brown
  2012-11-05 11:03     ` Mika Westerberg
  2012-11-08 18:48   ` Grant Likely
  2 siblings, 1 reply; 127+ messages in thread
From: Mark Brown @ 2012-11-05 10:54 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

[-- Attachment #1: Type: text/plain, Size: 325 bytes --]

On Sat, Nov 03, 2012 at 09:46:32AM +0200, Mika Westerberg wrote:

> +	strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
> +	if (info.gsi >= 0)
> +		spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
> +					     info.triggering, info.polarity);
> +	request_module(spi->modalias);

request_module()?  Why?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 10:31         ` Rafael J. Wysocki
@ 2012-11-05 10:56           ` Mika Westerberg
  2012-11-05 10:56             ` Mark Brown
  2012-11-05 16:54           ` Bjorn Helgaas
  1 sibling, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 10:56 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 11:31:19AM +0100, Rafael J. Wysocki wrote:
> The general idea is to move the _CRS parsing routine from acpi_platform.c
> to scan.c and make it attach resource objects to struct acpi_device.
> 
> I'm thinking about adding a list head to struct acpi_device pointing to a
> list of entries like:
> 
> struct resource_list_entry {
> 	struct list_head node;
> 	struct resource *resources;
> 	unsigned int count;
> };
> 
> where "resources" is an array of resources (e.g. interrupts) in the given
> entry and count is the size of that array.
> 
> That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
> ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.
> I think adding it would allow us to make acpi_create_platform_device(),
> acpi_spi_add_resources() and acpi_i2c_add_resources() more straightforward (and
> remove some code duplication between the last two routines).

This certainly sounds good to me.

> In addition to that, I'd add an entry containing serial bus information, if
> applicable, for the given struct acpi_device, something like:
> 
> union acpi_resource_serial_bus {
> 	struct acpi_resource_common_serialbus;
> 	struct acpi_resource_spi_serialbus;
> 	struct acpi_resource_i2c_serialbus;
> 	struct acpi_resource_uart_serialbus;
> };
> 
> struct acpi_device {
> 	...
> 	union acpi_resource_serial_bus *serial;
> 	...
> };

It is also possible to have several serial bus connectors on a single
device (although we've seen only one connector per device but it should not
be limited to that).

> Then, things like acpi_spi_add_resources() and acpi_i2c_add_resources() would
> be able to use struct acpi_device objects directly without running any AML.
> That could be done on top of the current series and I'm going to prepare a patch
> for that in the next few days if I find some time between the LCE sessions.

Cool :-) Let me know if you need any help, like testing the patches etc.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 10:56           ` Mika Westerberg
@ 2012-11-05 10:56             ` Mark Brown
  2012-11-05 12:02               ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Mark Brown @ 2012-11-05 10:56 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, grant.likely, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi

[-- Attachment #1: Type: text/plain, Size: 652 bytes --]

On Mon, Nov 05, 2012 at 12:56:02PM +0200, Mika Westerberg wrote:

> > struct acpi_device {
> > 	...
> > 	union acpi_resource_serial_bus *serial;
> > 	...
> > };

> It is also possible to have several serial bus connectors on a single
> device (although we've seen only one connector per device but it should not
> be limited to that).

I've got practical systems where there are multiple buses physically
connected, though in practice almost always only one is actually used at
runtime when it's I2C and SPI there are some systems (usually with other
buses) where you might want to use more than one bus.  Not sure those
buses will fit in here though.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 10:54   ` Mark Brown
@ 2012-11-05 11:03     ` Mika Westerberg
  2012-11-05 11:13       ` Mark Brown
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 11:03 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-kernel, lenb, rafael.j.wysocki, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Mon, Nov 05, 2012 at 11:54:55AM +0100, Mark Brown wrote:
> On Sat, Nov 03, 2012 at 09:46:32AM +0200, Mika Westerberg wrote:
> 
> > +	strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
> > +	if (info.gsi >= 0)
> > +		spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
> > +					     info.triggering, info.polarity);
> > +	request_module(spi->modalias);
> 
> request_module()?  Why?

The DT code does the same. I have no idea why it is there, really :-)

I can remove it in the next version if you think it is not needed.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 11:03     ` Mika Westerberg
@ 2012-11-05 11:13       ` Mark Brown
  0 siblings, 0 replies; 127+ messages in thread
From: Mark Brown @ 2012-11-05 11:13 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

[-- Attachment #1: Type: text/plain, Size: 668 bytes --]

On Mon, Nov 05, 2012 at 01:03:22PM +0200, Mika Westerberg wrote:
> On Mon, Nov 05, 2012 at 11:54:55AM +0100, Mark Brown wrote:
> > On Sat, Nov 03, 2012 at 09:46:32AM +0200, Mika Westerberg wrote:

> > > +	strlcpy(spi->modalias, acpi_device_hid(adev), sizeof(spi->modalias));
> > > +	if (info.gsi >= 0)
> > > +		spi->irq = acpi_register_gsi(&adev->dev, info.gsi,
> > > +					     info.triggering, info.polarity);
> > > +	request_module(spi->modalias);

> > request_module()?  Why?

> The DT code does the same. I have no idea why it is there, really :-)

> I can remove it in the next version if you think it is not needed.

Well, if you can't identify what it does...

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-03  7:46 ` [PATCH 1/3] gpio / ACPI: add ACPI support Mika Westerberg
@ 2012-11-05 11:53   ` Linus Walleij
  2012-11-05 12:14     ` Mathias Nyman
  2012-11-08 15:55   ` Grant Likely
  1 sibling, 1 reply; 127+ messages in thread
From: Linus Walleij @ 2012-11-05 11:53 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sat, Nov 3, 2012 at 8:46 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:

> +/**
> + * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API
> + * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
> + * @pin:       ACPI GPIO pin number (0-based, controller-relative)
> + *
> + * Returns GPIO number to use with Linux generic GPIO API, or errno error value
> + */

So by just looking at that we can see that this is yet another
instance of papering
over the fact that the Linux GPIO numbers are global to the kernel and not
per-chip, as would be preferred.

Can you please contribute to the parallel discussion on how to get rid of
the global GPIO numberspace, thread named:
"How about a gpio_get(device *, char *) function?"

Yours,
Linus Walleij

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 10:56             ` Mark Brown
@ 2012-11-05 12:02               ` Mika Westerberg
  2012-11-05 12:23                 ` Jean Delvare
  2012-11-06  8:11                 ` Mark Brown
  0 siblings, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 12:02 UTC (permalink / raw)
  To: Mark Brown
  Cc: Rafael J. Wysocki, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, grant.likely, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
> On Mon, Nov 05, 2012 at 12:56:02PM +0200, Mika Westerberg wrote:
> 
> > > struct acpi_device {
> > > 	...
> > > 	union acpi_resource_serial_bus *serial;
> > > 	...
> > > };
> 
> > It is also possible to have several serial bus connectors on a single
> > device (although we've seen only one connector per device but it should not
> > be limited to that).
> 
> I've got practical systems where there are multiple buses physically
> connected, though in practice almost always only one is actually used at
> runtime when it's I2C and SPI there are some systems (usually with other
> buses) where you might want to use more than one bus.  Not sure those
> buses will fit in here though.

Yeah, I just went through DSDT table of one of our machines and found a
device that actually has two I2CSerialBus connectors (and those are to the
same controller). What I'm not sure is that is it used to select between
two different addresses or doest the device really have two physical I2C
connections.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 11:53   ` Linus Walleij
@ 2012-11-05 12:14     ` Mathias Nyman
  2012-11-05 12:46       ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mathias Nyman @ 2012-11-05 12:14 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, khali, ben-linux, w.sang, linux-acpi

On 11/05/2012 01:53 PM, Linus Walleij wrote:
> On Sat, Nov 3, 2012 at 8:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com>  wrote:
>
>> +/**
>> + * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API
>> + * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
>> + * @pin:       ACPI GPIO pin number (0-based, controller-relative)
>> + *
>> + * Returns GPIO number to use with Linux generic GPIO API, or errno error value
>> + */
>
> So by just looking at that we can see that this is yet another
> instance of papering
> over the fact that the Linux GPIO numbers are global to the kernel and not
> per-chip, as would be preferred.

Yes, it is. ACPI5 GPIO resources are numbered per-chip. This is just a 
way for device drivers to find the corresponding Linux GPIO.

per-chip based numbering sounds saner, but this deals with what we 
currently have.

>
> Can you please contribute to the parallel discussion on how to get rid of
> the global GPIO numberspace, thread named:
> "How about a gpio_get(device *, char *) function?"

I'll take a look at it, (and see if I got anything of value to add)

-Mathias

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 12:02               ` Mika Westerberg
@ 2012-11-05 12:23                 ` Jean Delvare
  2012-11-05 12:59                   ` Rafael J. Wysocki
  2012-11-06  8:11                 ` Mark Brown
  1 sibling, 1 reply; 127+ messages in thread
From: Jean Delvare @ 2012-11-05 12:23 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Mark Brown, Rafael J. Wysocki, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, grant.likely, linus.walleij, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Mon, 5 Nov 2012 14:02:19 +0200, Mika Westerberg wrote:
> On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
> > I've got practical systems where there are multiple buses physically
> > connected, though in practice almost always only one is actually used at
> > runtime when it's I2C and SPI there are some systems (usually with other
> > buses) where you might want to use more than one bus.  Not sure those
> > buses will fit in here though.
> 
> Yeah, I just went through DSDT table of one of our machines and found a
> device that actually has two I2CSerialBus connectors (and those are to the
> same controller). What I'm not sure is that is it used to select between
> two different addresses or doest the device really have two physical I2C
> connections.

Neither would make sense from a hardware perspective.

-- 
Jean Delvare

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 12:14     ` Mathias Nyman
@ 2012-11-05 12:46       ` Rafael J. Wysocki
  2012-11-05 13:11         ` Linus Walleij
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-05 12:46 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: Linus Walleij, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Monday, November 05, 2012 02:14:21 PM Mathias Nyman wrote:
> On 11/05/2012 01:53 PM, Linus Walleij wrote:
> > On Sat, Nov 3, 2012 at 8:46 AM, Mika Westerberg
> > <mika.westerberg@linux.intel.com>  wrote:
> >
> >> +/**
> >> + * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API
> >> + * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
> >> + * @pin:       ACPI GPIO pin number (0-based, controller-relative)
> >> + *
> >> + * Returns GPIO number to use with Linux generic GPIO API, or errno error value
> >> + */
> >
> > So by just looking at that we can see that this is yet another
> > instance of papering
> > over the fact that the Linux GPIO numbers are global to the kernel and not
> > per-chip, as would be preferred.
> 
> Yes, it is. ACPI5 GPIO resources are numbered per-chip. This is just a 
> way for device drivers to find the corresponding Linux GPIO.
> 
> per-chip based numbering sounds saner, but this deals with what we 
> currently have.

And we need something to hook up drivers to right now.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 12:23                 ` Jean Delvare
@ 2012-11-05 12:59                   ` Rafael J. Wysocki
  2012-11-05 13:15                     ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-05 12:59 UTC (permalink / raw)
  To: Jean Delvare, Mika Westerberg
  Cc: Mark Brown, Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki,
	grant.likely, linus.walleij, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Monday, November 05, 2012 01:23:50 PM Jean Delvare wrote:
> On Mon, 5 Nov 2012 14:02:19 +0200, Mika Westerberg wrote:
> > On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
> > > I've got practical systems where there are multiple buses physically
> > > connected, though in practice almost always only one is actually used at
> > > runtime when it's I2C and SPI there are some systems (usually with other
> > > buses) where you might want to use more than one bus.  Not sure those
> > > buses will fit in here though.
> > 
> > Yeah, I just went through DSDT table of one of our machines and found a
> > device that actually has two I2CSerialBus connectors (and those are to the
> > same controller). What I'm not sure is that is it used to select between
> > two different addresses or doest the device really have two physical I2C
> > connections.
> 
> Neither would make sense from a hardware perspective.

Well, interesting. :-)

I wonder what we're supposed to do with things like that?
It looks like our patch [3/3] will use the last one found, but is that
correct?  Should it use the first one instead, perhaps?

That little conundrum aside, the observations above seem to indicate
that we'd need a list of "serial" resources per struct acpi_device too.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 12:46       ` Rafael J. Wysocki
@ 2012-11-05 13:11         ` Linus Walleij
  2012-11-05 13:19           ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Linus Walleij @ 2012-11-05 13:11 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mathias Nyman, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Mon, Nov 5, 2012 at 1:46 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, November 05, 2012 02:14:21 PM Mathias Nyman wrote:

>> per-chip based numbering sounds saner, but this deals with what we
>> currently have.
>
> And we need something to hook up drivers to right now.

So speaking of it I have these drivers consuming pinctrl that I need
to hook up right now and the subsystem maintainers are NACKing
the patches because they want a centralized solution instead of
per-driver hooks and I get the red light...

Do you think they will change their mind and give me green light if
I tell them I just need to do it right now? ;-)

I suggest to take it easy and prolong the deadline, but none of
my business primarily, you will have to go through Grant who is
probably way more reasonable than me.

Yours,
Linus Walleij

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 12:59                   ` Rafael J. Wysocki
@ 2012-11-05 13:15                     ` Mika Westerberg
  2012-11-05 13:20                       ` Linus Walleij
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 13:15 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Jean Delvare, Mark Brown, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, grant.likely, linus.walleij, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 01:59:23PM +0100, Rafael J. Wysocki wrote:
> On Monday, November 05, 2012 01:23:50 PM Jean Delvare wrote:
> > On Mon, 5 Nov 2012 14:02:19 +0200, Mika Westerberg wrote:
> > > On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
> > > > I've got practical systems where there are multiple buses physically
> > > > connected, though in practice almost always only one is actually used at
> > > > runtime when it's I2C and SPI there are some systems (usually with other
> > > > buses) where you might want to use more than one bus.  Not sure those
> > > > buses will fit in here though.
> > > 
> > > Yeah, I just went through DSDT table of one of our machines and found a
> > > device that actually has two I2CSerialBus connectors (and those are to the
> > > same controller). What I'm not sure is that is it used to select between
> > > two different addresses or doest the device really have two physical I2C
> > > connections.
> > 
> > Neither would make sense from a hardware perspective.
> 
> Well, interesting. :-)

It looks like some PMICs for example have two I2C control interfaces, like
TI's TWL6030 if I'm not mistaken. If both are put behind the same I2C
controller with different address, you have the situation like above.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 13:11         ` Linus Walleij
@ 2012-11-05 13:19           ` Rafael J. Wysocki
  2012-11-05 13:28             ` Linus Walleij
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-05 13:19 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mathias Nyman, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Monday, November 05, 2012 02:11:03 PM Linus Walleij wrote:
> On Mon, Nov 5, 2012 at 1:46 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, November 05, 2012 02:14:21 PM Mathias Nyman wrote:
> 
> >> per-chip based numbering sounds saner, but this deals with what we
> >> currently have.
> >
> > And we need something to hook up drivers to right now.
> 
> So speaking of it I have these drivers consuming pinctrl that I need
> to hook up right now and the subsystem maintainers are NACKing
> the patches because they want a centralized solution instead of
> per-driver hooks and I get the red light...
> 
> Do you think they will change their mind and give me green light if
> I tell them I just need to do it right now? ;-)

Well, it's just a matter of fairness to me, actually.

If you allowed somebody to do something in the past, it's simply unfair
to forbid someone else to do a similar thing later, isn't it?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 13:15                     ` Mika Westerberg
@ 2012-11-05 13:20                       ` Linus Walleij
  2012-11-05 13:43                         ` Mika Westerberg
  2012-11-05 14:03                         ` Jean Delvare
  0 siblings, 2 replies; 127+ messages in thread
From: Linus Walleij @ 2012-11-05 13:20 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Jean Delvare, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 5, 2012 at 2:15 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Mon, Nov 05, 2012 at 01:59:23PM +0100, Rafael J. Wysocki wrote:
>> On Monday, November 05, 2012 01:23:50 PM Jean Delvare wrote:
>> > On Mon, 5 Nov 2012 14:02:19 +0200, Mika Westerberg wrote:
>> > > On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
(...)
>> > > Yeah, I just went through DSDT table of one of our machines and found a
>> > > device that actually has two I2CSerialBus connectors (and those are to the
>> > > same controller). What I'm not sure is that is it used to select between
>> > > two different addresses or doest the device really have two physical I2C
>> > > connections.
>> >
>> > Neither would make sense from a hardware perspective.
>>
>> Well, interesting. :-)
>
> It looks like some PMICs for example have two I2C control interfaces, like
> TI's TWL6030 if I'm not mistaken. If both are put behind the same I2C
> controller with different address, you have the situation like above.

This is quite common. So for example the AB8500 (drivers/mfd/ab8500-core.c)
has this. The reason is usually that the device has more than 256 registers
to the address space simply is not big enough.

What we do is refer to the subaddresses as "banks" and they happen
to always be at the next consecutive address so n+1.

So the same device appear behind several addresses just to support
a lot of registers.

So you're not actually modelling the devices on the other end but the
multiple addresses of a single device.

If the addresses are consecutive like ours it makes sense
to just instantiate one device and have the driver know that it will
also be able to access address +1, +2 ... +n. So is it possible
to group the consecutive related addresses after each other
here at the acpi-spi level and just create a single device?

If the addresses are not consecutive I guess you need to have
one device driver bind to several devices and return -EPROBE_DEFER
until the driver has been probed for all of them or something like
that, this is what multi-block GPIO drivers sometimes do.

Yours,
Linus Walleij

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 13:19           ` Rafael J. Wysocki
@ 2012-11-05 13:28             ` Linus Walleij
  2012-11-05 13:50               ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Linus Walleij @ 2012-11-05 13:28 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mathias Nyman, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Mon, Nov 5, 2012 at 2:19 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, November 05, 2012 02:11:03 PM Linus Walleij wrote:
>> Do you think they will change their mind and give me green light if
>> I tell them I just need to do it right now? ;-)
>
> Well, it's just a matter of fairness to me, actually.
>
> If you allowed somebody to do something in the past, it's simply unfair
> to forbid someone else to do a similar thing later, isn't it?

So if some subsystem has previously merged clk_get() for
the silicon clock pertaining to a driver the maintainer should
be fair to the pinctrl people and merge pinctrl_get() as well.
Well, they don't. But it wasn't any of your subsystems so
I don't blame you.

I have been stand-in-maintaining the GPIO subsystem
for the last two merge windows and I am worrying about the
long term viability of the subsystem if we keep doing this
without facing the real problem of the global GPIO
numberspace.

But since Grant merged the gpiolib-of.c thing and is still the
main maintainer I can atleast chicken out by referring to him
this time ... hit me back if he doesn't respond and I will
have to refactor the world or something.

Yours,
Linus Walleij

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 13:20                       ` Linus Walleij
@ 2012-11-05 13:43                         ` Mika Westerberg
  2012-11-05 14:03                         ` Jean Delvare
  1 sibling, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 13:43 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafael J. Wysocki, Jean Delvare, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 02:20:52PM +0100, Linus Walleij wrote:
> >
> > It looks like some PMICs for example have two I2C control interfaces, like
> > TI's TWL6030 if I'm not mistaken. If both are put behind the same I2C
> > controller with different address, you have the situation like above.
> 
> This is quite common. So for example the AB8500 (drivers/mfd/ab8500-core.c)
> has this. The reason is usually that the device has more than 256 registers
> to the address space simply is not big enough.
> 
> What we do is refer to the subaddresses as "banks" and they happen
> to always be at the next consecutive address so n+1.
> 
> So the same device appear behind several addresses just to support
> a lot of registers.
> 
> So you're not actually modelling the devices on the other end but the
> multiple addresses of a single device.

That makes sense. Thanks for the explanation.

> If the addresses are consecutive like ours it makes sense
> to just instantiate one device and have the driver know that it will
> also be able to access address +1, +2 ... +n. So is it possible
> to group the consecutive related addresses after each other
> here at the acpi-spi level and just create a single device?

Not sure if it should be done there, unless we really can be sure that we
have a single device with multiple addresses (and that is usually something
that is only known by the actual driver) and not some device that has two
unrelated interfaces connecting the same controller.

> If the addresses are not consecutive I guess you need to have
> one device driver bind to several devices and return -EPROBE_DEFER
> until the driver has been probed for all of them or something like
> that, this is what multi-block GPIO drivers sometimes do.

The addresses in the DSDT table for this particular device are not
consecutive so we could do something like you propose above.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 13:28             ` Linus Walleij
@ 2012-11-05 13:50               ` Rafael J. Wysocki
  2012-11-05 14:40                 ` Linus Walleij
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-05 13:50 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mathias Nyman, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Monday, November 05, 2012 02:28:45 PM Linus Walleij wrote:
> On Mon, Nov 5, 2012 at 2:19 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, November 05, 2012 02:11:03 PM Linus Walleij wrote:
> >> Do you think they will change their mind and give me green light if
> >> I tell them I just need to do it right now? ;-)
> >
> > Well, it's just a matter of fairness to me, actually.
> >
> > If you allowed somebody to do something in the past, it's simply unfair
> > to forbid someone else to do a similar thing later, isn't it?
> 
> So if some subsystem has previously merged clk_get() for
> the silicon clock pertaining to a driver the maintainer should
> be fair to the pinctrl people and merge pinctrl_get() as well.

Well, let's just say if I were the maintainer of the subsystem in
question, I would propose a deal like this: I'm going to merge your
patches now, provided that you'll work on the centralized solution
going forward.  And it's quite easy to call them on the promise like
this in the future, when they ask you to merge something again.

> Well, they don't. But it wasn't any of your subsystems so
> I don't blame you.
> 
> I have been stand-in-maintaining the GPIO subsystem
> for the last two merge windows and I am worrying about the
> long term viability of the subsystem if we keep doing this
> without facing the real problem of the global GPIO
> numberspace.
> 
> But since Grant merged the gpiolib-of.c thing and is still the
> main maintainer I can atleast chicken out by referring to him
> this time ... hit me back if he doesn't respond and I will
> have to refactor the world or something.

No need to be grumpy. :-)

I forgot to mention that we want to hook up _existing_ drivers to those things,
and they already use the global GPIO numbers, don't they?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 13:20                       ` Linus Walleij
  2012-11-05 13:43                         ` Mika Westerberg
@ 2012-11-05 14:03                         ` Jean Delvare
  2012-11-05 14:19                           ` Rafael J. Wysocki
  2012-11-05 20:42                           ` Linus Walleij
  1 sibling, 2 replies; 127+ messages in thread
From: Jean Delvare @ 2012-11-05 14:03 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Mika Westerberg, Rafael J. Wysocki, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

Hi Linus,

On Mon, 5 Nov 2012 14:20:52 +0100, Linus Walleij wrote:
> On Mon, Nov 5, 2012 at 2:15 PM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Mon, Nov 05, 2012 at 01:59:23PM +0100, Rafael J. Wysocki wrote:
> >> On Monday, November 05, 2012 01:23:50 PM Jean Delvare wrote:
> >> > On Mon, 5 Nov 2012 14:02:19 +0200, Mika Westerberg wrote:
> >> > > On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
> (...)
> >> > > Yeah, I just went through DSDT table of one of our machines and found a
> >> > > device that actually has two I2CSerialBus connectors (and those are to the
> >> > > same controller). What I'm not sure is that is it used to select between
> >> > > two different addresses or doest the device really have two physical I2C
> >> > > connections.
> >> >
> >> > Neither would make sense from a hardware perspective.
> >>
> >> Well, interesting. :-)
> >
> > It looks like some PMICs for example have two I2C control interfaces, like
> > TI's TWL6030 if I'm not mistaken. If both are put behind the same I2C
> > controller with different address, you have the situation like above.

Ah, OK, if this is a degenerated case of a more complex initial design
then yes it makes some sense. I had never met chips like that and did
not know such chips existed.

That being said, from a software perspective, there is no difference
between one or two I2C pin pairs being soldered. All we care about is
which master they are ultimately connected to, and to which slave
address(es) the chip replies.

> This is quite common. So for example the AB8500 (drivers/mfd/ab8500-core.c)
> has this. The reason is usually that the device has more than 256 registers
> to the address space simply is not big enough.

This is completely different from the case being discussed above. Even
the most complex addressing scheme can be implemented using a single
hardware I2C interface. You can use 16-bit register addresses (if you
can live without SMBus compatibility, AT24C32 and larger EEPROMs do
that), or implement internal banks (using one of the registers as the
bank selector, hardware monitoring chips do that), or you can use
multiple slave addresses (AT24C04 to C16 EEPROMs do that.)

> What we do is refer to the subaddresses as "banks" and they happen
> to always be at the next consecutive address so n+1.
> 
> So the same device appear behind several addresses just to support
> a lot of registers.
> 
> So you're not actually modelling the devices on the other end but the
> multiple addresses of a single device.
> 
> If the addresses are consecutive like ours it makes sense
> to just instantiate one device and have the driver know that it will
> also be able to access address +1, +2 ... +n. So is it possible
> to group the consecutive related addresses after each other
> here at the acpi-spi level and just create a single device?

We were actually discussing I2C here, although I admit not in the right
thread, and maybe some of this applies to SPI as well.

There are I2C devices replying to multiple non-consecutive slave
addresses. Most notably Winbond hardware monitoring chips replying to
one address in 0x2c-0x2f and 2 addresses in 0x48-0x4f. And of course
there are the DDR3 DIMM SPD chips which have an EEPROM at 0x50-0x57 and
a thermal sensor at 0x18-0x1f. So if multiple slave addresses must be
supported, please do not limit this support to consecutive addresses.
There really is no reason to limit us that way anyway, as i2c-core
supports attaching any additional slave address to en existing
i2c_client using i2c_new_dummy().

Note for DDR3 DIMM SPD chips we currently have two different drivers
handling the two slave addresses (eeprom/at24 and jc42.) I don't know
if this is something that could be instantiated from ACPI. So it seems
we really have two different cases when a single chip replies to
multiple slave addresses: either they refer to the same function and we
want a single driver for all of them, or they are for unrelated
functions and we want separate drivers (and thus separate i2c_clients.)
Not sure how we can always handle that properly on the ACPI side.

> If the addresses are not consecutive I guess you need to have
> one device driver bind to several devices and return -EPROBE_DEFER
> until the driver has been probed for all of them or something like
> that, this is what multi-block GPIO drivers sometimes do.

Consecutive or not makes no difference really, as long as the driver
can deduce the additional addresses from the main address or register
contents accessible from the main address. This has always been the
case so far.

-- 
Jean Delvare

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 14:03                         ` Jean Delvare
@ 2012-11-05 14:19                           ` Rafael J. Wysocki
  2012-11-05 14:53                             ` Mika Westerberg
  2012-11-05 20:42                           ` Linus Walleij
  1 sibling, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-05 14:19 UTC (permalink / raw)
  To: Jean Delvare, Mika Westerberg
  Cc: Linus Walleij, Mark Brown, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, grant.likely, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Monday, November 05, 2012 03:03:26 PM Jean Delvare wrote:
> Hi Linus,
> 
> On Mon, 5 Nov 2012 14:20:52 +0100, Linus Walleij wrote:
> > On Mon, Nov 5, 2012 at 2:15 PM, Mika Westerberg
> > <mika.westerberg@linux.intel.com> wrote:
> > > On Mon, Nov 05, 2012 at 01:59:23PM +0100, Rafael J. Wysocki wrote:
> > >> On Monday, November 05, 2012 01:23:50 PM Jean Delvare wrote:
> > >> > On Mon, 5 Nov 2012 14:02:19 +0200, Mika Westerberg wrote:
> > >> > > On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:
> > (...)
> > >> > > Yeah, I just went through DSDT table of one of our machines and found a
> > >> > > device that actually has two I2CSerialBus connectors (and those are to the
> > >> > > same controller). What I'm not sure is that is it used to select between
> > >> > > two different addresses or doest the device really have two physical I2C
> > >> > > connections.
> > >> >
> > >> > Neither would make sense from a hardware perspective.
> > >>
> > >> Well, interesting. :-)
> > >
> > > It looks like some PMICs for example have two I2C control interfaces, like
> > > TI's TWL6030 if I'm not mistaken. If both are put behind the same I2C
> > > controller with different address, you have the situation like above.
> 
> Ah, OK, if this is a degenerated case of a more complex initial design
> then yes it makes some sense. I had never met chips like that and did
> not know such chips existed.
> 
> That being said, from a software perspective, there is no difference
> between one or two I2C pin pairs being soldered. All we care about is
> which master they are ultimately connected to, and to which slave
> address(es) the chip replies.
> 
> > This is quite common. So for example the AB8500 (drivers/mfd/ab8500-core.c)
> > has this. The reason is usually that the device has more than 256 registers
> > to the address space simply is not big enough.
> 
> This is completely different from the case being discussed above. Even
> the most complex addressing scheme can be implemented using a single
> hardware I2C interface. You can use 16-bit register addresses (if you
> can live without SMBus compatibility, AT24C32 and larger EEPROMs do
> that), or implement internal banks (using one of the registers as the
> bank selector, hardware monitoring chips do that), or you can use
> multiple slave addresses (AT24C04 to C16 EEPROMs do that.)
> 
> > What we do is refer to the subaddresses as "banks" and they happen
> > to always be at the next consecutive address so n+1.
> > 
> > So the same device appear behind several addresses just to support
> > a lot of registers.
> > 
> > So you're not actually modelling the devices on the other end but the
> > multiple addresses of a single device.
> > 
> > If the addresses are consecutive like ours it makes sense
> > to just instantiate one device and have the driver know that it will
> > also be able to access address +1, +2 ... +n. So is it possible
> > to group the consecutive related addresses after each other
> > here at the acpi-spi level and just create a single device?
> 
> We were actually discussing I2C here, although I admit not in the right
> thread, and maybe some of this applies to SPI as well.
> 
> There are I2C devices replying to multiple non-consecutive slave
> addresses. Most notably Winbond hardware monitoring chips replying to
> one address in 0x2c-0x2f and 2 addresses in 0x48-0x4f. And of course
> there are the DDR3 DIMM SPD chips which have an EEPROM at 0x50-0x57 and
> a thermal sensor at 0x18-0x1f. So if multiple slave addresses must be
> supported, please do not limit this support to consecutive addresses.
> There really is no reason to limit us that way anyway, as i2c-core
> supports attaching any additional slave address to en existing
> i2c_client using i2c_new_dummy().
> 
> Note for DDR3 DIMM SPD chips we currently have two different drivers
> handling the two slave addresses (eeprom/at24 and jc42.) I don't know
> if this is something that could be instantiated from ACPI. So it seems
> we really have two different cases when a single chip replies to
> multiple slave addresses: either they refer to the same function and we
> want a single driver for all of them, or they are for unrelated
> functions and we want separate drivers (and thus separate i2c_clients.)
> Not sure how we can always handle that properly on the ACPI side.
> 
> > If the addresses are not consecutive I guess you need to have
> > one device driver bind to several devices and return -EPROBE_DEFER
> > until the driver has been probed for all of them or something like
> > that, this is what multi-block GPIO drivers sometimes do.
> 
> Consecutive or not makes no difference really, as long as the driver
> can deduce the additional addresses from the main address or register
> contents accessible from the main address. This has always been the
> case so far.

In the ACPI namespace we have device nodes and serial interfaces below them.
In the above case we see that a single device node supports two different
interfaces and in that case we probably should create two different
struct i2c_adapter objects for the same ACPI device node.

Mika, what do you think?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 13:50               ` Rafael J. Wysocki
@ 2012-11-05 14:40                 ` Linus Walleij
  2012-11-06  9:39                   ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Linus Walleij @ 2012-11-05 14:40 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mathias Nyman, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Mon, Nov 5, 2012 at 2:50 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, November 05, 2012 02:28:45 PM Linus Walleij wrote:
>> But since Grant merged the gpiolib-of.c thing and is still the
>> main maintainer I can atleast chicken out by referring to him
>> this time ... hit me back if he doesn't respond and I will
>> have to refactor the world or something.
>
> No need to be grumpy. :-)

Just a little bit ... sorry.

> I forgot to mention that we want to hook up _existing_ drivers to those things,
> and they already use the global GPIO numbers, don't they?

Yes they do, usually this is either passed from the platform using platform
data or handled by device tree lookups to individual drivers.

So you will have to modify each such existing driver to do ACPI
probe akin to the DT codepath and call acpi_get_gpio() on every pin they
need going forward. But that is the plan I guess.

Yours,
Linus Walleij

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 14:19                           ` Rafael J. Wysocki
@ 2012-11-05 14:53                             ` Mika Westerberg
  2012-11-05 15:19                               ` Jean Delvare
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 14:53 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Jean Delvare, Linus Walleij, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 03:19:58PM +0100, Rafael J. Wysocki wrote:
> 
> In the ACPI namespace we have device nodes and serial interfaces below them.
> In the above case we see that a single device node supports two different
> interfaces and in that case we probably should create two different
> struct i2c_adapter objects for the same ACPI device node.
> 
> Mika, what do you think?

I agree.

Only problem I see is that then we have two I2C adapter devices with the
same ACPI ID (and hence the same i2c_client->name). I wonder what the I2C
core thinks about that.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 14:53                             ` Mika Westerberg
@ 2012-11-05 15:19                               ` Jean Delvare
  2012-11-05 17:12                                 ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Jean Delvare @ 2012-11-05 15:19 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Linus Walleij, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, 5 Nov 2012 16:53:15 +0200, Mika Westerberg wrote:
> On Mon, Nov 05, 2012 at 03:19:58PM +0100, Rafael J. Wysocki wrote:
> > 
> > In the ACPI namespace we have device nodes and serial interfaces below them.
> > In the above case we see that a single device node supports two different
> > interfaces and in that case we probably should create two different
> > struct i2c_adapter objects for the same ACPI device node.
> > 
> > Mika, what do you think?
> 
> I agree.
> 
> Only problem I see is that then we have two I2C adapter devices with the
> same ACPI ID (and hence the same i2c_client->name). I wonder what the I2C
> core thinks about that.

I2C core fears that you're mixing up everything ;) I2C adapter devices
are struct i2c_adapter aka i2c-0, i2c-1 etc. i2c_client is for slave
devices. There's nothing wrong with i2c_clients sharing ->name, that's
even how device driver matching is achieved. The uniqueness of
i2c_clients is on their bus_id which is the combination of i2c adapter
number and slave address (e.g. 0-0050)

i2c_adapter->name should, OTOH, be unique. In i2c bus drivers we
usually append the base I/O address at the end of the name to guarantee
that. ACPI will have to come up with something similar.

-- 
Jean Delvare

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03 20:39     ` Rafael J. Wysocki
@ 2012-11-05 16:54       ` Bjorn Helgaas
  2012-11-06 13:16         ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-05 16:54 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Sat, Nov 3, 2012 at 2:39 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Saturday, November 03, 2012 01:42:02 PM Bjorn Helgaas wrote:
>> On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
>> <mika.westerberg@linux.intel.com> wrote:
>> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
>> > configure the SPI slave devices behind the SPI controller. This patch adds
>> > support for this to the SPI core.
>> >
>> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
>> > the slave drivers to get the ACPI handle for further configuration.
>> >
>> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>> > ---
>> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-

>> > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
>> > +{
>> > +       struct acpi_spi_device_info *info = data;
>> > +       struct acpi_resource_spi_serialbus *sb;
>> > +       struct spi_device *spi = info->spi;
>> > +
>> > +       switch (res->type) {
>> > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
>> > +               sb = &res->data.spi_serial_bus;
>> > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
>> > +                       spi->chip_select = sb->device_selection;
>> > +                       spi->max_speed_hz = sb->connection_speed;
>> > +
>> > +                       /* Mode (clock phase/polarity/etc. */
>> > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
>> > +                               spi->mode |= SPI_CPHA;
>> > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
>> > +                               spi->mode |= SPI_CPOL;
>> > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
>> > +                               spi->mode |= SPI_CS_HIGH;
>> > +
>> > +                       /*
>> > +                        * The info is valid once we have found the
>> > +                        * SPISerialBus resource.
>> > +                        */
>> > +                       info->valid = true;
>> > +               }
>> > +               break;
>> > +
>> > +       case ACPI_RESOURCE_TYPE_IRQ:
>> > +               info->gsi = res->data.irq.interrupts[0];
>> > +               info->triggering = res->data.irq.triggering;
>> > +               info->polarity = res->data.irq.polarity;
>> > +               break;
>> > +
>> > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
>> > +               info->gsi = res->data.extended_irq.interrupts[0];
>> > +               info->triggering = res->data.extended_irq.triggering;
>> > +               info->polarity = res->data.extended_irq.polarity;
>>
>> A driver doesn't seem like the right place for _CRS parsing code.
>
> This is not a driver, however. :-)

OK.  Can you describe what this is?  I assume the picture involves an
SPI master device and one or more SPI slave devices, and the ACPI
namespace tells us something about them, and somehow this code is
related to those devices because it's looking at _CRS for them.

A _CRS method is associated with a Device in the namespace.  What is
that device in this case?  What is its PNP ID?  What driver claims
devices with that ID?

>> > +static void acpi_register_spi_devices(struct spi_master *master)
>> > +{
>> > +       acpi_status status;
>> > +       acpi_handle handle;
>> > +
>> > +       handle = master->dev.acpi_handle;
>> > +       if (!handle)
>> > +               return;
>> > +
>> > +       status = acpi_spi_enumerate(handle, acpi_spi_add_device, master);
>>
>> How does this work with hot-plug?  acpi_spi_enumerate() walks a
>> portion of the namespace.  How do we deal with changes to that part of
>> the namespace?  For example, what happens if this part of the
>> namespace gets pruned because an enclosing device is removed?  Is
>> there a way to discover new SPI devices if they get added?
>
> Yes, there should be a way to do that eventually.  No, we don't have any
> removable SPI devices described by ACPI yet, as far as I know.  So even if
> we added code for that now, we wouldn't be able to test it anyway with any
> real hardware until such devices become available.  I have no idea when that's
> going to happen, though.

I'm not asking about hotplug of devices on an SPI bus.  I'm asking
about hotplug of SPI masters.  For example, let's say you hot-add a
whole node that contains an SPI master.  I assume there's some ACPI
Device node that describes the SPI master, and a hot-add would add a
subtree to the namespace that contains a new SPI master Device.

Bjorn

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 10:31         ` Rafael J. Wysocki
  2012-11-05 10:56           ` Mika Westerberg
@ 2012-11-05 16:54           ` Bjorn Helgaas
  2012-11-06 13:43             ` Rafael J. Wysocki
  1 sibling, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-05 16:54 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Mon, Nov 5, 2012 at 3:31 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Saturday, November 03, 2012 09:59:28 PM Rafael J. Wysocki wrote:
>> On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
>> > On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
>> > > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
>> > > <mika.westerberg@linux.intel.com> wrote:
>> > > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
>> > > > configure the SPI slave devices behind the SPI controller. This patch adds
>> > > > support for this to the SPI core.
> [...]
>> > And if the ACPI core parses the _CRS, how does it pass all the resources to
>> > the drivers?
>>
>> Pretty much the same way the $subject patch does.
>>
>> Instead of parsing the entire subtree below an SPI controller and trying
>> acpi_spi_add_device() for each device node in there, it could call
>> acpi_spi_add_device() whenever it finds a device of type
>> ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
>> The only problem is how to pass "master" to it.
>>
>> So Bjorn, do you have any idea how we could pass the "master" pointer from the
>> ACPI core to acpi_spi_add_device() in a sensible way?
>>
>> An alternative might be to store the information obtained from _CRS in
>> struct acpi_device objects created by the ACPI core while parsing the
>> namespace.  We do that already for things like _PRW, so we might as well do it
>> for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
>> below the SPI controller's acpi_device to extract that information.
>> Maybe that's the way to go?
>
> The general idea is to move the _CRS parsing routine from acpi_platform.c
> to scan.c and make it attach resource objects to struct acpi_device.
>
> I'm thinking about adding a list head to struct acpi_device pointing to a
> list of entries like:
>
> struct resource_list_entry {
>         struct list_head node;
>         struct resource *resources;
>         unsigned int count;
> };
>
> where "resources" is an array of resources (e.g. interrupts) in the given
> entry and count is the size of that array.
>
> That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
> ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.

This is exactly what PNPACPI already does.  For every Device node in
the namespace, pnpacpi/rsparser.c parses _CRS and builds a list of
struct resources that correspond to it.  If you put this functionality
in acpi/scan.c, should we get rid of PNPACPI?

Bjorn

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 15:19                               ` Jean Delvare
@ 2012-11-05 17:12                                 ` Mika Westerberg
  2012-11-05 17:43                                   ` Bjorn Helgaas
  2012-11-05 17:49                                   ` Jean Delvare
  0 siblings, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 17:12 UTC (permalink / raw)
  To: Jean Delvare
  Cc: Rafael J. Wysocki, Linus Walleij, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 04:19:20PM +0100, Jean Delvare wrote:
> On Mon, 5 Nov 2012 16:53:15 +0200, Mika Westerberg wrote:
> > On Mon, Nov 05, 2012 at 03:19:58PM +0100, Rafael J. Wysocki wrote:
> > > 
> > > In the ACPI namespace we have device nodes and serial interfaces below them.
> > > In the above case we see that a single device node supports two different
> > > interfaces and in that case we probably should create two different
> > > struct i2c_adapter objects for the same ACPI device node.
> > > 
> > > Mika, what do you think?
> > 
> > I agree.
> > 
> > Only problem I see is that then we have two I2C adapter devices with the
> > same ACPI ID (and hence the same i2c_client->name). I wonder what the I2C
> > core thinks about that.
> 
> I2C core fears that you're mixing up everything ;) I2C adapter devices
> are struct i2c_adapter aka i2c-0, i2c-1 etc. i2c_client is for slave
> devices. There's nothing wrong with i2c_clients sharing ->name, that's
> even how device driver matching is achieved. The uniqueness of
> i2c_clients is on their bus_id which is the combination of i2c adapter
> number and slave address (e.g. 0-0050)

Yeah, I mixed I2C adapter and client. Thanks for correcting.

So if we create one I2C adapter from the platform bus code as we do now and
then for each I2CSerialBus connector we create one I2C client (well, the
one that is created when i2c_new_device() is called), everything should
work, right?

Then I suggest that we have a list of serial bus resources in the struct
acpi_device and create the I2C clients based on that.

> i2c_adapter->name should, OTOH, be unique. In i2c bus drivers we
> usually append the base I/O address at the end of the name to guarantee
> that. ACPI will have to come up with something similar.

It should already be unique in case of ACPI. We use ACPI _HID and _UID to
achieve that.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 17:12                                 ` Mika Westerberg
@ 2012-11-05 17:43                                   ` Bjorn Helgaas
  2012-11-05 18:08                                     ` Mika Westerberg
  2012-11-05 17:49                                   ` Jean Delvare
  1 sibling, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-05 17:43 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Jean Delvare, Rafael J. Wysocki, Linus Walleij, Mark Brown,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 5, 2012 at 10:12 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Mon, Nov 05, 2012 at 04:19:20PM +0100, Jean Delvare wrote:
>> On Mon, 5 Nov 2012 16:53:15 +0200, Mika Westerberg wrote:
>> > On Mon, Nov 05, 2012 at 03:19:58PM +0100, Rafael J. Wysocki wrote:
>> > >
>> > > In the ACPI namespace we have device nodes and serial interfaces below them.
>> > > In the above case we see that a single device node supports two different
>> > > interfaces and in that case we probably should create two different
>> > > struct i2c_adapter objects for the same ACPI device node.
>> > >
>> > > Mika, what do you think?
>> >
>> > I agree.
>> >
>> > Only problem I see is that then we have two I2C adapter devices with the
>> > same ACPI ID (and hence the same i2c_client->name). I wonder what the I2C
>> > core thinks about that.
>>
>> I2C core fears that you're mixing up everything ;) I2C adapter devices
>> are struct i2c_adapter aka i2c-0, i2c-1 etc. i2c_client is for slave
>> devices. There's nothing wrong with i2c_clients sharing ->name, that's
>> even how device driver matching is achieved. The uniqueness of
>> i2c_clients is on their bus_id which is the combination of i2c adapter
>> number and slave address (e.g. 0-0050)
>
> Yeah, I mixed I2C adapter and client. Thanks for correcting.
>
> So if we create one I2C adapter from the platform bus code as we do now and
> then for each I2CSerialBus connector we create one I2C client (well, the
> one that is created when i2c_new_device() is called), everything should
> work, right?
>
> Then I suggest that we have a list of serial bus resources in the struct
> acpi_device and create the I2C clients based on that.
>
>> i2c_adapter->name should, OTOH, be unique. In i2c bus drivers we
>> usually append the base I/O address at the end of the name to guarantee
>> that. ACPI will have to come up with something similar.
>
> It should already be unique in case of ACPI. We use ACPI _HID and _UID to
> achieve that.

Using only _HID and _UID to guarantee uniqueness means you're relying
on a property of the BIOS, so you're vulnerable to BIOS bugs.

If there's an ACPI Device for I2C adapters, why wouldn't you just use
its device name as set in acpi_device_register() (basically a _HID +
instance number)?

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 17:12                                 ` Mika Westerberg
  2012-11-05 17:43                                   ` Bjorn Helgaas
@ 2012-11-05 17:49                                   ` Jean Delvare
  1 sibling, 0 replies; 127+ messages in thread
From: Jean Delvare @ 2012-11-05 17:49 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Linus Walleij, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, 5 Nov 2012 19:12:48 +0200, Mika Westerberg wrote:
> On Mon, Nov 05, 2012 at 04:19:20PM +0100, Jean Delvare wrote:
> > I2C core fears that you're mixing up everything ;) I2C adapter devices
> > are struct i2c_adapter aka i2c-0, i2c-1 etc. i2c_client is for slave
> > devices. There's nothing wrong with i2c_clients sharing ->name, that's
> > even how device driver matching is achieved. The uniqueness of
> > i2c_clients is on their bus_id which is the combination of i2c adapter
> > number and slave address (e.g. 0-0050)
> 
> Yeah, I mixed I2C adapter and client. Thanks for correcting.
> 
> So if we create one I2C adapter from the platform bus code as we do now and
> then for each I2CSerialBus connector we create one I2C client (well, the
> one that is created when i2c_new_device() is called), everything should
> work, right?

Yes.

> Then I suggest that we have a list of serial bus resources in the struct
> acpi_device and create the I2C clients based on that.
> 
> > i2c_adapter->name should, OTOH, be unique. In i2c bus drivers we
> > usually append the base I/O address at the end of the name to guarantee
> > that. ACPI will have to come up with something similar.
> 
> It should already be unique in case of ACPI. We use ACPI _HID and _UID to
> achieve that.

Perfect.

-- 
Jean Delvare

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 17:43                                   ` Bjorn Helgaas
@ 2012-11-05 18:08                                     ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-05 18:08 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Jean Delvare, Rafael J. Wysocki, Linus Walleij, Mark Brown,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 05, 2012 at 10:43:17AM -0700, Bjorn Helgaas wrote:
> > It should already be unique in case of ACPI. We use ACPI _HID and _UID to
> > achieve that.
> 
> Using only _HID and _UID to guarantee uniqueness means you're relying
> on a property of the BIOS, so you're vulnerable to BIOS bugs.
> 
> If there's an ACPI Device for I2C adapters, why wouldn't you just use
> its device name as set in acpi_device_register() (basically a _HID +
> instance number)?

That's a good point - we could change to use that instead (the platform
code in linux-pm tree uses _HID + _UID but I guess it is pretty trivial to
change).

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 14:03                         ` Jean Delvare
  2012-11-05 14:19                           ` Rafael J. Wysocki
@ 2012-11-05 20:42                           ` Linus Walleij
  1 sibling, 0 replies; 127+ messages in thread
From: Linus Walleij @ 2012-11-05 20:42 UTC (permalink / raw)
  To: Jean Delvare
  Cc: Mika Westerberg, Rafael J. Wysocki, Mark Brown, Bjorn Helgaas,
	linux-kernel, lenb, rafael.j.wysocki, grant.likely, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Mon, Nov 5, 2012 at 3:03 PM, Jean Delvare <khali@linux-fr.org> wrote:
(...)
>> If the addresses are consecutive like ours it makes sense
>> to just instantiate one device and have the driver know that it will
>> also be able to access address +1, +2 ... +n. So is it possible
>> to group the consecutive related addresses after each other
>> here at the acpi-spi level and just create a single device?
>
> We were actually discussing I2C here, although I admit not in the right
> thread, and maybe some of this applies to SPI as well.

This is my typo. The AB8500 example is indeed I2C.

> So if multiple slave addresses must be
> supported, please do not limit this support to consecutive addresses.

I buy that ... in Nomadik we even have an instance of a single device
with two discrete *physical* interfaces connected to it, on both of
them it responds to the same address, but with totally different
register layouts ... hardware engineers rule! :-)

> There really is no reason to limit us that way anyway, as i2c-core
> supports attaching any additional slave address to en existing
> i2c_client using i2c_new_dummy().

Yes, this is how we do it in AB8500. We just take advantage of
the fact that the addresses are consecutive.

> Note for DDR3 DIMM SPD chips we currently have two different drivers
> handling the two slave addresses (eeprom/at24 and jc42.) I don't know
> if this is something that could be instantiated from ACPI. So it seems
> we really have two different cases when a single chip replies to
> multiple slave addresses: either they refer to the same function and we
> want a single driver for all of them, or they are for unrelated
> functions and we want separate drivers (and thus separate i2c_clients.)
> Not sure how we can always handle that properly on the ACPI side.

If they can be accessed concurrently and do not share
any locks or code they should be separate I think?
When they have strong dependencies we immediately sort of
fall into the MFD class where you need a mediator I think.

>> If the addresses are not consecutive I guess you need to have
>> one device driver bind to several devices and return -EPROBE_DEFER
>> until the driver has been probed for all of them or something like
>> that, this is what multi-block GPIO drivers sometimes do.
>
> Consecutive or not makes no difference really, as long as the driver
> can deduce the additional addresses from the main address or register
> contents accessible from the main address. This has always been the
> case so far.

You're right.

Yours,
Linus Walleij

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 12:02               ` Mika Westerberg
  2012-11-05 12:23                 ` Jean Delvare
@ 2012-11-06  8:11                 ` Mark Brown
  1 sibling, 0 replies; 127+ messages in thread
From: Mark Brown @ 2012-11-06  8:11 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, grant.likely, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi

[-- Attachment #1: Type: text/plain, Size: 1041 bytes --]

On Mon, Nov 05, 2012 at 02:02:19PM +0200, Mika Westerberg wrote:
> On Mon, Nov 05, 2012 at 11:56:39AM +0100, Mark Brown wrote:

> > I've got practical systems where there are multiple buses physically
> > connected, though in practice almost always only one is actually used at
> > runtime when it's I2C and SPI there are some systems (usually with other
> > buses) where you might want to use more than one bus.  Not sure those
> > buses will fit in here though.

> Yeah, I just went through DSDT table of one of our machines and found a
> device that actually has two I2CSerialBus connectors (and those are to the
> same controller). What I'm not sure is that is it used to select between
> two different addresses or doest the device really have two physical I2C
> connections.

That one is likely to be one device that responds on two addresses as
others have mentioned.  You do also get devices which have multiple
physical interfaces for various reasons, such as having a dedicated bus
for some functions that need to respond quickly.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-05 14:40                 ` Linus Walleij
@ 2012-11-06  9:39                   ` Mika Westerberg
  2012-11-06 10:15                     ` Linus Walleij
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-06  9:39 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Rafael J. Wysocki, Mathias Nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Mon, Nov 05, 2012 at 03:40:14PM +0100, Linus Walleij wrote:
> > I forgot to mention that we want to hook up _existing_ drivers to those things,
> > and they already use the global GPIO numbers, don't they?
> 
> Yes they do, usually this is either passed from the platform using platform
> data or handled by device tree lookups to individual drivers.
> 
> So you will have to modify each such existing driver to do ACPI
> probe akin to the DT codepath and call acpi_get_gpio() on every pin they
> need going forward. But that is the plan I guess.

Yes, that's the plan.

Do you think it is OK to go with this implementation (acpi_get_gpio()) for
now? We will try to make sure that the gpio_get() (or whatever it will be
called that time) supports ACPI as well.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-06  9:39                   ` Mika Westerberg
@ 2012-11-06 10:15                     ` Linus Walleij
  2012-11-07  8:54                       ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Linus Walleij @ 2012-11-06 10:15 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Mathias Nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, khali, ben-linux,
	w.sang, linux-acpi

On Tue, Nov 6, 2012 at 10:39 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Mon, Nov 05, 2012 at 03:40:14PM +0100, Linus Walleij wrote:
>> > I forgot to mention that we want to hook up _existing_ drivers to those things,
>> > and they already use the global GPIO numbers, don't they?
>>
>> Yes they do, usually this is either passed from the platform using platform
>> data or handled by device tree lookups to individual drivers.
>>
>> So you will have to modify each such existing driver to do ACPI
>> probe akin to the DT codepath and call acpi_get_gpio() on every pin they
>> need going forward. But that is the plan I guess.
>
> Yes, that's the plan.
>
> Do you think it is OK to go with this implementation (acpi_get_gpio()) for
> now? We will try to make sure that the gpio_get() (or whatever it will be
> called that time) supports ACPI as well.

Yes I'll be OK with it but I don't dare to merge it unless Grant
ACKs it.

Yours,
Linus Walleij

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 16:54       ` Bjorn Helgaas
@ 2012-11-06 13:16         ` Rafael J. Wysocki
  2012-11-06 20:53           ` Bjorn Helgaas
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-06 13:16 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Monday, November 05, 2012 09:54:37 AM Bjorn Helgaas wrote:
> On Sat, Nov 3, 2012 at 2:39 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Saturday, November 03, 2012 01:42:02 PM Bjorn Helgaas wrote:
> >> On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> >> <mika.westerberg@linux.intel.com> wrote:
> >> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> >> > configure the SPI slave devices behind the SPI controller. This patch adds
> >> > support for this to the SPI core.
> >> >
> >> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
> >> > the slave drivers to get the ACPI handle for further configuration.
> >> >
> >> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> >> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >> > ---
> >> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 
> >> > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
> >> > +{
> >> > +       struct acpi_spi_device_info *info = data;
> >> > +       struct acpi_resource_spi_serialbus *sb;
> >> > +       struct spi_device *spi = info->spi;
> >> > +
> >> > +       switch (res->type) {
> >> > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> >> > +               sb = &res->data.spi_serial_bus;
> >> > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
> >> > +                       spi->chip_select = sb->device_selection;
> >> > +                       spi->max_speed_hz = sb->connection_speed;
> >> > +
> >> > +                       /* Mode (clock phase/polarity/etc. */
> >> > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
> >> > +                               spi->mode |= SPI_CPHA;
> >> > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
> >> > +                               spi->mode |= SPI_CPOL;
> >> > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
> >> > +                               spi->mode |= SPI_CS_HIGH;
> >> > +
> >> > +                       /*
> >> > +                        * The info is valid once we have found the
> >> > +                        * SPISerialBus resource.
> >> > +                        */
> >> > +                       info->valid = true;
> >> > +               }
> >> > +               break;
> >> > +
> >> > +       case ACPI_RESOURCE_TYPE_IRQ:
> >> > +               info->gsi = res->data.irq.interrupts[0];
> >> > +               info->triggering = res->data.irq.triggering;
> >> > +               info->polarity = res->data.irq.polarity;
> >> > +               break;
> >> > +
> >> > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> >> > +               info->gsi = res->data.extended_irq.interrupts[0];
> >> > +               info->triggering = res->data.extended_irq.triggering;
> >> > +               info->polarity = res->data.extended_irq.polarity;
> >>
> >> A driver doesn't seem like the right place for _CRS parsing code.
> >
> > This is not a driver, however. :-)
> 
> OK.  Can you describe what this is?  I assume the picture involves an
> SPI master device and one or more SPI slave devices, and the ACPI
> namespace tells us something about them, and somehow this code is
> related to those devices because it's looking at _CRS for them.

This is part of the SPI core that looks for SPI devices below a controller.

> A _CRS method is associated with a Device in the namespace.  What is
> that device in this case?

An SPI device below a controller.

> What is its PNP ID?

I can't answer that from the top of my head, sorry.

> What driver claims devices with that ID?

The driver that declares support for it in its acpi_match_table[] array.


> >> > +static void acpi_register_spi_devices(struct spi_master *master)
> >> > +{
> >> > +       acpi_status status;
> >> > +       acpi_handle handle;
> >> > +
> >> > +       handle = master->dev.acpi_handle;
> >> > +       if (!handle)
> >> > +               return;
> >> > +
> >> > +       status = acpi_spi_enumerate(handle, acpi_spi_add_device, master);
> >>
> >> How does this work with hot-plug?  acpi_spi_enumerate() walks a
> >> portion of the namespace.  How do we deal with changes to that part of
> >> the namespace?  For example, what happens if this part of the
> >> namespace gets pruned because an enclosing device is removed?  Is
> >> there a way to discover new SPI devices if they get added?
> >
> > Yes, there should be a way to do that eventually.  No, we don't have any
> > removable SPI devices described by ACPI yet, as far as I know.  So even if
> > we added code for that now, we wouldn't be able to test it anyway with any
> > real hardware until such devices become available.  I have no idea when that's
> > going to happen, though.
> 
> I'm not asking about hotplug of devices on an SPI bus.  I'm asking
> about hotplug of SPI masters.  For example, let's say you hot-add a
> whole node that contains an SPI master.  I assume there's some ACPI
> Device node that describes the SPI master, and a hot-add would add a
> subtree to the namespace that contains a new SPI master Device.

The master will be a platform device and again, we're going to add support
for the hotplug of those, but the SPI controllers that we currently can test
it with are not removable.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-05 16:54           ` Bjorn Helgaas
@ 2012-11-06 13:43             ` Rafael J. Wysocki
  2012-11-06 20:35               ` Bjorn Helgaas
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-06 13:43 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Monday, November 05, 2012 09:54:42 AM Bjorn Helgaas wrote:
> On Mon, Nov 5, 2012 at 3:31 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Saturday, November 03, 2012 09:59:28 PM Rafael J. Wysocki wrote:
> >> On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
> >> > On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
> >> > > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> >> > > <mika.westerberg@linux.intel.com> wrote:
> >> > > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> >> > > > configure the SPI slave devices behind the SPI controller. This patch adds
> >> > > > support for this to the SPI core.
> > [...]
> >> > And if the ACPI core parses the _CRS, how does it pass all the resources to
> >> > the drivers?
> >>
> >> Pretty much the same way the $subject patch does.
> >>
> >> Instead of parsing the entire subtree below an SPI controller and trying
> >> acpi_spi_add_device() for each device node in there, it could call
> >> acpi_spi_add_device() whenever it finds a device of type
> >> ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
> >> The only problem is how to pass "master" to it.
> >>
> >> So Bjorn, do you have any idea how we could pass the "master" pointer from the
> >> ACPI core to acpi_spi_add_device() in a sensible way?
> >>
> >> An alternative might be to store the information obtained from _CRS in
> >> struct acpi_device objects created by the ACPI core while parsing the
> >> namespace.  We do that already for things like _PRW, so we might as well do it
> >> for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
> >> below the SPI controller's acpi_device to extract that information.
> >> Maybe that's the way to go?
> >
> > The general idea is to move the _CRS parsing routine from acpi_platform.c
> > to scan.c and make it attach resource objects to struct acpi_device.
> >
> > I'm thinking about adding a list head to struct acpi_device pointing to a
> > list of entries like:
> >
> > struct resource_list_entry {
> >         struct list_head node;
> >         struct resource *resources;
> >         unsigned int count;
> > };
> >
> > where "resources" is an array of resources (e.g. interrupts) in the given
> > entry and count is the size of that array.
> >
> > That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
> > ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.
> 
> This is exactly what PNPACPI already does.  For every Device node in
> the namespace, pnpacpi/rsparser.c parses _CRS and builds a list of
> struct resources that correspond to it.  If you put this functionality
> in acpi/scan.c, should we get rid of PNPACPI?

Quite likely.  At least this part of it, if you want the core to parse
resources.

That said, I actually tried to abstract out resource parsing in a more generic
fashion on the basis of our new platform device support code, but quite frankly
I wasn't able to.

The problem is that struct resource is too simple to be useful for representing
all of the information that can be encoded in ACPI resources.  As a result, some
information have to be stored directly in things like struct pnp_dev, struct
platform_device etc. and if we want to represent it generically, the only way
to do that seems to be using the ACPICA resource types as defined in acrestyp.h.

So we can attach a list of things like

struct acpi_resource_list_entry {
	struct list_head node;
	struct acpi_resource resource;
};

to struct acpi_device, but that doesn't help much, because the different
bus types will then need to extract the information they need from that list
anyway.  It would reduce the number of _CRS invocations, but beyond that I'm
not sure how usefult it's going to be.

Still, we probably should centralize things like
pnpacpi_parse_allocated_irqresource() to avoid duplicating that code.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 13:43             ` Rafael J. Wysocki
@ 2012-11-06 20:35               ` Bjorn Helgaas
  2012-11-06 22:28                 ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-06 20:35 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Tue, Nov 6, 2012 at 6:43 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, November 05, 2012 09:54:42 AM Bjorn Helgaas wrote:
>> On Mon, Nov 5, 2012 at 3:31 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > On Saturday, November 03, 2012 09:59:28 PM Rafael J. Wysocki wrote:
>> >> On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
>> >> > On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
>> >> > > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
>> >> > > <mika.westerberg@linux.intel.com> wrote:
>> >> > > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
>> >> > > > configure the SPI slave devices behind the SPI controller. This patch adds
>> >> > > > support for this to the SPI core.
>> > [...]
>> >> > And if the ACPI core parses the _CRS, how does it pass all the resources to
>> >> > the drivers?
>> >>
>> >> Pretty much the same way the $subject patch does.
>> >>
>> >> Instead of parsing the entire subtree below an SPI controller and trying
>> >> acpi_spi_add_device() for each device node in there, it could call
>> >> acpi_spi_add_device() whenever it finds a device of type
>> >> ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
>> >> The only problem is how to pass "master" to it.
>> >>
>> >> So Bjorn, do you have any idea how we could pass the "master" pointer from the
>> >> ACPI core to acpi_spi_add_device() in a sensible way?
>> >>
>> >> An alternative might be to store the information obtained from _CRS in
>> >> struct acpi_device objects created by the ACPI core while parsing the
>> >> namespace.  We do that already for things like _PRW, so we might as well do it
>> >> for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
>> >> below the SPI controller's acpi_device to extract that information.
>> >> Maybe that's the way to go?
>> >
>> > The general idea is to move the _CRS parsing routine from acpi_platform.c
>> > to scan.c and make it attach resource objects to struct acpi_device.
>> >
>> > I'm thinking about adding a list head to struct acpi_device pointing to a
>> > list of entries like:
>> >
>> > struct resource_list_entry {
>> >         struct list_head node;
>> >         struct resource *resources;
>> >         unsigned int count;
>> > };
>> >
>> > where "resources" is an array of resources (e.g. interrupts) in the given
>> > entry and count is the size of that array.
>> >
>> > That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
>> > ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.
>>
>> This is exactly what PNPACPI already does.  For every Device node in
>> the namespace, pnpacpi/rsparser.c parses _CRS and builds a list of
>> struct resources that correspond to it.  If you put this functionality
>> in acpi/scan.c, should we get rid of PNPACPI?
>
> Quite likely.  At least this part of it, if you want the core to parse
> resources.
>
> That said, I actually tried to abstract out resource parsing in a more generic
> fashion on the basis of our new platform device support code, but quite frankly
> I wasn't able to.
>
> The problem is that struct resource is too simple to be useful for representing
> all of the information that can be encoded in ACPI resources.  As a result, some
> information have to be stored directly in things like struct pnp_dev, struct
> platform_device etc. and if we want to represent it generically, the only way
> to do that seems to be using the ACPICA resource types as defined in acrestyp.h.

Really?  I didn't have that impression.  It might be that the new GPIO
and SERIAL_BUS stuff makes it too complicated for a struct resource,
but prior to that, I don't think it was.  It's true that there are
many different formats (IO, FIXED_IO, MEMORY24, MEMORY32, etc.), but
only the core needs to be aware of the encoding of all those formats.
As far as a *driver* is concerned, there are only IRQ, DMA, IO, and
MEM resources, and those fit easily in a struct resource.

I want to expand on what I said before about _CRS being the domain of
the core, not drivers.  The core must evaluate _CRS to know where
devices are and avoid conflicts when assigning resources.  The core
must evaluate _PRS and _SRS when making resource assignments.  It
doesn't make sense for drivers to be using _PRS and _SRS; they don't
have a global view of resources, and any assignment they make would
likely cause conflicts with other devices.  I think it makes sense to
consolidate all _CRS, _PRS, and _SRS management in the core rather
than splitting it up.  This is exactly analogous to PCI BAR
management, and we don't intend drivers to read and write BARs
directly.

Bjorn

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 13:16         ` Rafael J. Wysocki
@ 2012-11-06 20:53           ` Bjorn Helgaas
  2012-11-06 22:18             ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-06 20:53 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Tue, Nov 6, 2012 at 6:16 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Monday, November 05, 2012 09:54:37 AM Bjorn Helgaas wrote:
>> On Sat, Nov 3, 2012 at 2:39 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
>> > On Saturday, November 03, 2012 01:42:02 PM Bjorn Helgaas wrote:
>> >> On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
>> >> <mika.westerberg@linux.intel.com> wrote:
>> >> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
>> >> > configure the SPI slave devices behind the SPI controller. This patch adds
>> >> > support for this to the SPI core.
>> >> >
>> >> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
>> >> > the slave drivers to get the ACPI handle for further configuration.
>> >> >
>> >> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
>> >> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
>> >> > ---
>> >> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>
>> >> > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
>> >> > +{
>> >> > +       struct acpi_spi_device_info *info = data;
>> >> > +       struct acpi_resource_spi_serialbus *sb;
>> >> > +       struct spi_device *spi = info->spi;
>> >> > +
>> >> > +       switch (res->type) {
>> >> > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
>> >> > +               sb = &res->data.spi_serial_bus;
>> >> > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
>> >> > +                       spi->chip_select = sb->device_selection;
>> >> > +                       spi->max_speed_hz = sb->connection_speed;
>> >> > +
>> >> > +                       /* Mode (clock phase/polarity/etc. */
>> >> > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
>> >> > +                               spi->mode |= SPI_CPHA;
>> >> > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
>> >> > +                               spi->mode |= SPI_CPOL;
>> >> > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
>> >> > +                               spi->mode |= SPI_CS_HIGH;
>> >> > +
>> >> > +                       /*
>> >> > +                        * The info is valid once we have found the
>> >> > +                        * SPISerialBus resource.
>> >> > +                        */
>> >> > +                       info->valid = true;
>> >> > +               }
>> >> > +               break;
>> >> > +
>> >> > +       case ACPI_RESOURCE_TYPE_IRQ:
>> >> > +               info->gsi = res->data.irq.interrupts[0];
>> >> > +               info->triggering = res->data.irq.triggering;
>> >> > +               info->polarity = res->data.irq.polarity;
>> >> > +               break;
>> >> > +
>> >> > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
>> >> > +               info->gsi = res->data.extended_irq.interrupts[0];
>> >> > +               info->triggering = res->data.extended_irq.triggering;
>> >> > +               info->polarity = res->data.extended_irq.polarity;
>> >>
>> >> A driver doesn't seem like the right place for _CRS parsing code.
>> >
>> > This is not a driver, however. :-)
>>
>> OK.  Can you describe what this is?  I assume the picture involves an
>> SPI master device and one or more SPI slave devices, and the ACPI
>> namespace tells us something about them, and somehow this code is
>> related to those devices because it's looking at _CRS for them.
>
> This is part of the SPI core that looks for SPI devices below a controller.
>
>> A _CRS method is associated with a Device in the namespace.  What is
>> that device in this case?
>
> An SPI device below a controller.
>
>> What is its PNP ID?
>
> I can't answer that from the top of my head, sorry.
>
>> What driver claims devices with that ID?
>
> The driver that declares support for it in its acpi_match_table[] array.

OK, I guess my problem is in understanding the difference between (1)
a platform device where we use the acpi_match_table[] to locate
devices with matching ACPI IDs, and (2) a device where we use
pnp_register_driver() or acpi_bus_register_driver() to locate devices
with matching ACPI IDs.

They seem similar to me.  For example, take a PNP0A03 PCI host bridge.
 This seems like a platform device since there's no native hardware
method to enumerate it.  The ACPI namespace gives us a way to find it.
 We use acpi_bus_register_driver() to bind a driver to it.  The driver
has the struct acpi_device * and can access any ACPI state it needs.
The driver supplies .add() and .remove() methods, so in principle the
driver doesn't need to know anything about hotplug (assuming the ACPI
core handles hotplug correctly, which it doesn't yet).

How is the SPI controller different than this?  Is there some logical
difference that requires a different framework?  Or are you proposing
that we get rid of acpi_bus_register_driver() and migrate everything
to this new framework?

Bjorn

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 20:53           ` Bjorn Helgaas
@ 2012-11-06 22:18             ` Rafael J. Wysocki
  2012-11-07  9:56               ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-06 22:18 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Tuesday, November 06, 2012 01:53:01 PM Bjorn Helgaas wrote:
> On Tue, Nov 6, 2012 at 6:16 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, November 05, 2012 09:54:37 AM Bjorn Helgaas wrote:
> >> On Sat, Nov 3, 2012 at 2:39 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > On Saturday, November 03, 2012 01:42:02 PM Bjorn Helgaas wrote:
> >> >> On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> >> >> <mika.westerberg@linux.intel.com> wrote:
> >> >> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> >> >> > configure the SPI slave devices behind the SPI controller. This patch adds
> >> >> > support for this to the SPI core.
> >> >> >
> >> >> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
> >> >> > the slave drivers to get the ACPI handle for further configuration.
> >> >> >
> >> >> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> >> >> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >> >> > ---
> >> >> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >>
> >> >> > +static acpi_status acpi_spi_add_resources(struct acpi_resource *res, void *data)
> >> >> > +{
> >> >> > +       struct acpi_spi_device_info *info = data;
> >> >> > +       struct acpi_resource_spi_serialbus *sb;
> >> >> > +       struct spi_device *spi = info->spi;
> >> >> > +
> >> >> > +       switch (res->type) {
> >> >> > +       case ACPI_RESOURCE_TYPE_SERIAL_BUS:
> >> >> > +               sb = &res->data.spi_serial_bus;
> >> >> > +               if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
> >> >> > +                       spi->chip_select = sb->device_selection;
> >> >> > +                       spi->max_speed_hz = sb->connection_speed;
> >> >> > +
> >> >> > +                       /* Mode (clock phase/polarity/etc. */
> >> >> > +                       if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
> >> >> > +                               spi->mode |= SPI_CPHA;
> >> >> > +                       if (sb->clock_polarity == ACPI_SPI_START_HIGH)
> >> >> > +                               spi->mode |= SPI_CPOL;
> >> >> > +                       if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
> >> >> > +                               spi->mode |= SPI_CS_HIGH;
> >> >> > +
> >> >> > +                       /*
> >> >> > +                        * The info is valid once we have found the
> >> >> > +                        * SPISerialBus resource.
> >> >> > +                        */
> >> >> > +                       info->valid = true;
> >> >> > +               }
> >> >> > +               break;
> >> >> > +
> >> >> > +       case ACPI_RESOURCE_TYPE_IRQ:
> >> >> > +               info->gsi = res->data.irq.interrupts[0];
> >> >> > +               info->triggering = res->data.irq.triggering;
> >> >> > +               info->polarity = res->data.irq.polarity;
> >> >> > +               break;
> >> >> > +
> >> >> > +       case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> >> >> > +               info->gsi = res->data.extended_irq.interrupts[0];
> >> >> > +               info->triggering = res->data.extended_irq.triggering;
> >> >> > +               info->polarity = res->data.extended_irq.polarity;
> >> >>
> >> >> A driver doesn't seem like the right place for _CRS parsing code.
> >> >
> >> > This is not a driver, however. :-)
> >>
> >> OK.  Can you describe what this is?  I assume the picture involves an
> >> SPI master device and one or more SPI slave devices, and the ACPI
> >> namespace tells us something about them, and somehow this code is
> >> related to those devices because it's looking at _CRS for them.
> >
> > This is part of the SPI core that looks for SPI devices below a controller.
> >
> >> A _CRS method is associated with a Device in the namespace.  What is
> >> that device in this case?
> >
> > An SPI device below a controller.
> >
> >> What is its PNP ID?
> >
> > I can't answer that from the top of my head, sorry.
> >
> >> What driver claims devices with that ID?
> >
> > The driver that declares support for it in its acpi_match_table[] array.
> 
> OK, I guess my problem is in understanding the difference between (1)
> a platform device where we use the acpi_match_table[] to locate
> devices with matching ACPI IDs, and (2) a device where we use
> pnp_register_driver() or acpi_bus_register_driver() to locate devices
> with matching ACPI IDs.
> 
> They seem similar to me.  For example, take a PNP0A03 PCI host bridge.
>  This seems like a platform device since there's no native hardware
> method to enumerate it.  The ACPI namespace gives us a way to find it.
>  We use acpi_bus_register_driver() to bind a driver to it.  The driver
> has the struct acpi_device * and can access any ACPI state it needs.
> The driver supplies .add() and .remove() methods, so in principle the
> driver doesn't need to know anything about hotplug (assuming the ACPI
> core handles hotplug correctly, which it doesn't yet).

Well, I hope this is the last time I need to explain that. :-)

Please see this message for detailed discussion:

http://marc.info/?l=linux-kernel&m=135180467616074&w=4

> How is the SPI controller different than this?  Is there some logical
> difference that requires a different framework?  Or are you proposing
> that we get rid of acpi_bus_register_driver() and migrate everything
> to this new framework?

Yes, I do, but let's just do it gradually.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 20:35               ` Bjorn Helgaas
@ 2012-11-06 22:28                 ` Rafael J. Wysocki
  2012-11-06 22:36                   ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-06 22:28 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Tuesday, November 06, 2012 01:35:56 PM Bjorn Helgaas wrote:
> On Tue, Nov 6, 2012 at 6:43 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Monday, November 05, 2012 09:54:42 AM Bjorn Helgaas wrote:
> >> On Mon, Nov 5, 2012 at 3:31 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> >> > On Saturday, November 03, 2012 09:59:28 PM Rafael J. Wysocki wrote:
> >> >> On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
> >> >> > On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
> >> >> > > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> >> >> > > <mika.westerberg@linux.intel.com> wrote:
> >> >> > > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> >> >> > > > configure the SPI slave devices behind the SPI controller. This patch adds
> >> >> > > > support for this to the SPI core.
> >> > [...]
> >> >> > And if the ACPI core parses the _CRS, how does it pass all the resources to
> >> >> > the drivers?
> >> >>
> >> >> Pretty much the same way the $subject patch does.
> >> >>
> >> >> Instead of parsing the entire subtree below an SPI controller and trying
> >> >> acpi_spi_add_device() for each device node in there, it could call
> >> >> acpi_spi_add_device() whenever it finds a device of type
> >> >> ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
> >> >> The only problem is how to pass "master" to it.
> >> >>
> >> >> So Bjorn, do you have any idea how we could pass the "master" pointer from the
> >> >> ACPI core to acpi_spi_add_device() in a sensible way?
> >> >>
> >> >> An alternative might be to store the information obtained from _CRS in
> >> >> struct acpi_device objects created by the ACPI core while parsing the
> >> >> namespace.  We do that already for things like _PRW, so we might as well do it
> >> >> for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
> >> >> below the SPI controller's acpi_device to extract that information.
> >> >> Maybe that's the way to go?
> >> >
> >> > The general idea is to move the _CRS parsing routine from acpi_platform.c
> >> > to scan.c and make it attach resource objects to struct acpi_device.
> >> >
> >> > I'm thinking about adding a list head to struct acpi_device pointing to a
> >> > list of entries like:
> >> >
> >> > struct resource_list_entry {
> >> >         struct list_head node;
> >> >         struct resource *resources;
> >> >         unsigned int count;
> >> > };
> >> >
> >> > where "resources" is an array of resources (e.g. interrupts) in the given
> >> > entry and count is the size of that array.
> >> >
> >> > That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
> >> > ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.
> >>
> >> This is exactly what PNPACPI already does.  For every Device node in
> >> the namespace, pnpacpi/rsparser.c parses _CRS and builds a list of
> >> struct resources that correspond to it.  If you put this functionality
> >> in acpi/scan.c, should we get rid of PNPACPI?
> >
> > Quite likely.  At least this part of it, if you want the core to parse
> > resources.
> >
> > That said, I actually tried to abstract out resource parsing in a more generic
> > fashion on the basis of our new platform device support code, but quite frankly
> > I wasn't able to.
> >
> > The problem is that struct resource is too simple to be useful for representing
> > all of the information that can be encoded in ACPI resources.  As a result, some
> > information have to be stored directly in things like struct pnp_dev, struct
> > platform_device etc. and if we want to represent it generically, the only way
> > to do that seems to be using the ACPICA resource types as defined in acrestyp.h.
> 
> Really?  I didn't have that impression.  It might be that the new GPIO
> and SERIAL_BUS stuff makes it too complicated for a struct resource,
> but prior to that, I don't think it was.  It's true that there are
> many different formats (IO, FIXED_IO, MEMORY24, MEMORY32, etc.), but
> only the core needs to be aware of the encoding of all those formats.
> As far as a *driver* is concerned, there are only IRQ, DMA, IO, and
> MEM resources, and those fit easily in a struct resource.

However, for example expanding ACPI_RESOURCE_TYPE_EXTENDED_IRQ into an
array of struct resource objects before anyone actually needs it seems a
bit wasteful to me.  Let alone registering GSI for the interrupts while
we're parsing those resources.

> I want to expand on what I said before about _CRS being the domain of
> the core, not drivers.

Well, I see a difference between _evaluating_ _CRS and _parsing_ its
output.  In particular, I don't see a reason to do those two things in
one operation.  In fact, I see reasons to do otherwise. :-)

> The core must evaluate _CRS to know where
> devices are and avoid conflicts when assigning resources.  The core
> must evaluate _PRS and _SRS when making resource assignments.  It
> doesn't make sense for drivers to be using _PRS and _SRS; they don't
> have a global view of resources, and any assignment they make would
> likely cause conflicts with other devices.  I think it makes sense to
> consolidate all _CRS, _PRS, and _SRS management in the core rather
> than splitting it up.  This is exactly analogous to PCI BAR
> management, and we don't intend drivers to read and write BARs
> directly.

OK, but then we need to pass the information obtained from _CRS
(presumably after some adjustments through _SRS) to drivers, or rather to
things like the SPI core, I2C core etc. so that they can create device
objects for drivers to bind to and quite frankly I don't see why not to use
ACPI resources for that.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 22:28                 ` Rafael J. Wysocki
@ 2012-11-06 22:36                   ` Rafael J. Wysocki
  2012-11-07  9:58                     ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-06 22:36 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Tuesday, November 06, 2012 11:28:37 PM Rafael J. Wysocki wrote:
> On Tuesday, November 06, 2012 01:35:56 PM Bjorn Helgaas wrote:
> > On Tue, Nov 6, 2012 at 6:43 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > > On Monday, November 05, 2012 09:54:42 AM Bjorn Helgaas wrote:
> > >> On Mon, Nov 5, 2012 at 3:31 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > >> > On Saturday, November 03, 2012 09:59:28 PM Rafael J. Wysocki wrote:
> > >> >> On Saturday, November 03, 2012 10:13:10 PM Mika Westerberg wrote:
> > >> >> > On Sat, Nov 03, 2012 at 01:42:02PM -0600, Bjorn Helgaas wrote:
> > >> >> > > On Sat, Nov 3, 2012 at 1:46 AM, Mika Westerberg
> > >> >> > > <mika.westerberg@linux.intel.com> wrote:
> > >> >> > > > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> > >> >> > > > configure the SPI slave devices behind the SPI controller. This patch adds
> > >> >> > > > support for this to the SPI core.
> > >> > [...]
> > >> >> > And if the ACPI core parses the _CRS, how does it pass all the resources to
> > >> >> > the drivers?
> > >> >>
> > >> >> Pretty much the same way the $subject patch does.
> > >> >>
> > >> >> Instead of parsing the entire subtree below an SPI controller and trying
> > >> >> acpi_spi_add_device() for each device node in there, it could call
> > >> >> acpi_spi_add_device() whenever it finds a device of type
> > >> >> ACPI_RESOURCE_TYPE_SERIAL_BUS/ACPI_RESOURCE_SERIAL_TYPE_SPI.
> > >> >> The only problem is how to pass "master" to it.
> > >> >>
> > >> >> So Bjorn, do you have any idea how we could pass the "master" pointer from the
> > >> >> ACPI core to acpi_spi_add_device() in a sensible way?
> > >> >>
> > >> >> An alternative might be to store the information obtained from _CRS in
> > >> >> struct acpi_device objects created by the ACPI core while parsing the
> > >> >> namespace.  We do that already for things like _PRW, so we might as well do it
> > >> >> for _CRS.  Then, the SPI core could just walk the subtree of the device hierarchy
> > >> >> below the SPI controller's acpi_device to extract that information.
> > >> >> Maybe that's the way to go?
> > >> >
> > >> > The general idea is to move the _CRS parsing routine from acpi_platform.c
> > >> > to scan.c and make it attach resource objects to struct acpi_device.
> > >> >
> > >> > I'm thinking about adding a list head to struct acpi_device pointing to a
> > >> > list of entries like:
> > >> >
> > >> > struct resource_list_entry {
> > >> >         struct list_head node;
> > >> >         struct resource *resources;
> > >> >         unsigned int count;
> > >> > };
> > >> >
> > >> > where "resources" is an array of resources (e.g. interrupts) in the given
> > >> > entry and count is the size of that array.
> > >> >
> > >> > That list would contain common resources like ACPI_RESOURCE_TYPE_FIXED_MEMORY32,
> > >> > ACPI_RESOURCE_TYPE_IRQ, ACPI_RESOURCE_TYPE_ADDRESS32, ACPI_RESOURCE_TYPE_EXTENDED_IRQ.
> > >>
> > >> This is exactly what PNPACPI already does.  For every Device node in
> > >> the namespace, pnpacpi/rsparser.c parses _CRS and builds a list of
> > >> struct resources that correspond to it.  If you put this functionality
> > >> in acpi/scan.c, should we get rid of PNPACPI?
> > >
> > > Quite likely.  At least this part of it, if you want the core to parse
> > > resources.
> > >
> > > That said, I actually tried to abstract out resource parsing in a more generic
> > > fashion on the basis of our new platform device support code, but quite frankly
> > > I wasn't able to.
> > >
> > > The problem is that struct resource is too simple to be useful for representing
> > > all of the information that can be encoded in ACPI resources.  As a result, some
> > > information have to be stored directly in things like struct pnp_dev, struct
> > > platform_device etc. and if we want to represent it generically, the only way
> > > to do that seems to be using the ACPICA resource types as defined in acrestyp.h.
> > 
> > Really?  I didn't have that impression.  It might be that the new GPIO
> > and SERIAL_BUS stuff makes it too complicated for a struct resource,
> > but prior to that, I don't think it was.  It's true that there are
> > many different formats (IO, FIXED_IO, MEMORY24, MEMORY32, etc.), but
> > only the core needs to be aware of the encoding of all those formats.
> > As far as a *driver* is concerned, there are only IRQ, DMA, IO, and
> > MEM resources, and those fit easily in a struct resource.
> 
> However, for example expanding ACPI_RESOURCE_TYPE_EXTENDED_IRQ into an
> array of struct resource objects before anyone actually needs it seems a
> bit wasteful to me.  Let alone registering GSI for the interrupts while
> we're parsing those resources.
> 
> > I want to expand on what I said before about _CRS being the domain of
> > the core, not drivers.
> 
> Well, I see a difference between _evaluating_ _CRS and _parsing_ its
> output.  In particular, I don't see a reason to do those two things in
> one operation.  In fact, I see reasons to do otherwise. :-)
> 
> > The core must evaluate _CRS to know where
> > devices are and avoid conflicts when assigning resources.  The core
> > must evaluate _PRS and _SRS when making resource assignments.  It
> > doesn't make sense for drivers to be using _PRS and _SRS; they don't
> > have a global view of resources, and any assignment they make would
> > likely cause conflicts with other devices.  I think it makes sense to
> > consolidate all _CRS, _PRS, and _SRS management in the core rather
> > than splitting it up.  This is exactly analogous to PCI BAR
> > management, and we don't intend drivers to read and write BARs
> > directly.
> 
> OK, but then we need to pass the information obtained from _CRS
> (presumably after some adjustments through _SRS) to drivers, or rather to
> things like the SPI core, I2C core etc. so that they can create device
> objects for drivers to bind to and quite frankly I don't see why not to use
> ACPI resources for that.

Nevertheless, the routines for parsing those resources should belong
to the ACPI core, mostly to avoid code duplication.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-06 10:15                     ` Linus Walleij
@ 2012-11-07  8:54                       ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-07  8:54 UTC (permalink / raw)
  To: Linus Walleij, grant.likely
  Cc: Rafael J. Wysocki, Mathias Nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, khali, ben-linux, w.sang, linux-acpi

On Tue, Nov 06, 2012 at 11:15:21AM +0100, Linus Walleij wrote:
> On Tue, Nov 6, 2012 at 10:39 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Mon, Nov 05, 2012 at 03:40:14PM +0100, Linus Walleij wrote:
> >> > I forgot to mention that we want to hook up _existing_ drivers to those things,
> >> > and they already use the global GPIO numbers, don't they?
> >>
> >> Yes they do, usually this is either passed from the platform using platform
> >> data or handled by device tree lookups to individual drivers.
> >>
> >> So you will have to modify each such existing driver to do ACPI
> >> probe akin to the DT codepath and call acpi_get_gpio() on every pin they
> >> need going forward. But that is the plan I guess.
> >
> > Yes, that's the plan.
> >
> > Do you think it is OK to go with this implementation (acpi_get_gpio()) for
> > now? We will try to make sure that the gpio_get() (or whatever it will be
> > called that time) supports ACPI as well.
> 
> Yes I'll be OK with it but I don't dare to merge it unless Grant
> ACKs it.

Is that an Ack from you? ;-)

Since there is a dependency to linux-pm tree (we use the new
dev->acpi_handle member) I would like this series merged via that tree.

Grant, are you OK with this?

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 22:18             ` Rafael J. Wysocki
@ 2012-11-07  9:56               ` Mika Westerberg
  2012-11-08 19:32                 ` Bjorn Helgaas
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-07  9:56 UTC (permalink / raw)
  To: Bjorn Helgaas, Rafael J. Wysocki
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Tue, Nov 06, 2012 at 11:18:11PM +0100, Rafael J. Wysocki wrote:
> > How is the SPI controller different than this?  Is there some logical
> > difference that requires a different framework?  Or are you proposing
> > that we get rid of acpi_bus_register_driver() and migrate everything
> > to this new framework?
> 
> Yes, I do, but let's just do it gradually.

Bjorn, here is a concrete example how this is supposed to be used.

Lets say we have an existing SPI slave driver that we want to extend to
support enumeration from ACPI. Instead of writing acpi_driver glue for that
(and registering it using acpi_bus_register_driver()) what we do is simple
add these to the existing SPI driver:

	#ifdef CONFIG_ACPI
	static struct acpi_device_id my_spidrv_match[] = {
		/* ACPI IDs here */
		{ }
	};
	MODULE_DEVICE_TABLE(acpi, my_spidrv_match);
	#endif

	static struct spi_driver my_spidrv = {
		...
		.driver = {
			.acpi_match_table = ACPI_PTR(my_spidrv_match),
		},
	};

The same thing works with platform, I2c and SPI drivers and can be extented
to others as well. If the driver needs to do some ACPI specific
configuration it can get the ACPI handle using its dev->acpi_handle.

The above example now supports both, normal SPI (where the devices are
enumerated by populating spi_board_info()) and ACPI. Adding support for
Device Tree is similar than ACPI so a single driver can support all three
easily at the same time.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-06 22:36                   ` Rafael J. Wysocki
@ 2012-11-07  9:58                     ` Mika Westerberg
  2012-11-07 11:14                       ` Rafael J. Wysocki
  2012-11-08 18:05                       ` Grant Likely
  0 siblings, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-07  9:58 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Tue, Nov 06, 2012 at 11:36:08PM +0100, Rafael J. Wysocki wrote:
> > 
> > OK, but then we need to pass the information obtained from _CRS
> > (presumably after some adjustments through _SRS) to drivers, or rather to
> > things like the SPI core, I2C core etc. so that they can create device
> > objects for drivers to bind to and quite frankly I don't see why not to use
> > ACPI resources for that.
> 
> Nevertheless, the routines for parsing those resources should belong
> to the ACPI core, mostly to avoid code duplication.

Rafael,

So is the idea now that the ACPI core parses the resources and passes them
forward via struct acpi_device? I'm just wondering how to proceed with
these I2C and SPI enumeration patches.

Thanks.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-07  9:58                     ` Mika Westerberg
@ 2012-11-07 11:14                       ` Rafael J. Wysocki
  2012-11-07 13:05                         ` Mika Westerberg
  2012-11-08 18:05                       ` Grant Likely
  1 sibling, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-07 11:14 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Wednesday, November 07, 2012 11:58:42 AM Mika Westerberg wrote:
> On Tue, Nov 06, 2012 at 11:36:08PM +0100, Rafael J. Wysocki wrote:
> > > 
> > > OK, but then we need to pass the information obtained from _CRS
> > > (presumably after some adjustments through _SRS) to drivers, or rather to
> > > things like the SPI core, I2C core etc. so that they can create device
> > > objects for drivers to bind to and quite frankly I don't see why not to use
> > > ACPI resources for that.
> > 
> > Nevertheless, the routines for parsing those resources should belong
> > to the ACPI core, mostly to avoid code duplication.
> 
> Rafael,
> 
> So is the idea now that the ACPI core parses the resources and passes them
> forward via struct acpi_device? I'm just wondering how to proceed with
> these I2C and SPI enumeration patches.

Well, we definitely don't want to duplicate what drivers/pnp/pnpacpi/rsparser.c
does, so the idea is to move the code from there to the core in such a way that
both the SPI/I2C patches and the PNP layer can use it.

I'll have some prototype code ready shortly, hopefully, and I'll post it
in that form for comments (and so that you know what to expect).

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-07 11:14                       ` Rafael J. Wysocki
@ 2012-11-07 13:05                         ` Mika Westerberg
  2012-11-08  0:46                           ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-07 13:05 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Wed, Nov 07, 2012 at 12:14:31PM +0100, Rafael J. Wysocki wrote:
> > So is the idea now that the ACPI core parses the resources and passes them
> > forward via struct acpi_device? I'm just wondering how to proceed with
> > these I2C and SPI enumeration patches.
> 
> Well, we definitely don't want to duplicate what drivers/pnp/pnpacpi/rsparser.c
> does, so the idea is to move the code from there to the core in such a way that
> both the SPI/I2C patches and the PNP layer can use it.

Ok.

> I'll have some prototype code ready shortly, hopefully, and I'll post it
> in that form for comments (and so that you know what to expect).

Sounds good. Thanks!

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-07 13:05                         ` Mika Westerberg
@ 2012-11-08  0:46                           ` Rafael J. Wysocki
  2012-11-08 20:20                             ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-08  0:46 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Wednesday, November 07, 2012 03:05:48 PM Mika Westerberg wrote:
> On Wed, Nov 07, 2012 at 12:14:31PM +0100, Rafael J. Wysocki wrote:
> > > So is the idea now that the ACPI core parses the resources and passes them
> > > forward via struct acpi_device? I'm just wondering how to proceed with
> > > these I2C and SPI enumeration patches.
> > 
> > Well, we definitely don't want to duplicate what drivers/pnp/pnpacpi/rsparser.c
> > does, so the idea is to move the code from there to the core in such a way that
> > both the SPI/I2C patches and the PNP layer can use it.
> 
> Ok.
> 
> > I'll have some prototype code ready shortly, hopefully, and I'll post it
> > in that form for comments (and so that you know what to expect).
> 
> Sounds good. Thanks!

There you go.

I haven't even try to compile it, so most likely it breaks things left, right
and in between, but I hope it shows the idea.

It does a couple of things at the same time, so it should be split into a few
simpler patches.  First, it moves some code from drivers/pnp/pnpacpi/rsparser.c
to a new file drivers/acpi/resource.c and makes pnpacpi use functions from
there.  Second, it changes acpi_platform.c to use those functions too.
Finally, it adds a list of ACPI resources to struct acpi_device and
makes acpi_platform.c use that list intead of evaluating _CRS and parsing its
output with acpi_walk_resources().

While changing acpi_platform.c I noticed that we had a bug in there, because
GSIs were registered for the struct acpi_device object, although they should be
registered for the struct platform_device one created by that code.  I didn't
try to fix that in the patch below, but it generally needs fixing.

Thanks,
Rafael


Prototype, no sign-off.
---
 drivers/acpi/Makefile          |    1 
 drivers/acpi/acpi_platform.c   |  122 +++++-------------
 drivers/acpi/resource.c        |  269 +++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c            |   48 +++++++
 drivers/pnp/base.h             |    2 
 drivers/pnp/pnpacpi/rsparser.c |  150 +---------------------
 drivers/pnp/resource.c         |   16 ++
 include/acpi/acpi_bus.h        |    6 
 8 files changed, 386 insertions(+), 228 deletions(-)

Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -259,6 +259,11 @@ struct acpi_device_physical_node {
 	struct device *dev;
 };
 
+struct acpi_resource_list_entry {
+	struct list_head node;
+	struct acpi_resource resource;
+};
+
 /* set maximum of physical nodes to 32 for expansibility */
 #define ACPI_MAX_PHYSICAL_NODE	32
 
@@ -269,6 +274,7 @@ struct acpi_device {
 	struct acpi_device *parent;
 	struct list_head children;
 	struct list_head node;
+	struct list_head resources;	/* Device resources. */
 	struct list_head wakeup_list;
 	struct acpi_device_status status;
 	struct acpi_device_flags flags;
Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -670,6 +670,8 @@ end:
 
 static void acpi_device_unregister(struct acpi_device *device, int type)
 {
+	struct acpi_resource_list_entry *entry, *s;
+
 	mutex_lock(&acpi_device_lock);
 	if (device->parent)
 		list_del(&device->node);
@@ -681,6 +683,9 @@ static void acpi_device_unregister(struc
 
 	acpi_device_remove_files(device);
 	device_unregister(&device->dev);
+
+	list_for_each_entry_safe(entry, s, &device->resources, node)
+		kfree(entry);
 }
 
 /* --------------------------------------------------------------------------
@@ -990,6 +995,40 @@ static void acpi_bus_get_wakeup_device_f
 				"error in _DSW or _PSW evaluation\n"));
 }
 
+static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
+					 void *context)
+{
+	struct list_head *list = context;
+	struct acpi_resource_list_entry *entry;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return AE_NO_MEMORY;
+
+	entry->resource = *res;
+	list_add_tail(&entry->node, list);
+	return AE_OK;
+}
+
+static int acpi_bus_get_resources(struct acpi_device *adev)
+{
+	acpi_status status;
+	int ret = 0;
+
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_bus_add_resource, &adev->resources);
+	if (ACPI_FAILURE(status)) {
+		switch(status) {
+		case AE_NO_MEMORY:
+			ret = -ENOMEM;
+			break;
+		default:
+			ret = -EIO;
+		}
+	}
+	return ret;
+}
+
 static void acpi_bus_add_power_resource(acpi_handle handle);
 
 static int acpi_bus_get_power_flags(struct acpi_device *device)
@@ -1412,6 +1451,15 @@ static int acpi_add_single_object(struct
 	acpi_device_set_id(device);
 
 	/*
+	 * Device Resources
+	 * ----------------
+	 */
+	INIT_LIST_HEAD(&device->resources);
+	result = acpi_bus_get_resources(device);
+	if (result)
+		goto end;
+
+	/*
 	 * Power Management
 	 * ----------------
 	 */
Index: linux-pm/drivers/acpi/resource.c
===================================================================
--- /dev/null
+++ linux-pm/drivers/acpi/resource.c
@@ -0,0 +1,269 @@
+/*
+ * drivers/acpi/resource.c - ACPI device resources management.
+ *
+ * Copyright (C) 2012, Intel Corp.
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/ioport.h>
+
+#include <acpi/acpi.h>
+#include <acpi/acpi_bus.h>
+
+static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect,
+						bool window)
+{
+	unsigned long flags = IORESOURCE_MEM;
+
+	if (len == 0)
+		flags |= IORESOURCE_DISABLED;
+
+	if (write_protect == ACPI_READ_WRITE_MEMORY)
+		flags |= IORESOURCE_MEM_WRITEABLE;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
+				     u8 write_protect)
+{
+	res->start = start;
+	res->end = start + len - 1;
+	res->flags = acpi_dev_memresource_flags(len, write_protect, false);
+}
+
+/**
+ * acpi_dev_resource_memory - Extract ACPI memory resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents a memory resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_memory24 *memory24;
+	struct acpi_resource_memory32 *memory32;
+	struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+		memory24 = &ares->data.memory24;
+		acpi_dev_get_memresource(res, memory24->minimum,
+					 memory24->address_length,
+					 memory24->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+		memory32 = &ares->data.memory32;
+		acpi_dev_get_memresource(res, memory32->minimum,
+					 memory32->address_length,
+					 memory32->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		fixed_memory32 = &ares->data.fixed_memory32;
+		acpi_dev_get_memresource(res, fixed_memory32->address,
+					 fixed_memory32->address_length,
+					 fixed_memory32->write_protect);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
+
+static void acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode,
+				      bool window)
+{
+	int flags = IORESOURCE_IO;
+
+	if (io_decode == ACPI_DECODE_16)
+		flags |= IORESOURCE_IO_16BIT_ADDR;
+
+	if (start > end || end >= 0x10003)
+		flags |= IORESOURCE_DISABLED;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
+				    u8 io_decode)
+{
+	u64 end = start + len - 1;
+
+	res->start = start;
+	res->end = end;
+	res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false);
+}
+
+/**
+ * acpi_dev_resource_io - Extract ACPI I/O resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an I/O resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_io *io;
+	struct acpi_resource_fixed_io *fixed_io;
+
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_IO:
+		io = &ares->data.io;
+		acpi_dev_get_ioresource(res, io->minimum,
+					  io->address_length,
+					  io->io_decode);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_IO
+		fixed_io = &res->data.fixed_io;
+		acpi_dev_get_ioresource(res, fixed_io->address,
+					  fixed_io->address_length,
+					  ACPI_DECODE_10);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
+
+/**
+ * acpi_dev_resource_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an address space resource
+ * and if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res)
+{
+	acpi_status status;
+	struct acpi_resource_address64 addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+		break;
+	default:
+		return false;
+	}
+
+	status = acpi_resource_to_address64(ares, &addr);
+	if (ACPI_FAILURE(status))
+		return true;
+
+	res->start = addr.minimum;
+	res->end = addr.maximum;
+	window = addr.producer_consumer == ACPI_PRODUCER;
+
+	switch(resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = addr.maximum - addr.minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+						addr.info.mem.write_protect,
+						window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = addr.granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(addr.minimum,
+						       addr.maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
+
+/**
+ * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an extended address space
+ * resource and if that's the case, use the information in it to populate the
+ * generic resource object pointed to by @res.
+ */
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res)
+{
+	acpi_status status;
+	struct acpi_resource_extended_address64 *ext_addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	if (res->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
+		return false;
+
+	ext_addr = &res->data.ext_address64;
+
+	res->start = ext_addr->minimum;
+	res->end = ext_addr->maximum;
+	window = ext_addr->producer_consumer == ACPI_PRODUCER;
+
+	switch(resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = ext_addr->maximum - ext_addr->minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+					ext_addr->info.mem.write_protect,
+					window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = ext_addr->granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(ext_addr->minimum,
+						       ext_addr->maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
Index: linux-pm/drivers/acpi/Makefile
===================================================================
--- linux-pm.orig/drivers/acpi/Makefile
+++ linux-pm/drivers/acpi/Makefile
@@ -33,6 +33,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 #
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
+acpi-y				+= resource.o
 acpi-y				+= processor_core.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
Index: linux-pm/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- linux-pm.orig/drivers/pnp/pnpacpi/rsparser.c
+++ linux-pm/drivers/pnp/pnpacpi/rsparser.c
@@ -177,23 +177,6 @@ static int dma_flags(struct pnp_dev *dev
 	return flags;
 }
 
-static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
-					       u64 len, int io_decode,
-					       int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
-
-	if (io_decode == ACPI_DECODE_16)
-		flags |= IORESOURCE_IO_16BIT_ADDR;
-	if (len == 0 || end >= 0x10003)
-		flags |= IORESOURCE_DISABLED;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
-
-	pnp_add_io_resource(dev, start, end, flags);
-}
-
 /*
  * Device CSRs that do not appear in PCI config space should be described
  * via ACPI.  This would normally be done with Address Space Descriptors
@@ -249,83 +232,6 @@ static void pnpacpi_parse_allocated_vend
 	}
 }
 
-static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
-						u64 start, u64 len,
-						int write_protect, int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
-
-	if (len == 0)
-		flags |= IORESOURCE_DISABLED;
-	if (write_protect == ACPI_READ_WRITE_MEMORY)
-		flags |= IORESOURCE_MEM_WRITEABLE;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
-
-	pnp_add_mem_resource(dev, start, end, flags);
-}
-
-static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
-						u64 start, u64 len)
-{
-	u64 end = start + len - 1;
-
-	pnp_add_bus_resource(dev, start, end);
-}
-
-static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
-						  struct acpi_resource *res)
-{
-	struct acpi_resource_address64 addr, *p = &addr;
-	acpi_status status;
-	int window;
-	u64 len;
-
-	status = acpi_resource_to_address64(res, p);
-	if (!ACPI_SUCCESS(status)) {
-		dev_warn(&dev->dev, "failed to convert resource type %d\n",
-			 res->type);
-		return;
-	}
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
-static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
-						      struct acpi_resource *res)
-{
-	struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
-	int window;
-	u64 len;
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
 					      void *data)
 {
@@ -339,8 +245,17 @@ static acpi_status pnpacpi_allocated_res
 	struct acpi_resource_memory32 *memory32;
 	struct acpi_resource_fixed_memory32 *fixed_memory32;
 	struct acpi_resource_extended_irq *extended_irq;
+	struct resource r;
 	int i, flags;
 
+	if (acpi_dev_resource_memory(res, &r)
+	    || acpi_dev_resource_io(res, &r)
+	    || acpi_dev_resource_address_space(res, &r)
+	    || acpi_dev_resource_ext_address_space(res, &r))
+		pnp_add_resource(dev, &r);
+		return AE_OK;
+	}
+
 	switch (res->type) {
 	case ACPI_RESOURCE_TYPE_IRQ:
 		/*
@@ -383,26 +298,10 @@ static acpi_status pnpacpi_allocated_res
 		pnp_add_dma_resource(dev, dma->channels[0], flags);
 		break;
 
-	case ACPI_RESOURCE_TYPE_IO:
-		io = &res->data.io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			io->minimum,
-			io->address_length,
-			io->io_decode, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 		break;
 
-	case ACPI_RESOURCE_TYPE_FIXED_IO:
-		fixed_io = &res->data.fixed_io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			fixed_io->address,
-			fixed_io->address_length,
-			ACPI_DECODE_10, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_VENDOR:
 		vendor_typed = &res->data.vendor_typed;
 		pnpacpi_parse_allocated_vendor(dev, vendor_typed);
@@ -411,37 +310,6 @@ static acpi_status pnpacpi_allocated_res
 	case ACPI_RESOURCE_TYPE_END_TAG:
 		break;
 
-	case ACPI_RESOURCE_TYPE_MEMORY24:
-		memory24 = &res->data.memory24;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory24->minimum,
-			memory24->address_length,
-			memory24->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_MEMORY32:
-		memory32 = &res->data.memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory32->minimum,
-			memory32->address_length,
-			memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		fixed_memory32 = &res->data.fixed_memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			fixed_memory32->address,
-			fixed_memory32->address_length,
-			fixed_memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS16:
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-	case ACPI_RESOURCE_TYPE_ADDRESS64:
-		pnpacpi_parse_allocated_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
-		pnpacpi_parse_allocated_ext_address_space(dev, res);
-		break;
-
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		extended_irq = &res->data.extended_irq;
 
Index: linux-pm/drivers/pnp/base.h
===================================================================
--- linux-pm.orig/drivers/pnp/base.h
+++ linux-pm/drivers/pnp/base.h
@@ -159,6 +159,8 @@ struct pnp_resource {
 
 void pnp_free_resource(struct pnp_resource *pnp_res);
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res);
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags);
 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
Index: linux-pm/drivers/pnp/resource.c
===================================================================
--- linux-pm.orig/drivers/pnp/resource.c
+++ linux-pm/drivers/pnp/resource.c
@@ -503,6 +503,22 @@ static struct pnp_resource *pnp_new_reso
 	return pnp_res;
 }
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res)
+{
+	struct pnp_resource *pnp_res;
+
+	pnp_res = pnp_new_resource(dev);
+	if (!pnp_res) {
+		dev_err(&dev->dev, "can't add resource %pR\n", res);
+		return NULL;
+	}
+
+	pnp_res->res = *res;
+	dev_dbg(&dev->dev, "%pR\n", res);
+	return pnp_res;
+}
+
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags)
 {
Index: linux-pm/drivers/acpi/acpi_platform.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpi_platform.c
+++ linux-pm/drivers/acpi/acpi_platform.c
@@ -19,76 +19,30 @@
 
 ACPI_MODULE_NAME("platform");
 
-struct resource_info {
-	struct device *dev;
-	struct resource *res;
-	size_t n, cur;
-};
-
-static acpi_status acpi_platform_count_resources(struct acpi_resource *res,
-						 void *data)
+static acpi_status acpi_platform_resource_size(struct acpi_resource *res)
 {
-	struct acpi_resource_extended_irq *acpi_xirq;
-	struct resource_info *ri = data;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-	case ACPI_RESOURCE_TYPE_IRQ:
-		ri->n++;
-		break;
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		acpi_xirq = &res->data.extended_irq;
-		ri->n += acpi_xirq->interrupt_count;
-		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		if (res->data.address32.resource_type == ACPI_IO_RANGE)
-			ri->n++;
-		break;
-	}
-
-	return AE_OK;
+	return res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ ?
+			res->data.extended_irq.interrupt_count : 1;
 }
 
-static acpi_status acpi_platform_add_resources(struct acpi_resource *res,
-					       void *data)
+static acpi_status acpi_platform_add_resource(struct device *dev,
+					      struct acpi_resource *res,
+					      struct resource *resources,
+					      unsigned int count)
 {
-	struct acpi_resource_fixed_memory32 *acpi_mem;
-	struct acpi_resource_address32 *acpi_add32;
 	struct acpi_resource_extended_irq *acpi_xirq;
 	struct acpi_resource_irq *acpi_irq;
-	struct resource_info *ri = data;
-	struct resource *r;
+	struct resource *r = resources + count;
 	int irq, i;
 
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		acpi_mem = &res->data.fixed_memory32;
-		r = &ri->res[ri->cur++];
-
-		r->start = acpi_mem->address;
-		r->end = r->start + acpi_mem->address_length - 1;
-		r->flags = IORESOURCE_MEM;
-
-		dev_dbg(ri->dev, "Memory32Fixed %pR\n", r);
-		break;
-
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		acpi_add32 = &res->data.address32;
-
-		if (acpi_add32->resource_type == ACPI_IO_RANGE) {
-			r = &ri->res[ri->cur++];
-			r->start = acpi_add32->minimum;
-			r->end = r->start + acpi_add32->address_length - 1;
-			r->flags = IORESOURCE_IO;
-			dev_dbg(ri->dev, "Address32 %pR\n", r);
-		}
-		break;
+	if (acpi_dev_resource_memory(res, &r)
+	    || acpi_dev_resource_address_space(res, &r))
+		return 1;
 
+	switch (res->type) {
 	case ACPI_RESOURCE_TYPE_IRQ:
 		acpi_irq = &res->data.irq;
-		r = &ri->res[ri->cur++];
-
-		irq = acpi_register_gsi(ri->dev,
+		irq = acpi_register_gsi(dev,
 					acpi_irq->interrupts[0],
 					acpi_irq->triggering,
 					acpi_irq->polarity);
@@ -96,15 +50,13 @@ static acpi_status acpi_platform_add_res
 		r->start = r->end = irq;
 		r->flags = IORESOURCE_IRQ;
 
-		dev_dbg(ri->dev, "IRQ %pR\n", r);
-		break;
+		dev_dbg(dev, "Interrupt %pR\n", r);
+		return 1;
 
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		acpi_xirq = &res->data.extended_irq;
-
-		for (i = 0; i < acpi_xirq->interrupt_count; i++, ri->cur++) {
-			r = &ri->res[ri->cur];
-			irq = acpi_register_gsi(ri->dev,
+		for (i = 0; i < acpi_xirq->interrupt_count; i++, r++) {
+			irq = acpi_register_gsi(dev,
 						acpi_xirq->interrupts[i],
 						acpi_xirq->triggering,
 						acpi_xirq->polarity);
@@ -112,12 +64,12 @@ static acpi_status acpi_platform_add_res
 			r->start = r->end = irq;
 			r->flags = IORESOURCE_IRQ;
 
-			dev_dbg(ri->dev, "Interrupt %pR\n", r);
+			dev_dbg(dev, "Interrupt %pR\n", r);
 		}
-		break;
+		return i;
 	}
 
-	return AE_OK;
+	return 0;
 }
 
 static acpi_status acpi_platform_get_device_uid(struct acpi_device *adev,
@@ -154,7 +106,9 @@ struct platform_device *acpi_create_plat
 	struct platform_device *pdev = NULL;
 	struct acpi_device *acpi_parent;
 	struct device *parent = NULL;
-	struct resource_info ri;
+	struct acpi_resource_list_entry *entry;
+	struct resource *resources;
+	unsigned int count = 0;
 	acpi_status status;
 	int devid;
 
@@ -170,29 +124,22 @@ struct platform_device *acpi_create_plat
 	memset(&ri, 0, sizeof(ri));
 
 	/* First, count the resources. */
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_count_resources, &ri);
-	if (ACPI_FAILURE(status) || !ri.n)
-		return NULL;
+	list_for_each_entry(entry, &adev->resources, node)
+		count += acpi_platform_resource_size(&entry->resource);
 
 	/* Next, allocate memory for all the resources and populate it. */
-	ri.dev = &adev->dev;
-	ri.res = kzalloc(ri.n * sizeof(struct resource), GFP_KERNEL);
-	if (!ri.res) {
+	resources = kalloc(count * sizeof(struct resource), GFP_KERNEL);
+	if (!resources) {
 		dev_err(&adev->dev,
 			"failed to allocate memory for resources\n");
 		return NULL;
 	}
 
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_add_resources, &ri);
-	if (ACPI_FAILURE(status)) {
-		dev_err(&adev->dev, "failed to walk resources\n");
-		goto out;
-	}
-
-	if (WARN_ON(ri.n != ri.cur))
-		goto out;
+	count = 0;
+	list_for_each_entry(entry, &adev->resources, node)
+		count += acpi_platform_add_resource(&adev->dev,
+						    &entry->resource,
+						    resources, count);
 
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
@@ -215,7 +162,8 @@ struct platform_device *acpi_create_plat
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
 	pdev = platform_device_register_resndata(parent, acpi_device_hid(adev),
-						 devid, ri.res, ri.n, NULL, 0);
+						 devid, resources, count,
+						 NULL, 0);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));
@@ -226,7 +174,7 @@ struct platform_device *acpi_create_plat
 	}
 
  out:
-	kfree(ri.res);
+	kfree(resources);
 	return pdev;
 }
 

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-03  7:46 ` [PATCH 1/3] gpio / ACPI: add ACPI support Mika Westerberg
  2012-11-05 11:53   ` Linus Walleij
@ 2012-11-08 15:55   ` Grant Likely
  2012-11-08 19:38     ` Mika Westerberg
  1 sibling, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-08 15:55 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

Hi Mika,

On Sat, Nov 3, 2012 at 7:46 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> From: Mathias Nyman <mathias.nyman@linux.intel.com>
>
> Add support for translating ACPI GPIO pin numbers to Linux GPIO API pins.
> Needs a gpio controller driver with the acpi handler hook set.
>
> Drivers can use acpi_get_gpio() to translate ACPI5 GpioIO and GpioInt
> resources to Linux GPIO's.

How does the mapping work? Is the ACPI gpio number space kept
completely separate from the Linux GPIO numbers, or is there any
attempt to line up ACPI and Linux GPIO numbering? From my reading, it
/looks/ like the ACPI GPIO numbering is controller-local (no single
large global space) because both a full path and a pin number are
specified, but I'd like to know for sure.

> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/gpio/Kconfig        |    4 +++
>  drivers/gpio/Makefile       |    1 +
>  drivers/gpio/gpiolib-acpi.c |   60 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi_gpio.h   |   19 ++++++++++++++
>  4 files changed, 84 insertions(+)
>  create mode 100644 drivers/gpio/gpiolib-acpi.c
>  create mode 100644 include/linux/acpi_gpio.h
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index d055cee..2f1905b 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -49,6 +49,10 @@ config OF_GPIO
>         def_bool y
>         depends on OF && !SPARC
>
> +config ACPI_GPIO

Nit: Can you flip this around to GPIO_ACPI? I know OF_GPIO is the
other way around, but it should be changed.

> diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
> new file mode 100644
> index 0000000..ef56ea4
> --- /dev/null
> +++ b/drivers/gpio/gpiolib-acpi.c
> @@ -0,0 +1,60 @@
> +/*
> + * ACPI helpers for GPIO API
> + *
> + * Copyright (C) 2012, Intel Corporation
> + * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/gpio.h>
> +#include <linux/module.h>
> +#include <linux/acpi_gpio.h>
> +#include <linux/acpi.h>
> +
> +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
> +{
> +       acpi_handle handle = data;
> +       acpi_handle gc_handle;
> +
> +       if (!gc->dev)
> +               return false;
> +
> +       gc_handle = gc->dev->acpi_handle;
> +       if (!gc_handle)
> +               return false;

This test is redundant with the next one... unless 'handle' is also NULL :-)

Is it at all possible for multiple gpiochips to be used for a single
ACPI gpio controller node? Such as if the gpio controller has multiple
banks that should be controlled separately? If so then this won't be
sufficient. I've got the same issue with DT support where the find
function needs to also check if the pin is provided by that specific
gpiochip.

Overall the patch looks good, but I need to see how it is used. It
would be really nice if device drivers could use basically the same
interface to obtain Linux gpio numbers regardless of if the backing
data was ACPI or DT. This API is one level below that.

> +
> +       return gc_handle == handle;
> +}
> +
> +/**
> + * acpi_get_gpio() - Translate ACPI GPIO pin to GPIO number usable with GPIO API
> + * @path:      ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
> + * @pin:       ACPI GPIO pin number (0-based, controller-relative)
> + *
> + * Returns GPIO number to use with Linux generic GPIO API, or errno error value
> + */
> +
> +int acpi_get_gpio(char *path, int pin)
> +{
> +       struct gpio_chip *chip;
> +       acpi_handle handle;
> +       acpi_status status;
> +
> +       status = acpi_get_handle(NULL, path, &handle);
> +       if (ACPI_FAILURE(status))
> +               return -ENODEV;
> +
> +       chip = gpiochip_find(handle, acpi_gpiochip_find);
> +       if (!chip)
> +               return -ENODEV;
> +
> +       if (!gpio_is_valid(chip->base + pin))
> +               return -EINVAL;
> +
> +       return chip->base + pin;
> +}
> +EXPORT_SYMBOL(acpi_get_gpio);
> diff --git a/include/linux/acpi_gpio.h b/include/linux/acpi_gpio.h
> new file mode 100644
> index 0000000..e025664
> --- /dev/null
> +++ b/include/linux/acpi_gpio.h
> @@ -0,0 +1,19 @@
> +#ifndef _LINUX_ACPI_GPIO_H_
> +#define _LINUX_ACPI_GPIO_H_
> +
> +#include <linux/errno.h>
> +
> +#ifdef CONFIG_ACPI_GPIO
> +
> +int acpi_get_gpio(char *path, int pin);
> +
> +#else /* CONFIG_ACPI_GPIO */
> +
> +static inline int acpi_get_gpio(char *path, int pin)
> +{
> +       return -ENODEV;
> +}
> +
> +#endif /* CONFIG_ACPI_GPIO */
> +
> +#endif /* _LINUX_ACPI_GPIO_H_ */
> --
> 1.7.10.4
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-07  9:58                     ` Mika Westerberg
  2012-11-07 11:14                       ` Rafael J. Wysocki
@ 2012-11-08 18:05                       ` Grant Likely
  2012-11-08 21:06                         ` Rafael J. Wysocki
  1 sibling, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-08 18:05 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Wed, Nov 7, 2012 at 9:58 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Tue, Nov 06, 2012 at 11:36:08PM +0100, Rafael J. Wysocki wrote:
>> >
>> > OK, but then we need to pass the information obtained from _CRS
>> > (presumably after some adjustments through _SRS) to drivers, or rather to
>> > things like the SPI core, I2C core etc. so that they can create device
>> > objects for drivers to bind to and quite frankly I don't see why not to use
>> > ACPI resources for that.
>>
>> Nevertheless, the routines for parsing those resources should belong
>> to the ACPI core, mostly to avoid code duplication.
>
> Rafael,
>
> So is the idea now that the ACPI core parses the resources and passes them
> forward via struct acpi_device? I'm just wondering how to proceed with
> these I2C and SPI enumeration patches.

>From my experience with device tree, that seems the wrong way around.
Device Tree used to have a separate "of_device" which is analogous to
an acpi_device. The problem was always that of_devices never fit into
the view that Linux has of the system. That would mean having both an
of_device and and spi_device in completely separate parts of the
driver model tree to support an spi device. Same for platform, i2c and
onewire and others. Blech.

So, yes I agree that ACPI core should have the tools for parsing the
resources, but it makes sense for those functions to be helpers that
the spi core acpi support and the i2c core acpi support use to
populate the native spi_device and i2c_client structures. Plus
individual drivers can call the same functions if (and only if) the
needed resources cannot fit into the bus type's native format.

We really could also use more common code between bus types for
storing various kinds of resources, but that's a separate issue and
doesn't affect this discussion.

g.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-03  7:46 ` [PATCH 2/3] spi / ACPI: add ACPI enumeration support Mika Westerberg
  2012-11-03 19:42   ` Bjorn Helgaas
  2012-11-05 10:54   ` Mark Brown
@ 2012-11-08 18:48   ` Grant Likely
  2012-11-09  3:50     ` Mika Westerberg
  2 siblings, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-08 18:48 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sat, Nov 3, 2012 at 7:46 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> configure the SPI slave devices behind the SPI controller. This patch adds
> support for this to the SPI core.
>
> In addition we bind ACPI nodes to SPI devices. This makes it possible for
> the slave drivers to get the ACPI handle for further configuration.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 230 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> index 84c2861..de22a6e 100644
> --- a/drivers/spi/spi.c
> +++ b/drivers/spi/spi.c
> @@ -35,6 +35,7 @@
>  #include <linux/sched.h>
>  #include <linux/delay.h>
>  #include <linux/kthread.h>
> +#include <linux/acpi.h>
>
>  static void spidev_release(struct device *dev)
>  {
> @@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
>         if (of_driver_match_device(dev, drv))
>                 return 1;
>
> +       /* Then try ACPI */
> +       if (acpi_driver_match_device(dev, drv))
> +               return 1;
> +
>         if (sdrv->id_table)
>                 return !!spi_match_id(sdrv->id_table, spi);
>
> @@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
>  static void of_register_spi_devices(struct spi_master *master) { }
>  #endif
>
> +#ifdef CONFIG_ACPI
> +struct acpi_spi {
> +       acpi_status (*callback)(struct acpi_device *, void *);
> +       void *data;
> +};
> +
> +static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
> +                                            void *data, void **return_value)
> +{
> +       struct acpi_spi *acpi_spi = data;
> +       struct acpi_device *adev;
> +
> +       if (acpi_bus_get_device(handle, &adev))
> +               return AE_OK;
> +       if (acpi_bus_get_status(adev) || !adev->status.present)
> +               return AE_OK;
> +
> +       return acpi_spi->callback(adev, acpi_spi->data);
> +}
> +
> +static acpi_status acpi_spi_enumerate(acpi_handle handle,
> +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> +{
> +       struct acpi_spi acpi_spi;
> +
> +       acpi_spi.callback = callback;
> +       acpi_spi.data = data;
> +
> +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +                                  acpi_spi_enumerate_device, NULL,
> +                                  &acpi_spi, NULL);
> +}

>From my reading of this, the block causes 2 levels of callback
indirection. First to either acpi_spi_find_child or
acpi_spi_add_device and second to acpi_spi_enumerate_device. All to
share about 4 lines of code in acpi_spi_enumerate_device. It took me a
while to unravel it. I think acpi_spi_find_child and
acpi_spi_add_device should be passed directly to acpi_walk_namespace.
Is there anything that prevents that?

I also agree with the discussion that the actual parsing code for the
resources should be common,. Retrieving things like IRQs and address
resources should be function calls into ACPI helpers instead of open
coding it in the spi core code.

Otherwise the patch looks sane to me.

g.

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

* Re: [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-03  7:46 ` [PATCH 3/3] i2c " Mika Westerberg
  2012-11-03 21:52   ` Jean Delvare
@ 2012-11-08 18:58   ` Grant Likely
  2012-11-09  3:51     ` Mika Westerberg
  1 sibling, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-08 18:58 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Sat, Nov 3, 2012 at 7:46 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> ACPI 5 introduced I2cSerialBus resource that makes it possible to enumerate
> and configure the I2C slave devices behind the I2C controller. This patch
> adds helper functions to support I2C slave enumeration.
>
> An ACPI enabled I2C controller driver only needs to call acpi_i2c_register_devices()
> in order to get its slave devices enumerated, created and bound to the
> corresponding ACPI handle.
>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/acpi/Kconfig     |    6 ++
>  drivers/acpi/Makefile    |    1 +
>  drivers/acpi/acpi_i2c.c  |  234 ++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/i2c/i2c-core.c   |    9 ++
>  include/linux/acpi_i2c.h |   29 ++++++
>  5 files changed, 279 insertions(+)
>  create mode 100644 drivers/acpi/acpi_i2c.c
>  create mode 100644 include/linux/acpi_i2c.h
>
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 119d58d..0300bf6 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -181,6 +181,12 @@ config ACPI_DOCK
>           This driver supports ACPI-controlled docking stations and removable
>           drive bays such as the IBM Ultrabay and the Dell Module Bay.
>
> +config ACPI_I2C
> +       def_tristate I2C
> +       depends on I2C
> +       help
> +         ACPI I2C enumeration support.
> +
>  config ACPI_PROCESSOR
>         tristate "Processor"
>         select THERMAL
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index a7badb5..8573346 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -69,6 +69,7 @@ obj-$(CONFIG_ACPI_HED)                += hed.o
>  obj-$(CONFIG_ACPI_EC_DEBUGFS)  += ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)                += bgrt.o
> +obj-$(CONFIG_ACPI_I2C)         += acpi_i2c.o
>
>  # processor has its own "processor." module_param namespace
>  processor-y                    := processor_driver.o processor_throttling.o
> diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
> new file mode 100644
> index 0000000..dc6997e
> --- /dev/null
> +++ b/drivers/acpi/acpi_i2c.c
> @@ -0,0 +1,234 @@
> +/*
> + * ACPI I2C enumeration support
> + *
> + * Copyright (C) 2012, Intel Corporation
> + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/acpi.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +
> +struct acpi_i2c {
> +       acpi_status (*callback)(struct acpi_device *, void *);
> +       void *data;
> +};
> +
> +static acpi_status acpi_i2c_enumerate_device(acpi_handle handle, u32 level,
> +                                            void *data, void **return_value)
> +{
> +       struct acpi_i2c *acpi_i2c = data;
> +       struct acpi_device *adev;
> +
> +       if (acpi_bus_get_device(handle, &adev))
> +               return AE_OK;
> +       if (acpi_bus_get_status(adev) || !adev->status.present)
> +               return AE_OK;
> +
> +       return acpi_i2c->callback(adev, acpi_i2c->data);
> +}
> +
> +static acpi_status acpi_i2c_enumerate(acpi_handle handle,
> +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> +{
> +       struct acpi_i2c acpi_i2c;
> +
> +       acpi_i2c.callback = callback;
> +       acpi_i2c.data = data;
> +
> +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> +                                  acpi_i2c_enumerate_device, NULL,
> +                                  &acpi_i2c, NULL);
> +}

Same comment here as for the SPI patch. The two levels of indirection
is more convoluted than it needs to be. Can acpi_i2c_find_client and
acpi_i2c_add_device be passed directly to acpi_walk_namespace?

g.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-07  9:56               ` Mika Westerberg
@ 2012-11-08 19:32                 ` Bjorn Helgaas
  2012-11-08 20:04                   ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-08 19:32 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Wed, Nov 7, 2012 at 2:56 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Tue, Nov 06, 2012 at 11:18:11PM +0100, Rafael J. Wysocki wrote:
>> > How is the SPI controller different than this?  Is there some logical
>> > difference that requires a different framework?  Or are you proposing
>> > that we get rid of acpi_bus_register_driver() and migrate everything
>> > to this new framework?
>>
>> Yes, I do, but let's just do it gradually.
>
> Bjorn, here is a concrete example how this is supposed to be used.
>
> Lets say we have an existing SPI slave driver that we want to extend to
> support enumeration from ACPI. Instead of writing acpi_driver glue for that
> (and registering it using acpi_bus_register_driver()) what we do is simple
> add these to the existing SPI driver:
>
>         #ifdef CONFIG_ACPI
>         static struct acpi_device_id my_spidrv_match[] = {
>                 /* ACPI IDs here */
>                 { }
>         };
>         MODULE_DEVICE_TABLE(acpi, my_spidrv_match);
>         #endif
>
>         static struct spi_driver my_spidrv = {
>                 ...
>                 .driver = {
>                         .acpi_match_table = ACPI_PTR(my_spidrv_match),
>                 },
>         };
>
> The same thing works with platform, I2c and SPI drivers and can be extented
> to others as well. If the driver needs to do some ACPI specific
> configuration it can get the ACPI handle using its dev->acpi_handle.
>
> The above example now supports both, normal SPI (where the devices are
> enumerated by populating spi_board_info()) and ACPI. Adding support for
> Device Tree is similar than ACPI so a single driver can support all three
> easily at the same time.

Thanks for the concrete example; that helps me a lot.

Struct device_driver is a generic structure, so it seems strange to
have to include non-generic things like of_device_id and now
acpi_match_table there.

I'm actually interested in the details you didn't include above, too.
For example, I don't know of a generic way to get resource information
from a "struct device *", so I assume you need to figure out what sort
of device it is and then do the appropriate PCI/ACPI/OF/DT/etc
operations to learn the resources?

I think it would be cool if there *were* a generic way to get "struct
device" resources.  Then you could imagine a mechanism where a driver
supplied a list of identifiers it could claim, e.g.,
PCI_VEN_DEV(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART),
ACPI_ID("PNP0501"), etc.,  and it might not need to know anything more
than what the identifier is.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-08 15:55   ` Grant Likely
@ 2012-11-08 19:38     ` Mika Westerberg
  2012-11-09 14:11       ` Mathias Nyman
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-08 19:38 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Thu, Nov 08, 2012 at 03:55:18PM +0000, Grant Likely wrote:
> Hi Mika,
> 
> On Sat, Nov 3, 2012 at 7:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > From: Mathias Nyman <mathias.nyman@linux.intel.com>
> >
> > Add support for translating ACPI GPIO pin numbers to Linux GPIO API pins.
> > Needs a gpio controller driver with the acpi handler hook set.
> >
> > Drivers can use acpi_get_gpio() to translate ACPI5 GpioIO and GpioInt
> > resources to Linux GPIO's.
> 
> How does the mapping work? Is the ACPI gpio number space kept
> completely separate from the Linux GPIO numbers, or is there any
> attempt to line up ACPI and Linux GPIO numbering? From my reading, it
> /looks/ like the ACPI GPIO numbering is controller-local (no single
> large global space) because both a full path and a pin number are
> specified, but I'd like to know for sure.

Yes, the ACPI GPIO number from GpioIO/GpioInt resources are controller
relative and we use the path from the resource to find the actual
controller.

> 
> > Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/gpio/Kconfig        |    4 +++
> >  drivers/gpio/Makefile       |    1 +
> >  drivers/gpio/gpiolib-acpi.c |   60 +++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/acpi_gpio.h   |   19 ++++++++++++++
> >  4 files changed, 84 insertions(+)
> >  create mode 100644 drivers/gpio/gpiolib-acpi.c
> >  create mode 100644 include/linux/acpi_gpio.h
> >
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index d055cee..2f1905b 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -49,6 +49,10 @@ config OF_GPIO
> >         def_bool y
> >         depends on OF && !SPARC
> >
> > +config ACPI_GPIO
> 
> Nit: Can you flip this around to GPIO_ACPI? I know OF_GPIO is the
> other way around, but it should be changed.

Sure.

> 
> > diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
> > new file mode 100644
> > index 0000000..ef56ea4
> > --- /dev/null
> > +++ b/drivers/gpio/gpiolib-acpi.c
> > @@ -0,0 +1,60 @@
> > +/*
> > + * ACPI helpers for GPIO API
> > + *
> > + * Copyright (C) 2012, Intel Corporation
> > + * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/errno.h>
> > +#include <linux/gpio.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi_gpio.h>
> > +#include <linux/acpi.h>
> > +
> > +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
> > +{
> > +       acpi_handle handle = data;
> > +       acpi_handle gc_handle;
> > +
> > +       if (!gc->dev)
> > +               return false;
> > +
> > +       gc_handle = gc->dev->acpi_handle;
> > +       if (!gc_handle)
> > +               return false;
> 
> This test is redundant with the next one... unless 'handle' is also NULL :-)
> 
> Is it at all possible for multiple gpiochips to be used for a single
> ACPI gpio controller node? Such as if the gpio controller has multiple
> banks that should be controlled separately? If so then this won't be
> sufficient. I've got the same issue with DT support where the find
> function needs to also check if the pin is provided by that specific
> gpiochip.

AFAIK no but I'll let Mathias to answer that as he knows this better.

> Overall the patch looks good, but I need to see how it is used. It
> would be really nice if device drivers could use basically the same
> interface to obtain Linux gpio numbers regardless of if the backing
> data was ACPI or DT. This API is one level below that.

Yeah, this patch just mimics the DT version but in general it would be
better if there was only one API to get the GPIO. There has been discussion
about adding gpio_get() or something similar which could perhaps be used to
abstract away DT or ACPI.

We use this in a driver so that we walk through the ACPI resources for a
given device (if we have the ACPI handle) and parse the GpioIO/GpioInt
resources like:

	struct acpi_resource_gpio *acpi_gpio;
	struct acpi_device *adev;
	acpi_resource *res;
	int gpio;

	/* obtain the ACPI device from handle */
	...

	/* walk through the resources attached to adev */
	...
		switch (res->type) {
		case ACPI_RESOURCE_TYPE_GPIO:
			acpi_gpio = &res->data.gpio;

			gpio = acpi_get_gpio(acpi_gpio->resource_source.string_ptr,
					     acpi_gpio->pin_table[0]);
			...
		}

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08 19:32                 ` Bjorn Helgaas
@ 2012-11-08 20:04                   ` Mika Westerberg
  2012-11-09 15:11                     ` Bjorn Helgaas
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-08 20:04 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Rafael J. Wysocki, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
> Struct device_driver is a generic structure, so it seems strange to
> have to include non-generic things like of_device_id and now
> acpi_match_table there.

Yes, but in a sense the DT and ACPI are "generic". So that they are used to
describe the configuration of a machine.

> I'm actually interested in the details you didn't include above, too.
> For example, I don't know of a generic way to get resource information
> from a "struct device *", so I assume you need to figure out what sort
> of device it is and then do the appropriate PCI/ACPI/OF/DT/etc
> operations to learn the resources?

Right. Typically you check, dev->of_node (or dev->acpi_handle) in a driver
and if it is non-NULL you can extract the resources using DT or ACPI
specific API calls.

Some things like IRQs and MMIO addresses can be passed to the driver using
the struct resource (and we do that already) but others we can't, like
GPIOs and some DT specific properties. Also with ACPI there might be need
to call some ACPI method, like _DSM where we need to have access to the
ACPI handle.

> I think it would be cool if there *were* a generic way to get "struct
> device" resources.  Then you could imagine a mechanism where a driver
> supplied a list of identifiers it could claim, e.g.,
> PCI_VEN_DEV(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART),
> ACPI_ID("PNP0501"), etc.,  and it might not need to know anything more
> than what the identifier is.

Indeed that would be cool, and we should probably try to implement
something like that, eventually. If you have followed the discusion there
is already talks about having a single API to get GPIOs to the driver in a
generic way.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08  0:46                           ` Rafael J. Wysocki
@ 2012-11-08 20:20                             ` Mika Westerberg
  2012-11-08 20:54                               ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-08 20:20 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Thu, Nov 08, 2012 at 01:46:24AM +0100, Rafael J. Wysocki wrote:
> On Wednesday, November 07, 2012 03:05:48 PM Mika Westerberg wrote:
> > On Wed, Nov 07, 2012 at 12:14:31PM +0100, Rafael J. Wysocki wrote:
> > > > So is the idea now that the ACPI core parses the resources and passes them
> > > > forward via struct acpi_device? I'm just wondering how to proceed with
> > > > these I2C and SPI enumeration patches.
> > > 
> > > Well, we definitely don't want to duplicate what drivers/pnp/pnpacpi/rsparser.c
> > > does, so the idea is to move the code from there to the core in such a way that
> > > both the SPI/I2C patches and the PNP layer can use it.
> > 
> > Ok.
> > 
> > > I'll have some prototype code ready shortly, hopefully, and I'll post it
> > > in that form for comments (and so that you know what to expect).
> > 
> > Sounds good. Thanks!
> 
> There you go.
> 
> I haven't even try to compile it, so most likely it breaks things left, right
> and in between, but I hope it shows the idea.

Thanks Rafael!

I'll try this tomorrow (we had problems with the HW today so I wasn't able
to do any testing).

I'll convert the SPI and I2C enumeration patches to use this method.

> It does a couple of things at the same time, so it should be split into a few
> simpler patches.  First, it moves some code from drivers/pnp/pnpacpi/rsparser.c
> to a new file drivers/acpi/resource.c and makes pnpacpi use functions from
> there.  Second, it changes acpi_platform.c to use those functions too.
> Finally, it adds a list of ACPI resources to struct acpi_device and
> makes acpi_platform.c use that list intead of evaluating _CRS and parsing its
> output with acpi_walk_resources().
> 
> While changing acpi_platform.c I noticed that we had a bug in there, because
> GSIs were registered for the struct acpi_device object, although they should be
> registered for the struct platform_device one created by that code.  I didn't
> try to fix that in the patch below, but it generally needs fixing.

Good point.

I wonder if the acpi_register_gsi() wants a device that is registered to
the Linux device framework? At least with the SPI and I2C we generally
don't have such until we call i2c_new_device() or spi_add_device() and they
are getting passed the IRQ number which should be translated to the Linux
IRQ before that...

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08 20:20                             ` Mika Westerberg
@ 2012-11-08 20:54                               ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-08 20:54 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi

On Thursday, November 08, 2012 10:20:42 PM Mika Westerberg wrote:
> On Thu, Nov 08, 2012 at 01:46:24AM +0100, Rafael J. Wysocki wrote:
> > On Wednesday, November 07, 2012 03:05:48 PM Mika Westerberg wrote:
> > > On Wed, Nov 07, 2012 at 12:14:31PM +0100, Rafael J. Wysocki wrote:
> > > > > So is the idea now that the ACPI core parses the resources and passes them
> > > > > forward via struct acpi_device? I'm just wondering how to proceed with
> > > > > these I2C and SPI enumeration patches.
> > > > 
> > > > Well, we definitely don't want to duplicate what drivers/pnp/pnpacpi/rsparser.c
> > > > does, so the idea is to move the code from there to the core in such a way that
> > > > both the SPI/I2C patches and the PNP layer can use it.
> > > 
> > > Ok.
> > > 
> > > > I'll have some prototype code ready shortly, hopefully, and I'll post it
> > > > in that form for comments (and so that you know what to expect).
> > > 
> > > Sounds good. Thanks!
> > 
> > There you go.
> > 
> > I haven't even try to compile it, so most likely it breaks things left, right
> > and in between, but I hope it shows the idea.
> 
> Thanks Rafael!
> 
> I'll try this tomorrow (we had problems with the HW today so I wasn't able
> to do any testing).
> 
> I'll convert the SPI and I2C enumeration patches to use this method.

OK, but I still need to move parsers of interrupt resources from rsparser.c
to resource.c. :-)

> > It does a couple of things at the same time, so it should be split into a few
> > simpler patches.  First, it moves some code from drivers/pnp/pnpacpi/rsparser.c
> > to a new file drivers/acpi/resource.c and makes pnpacpi use functions from
> > there.  Second, it changes acpi_platform.c to use those functions too.
> > Finally, it adds a list of ACPI resources to struct acpi_device and
> > makes acpi_platform.c use that list intead of evaluating _CRS and parsing its
> > output with acpi_walk_resources().
> > 
> > While changing acpi_platform.c I noticed that we had a bug in there, because
> > GSIs were registered for the struct acpi_device object, although they should be
> > registered for the struct platform_device one created by that code.  I didn't
> > try to fix that in the patch below, but it generally needs fixing.
> 
> Good point.
> 
> I wonder if the acpi_register_gsi() wants a device that is registered to
> the Linux device framework?

No, it doesn't, as far as I can tell.  At least the pnpacpi code adds
devices after registering GSIs for them.  Also the existing implementations
of acpi_register_gsi() don't require that.

> At least with the SPI and I2C we generally
> don't have such until we call i2c_new_device() or spi_add_device() and they
> are getting passed the IRQ number which should be translated to the Linux
> IRQ before that...

That's correct.

It looks like we could follow the hpet code and pass NULL as the dev argument
to acpi_register_gsi() from there, as apparently the dev argument is only
used to special-case PCI devices in mp_config_acpi_gsi().

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08 18:05                       ` Grant Likely
@ 2012-11-08 21:06                         ` Rafael J. Wysocki
  2012-11-08 21:34                           ` Grant Likely
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-08 21:06 UTC (permalink / raw)
  To: Grant Likely, Mika Westerberg
  Cc: Bjorn Helgaas, linux-kernel, lenb, rafael.j.wysocki, broonie,
	linus.walleij, khali, ben-linux, w.sang, mathias.nyman,
	linux-acpi

On Thursday, November 08, 2012 06:05:23 PM Grant Likely wrote:
> On Wed, Nov 7, 2012 at 9:58 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Tue, Nov 06, 2012 at 11:36:08PM +0100, Rafael J. Wysocki wrote:
> >> >
> >> > OK, but then we need to pass the information obtained from _CRS
> >> > (presumably after some adjustments through _SRS) to drivers, or rather to
> >> > things like the SPI core, I2C core etc. so that they can create device
> >> > objects for drivers to bind to and quite frankly I don't see why not to use
> >> > ACPI resources for that.
> >>
> >> Nevertheless, the routines for parsing those resources should belong
> >> to the ACPI core, mostly to avoid code duplication.
> >
> > Rafael,
> >
> > So is the idea now that the ACPI core parses the resources and passes them
> > forward via struct acpi_device?

Not exactly.  The idea is to execute _CRS in the core and attach the result
as a list of resources the struct acpi_device object representing the given
device node.

> > I'm just wondering how to proceed with these I2C and SPI enumeration patches.
> 
> From my experience with device tree, that seems the wrong way around.
> Device Tree used to have a separate "of_device" which is analogous to
> an acpi_device.

No, it is not.  If anything, struct acpi_device is a counterpart of struct
device_node. :-)

Yes, the name is misleading and it should be something like struct acpi_dev_node.
Yes, these objects _are_ registered as devices with the driver model and there
are drivers that bind to some of them.  Yes, this is a mistake, but fixing it
will take quite some time, because it involves converting the drivers in
question.

No, acpi_handle is not analogous to struct device_node, because it only is
a pointer to a structure used internally by the AML interpreter.  It only
is useful for executing AML methods with the help of the interpreter, but
there are reasons why _CRS, in particular, should only be executed by the
ACPI core.

> The problem was always that of_devices never fit into
> the view that Linux has of the system. That would mean having both an
> of_device and and spi_device in completely separate parts of the
> driver model tree to support an spi device. Same for platform, i2c and
> onewire and others. Blech.
> 
> So, yes I agree that ACPI core should have the tools for parsing the
> resources, but it makes sense for those functions to be helpers that
> the spi core acpi support and the i2c core acpi support use to
> populate the native spi_device and i2c_client structures.

Yes, that exactly is the plan, although I2C and SPI will not receive the
resources directly from _CRS. :-)

> Plus individual drivers can call the same functions if (and only if) the
> needed resources cannot fit into the bus type's native format.

I'm kind of cautious about this particular thing.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08 21:06                         ` Rafael J. Wysocki
@ 2012-11-08 21:34                           ` Grant Likely
  0 siblings, 0 replies; 127+ messages in thread
From: Grant Likely @ 2012-11-08 21:34 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, Bjorn Helgaas, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi

On Thu, Nov 8, 2012 at 9:06 PM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Thursday, November 08, 2012 06:05:23 PM Grant Likely wrote:
>> On Wed, Nov 7, 2012 at 9:58 AM, Mika Westerberg
>> <mika.westerberg@linux.intel.com> wrote:
>> > On Tue, Nov 06, 2012 at 11:36:08PM +0100, Rafael J. Wysocki wrote:
>> >> >
>> >> > OK, but then we need to pass the information obtained from _CRS
>> >> > (presumably after some adjustments through _SRS) to drivers, or rather to
>> >> > things like the SPI core, I2C core etc. so that they can create device
>> >> > objects for drivers to bind to and quite frankly I don't see why not to use
>> >> > ACPI resources for that.
>> >>
>> >> Nevertheless, the routines for parsing those resources should belong
>> >> to the ACPI core, mostly to avoid code duplication.
>> >
>> > Rafael,
>> >
>> > So is the idea now that the ACPI core parses the resources and passes them
>> > forward via struct acpi_device?
>
> Not exactly.  The idea is to execute _CRS in the core and attach the result
> as a list of resources the struct acpi_device object representing the given
> device node.
>
>> > I'm just wondering how to proceed with these I2C and SPI enumeration patches.
>>
>> From my experience with device tree, that seems the wrong way around.
>> Device Tree used to have a separate "of_device" which is analogous to
>> an acpi_device.
>
> No, it is not.  If anything, struct acpi_device is a counterpart of struct
> device_node. :-)
>
> Yes, the name is misleading and it should be something like struct acpi_dev_node.
> Yes, these objects _are_ registered as devices with the driver model and there
> are drivers that bind to some of them.  Yes, this is a mistake, but fixing it
> will take quite some time, because it involves converting the drivers in
> question.

Okay, fair enough. I was indeed thrown off by the fact that it embeds
a struct device and there are drivers that bind against it. At least
that is the sort of thing that can be fixed over the long haul without
undue pain.

I can certainly see the advantage of having acpi nodes appear in
sysfs. Interestingly enough I'm currently playing with a patch set
that makes struct device_node  a kobject so it can do the same. It is
quite nice to get a back symlink from a struct device to a struct
device_node when the pointer is populated.

>> Plus individual drivers can call the same functions if (and only if) the
>> needed resources cannot fit into the bus type's native format.
>
> I'm kind of cautious about this particular thing.

I've seen enough cases where something doesn't quite fit into the
model provided by a subsystem and it requires the driver to go asking
for something specific. But I completely agree that caution is
absolutely required and it shouldn't be done casually.

g.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08 18:48   ` Grant Likely
@ 2012-11-09  3:50     ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-09  3:50 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Thu, Nov 08, 2012 at 06:48:05PM +0000, Grant Likely wrote:
> On Sat, Nov 3, 2012 at 7:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > ACPI 5 introduced SPISerialBus resource that allows us to enumerate and
> > configure the SPI slave devices behind the SPI controller. This patch adds
> > support for this to the SPI core.
> >
> > In addition we bind ACPI nodes to SPI devices. This makes it possible for
> > the slave drivers to get the ACPI handle for further configuration.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/spi/spi.c |  231 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 230 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> > index 84c2861..de22a6e 100644
> > --- a/drivers/spi/spi.c
> > +++ b/drivers/spi/spi.c
> > @@ -35,6 +35,7 @@
> >  #include <linux/sched.h>
> >  #include <linux/delay.h>
> >  #include <linux/kthread.h>
> > +#include <linux/acpi.h>
> >
> >  static void spidev_release(struct device *dev)
> >  {
> > @@ -93,6 +94,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
> >         if (of_driver_match_device(dev, drv))
> >                 return 1;
> >
> > +       /* Then try ACPI */
> > +       if (acpi_driver_match_device(dev, drv))
> > +               return 1;
> > +
> >         if (sdrv->id_table)
> >                 return !!spi_match_id(sdrv->id_table, spi);
> >
> > @@ -888,6 +893,227 @@ static void of_register_spi_devices(struct spi_master *master)
> >  static void of_register_spi_devices(struct spi_master *master) { }
> >  #endif
> >
> > +#ifdef CONFIG_ACPI
> > +struct acpi_spi {
> > +       acpi_status (*callback)(struct acpi_device *, void *);
> > +       void *data;
> > +};
> > +
> > +static acpi_status acpi_spi_enumerate_device(acpi_handle handle, u32 level,
> > +                                            void *data, void **return_value)
> > +{
> > +       struct acpi_spi *acpi_spi = data;
> > +       struct acpi_device *adev;
> > +
> > +       if (acpi_bus_get_device(handle, &adev))
> > +               return AE_OK;
> > +       if (acpi_bus_get_status(adev) || !adev->status.present)
> > +               return AE_OK;
> > +
> > +       return acpi_spi->callback(adev, acpi_spi->data);
> > +}
> > +
> > +static acpi_status acpi_spi_enumerate(acpi_handle handle,
> > +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> > +{
> > +       struct acpi_spi acpi_spi;
> > +
> > +       acpi_spi.callback = callback;
> > +       acpi_spi.data = data;
> > +
> > +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> > +                                  acpi_spi_enumerate_device, NULL,
> > +                                  &acpi_spi, NULL);
> > +}
> 
> >From my reading of this, the block causes 2 levels of callback
> indirection. First to either acpi_spi_find_child or
> acpi_spi_add_device and second to acpi_spi_enumerate_device. All to
> share about 4 lines of code in acpi_spi_enumerate_device. It took me a
> while to unravel it. I think acpi_spi_find_child and
> acpi_spi_add_device should be passed directly to acpi_walk_namespace.
> Is there anything that prevents that?

No, I'll fix that up in the next version of the series.

> I also agree with the discussion that the actual parsing code for the
> resources should be common,. Retrieving things like IRQs and address
> resources should be function calls into ACPI helpers instead of open
> coding it in the spi core code.

We are working on that and I'm hoping the second version will use the
resources as provided by the ACPI core instead of calling _CRS directly
here.

> Otherwise the patch looks sane to me.

Thanks.

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

* Re: [PATCH 3/3] i2c / ACPI: add ACPI enumeration support
  2012-11-08 18:58   ` Grant Likely
@ 2012-11-09  3:51     ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-09  3:51 UTC (permalink / raw)
  To: Grant Likely
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, linus.walleij,
	khali, ben-linux, w.sang, mathias.nyman, linux-acpi

On Thu, Nov 08, 2012 at 06:58:47PM +0000, Grant Likely wrote:
> On Sat, Nov 3, 2012 at 7:46 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > ACPI 5 introduced I2cSerialBus resource that makes it possible to enumerate
> > and configure the I2C slave devices behind the I2C controller. This patch
> > adds helper functions to support I2C slave enumeration.
> >
> > An ACPI enabled I2C controller driver only needs to call acpi_i2c_register_devices()
> > in order to get its slave devices enumerated, created and bound to the
> > corresponding ACPI handle.
> >
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/acpi/Kconfig     |    6 ++
> >  drivers/acpi/Makefile    |    1 +
> >  drivers/acpi/acpi_i2c.c  |  234 ++++++++++++++++++++++++++++++++++++++++++++++
> >  drivers/i2c/i2c-core.c   |    9 ++
> >  include/linux/acpi_i2c.h |   29 ++++++
> >  5 files changed, 279 insertions(+)
> >  create mode 100644 drivers/acpi/acpi_i2c.c
> >  create mode 100644 include/linux/acpi_i2c.h
> >
> > diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> > index 119d58d..0300bf6 100644
> > --- a/drivers/acpi/Kconfig
> > +++ b/drivers/acpi/Kconfig
> > @@ -181,6 +181,12 @@ config ACPI_DOCK
> >           This driver supports ACPI-controlled docking stations and removable
> >           drive bays such as the IBM Ultrabay and the Dell Module Bay.
> >
> > +config ACPI_I2C
> > +       def_tristate I2C
> > +       depends on I2C
> > +       help
> > +         ACPI I2C enumeration support.
> > +
> >  config ACPI_PROCESSOR
> >         tristate "Processor"
> >         select THERMAL
> > diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> > index a7badb5..8573346 100644
> > --- a/drivers/acpi/Makefile
> > +++ b/drivers/acpi/Makefile
> > @@ -69,6 +69,7 @@ obj-$(CONFIG_ACPI_HED)                += hed.o
> >  obj-$(CONFIG_ACPI_EC_DEBUGFS)  += ec_sys.o
> >  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
> >  obj-$(CONFIG_ACPI_BGRT)                += bgrt.o
> > +obj-$(CONFIG_ACPI_I2C)         += acpi_i2c.o
> >
> >  # processor has its own "processor." module_param namespace
> >  processor-y                    := processor_driver.o processor_throttling.o
> > diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c
> > new file mode 100644
> > index 0000000..dc6997e
> > --- /dev/null
> > +++ b/drivers/acpi/acpi_i2c.c
> > @@ -0,0 +1,234 @@
> > +/*
> > + * ACPI I2C enumeration support
> > + *
> > + * Copyright (C) 2012, Intel Corporation
> > + * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/acpi.h>
> > +#include <linux/i2c.h>
> > +#include <linux/module.h>
> > +
> > +struct acpi_i2c {
> > +       acpi_status (*callback)(struct acpi_device *, void *);
> > +       void *data;
> > +};
> > +
> > +static acpi_status acpi_i2c_enumerate_device(acpi_handle handle, u32 level,
> > +                                            void *data, void **return_value)
> > +{
> > +       struct acpi_i2c *acpi_i2c = data;
> > +       struct acpi_device *adev;
> > +
> > +       if (acpi_bus_get_device(handle, &adev))
> > +               return AE_OK;
> > +       if (acpi_bus_get_status(adev) || !adev->status.present)
> > +               return AE_OK;
> > +
> > +       return acpi_i2c->callback(adev, acpi_i2c->data);
> > +}
> > +
> > +static acpi_status acpi_i2c_enumerate(acpi_handle handle,
> > +       acpi_status (*callback)(struct acpi_device *, void *), void *data)
> > +{
> > +       struct acpi_i2c acpi_i2c;
> > +
> > +       acpi_i2c.callback = callback;
> > +       acpi_i2c.data = data;
> > +
> > +       return acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
> > +                                  acpi_i2c_enumerate_device, NULL,
> > +                                  &acpi_i2c, NULL);
> > +}
> 
> Same comment here as for the SPI patch. The two levels of indirection
> is more convoluted than it needs to be. Can acpi_i2c_find_client and
> acpi_i2c_add_device be passed directly to acpi_walk_namespace?

Yes they can, I'll do that in the next version. Thanks.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-08 19:38     ` Mika Westerberg
@ 2012-11-09 14:11       ` Mathias Nyman
  2012-11-09 14:18         ` Grant Likely
  0 siblings, 1 reply; 127+ messages in thread
From: Mathias Nyman @ 2012-11-09 14:11 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Grant Likely, linux-kernel, lenb, rafael.j.wysocki, broonie,
	linus.walleij, khali, ben-linux, w.sang, linux-acpi

On 11/08/2012 09:38 PM, Mika Westerberg wrote:
...
>>> +#include<linux/errno.h>
>>> +#include<linux/gpio.h>
>>> +#include<linux/module.h>
>>> +#include<linux/acpi_gpio.h>
>>> +#include<linux/acpi.h>
>>> +
>>> +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
>>> +{
>>> +       acpi_handle handle = data;
>>> +       acpi_handle gc_handle;
>>> +
>>> +       if (!gc->dev)
>>> +               return false;
>>> +
>>> +       gc_handle = gc->dev->acpi_handle;
>>> +       if (!gc_handle)
>>> +               return false;
>>
>> This test is redundant with the next one... unless 'handle' is also NULL :-)
>>
>> Is it at all possible for multiple gpiochips to be used for a single
>> ACPI gpio controller node? Such as if the gpio controller has multiple
>> banks that should be controlled separately? If so then this won't be
>> sufficient. I've got the same issue with DT support where the find
>> function needs to also check if the pin is provided by that specific
>> gpiochip.
>
> AFAIK no but I'll let Mathias to answer that as he knows this better.

I'm interpreting it the same way as Mika, max one actual controller per 
ACPI device node

The path (called ResourceSource in ACPI5 specs) in GpioIO/GpioInt 
resources is a "string which uniquely identifies the GPIO controller 
referred to by this descriptor."  The pin number is zero based 
controller relative.

The  ACPI device controller node includes all other resources needed by 
the controller driver (ioport/mem base, range, interrupt, and Hardware 
ID used to pair with a driver)

Checked a board with two identical gpio controllers on it and it had two 
separate ACPI device node entries. (with only different io address base 
and interrupt resources)

-Mathias

>
>> Overall the patch looks good, but I need to see how it is used. It
>> would be really nice if device drivers could use basically the same
>> interface to obtain Linux gpio numbers regardless of if the backing
>> data was ACPI or DT. This API is one level below that.
>
> Yeah, this patch just mimics the DT version but in general it would be
> better if there was only one API to get the GPIO. There has been discussion
> about adding gpio_get() or something similar which could perhaps be used to
> abstract away DT or ACPI.
>
> We use this in a driver so that we walk through the ACPI resources for a
> given device (if we have the ACPI handle) and parse the GpioIO/GpioInt
> resources like:
>
> 	struct acpi_resource_gpio *acpi_gpio;
> 	struct acpi_device *adev;
> 	acpi_resource *res;
> 	int gpio;
>
> 	/* obtain the ACPI device from handle */
> 	...
>
> 	/* walk through the resources attached to adev */
> 	...
> 		switch (res->type) {
> 		case ACPI_RESOURCE_TYPE_GPIO:
> 			acpi_gpio =&res->data.gpio;
>
> 			gpio = acpi_get_gpio(acpi_gpio->resource_source.string_ptr,
> 					     acpi_gpio->pin_table[0]);
> 			...
> 		}


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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-09 14:11       ` Mathias Nyman
@ 2012-11-09 14:18         ` Grant Likely
  2012-11-09 15:05           ` Mathias Nyman
  0 siblings, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-09 14:18 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	linus.walleij, khali, ben-linux, w.sang, linux-acpi

On Fri, Nov 9, 2012 at 2:11 PM, Mathias Nyman
<mathias.nyman@linux.intel.com> wrote:
> On 11/08/2012 09:38 PM, Mika Westerberg wrote:
> ...
>
>>>> +#include<linux/errno.h>
>>>> +#include<linux/gpio.h>
>>>> +#include<linux/module.h>
>>>> +#include<linux/acpi_gpio.h>
>>>> +#include<linux/acpi.h>
>>>> +
>>>> +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
>>>> +{
>>>> +       acpi_handle handle = data;
>>>> +       acpi_handle gc_handle;
>>>> +
>>>> +       if (!gc->dev)
>>>> +               return false;
>>>> +
>>>> +       gc_handle = gc->dev->acpi_handle;
>>>> +       if (!gc_handle)
>>>> +               return false;
>>>
>>>
>>> This test is redundant with the next one... unless 'handle' is also NULL
>>> :-)
>>>
>>> Is it at all possible for multiple gpiochips to be used for a single
>>> ACPI gpio controller node? Such as if the gpio controller has multiple
>>> banks that should be controlled separately? If so then this won't be
>>> sufficient. I've got the same issue with DT support where the find
>>> function needs to also check if the pin is provided by that specific
>>> gpiochip.
>>
>>
>> AFAIK no but I'll let Mathias to answer that as he knows this better.
>
>
> I'm interpreting it the same way as Mika, max one actual controller per ACPI
> device node
>
> The path (called ResourceSource in ACPI5 specs) in GpioIO/GpioInt resources
> is a "string which uniquely identifies the GPIO controller referred to by
> this descriptor."  The pin number is zero based controller relative.
>
> The  ACPI device controller node includes all other resources needed by the
> controller driver (ioport/mem base, range, interrupt, and Hardware ID used
> to pair with a driver)
>
> Checked a board with two identical gpio controllers on it and it had two
> separate ACPI device node entries. (with only different io address base and
> interrupt resources)

That's not really the situation that I'm thinking about. What I mean
is for a gpio controller that is more convenient for Linux to support
using multiple gpiochips (Linux internal detail), even though there it
is described with a single ACPI node.

g.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-09 14:18         ` Grant Likely
@ 2012-11-09 15:05           ` Mathias Nyman
  2012-11-09 15:46             ` Grant Likely
  0 siblings, 1 reply; 127+ messages in thread
From: Mathias Nyman @ 2012-11-09 15:05 UTC (permalink / raw)
  To: Grant Likely
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	linus.walleij, khali, ben-linux, w.sang, linux-acpi

On 11/09/2012 04:18 PM, Grant Likely wrote:
> On Fri, Nov 9, 2012 at 2:11 PM, Mathias Nyman
> <mathias.nyman@linux.intel.com>  wrote:
>> On 11/08/2012 09:38 PM, Mika Westerberg wrote:
>> ...
>>
>>>>> +#include<linux/errno.h>
>>>>> +#include<linux/gpio.h>
>>>>> +#include<linux/module.h>
>>>>> +#include<linux/acpi_gpio.h>
>>>>> +#include<linux/acpi.h>
>>>>> +
>>>>> +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
>>>>> +{
>>>>> +       acpi_handle handle = data;
>>>>> +       acpi_handle gc_handle;
>>>>> +
>>>>> +       if (!gc->dev)
>>>>> +               return false;
>>>>> +
>>>>> +       gc_handle = gc->dev->acpi_handle;
>>>>> +       if (!gc_handle)
>>>>> +               return false;
>>>>
>>>>
>>>> This test is redundant with the next one... unless 'handle' is also NULL
>>>> :-)
>>>>
>>>> Is it at all possible for multiple gpiochips to be used for a single
>>>> ACPI gpio controller node? Such as if the gpio controller has multiple
>>>> banks that should be controlled separately? If so then this won't be
>>>> sufficient. I've got the same issue with DT support where the find
>>>> function needs to also check if the pin is provided by that specific
>>>> gpiochip.
>>>
>>>
>>> AFAIK no but I'll let Mathias to answer that as he knows this better.
>>
>>
>> I'm interpreting it the same way as Mika, max one actual controller per ACPI
>> device node
>>
>> The path (called ResourceSource in ACPI5 specs) in GpioIO/GpioInt resources
>> is a "string which uniquely identifies the GPIO controller referred to by
>> this descriptor."  The pin number is zero based controller relative.
>>
>> The  ACPI device controller node includes all other resources needed by the
>> controller driver (ioport/mem base, range, interrupt, and Hardware ID used
>> to pair with a driver)
>>
>> Checked a board with two identical gpio controllers on it and it had two
>> separate ACPI device node entries. (with only different io address base and
>> interrupt resources)
>
> That's not really the situation that I'm thinking about. What I mean
> is for a gpio controller that is more convenient for Linux to support
> using multiple gpiochips (Linux internal detail), even though there it
> is described with a single ACPI node.
>

Ok, now I get it.

Yes, in case a driver uses several gpiochips internally for different 
banks of a controller then all would have the same acpi_handle.
acpi_get_gpio() would use the gpiobase of the first gpiochip that 
matches the handle, even if it's the wrong one.

I guess It's possible to write a driver like that.
The only acpi enumerated driver with the acpi_handle set (soon coming to 
upstream) is not done like that.

Do you think this is a case that should be solved now?  or just expect 
acpi gpio device driver to not use several gpiochips in one driver?

-Mathias

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-08 20:04                   ` Mika Westerberg
@ 2012-11-09 15:11                     ` Bjorn Helgaas
  2012-11-09 15:45                       ` Grant Likely
  0 siblings, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-09 15:11 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Rafael J. Wysocki, linux-kernel, lenb, rafael.j.wysocki, broonie,
	grant.likely, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi, Greg Kroah-Hartman, H. Peter Anvin,
	Tony Luck

[+cc Greg, Peter, Tony since they acked the original patch [1]]

On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>> Struct device_driver is a generic structure, so it seems strange to
>> have to include non-generic things like of_device_id and now
>> acpi_match_table there.
>
> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
> describe the configuration of a machine.

What I meant by "generic" was "useful across all architectures."  The
new acpi_match_table and acpi_handle fields [1] are not generic in
that sense because they're present on all architectures but used only
on x86 and ia64.  The existing of_match_table and of_node are
similarly unused on many architectures.  This doesn't seem like a
scalable strategy to me.  Are we going to add a pnpbios_node for x86
PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
etc.?

[1] https://patchwork.kernel.org/patch/1677221/

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-09 15:11                     ` Bjorn Helgaas
@ 2012-11-09 15:45                       ` Grant Likely
  2012-11-09 16:35                         ` Bjorn Helgaas
  0 siblings, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-09 15:45 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, Rafael J. Wysocki, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> [+cc Greg, Peter, Tony since they acked the original patch [1]]
>
> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>>> Struct device_driver is a generic structure, so it seems strange to
>>> have to include non-generic things like of_device_id and now
>>> acpi_match_table there.
>>
>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
>> describe the configuration of a machine.
>
> What I meant by "generic" was "useful across all architectures."  The
> new acpi_match_table and acpi_handle fields [1] are not generic in
> that sense because they're present on all architectures but used only
> on x86 and ia64.  The existing of_match_table and of_node are
> similarly unused on many architectures.  This doesn't seem like a
> scalable strategy to me.  Are we going to add a pnpbios_node for x86
> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
> etc.?
>
> [1] https://patchwork.kernel.org/patch/1677221/

Ultimately yes, I think that is what we want to do, but there is first
the non-trivial problem to solve of figuring out how ACPI/DT/whatever
data maps into what the driver expects. For example, say a device uses
two GPIOs (A & B) and we have a generic get_gpio(int index) function
that works for both ACPI and DT. But what if the ACPI binding has the
gpios in the order A,B and DT orders them B,A? I do want to coordinate
between the DT and ACPI camps to avoid those situations as much as
possible, but they will happen. When they do the driver will still
need firmware specific data. It doesn't make any sense to put that
stuff outside the driver because only that specific driver needs the
extra information.

g.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-09 15:05           ` Mathias Nyman
@ 2012-11-09 15:46             ` Grant Likely
  2012-11-11  9:50               ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Grant Likely @ 2012-11-09 15:46 UTC (permalink / raw)
  To: Mathias Nyman
  Cc: Mika Westerberg, linux-kernel, lenb, rafael.j.wysocki, broonie,
	linus.walleij, khali, ben-linux, w.sang, linux-acpi

On Fri, Nov 9, 2012 at 3:05 PM, Mathias Nyman
<mathias.nyman@linux.intel.com> wrote:
> On 11/09/2012 04:18 PM, Grant Likely wrote:
>>
>> On Fri, Nov 9, 2012 at 2:11 PM, Mathias Nyman
>> <mathias.nyman@linux.intel.com>  wrote:
>>>
>>> On 11/08/2012 09:38 PM, Mika Westerberg wrote:
>>> ...
>>>
>>>>>> +#include<linux/errno.h>
>>>>>> +#include<linux/gpio.h>
>>>>>> +#include<linux/module.h>
>>>>>> +#include<linux/acpi_gpio.h>
>>>>>> +#include<linux/acpi.h>
>>>>>> +
>>>>>> +static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
>>>>>> +{
>>>>>> +       acpi_handle handle = data;
>>>>>> +       acpi_handle gc_handle;
>>>>>> +
>>>>>> +       if (!gc->dev)
>>>>>> +               return false;
>>>>>> +
>>>>>> +       gc_handle = gc->dev->acpi_handle;
>>>>>> +       if (!gc_handle)
>>>>>> +               return false;
>>>>>
>>>>>
>>>>>
>>>>> This test is redundant with the next one... unless 'handle' is also
>>>>> NULL
>>>>> :-)
>>>>>
>>>>> Is it at all possible for multiple gpiochips to be used for a single
>>>>> ACPI gpio controller node? Such as if the gpio controller has multiple
>>>>> banks that should be controlled separately? If so then this won't be
>>>>> sufficient. I've got the same issue with DT support where the find
>>>>> function needs to also check if the pin is provided by that specific
>>>>> gpiochip.
>>>>
>>>>
>>>>
>>>> AFAIK no but I'll let Mathias to answer that as he knows this better.
>>>
>>>
>>>
>>> I'm interpreting it the same way as Mika, max one actual controller per
>>> ACPI
>>> device node
>>>
>>> The path (called ResourceSource in ACPI5 specs) in GpioIO/GpioInt
>>> resources
>>> is a "string which uniquely identifies the GPIO controller referred to by
>>> this descriptor."  The pin number is zero based controller relative.
>>>
>>> The  ACPI device controller node includes all other resources needed by
>>> the
>>> controller driver (ioport/mem base, range, interrupt, and Hardware ID
>>> used
>>> to pair with a driver)
>>>
>>> Checked a board with two identical gpio controllers on it and it had two
>>> separate ACPI device node entries. (with only different io address base
>>> and
>>> interrupt resources)
>>
>>
>> That's not really the situation that I'm thinking about. What I mean
>> is for a gpio controller that is more convenient for Linux to support
>> using multiple gpiochips (Linux internal detail), even though there it
>> is described with a single ACPI node.
>>
>
> Ok, now I get it.
>
> Yes, in case a driver uses several gpiochips internally for different banks
> of a controller then all would have the same acpi_handle.
> acpi_get_gpio() would use the gpiobase of the first gpiochip that matches
> the handle, even if it's the wrong one.
>
> I guess It's possible to write a driver like that.
> The only acpi enumerated driver with the acpi_handle set (soon coming to
> upstream) is not done like that.
>
> Do you think this is a case that should be solved now?  or just expect acpi
> gpio device driver to not use several gpiochips in one driver?

Look at what the DT code does. It is actually pretty easy to solve. I
would do it now, but I won't block the changes if you do not.

g.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-09 15:45                       ` Grant Likely
@ 2012-11-09 16:35                         ` Bjorn Helgaas
  2012-11-09 16:43                           ` Grant Likely
  0 siblings, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-09 16:35 UTC (permalink / raw)
  To: Grant Likely
  Cc: Mika Westerberg, Rafael J. Wysocki, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
>>
>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
>> <mika.westerberg@linux.intel.com> wrote:
>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>>>> Struct device_driver is a generic structure, so it seems strange to
>>>> have to include non-generic things like of_device_id and now
>>>> acpi_match_table there.
>>>
>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
>>> describe the configuration of a machine.
>>
>> What I meant by "generic" was "useful across all architectures."  The
>> new acpi_match_table and acpi_handle fields [1] are not generic in
>> that sense because they're present on all architectures but used only
>> on x86 and ia64.  The existing of_match_table and of_node are
>> similarly unused on many architectures.  This doesn't seem like a
>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
>> etc.?
>>
>> [1] https://patchwork.kernel.org/patch/1677221/
>
> Ultimately yes, I think that is what we want to do,

Just to be clear, you think we *should* add things like pnpbios_node,
pdc_hpa, etc., to struct device, one field for every scheme of telling
the OS about non-enumerable devices, where only one of the N fields is
used on any given machine?  That seems surprising to me, but maybe I
just need to be educated :)

> but there is first
> the non-trivial problem to solve of figuring out how ACPI/DT/whatever
> data maps into what the driver expects. For example, say a device uses
> two GPIOs (A & B) and we have a generic get_gpio(int index) function
> that works for both ACPI and DT. But what if the ACPI binding has the
> gpios in the order A,B and DT orders them B,A? I do want to coordinate
> between the DT and ACPI camps to avoid those situations as much as
> possible, but they will happen. When they do the driver will still
> need firmware specific data. It doesn't make any sense to put that
> stuff outside the driver because only that specific driver needs the
> extra information.

Sure.  This seems like just a special case of "drivers need a way to
access the underlying ACPI/DT/whatever-specific functionality," e.g.,

    gpio = get_gpio(dev, dev_is_acpi(dev) ? 1 : 0);

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-09 16:35                         ` Bjorn Helgaas
@ 2012-11-09 16:43                           ` Grant Likely
  2012-11-09 16:48                             ` Mark Brown
  2012-11-09 16:53                             ` Bjorn Helgaas
  0 siblings, 2 replies; 127+ messages in thread
From: Grant Likely @ 2012-11-09 16:43 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Mika Westerberg, Rafael J. Wysocki, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Fri, Nov 9, 2012 at 4:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
>>>
>>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
>>> <mika.westerberg@linux.intel.com> wrote:
>>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>>>>> Struct device_driver is a generic structure, so it seems strange to
>>>>> have to include non-generic things like of_device_id and now
>>>>> acpi_match_table there.
>>>>
>>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
>>>> describe the configuration of a machine.
>>>
>>> What I meant by "generic" was "useful across all architectures."  The
>>> new acpi_match_table and acpi_handle fields [1] are not generic in
>>> that sense because they're present on all architectures but used only
>>> on x86 and ia64.  The existing of_match_table and of_node are
>>> similarly unused on many architectures.  This doesn't seem like a
>>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
>>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
>>> etc.?
>>>
>>> [1] https://patchwork.kernel.org/patch/1677221/
>>
>> Ultimately yes, I think that is what we want to do,
>
> Just to be clear, you think we *should* add things like pnpbios_node,
> pdc_hpa, etc., to struct device, one field for every scheme of telling
> the OS about non-enumerable devices, where only one of the N fields is
> used on any given machine?  That seems surprising to me, but maybe I
> just need to be educated :)

Ah, I see what you're asking.

In the short term, yes but only because we don't have any other
alternative. What I'd really rather have is a safe way to attach datum
(ie. acpi_device or device_node) to a struct device and get it back
later in a type safe way. It would actually be useful for all manner
of things, not just ACPI/DT. I experimented a bit with trying to
implement something a year back, but never spent enough time on it.

g.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-09 16:43                           ` Grant Likely
@ 2012-11-09 16:48                             ` Mark Brown
  2012-11-09 16:53                             ` Bjorn Helgaas
  1 sibling, 0 replies; 127+ messages in thread
From: Mark Brown @ 2012-11-09 16:48 UTC (permalink / raw)
  To: Grant Likely
  Cc: Bjorn Helgaas, Mika Westerberg, Rafael J. Wysocki, linux-kernel,
	lenb, rafael.j.wysocki, linus.walleij, khali, ben-linux, w.sang,
	mathias.nyman, linux-acpi, Greg Kroah-Hartman, H. Peter Anvin,
	Tony Luck

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

On Fri, Nov 09, 2012 at 04:43:27PM +0000, Grant Likely wrote:

> In the short term, yes but only because we don't have any other
> alternative. What I'd really rather have is a safe way to attach datum
> (ie. acpi_device or device_node) to a struct device and get it back
> later in a type safe way. It would actually be useful for all manner
> of things, not just ACPI/DT. I experimented a bit with trying to
> implement something a year back, but never spent enough time on it.

devres might already do what you need here if you are OK with the
performance (and frees things too for super bonus fun points!).  That's
how dev_get_regmap() is implemented, it's not awesome in a fast path but
it seems OK otherwise.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-09 16:43                           ` Grant Likely
  2012-11-09 16:48                             ` Mark Brown
@ 2012-11-09 16:53                             ` Bjorn Helgaas
  2012-11-10 11:10                               ` Rafael J. Wysocki
  1 sibling, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-09 16:53 UTC (permalink / raw)
  To: Grant Likely
  Cc: Mika Westerberg, Rafael J. Wysocki, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Fri, Nov 9, 2012 at 9:43 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Fri, Nov 9, 2012 at 4:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>>> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>>>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
>>>>
>>>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
>>>> <mika.westerberg@linux.intel.com> wrote:
>>>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>>>>>> Struct device_driver is a generic structure, so it seems strange to
>>>>>> have to include non-generic things like of_device_id and now
>>>>>> acpi_match_table there.
>>>>>
>>>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
>>>>> describe the configuration of a machine.
>>>>
>>>> What I meant by "generic" was "useful across all architectures."  The
>>>> new acpi_match_table and acpi_handle fields [1] are not generic in
>>>> that sense because they're present on all architectures but used only
>>>> on x86 and ia64.  The existing of_match_table and of_node are
>>>> similarly unused on many architectures.  This doesn't seem like a
>>>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
>>>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
>>>> etc.?
>>>>
>>>> [1] https://patchwork.kernel.org/patch/1677221/
>>>
>>> Ultimately yes, I think that is what we want to do,
>>
>> Just to be clear, you think we *should* add things like pnpbios_node,
>> pdc_hpa, etc., to struct device, one field for every scheme of telling
>> the OS about non-enumerable devices, where only one of the N fields is
>> used on any given machine?  That seems surprising to me, but maybe I
>> just need to be educated :)
>
> Ah, I see what you're asking.
>
> In the short term, yes but only because we don't have any other
> alternative. What I'd really rather have is a safe way to attach datum
> (ie. acpi_device or device_node) to a struct device and get it back
> later in a type safe way.

Yep, *that* makes perfect sense to me.  Something along these lines, maybe:

    #define dev_is_acpi(d)    ((d)->bus == &acpi_bus_type)
    #define dev_acpi_handle(d)    (dev_is_acpi(d) ? (acpi_handle)
d->datum : NULL)

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-09 16:53                             ` Bjorn Helgaas
@ 2012-11-10 11:10                               ` Rafael J. Wysocki
  2012-11-10 11:16                                 ` Grant Likely
  2012-11-10 17:14                                 ` Bjorn Helgaas
  0 siblings, 2 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-10 11:10 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Grant Likely, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Friday, November 09, 2012 09:53:26 AM Bjorn Helgaas wrote:
> On Fri, Nov 9, 2012 at 9:43 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> > On Fri, Nov 9, 2012 at 4:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> >> On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> >>> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> >>>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
> >>>>
> >>>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
> >>>> <mika.westerberg@linux.intel.com> wrote:
> >>>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
> >>>>>> Struct device_driver is a generic structure, so it seems strange to
> >>>>>> have to include non-generic things like of_device_id and now
> >>>>>> acpi_match_table there.
> >>>>>
> >>>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
> >>>>> describe the configuration of a machine.
> >>>>
> >>>> What I meant by "generic" was "useful across all architectures."  The
> >>>> new acpi_match_table and acpi_handle fields [1] are not generic in
> >>>> that sense because they're present on all architectures but used only
> >>>> on x86 and ia64.  The existing of_match_table and of_node are
> >>>> similarly unused on many architectures.  This doesn't seem like a
> >>>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
> >>>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
> >>>> etc.?
> >>>>
> >>>> [1] https://patchwork.kernel.org/patch/1677221/
> >>>
> >>> Ultimately yes, I think that is what we want to do,
> >>
> >> Just to be clear, you think we *should* add things like pnpbios_node,
> >> pdc_hpa, etc., to struct device, one field for every scheme of telling
> >> the OS about non-enumerable devices, where only one of the N fields is
> >> used on any given machine?  That seems surprising to me, but maybe I
> >> just need to be educated :)
> >
> > Ah, I see what you're asking.
> >
> > In the short term, yes but only because we don't have any other
> > alternative. What I'd really rather have is a safe way to attach datum
> > (ie. acpi_device or device_node) to a struct device and get it back
> > later in a type safe way.
> 
> Yep, *that* makes perfect sense to me.  Something along these lines, maybe:
> 
>     #define dev_is_acpi(d)    ((d)->bus == &acpi_bus_type)

No, that's not right.  It won't work for things like SPI and I2C with a
"backing" ACPI device node anyway (and for PCI too, by the way :-)).

>     #define dev_acpi_handle(d)    (dev_is_acpi(d) ? (acpi_handle)
> d->datum : NULL)

The problem basically is how we can tell that the given struct device has
a "backing" object containing device information (e.g. resources) and what
that "backing" object is.  For device trees that would be a struct device_node
and for ACPI that would be an acpi_handle or a struct acpi_device etc.  And by
the way, they _can_ be used simultaneously, in principle.

So we need something like of_node(dev) or acpi_node(dev), but that can't be
something following two pointers or calling a function just in order to check
if the pointer _is_ _there_ in either case.

And since we added of_node to struct device at one point, it is only logical to
treat ACPI in the same way.  If we come up with a better idea _later_, then we
can convert _all_ things to this new idea, whatever it is.

Are you seriously expecting us to come up with such an idea on the fly just so
that we can use ACPI support, which already is there in the form of
archdata.acpi_handle anyway, on equal footing with Device Trees?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-10 11:10                               ` Rafael J. Wysocki
@ 2012-11-10 11:16                                 ` Grant Likely
  2012-11-10 17:14                                 ` Bjorn Helgaas
  1 sibling, 0 replies; 127+ messages in thread
From: Grant Likely @ 2012-11-10 11:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Bjorn Helgaas, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Sat, Nov 10, 2012 at 11:10 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, November 09, 2012 09:53:26 AM Bjorn Helgaas wrote:
>> On Fri, Nov 9, 2012 at 9:43 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> > On Fri, Nov 9, 2012 at 4:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> >> On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> >>> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> >>>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
>> >>>>
>> >>>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
>> >>>> <mika.westerberg@linux.intel.com> wrote:
>> >>>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>> >>>>>> Struct device_driver is a generic structure, so it seems strange to
>> >>>>>> have to include non-generic things like of_device_id and now
>> >>>>>> acpi_match_table there.
>> >>>>>
>> >>>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
>> >>>>> describe the configuration of a machine.
>> >>>>
>> >>>> What I meant by "generic" was "useful across all architectures."  The
>> >>>> new acpi_match_table and acpi_handle fields [1] are not generic in
>> >>>> that sense because they're present on all architectures but used only
>> >>>> on x86 and ia64.  The existing of_match_table and of_node are
>> >>>> similarly unused on many architectures.  This doesn't seem like a
>> >>>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
>> >>>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
>> >>>> etc.?
>> >>>>
>> >>>> [1] https://patchwork.kernel.org/patch/1677221/
>> >>>
>> >>> Ultimately yes, I think that is what we want to do,
>> >>
>> >> Just to be clear, you think we *should* add things like pnpbios_node,
>> >> pdc_hpa, etc., to struct device, one field for every scheme of telling
>> >> the OS about non-enumerable devices, where only one of the N fields is
>> >> used on any given machine?  That seems surprising to me, but maybe I
>> >> just need to be educated :)
>> >
>> > Ah, I see what you're asking.
>> >
>> > In the short term, yes but only because we don't have any other
>> > alternative. What I'd really rather have is a safe way to attach datum
>> > (ie. acpi_device or device_node) to a struct device and get it back
>> > later in a type safe way.
>>
>> Yep, *that* makes perfect sense to me.  Something along these lines, maybe:
>>
>>     #define dev_is_acpi(d)    ((d)->bus == &acpi_bus_type)
>
> No, that's not right.  It won't work for things like SPI and I2C with a
> "backing" ACPI device node anyway (and for PCI too, by the way :-)).
>
>>     #define dev_acpi_handle(d)    (dev_is_acpi(d) ? (acpi_handle)
>> d->datum : NULL)
>
> The problem basically is how we can tell that the given struct device has
> a "backing" object containing device information (e.g. resources) and what
> that "backing" object is.  For device trees that would be a struct device_node
> and for ACPI that would be an acpi_handle or a struct acpi_device etc.  And by
> the way, they _can_ be used simultaneously, in principle.
>
> So we need something like of_node(dev) or acpi_node(dev), but that can't be
> something following two pointers or calling a function just in order to check
> if the pointer _is_ _there_ in either case.
>
> And since we added of_node to struct device at one point, it is only logical to
> treat ACPI in the same way.  If we come up with a better idea _later_, then we
> can convert _all_ things to this new idea, whatever it is.
>
> Are you seriously expecting us to come up with such an idea on the fly just so
> that we can use ACPI support, which already is there in the form of
> archdata.acpi_handle anyway, on equal footing with Device Trees?

I'm certainly not. I agree with adding it to struct device now and
replace it later if someone designs something better.

I also agree with using a dev_acpi_node() macro as you described
above. I went the opposite way with device tree, and I absolutely
regret it.

g.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-10 11:10                               ` Rafael J. Wysocki
  2012-11-10 11:16                                 ` Grant Likely
@ 2012-11-10 17:14                                 ` Bjorn Helgaas
  2012-11-10 19:40                                   ` Rafael J. Wysocki
  1 sibling, 1 reply; 127+ messages in thread
From: Bjorn Helgaas @ 2012-11-10 17:14 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Grant Likely, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Sat, Nov 10, 2012 at 4:10 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> On Friday, November 09, 2012 09:53:26 AM Bjorn Helgaas wrote:
>> On Fri, Nov 9, 2012 at 9:43 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> > On Fri, Nov 9, 2012 at 4:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> >> On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> >>> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> >>>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
>> >>>>
>> >>>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
>> >>>> <mika.westerberg@linux.intel.com> wrote:
>> >>>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
>> >>>>>> Struct device_driver is a generic structure, so it seems strange to
>> >>>>>> have to include non-generic things like of_device_id and now
>> >>>>>> acpi_match_table there.
>> >>>>>
>> >>>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
>> >>>>> describe the configuration of a machine.
>> >>>>
>> >>>> What I meant by "generic" was "useful across all architectures."  The
>> >>>> new acpi_match_table and acpi_handle fields [1] are not generic in
>> >>>> that sense because they're present on all architectures but used only
>> >>>> on x86 and ia64.  The existing of_match_table and of_node are
>> >>>> similarly unused on many architectures.  This doesn't seem like a
>> >>>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
>> >>>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
>> >>>> etc.?
>> >>>>
>> >>>> [1] https://patchwork.kernel.org/patch/1677221/
>> >>>
>> >>> Ultimately yes, I think that is what we want to do,
>> >>
>> >> Just to be clear, you think we *should* add things like pnpbios_node,
>> >> pdc_hpa, etc., to struct device, one field for every scheme of telling
>> >> the OS about non-enumerable devices, where only one of the N fields is
>> >> used on any given machine?  That seems surprising to me, but maybe I
>> >> just need to be educated :)
>> >
>> > Ah, I see what you're asking.
>> >
>> > In the short term, yes but only because we don't have any other
>> > alternative. What I'd really rather have is a safe way to attach datum
>> > (ie. acpi_device or device_node) to a struct device and get it back
>> > later in a type safe way.
>>
>> Yep, *that* makes perfect sense to me.  Something along these lines, maybe:
>>
>>     #define dev_is_acpi(d)    ((d)->bus == &acpi_bus_type)
>
> No, that's not right.  It won't work for things like SPI and I2C with a
> "backing" ACPI device node anyway (and for PCI too, by the way :-)).
>
>>     #define dev_acpi_handle(d)    (dev_is_acpi(d) ? (acpi_handle)
>> d->datum : NULL)
>
> The problem basically is how we can tell that the given struct device has
> a "backing" object containing device information (e.g. resources) and what
> that "backing" object is.  For device trees that would be a struct device_node
> and for ACPI that would be an acpi_handle or a struct acpi_device etc.  And by
> the way, they _can_ be used simultaneously, in principle.
>
> So we need something like of_node(dev) or acpi_node(dev), but that can't be
> something following two pointers or calling a function just in order to check
> if the pointer _is_ _there_ in either case.
>
> And since we added of_node to struct device at one point, it is only logical to
> treat ACPI in the same way.  If we come up with a better idea _later_, then we
> can convert _all_ things to this new idea, whatever it is.
>
> Are you seriously expecting us to come up with such an idea on the fly just so
> that we can use ACPI support, which already is there in the form of
> archdata.acpi_handle anyway, on equal footing with Device Trees?

Of course not.  I'm just trying to understand where we're headed.
That was not obvious from the patches I've seen so far.

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

* Re: [PATCH 2/3] spi / ACPI: add ACPI enumeration support
  2012-11-10 17:14                                 ` Bjorn Helgaas
@ 2012-11-10 19:40                                   ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-10 19:40 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Grant Likely, Mika Westerberg, linux-kernel, lenb,
	rafael.j.wysocki, broonie, linus.walleij, khali, ben-linux,
	w.sang, mathias.nyman, linux-acpi, Greg Kroah-Hartman,
	H. Peter Anvin, Tony Luck

On Saturday, November 10, 2012 10:14:47 AM Bjorn Helgaas wrote:
> On Sat, Nov 10, 2012 at 4:10 AM, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> > On Friday, November 09, 2012 09:53:26 AM Bjorn Helgaas wrote:
> >> On Fri, Nov 9, 2012 at 9:43 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> >> > On Fri, Nov 9, 2012 at 4:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> >> >> On Fri, Nov 9, 2012 at 8:45 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> >> >>> On Fri, Nov 9, 2012 at 3:11 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> >> >>>> [+cc Greg, Peter, Tony since they acked the original patch [1]]
> >> >>>>
> >> >>>> On Thu, Nov 8, 2012 at 1:04 PM, Mika Westerberg
> >> >>>> <mika.westerberg@linux.intel.com> wrote:
> >> >>>>> On Thu, Nov 08, 2012 at 12:32:25PM -0700, Bjorn Helgaas wrote:
> >> >>>>>> Struct device_driver is a generic structure, so it seems strange to
> >> >>>>>> have to include non-generic things like of_device_id and now
> >> >>>>>> acpi_match_table there.
> >> >>>>>
> >> >>>>> Yes, but in a sense the DT and ACPI are "generic". So that they are used to
> >> >>>>> describe the configuration of a machine.
> >> >>>>
> >> >>>> What I meant by "generic" was "useful across all architectures."  The
> >> >>>> new acpi_match_table and acpi_handle fields [1] are not generic in
> >> >>>> that sense because they're present on all architectures but used only
> >> >>>> on x86 and ia64.  The existing of_match_table and of_node are
> >> >>>> similarly unused on many architectures.  This doesn't seem like a
> >> >>>> scalable strategy to me.  Are we going to add a pnpbios_node for x86
> >> >>>> PNPBIOS machines without ACPI, a pdc_hpa for parisc machines with PDC,
> >> >>>> etc.?
> >> >>>>
> >> >>>> [1] https://patchwork.kernel.org/patch/1677221/
> >> >>>
> >> >>> Ultimately yes, I think that is what we want to do,
> >> >>
> >> >> Just to be clear, you think we *should* add things like pnpbios_node,
> >> >> pdc_hpa, etc., to struct device, one field for every scheme of telling
> >> >> the OS about non-enumerable devices, where only one of the N fields is
> >> >> used on any given machine?  That seems surprising to me, but maybe I
> >> >> just need to be educated :)
> >> >
> >> > Ah, I see what you're asking.
> >> >
> >> > In the short term, yes but only because we don't have any other
> >> > alternative. What I'd really rather have is a safe way to attach datum
> >> > (ie. acpi_device or device_node) to a struct device and get it back
> >> > later in a type safe way.
> >>
> >> Yep, *that* makes perfect sense to me.  Something along these lines, maybe:
> >>
> >>     #define dev_is_acpi(d)    ((d)->bus == &acpi_bus_type)
> >
> > No, that's not right.  It won't work for things like SPI and I2C with a
> > "backing" ACPI device node anyway (and for PCI too, by the way :-)).
> >
> >>     #define dev_acpi_handle(d)    (dev_is_acpi(d) ? (acpi_handle)
> >> d->datum : NULL)
> >
> > The problem basically is how we can tell that the given struct device has
> > a "backing" object containing device information (e.g. resources) and what
> > that "backing" object is.  For device trees that would be a struct device_node
> > and for ACPI that would be an acpi_handle or a struct acpi_device etc.  And by
> > the way, they _can_ be used simultaneously, in principle.
> >
> > So we need something like of_node(dev) or acpi_node(dev), but that can't be
> > something following two pointers or calling a function just in order to check
> > if the pointer _is_ _there_ in either case.
> >
> > And since we added of_node to struct device at one point, it is only logical to
> > treat ACPI in the same way.  If we come up with a better idea _later_, then we
> > can convert _all_ things to this new idea, whatever it is.
> >
> > Are you seriously expecting us to come up with such an idea on the fly just so
> > that we can use ACPI support, which already is there in the form of
> > archdata.acpi_handle anyway, on equal footing with Device Trees?
> 
> Of course not.  I'm just trying to understand where we're headed.
> That was not obvious from the patches I've seen so far.

No, it wasn't, fair enough.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 1/3] gpio / ACPI: add ACPI support
  2012-11-09 15:46             ` Grant Likely
@ 2012-11-11  9:50               ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-11  9:50 UTC (permalink / raw)
  To: Grant Likely
  Cc: Mathias Nyman, linux-kernel, lenb, rafael.j.wysocki, broonie,
	linus.walleij, khali, ben-linux, w.sang, linux-acpi

On Fri, Nov 09, 2012 at 03:46:58PM +0000, Grant Likely wrote:
> > I guess It's possible to write a driver like that.
> > The only acpi enumerated driver with the acpi_handle set (soon coming to
> > upstream) is not done like that.
> >
> > Do you think this is a case that should be solved now?  or just expect acpi
> > gpio device driver to not use several gpiochips in one driver?
> 
> Look at what the DT code does. It is actually pretty easy to solve. I
> would do it now, but I won't block the changes if you do not.

I think for now we just implement the single gpiochip solution and once (if
ever) there emerges need for multiple gpiochips in a single driver, we add
the support then.

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

* [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C)
  2012-11-03  7:46 [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Mika Westerberg
                   ` (3 preceding siblings ...)
  2012-11-04 18:29 ` [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Linus Walleij
@ 2012-11-12 11:51 ` Rafael J. Wysocki
  2012-11-12 12:00   ` [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
                     ` (3 more replies)
  4 siblings, 4 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-12 11:51 UTC (permalink / raw)
  To: Mika Westerberg, mathias.nyman, linux-acpi
  Cc: linux-kernel, lenb, rafael.j.wysocki, broonie, grant.likely,
	linus.walleij, khali, Bjorn Helgaas

On Saturday, November 03, 2012 09:46:30 AM Mika Westerberg wrote:
> Hi,
> 
> With ACPI 5 we can now describe how devices are connected to their bus
> using new resources: SPISerialBus and I2CSerialBus. Also it is now possible
> to add GPIO connections for the devices with the help of GpioIO and GpioInt
> resources.
> 
> This series adds support for these new resources.
> 
> The series based on the ACPI 5 enumeration support patches that are available
> on Rafael's linux-next branch:
> 
> 	git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next	
> 
> Specifically patches from this thread:
> 
> 	https://lkml.org/lkml/2012/10/31/154
> 
> Since these patches depend on the above patches on Rafael's linux-next branch
> I suggest that these be merged via that branch, if there are no objections.
> 
> The series follows the Device Tree way so that it would be easy to add ACPI
> support for the existing SPI and I2C drivers if one is familiar how the
> corresponding DT support is done.
> 
> For GPIO we introduce a function that maps between ACPI GPIO numbers and Linux
> ones - acpi_get_gpio().
> 
> SPI slave devices gets enumerated automatically if the master device has
> master->dev.acpi_handle set (this is analogous to master->dev.of_mode). The
> platform bus code in Rafael's branch assigns the ACPI handle to the master
> device.
> 
> I2C slave devices can be enumerated by calling acpi_i2c_register_devices() in
> the adapter driver.

Following the previous discussion, the patches below move some ACPI resources
parsing code from drivers/pnp/pnpacpi/rsparser.c to a new file
drivers/acpi/resource.c and reformat it so that it can be used by other
subsystems (patch [1/3]), convert the new ACPI platform devices creation
code to use the routines in drivers/acpi/resource.c instead of doing its
own resource parsing (patch [2/3]) and make the ACPI namespace scan attach
a list of _CRS resources to each struct acpi_device it creates, where
applicable (patch [3/3] - the ACPI platform device code is converted to use
that instead of executing _CRS by itself via acpi_walk_resources()).

The patchset is on top of the current linux-pm.git/linux-next branch and
has been tested somewhat.  Please let me know if you find any problems in it.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core
  2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
@ 2012-11-12 12:00   ` Rafael J. Wysocki
  2012-11-12 13:27     ` Mika Westerberg
  2012-11-12 12:01   ` [PATCH 2/3] ACPI / platform: Use common ACPI device resource parsing routines Rafael J. Wysocki
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-12 12:00 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Move some code used for parsing ACPI device resources from the PNP
subsystem to the ACPI core, so that other bus types (platform, SPI,
I2C) can use the same routines for parsing resources in a consistent
way, without duplicating code.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/Makefile          |    1 
 drivers/acpi/resource.c        |  393 +++++++++++++++++++++++++++++++++++++++++
 drivers/pnp/base.h             |    2 
 drivers/pnp/pnpacpi/rsparser.c |  296 +++---------------------------
 drivers/pnp/resource.c         |   16 +
 include/linux/acpi.h           |   10 +
 6 files changed, 454 insertions(+), 264 deletions(-)

Index: linux/drivers/acpi/resource.c
===================================================================
--- /dev/null
+++ linux/drivers/acpi/resource.c
@@ -0,0 +1,393 @@
+/*
+ * drivers/acpi/resource.c - ACPI device resources interpretation.
+ *
+ * Copyright (C) 2012, Intel Corp.
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_X86
+#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+#else
+#define valid_IRQ(i) (true)
+#endif
+
+static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect,
+						bool window)
+{
+	unsigned long flags = IORESOURCE_MEM;
+
+	if (len == 0)
+		flags |= IORESOURCE_DISABLED;
+
+	if (write_protect == ACPI_READ_WRITE_MEMORY)
+		flags |= IORESOURCE_MEM_WRITEABLE;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
+				     u8 write_protect)
+{
+	res->start = start;
+	res->end = start + len - 1;
+	res->flags = acpi_dev_memresource_flags(len, write_protect, false);
+}
+
+/**
+ * acpi_dev_resource_memory - Extract ACPI memory resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents a memory resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_memory24 *memory24;
+	struct acpi_resource_memory32 *memory32;
+	struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+		memory24 = &ares->data.memory24;
+		acpi_dev_get_memresource(res, memory24->minimum,
+					 memory24->address_length,
+					 memory24->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+		memory32 = &ares->data.memory32;
+		acpi_dev_get_memresource(res, memory32->minimum,
+					 memory32->address_length,
+					 memory32->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		fixed_memory32 = &ares->data.fixed_memory32;
+		acpi_dev_get_memresource(res, fixed_memory32->address,
+					 fixed_memory32->address_length,
+					 fixed_memory32->write_protect);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
+
+static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode,
+					      bool window)
+{
+	int flags = IORESOURCE_IO;
+
+	if (io_decode == ACPI_DECODE_16)
+		flags |= IORESOURCE_IO_16BIT_ADDR;
+
+	if (start > end || end >= 0x10003)
+		flags |= IORESOURCE_DISABLED;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
+				    u8 io_decode)
+{
+	u64 end = start + len - 1;
+
+	res->start = start;
+	res->end = end;
+	res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false);
+}
+
+/**
+ * acpi_dev_resource_io - Extract ACPI I/O resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an I/O resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_io *io;
+	struct acpi_resource_fixed_io *fixed_io;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IO:
+		io = &ares->data.io;
+		acpi_dev_get_ioresource(res, io->minimum,
+					io->address_length,
+					io->io_decode);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+		fixed_io = &ares->data.fixed_io;
+		acpi_dev_get_ioresource(res, fixed_io->address,
+					fixed_io->address_length,
+					ACPI_DECODE_10);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
+
+/**
+ * acpi_dev_resource_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an address space resource
+ * and if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res)
+{
+	acpi_status status;
+	struct acpi_resource_address64 addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+		break;
+	default:
+		return false;
+	}
+
+	status = acpi_resource_to_address64(ares, &addr);
+	if (ACPI_FAILURE(status))
+		return true;
+
+	res->start = addr.minimum;
+	res->end = addr.maximum;
+	window = addr.producer_consumer == ACPI_PRODUCER;
+
+	switch(addr.resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = addr.maximum - addr.minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+						addr.info.mem.write_protect,
+						window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = addr.granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(addr.minimum,
+						       addr.maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
+
+/**
+ * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an extended address space
+ * resource and if that's the case, use the information in it to populate the
+ * generic resource object pointed to by @res.
+ */
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res)
+{
+	struct acpi_resource_extended_address64 *ext_addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
+		return false;
+
+	ext_addr = &ares->data.ext_address64;
+
+	res->start = ext_addr->minimum;
+	res->end = ext_addr->maximum;
+	window = ext_addr->producer_consumer == ACPI_PRODUCER;
+
+	switch(ext_addr->resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = ext_addr->maximum - ext_addr->minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+					ext_addr->info.mem.write_protect,
+					window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = ext_addr->granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(ext_addr->minimum,
+						       ext_addr->maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
+
+/**
+ * acpi_dev_irq_flags - Determine IRQ resource flags.
+ * @triggering: Triggering type as provided by ACPI.
+ * @polarity: Interrupt polarity as provided by ACPI.
+ * @shareable: Whether or not the interrupt is shareable.
+ */
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
+{
+	unsigned long flags = IORESOURCE_IRQ;
+
+	if (triggering == ACPI_LEVEL_SENSITIVE)
+		flags = polarity == ACPI_ACTIVE_LOW ?
+			IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
+	else
+		flags = polarity == ACPI_ACTIVE_LOW ?
+			IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
+
+	if (shareable == ACPI_SHARED)
+		flags |= IORESOURCE_IRQ_SHAREABLE;
+
+	return flags;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
+
+static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
+{
+	res->start = gsi;
+	res->end = gsi;
+	res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED;
+}
+
+static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+				     u8 triggering, u8 polarity, u8 shareable)
+{
+	int irq, p, t;
+
+	if (!valid_IRQ(gsi)) {
+		acpi_dev_irqresource_disabled(res, gsi);
+		return;
+	}
+
+	/*
+	 * In IO-APIC mode, use overrided attribute. Two reasons:
+	 * 1. BIOS bug in DSDT
+	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
+	 */
+	if (!acpi_get_override_irq(gsi, &t, &p)) {
+		u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+		u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+		if (triggering != trig || polarity != pol) {
+			pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
+				   t ? "edge" : "level", p ? "low" : "high");
+			triggering = trig;
+			polarity = pol;
+		}
+	}
+
+	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
+	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+	if (irq >= 0) {
+		res->start = irq;
+		res->end = irq;
+	} else {
+		acpi_dev_irqresource_disabled(res, gsi);
+	}
+}
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)).  If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly.  If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res)
+{
+	struct acpi_resource_irq *irq;
+	struct acpi_resource_extended_irq *ext_irq;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
+		/*
+		 * Per spec, only one interrupt per descriptor is allowed in
+		 * _CRS, but some firmware violates this, so parse them all.
+		 */
+		irq = &ares->data.irq;
+		if (index >= irq->interrupt_count) {
+			acpi_dev_irqresource_disabled(res, 0);
+			return false;
+		}
+		acpi_dev_get_irqresource(res, irq->interrupts[index],
+					 irq->triggering, irq->polarity,
+					 irq->sharable);
+		break;
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		ext_irq = &ares->data.extended_irq;
+		if (index >= ext_irq->interrupt_count) {
+			acpi_dev_irqresource_disabled(res, 0);
+			return false;
+		}
+		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+					 ext_irq->triggering, ext_irq->polarity,
+					 ext_irq->sharable);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
Index: linux/drivers/acpi/Makefile
===================================================================
--- linux.orig/drivers/acpi/Makefile
+++ linux/drivers/acpi/Makefile
@@ -33,6 +33,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 #
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
+acpi-y				+= resource.o
 acpi-y				+= processor_core.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
Index: linux/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- linux.orig/drivers/pnp/pnpacpi/rsparser.c
+++ linux/drivers/pnp/pnpacpi/rsparser.c
@@ -28,37 +28,6 @@
 #include "../base.h"
 #include "pnpacpi.h"
 
-#ifdef CONFIG_IA64
-#define valid_IRQ(i) (1)
-#else
-#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
-#endif
-
-/*
- * Allocated Resources
- */
-static int irq_flags(int triggering, int polarity, int shareable)
-{
-	int flags;
-
-	if (triggering == ACPI_LEVEL_SENSITIVE) {
-		if (polarity == ACPI_ACTIVE_LOW)
-			flags = IORESOURCE_IRQ_LOWLEVEL;
-		else
-			flags = IORESOURCE_IRQ_HIGHLEVEL;
-	} else {
-		if (polarity == ACPI_ACTIVE_LOW)
-			flags = IORESOURCE_IRQ_LOWEDGE;
-		else
-			flags = IORESOURCE_IRQ_HIGHEDGE;
-	}
-
-	if (shareable == ACPI_SHARED)
-		flags |= IORESOURCE_IRQ_SHAREABLE;
-
-	return flags;
-}
-
 static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
 			     int *polarity, int *shareable)
 {
@@ -94,45 +63,6 @@ static void decode_irq_flags(struct pnp_
 		*shareable = ACPI_EXCLUSIVE;
 }
 
-static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
-						u32 gsi, int triggering,
-						int polarity, int shareable)
-{
-	int irq, flags;
-	int p, t;
-
-	if (!valid_IRQ(gsi)) {
-		pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
-		return;
-	}
-
-	/*
-	 * in IO-APIC mode, use overrided attribute. Two reasons:
-	 * 1. BIOS bug in DSDT
-	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
-	 */
-	if (!acpi_get_override_irq(gsi, &t, &p)) {
-		t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
-		p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
-
-		if (triggering != t || polarity != p) {
-			dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
-				gsi, t ? "edge":"level", p ? "low":"high");
-			triggering = t;
-			polarity = p;
-		}
-	}
-
-	flags = irq_flags(triggering, polarity, shareable);
-	irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
-	if (irq >= 0)
-		pcibios_penalize_isa_irq(irq, 1);
-	else
-		flags |= IORESOURCE_DISABLED;
-
-	pnp_add_irq_resource(dev, irq, flags);
-}
-
 static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
 		     int transfer)
 {
@@ -177,21 +107,16 @@ static int dma_flags(struct pnp_dev *dev
 	return flags;
 }
 
-static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
-					       u64 len, int io_decode,
-					       int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
+/*
+ * Allocated Resources
+ */
 
-	if (io_decode == ACPI_DECODE_16)
-		flags |= IORESOURCE_IO_16BIT_ADDR;
-	if (len == 0 || end >= 0x10003)
-		flags |= IORESOURCE_DISABLED;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
+static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r)
+{
+	if (!(r->flags & IORESOURCE_DISABLED))
+		pcibios_penalize_isa_irq(r->start, 1);
 
-	pnp_add_io_resource(dev, start, end, flags);
+	pnp_add_resource(dev, r);
 }
 
 /*
@@ -249,130 +174,49 @@ static void pnpacpi_parse_allocated_vend
 	}
 }
 
-static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
-						u64 start, u64 len,
-						int write_protect, int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
-
-	if (len == 0)
-		flags |= IORESOURCE_DISABLED;
-	if (write_protect == ACPI_READ_WRITE_MEMORY)
-		flags |= IORESOURCE_MEM_WRITEABLE;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
-
-	pnp_add_mem_resource(dev, start, end, flags);
-}
-
-static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
-						u64 start, u64 len)
-{
-	u64 end = start + len - 1;
-
-	pnp_add_bus_resource(dev, start, end);
-}
-
-static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
-						  struct acpi_resource *res)
-{
-	struct acpi_resource_address64 addr, *p = &addr;
-	acpi_status status;
-	int window;
-	u64 len;
-
-	status = acpi_resource_to_address64(res, p);
-	if (!ACPI_SUCCESS(status)) {
-		dev_warn(&dev->dev, "failed to convert resource type %d\n",
-			 res->type);
-		return;
-	}
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
-static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
-						      struct acpi_resource *res)
-{
-	struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
-	int window;
-	u64 len;
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
 					      void *data)
 {
 	struct pnp_dev *dev = data;
-	struct acpi_resource_irq *irq;
 	struct acpi_resource_dma *dma;
-	struct acpi_resource_io *io;
-	struct acpi_resource_fixed_io *fixed_io;
 	struct acpi_resource_vendor_typed *vendor_typed;
-	struct acpi_resource_memory24 *memory24;
-	struct acpi_resource_memory32 *memory32;
-	struct acpi_resource_fixed_memory32 *fixed_memory32;
-	struct acpi_resource_extended_irq *extended_irq;
+	struct resource r;
 	int i, flags;
 
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		/*
-		 * Per spec, only one interrupt per descriptor is allowed in
-		 * _CRS, but some firmware violates this, so parse them all.
-		 */
-		irq = &res->data.irq;
-		if (irq->interrupt_count == 0)
-			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
-		else {
-			for (i = 0; i < irq->interrupt_count; i++) {
-				pnpacpi_parse_allocated_irqresource(dev,
-					irq->interrupts[i],
-					irq->triggering,
-					irq->polarity,
-				    irq->sharable);
-			}
+	if (acpi_dev_resource_memory(res, &r)
+	    || acpi_dev_resource_io(res, &r)
+	    || acpi_dev_resource_address_space(res, &r)
+	    || acpi_dev_resource_ext_address_space(res, &r)) {
+		pnp_add_resource(dev, &r);
+		return AE_OK;
+	}
+
+	r.flags = 0;
+	if (acpi_dev_resource_interrupt(res, 0, &r)) {
+		pnpacpi_add_irqresource(dev, &r);
+		for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++)
+			pnpacpi_add_irqresource(dev, &r);
 
+		if (i > 1) {
 			/*
 			 * The IRQ encoder puts a single interrupt in each
 			 * descriptor, so if a _CRS descriptor has more than
 			 * one interrupt, we won't be able to re-encode it.
 			 */
-			if (pnp_can_write(dev) && irq->interrupt_count > 1) {
+			if (pnp_can_write(dev)) {
 				dev_warn(&dev->dev, "multiple interrupts in "
 					 "_CRS descriptor; configuration can't "
 					 "be changed\n");
 				dev->capabilities &= ~PNP_WRITE;
 			}
 		}
-		break;
+		return AE_OK;
+	} else if (r.flags & IORESOURCE_DISABLED) {
+		pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
+		return AE_OK;
+	}
 
+	switch (res->type) {
 	case ACPI_RESOURCE_TYPE_DMA:
 		dma = &res->data.dma;
 		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
@@ -383,26 +227,10 @@ static acpi_status pnpacpi_allocated_res
 		pnp_add_dma_resource(dev, dma->channels[0], flags);
 		break;
 
-	case ACPI_RESOURCE_TYPE_IO:
-		io = &res->data.io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			io->minimum,
-			io->address_length,
-			io->io_decode, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 		break;
 
-	case ACPI_RESOURCE_TYPE_FIXED_IO:
-		fixed_io = &res->data.fixed_io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			fixed_io->address,
-			fixed_io->address_length,
-			ACPI_DECODE_10, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_VENDOR:
 		vendor_typed = &res->data.vendor_typed;
 		pnpacpi_parse_allocated_vendor(dev, vendor_typed);
@@ -411,66 +239,6 @@ static acpi_status pnpacpi_allocated_res
 	case ACPI_RESOURCE_TYPE_END_TAG:
 		break;
 
-	case ACPI_RESOURCE_TYPE_MEMORY24:
-		memory24 = &res->data.memory24;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory24->minimum,
-			memory24->address_length,
-			memory24->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_MEMORY32:
-		memory32 = &res->data.memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory32->minimum,
-			memory32->address_length,
-			memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		fixed_memory32 = &res->data.fixed_memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			fixed_memory32->address,
-			fixed_memory32->address_length,
-			fixed_memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS16:
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-	case ACPI_RESOURCE_TYPE_ADDRESS64:
-		pnpacpi_parse_allocated_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
-		pnpacpi_parse_allocated_ext_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		extended_irq = &res->data.extended_irq;
-
-		if (extended_irq->interrupt_count == 0)
-			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
-		else {
-			for (i = 0; i < extended_irq->interrupt_count; i++) {
-				pnpacpi_parse_allocated_irqresource(dev,
-					extended_irq->interrupts[i],
-					extended_irq->triggering,
-					extended_irq->polarity,
-					extended_irq->sharable);
-			}
-
-			/*
-			 * The IRQ encoder puts a single interrupt in each
-			 * descriptor, so if a _CRS descriptor has more than
-			 * one interrupt, we won't be able to re-encode it.
-			 */
-			if (pnp_can_write(dev) &&
-			    extended_irq->interrupt_count > 1) {
-				dev_warn(&dev->dev, "multiple interrupts in "
-					 "_CRS descriptor; configuration can't "
-					 "be changed\n");
-				dev->capabilities &= ~PNP_WRITE;
-			}
-		}
-		break;
-
 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 		break;
 
@@ -531,7 +299,7 @@ static __init void pnpacpi_parse_irq_opt
 		if (p->interrupts[i])
 			__set_bit(p->interrupts[i], map.bits);
 
-	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
@@ -555,7 +323,7 @@ static __init void pnpacpi_parse_ext_irq
 		}
 	}
 
-	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
Index: linux/drivers/pnp/base.h
===================================================================
--- linux.orig/drivers/pnp/base.h
+++ linux/drivers/pnp/base.h
@@ -159,6 +159,8 @@ struct pnp_resource {
 
 void pnp_free_resource(struct pnp_resource *pnp_res);
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res);
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags);
 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
Index: linux/drivers/pnp/resource.c
===================================================================
--- linux.orig/drivers/pnp/resource.c
+++ linux/drivers/pnp/resource.c
@@ -503,6 +503,22 @@ static struct pnp_resource *pnp_new_reso
 	return pnp_res;
 }
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res)
+{
+	struct pnp_resource *pnp_res;
+
+	pnp_res = pnp_new_resource(dev);
+	if (!pnp_res) {
+		dev_err(&dev->dev, "can't add resource %pR\n", res);
+		return NULL;
+	}
+
+	pnp_res->res = *res;
+	dev_dbg(&dev->dev, "%pR\n", res);
+	return pnp_res;
+}
+
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags)
 {
Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -251,6 +251,16 @@ extern int pnpacpi_disabled;
 
 #define PXM_INVAL	(-1)
 
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res);
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res);
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res);
+
 int acpi_check_resource_conflict(const struct resource *res);
 
 int acpi_check_region(resource_size_t start, resource_size_t n,

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

* [PATCH 2/3] ACPI / platform: Use common ACPI device resource parsing routines
  2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
  2012-11-12 12:00   ` [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
@ 2012-11-12 12:01   ` Rafael J. Wysocki
  2012-11-12 12:02   ` [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects Rafael J. Wysocki
  2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
  3 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-12 12:01 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Use common routines in drivers/acpi/resource.c to parse ACPI device
resources while creating platform device objects.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_platform.c |   89 +++++++++----------------------------------
 1 file changed, 20 insertions(+), 69 deletions(-)

Index: linux/drivers/acpi/acpi_platform.c
===================================================================
--- linux.orig/drivers/acpi/acpi_platform.c
+++ linux/drivers/acpi/acpi_platform.c
@@ -29,21 +29,20 @@ static acpi_status acpi_platform_count_r
 						 void *data)
 {
 	struct acpi_resource_extended_irq *acpi_xirq;
+	struct acpi_resource_irq *acpi_irq;
 	struct resource_info *ri = data;
 
 	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 	case ACPI_RESOURCE_TYPE_IRQ:
-		ri->n++;
+		acpi_irq = &res->data.irq;
+		ri->n += acpi_irq->interrupt_count;
 		break;
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		acpi_xirq = &res->data.extended_irq;
 		ri->n += acpi_xirq->interrupt_count;
 		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		if (res->data.address32.resource_type == ACPI_IO_RANGE)
-			ri->n++;
-		break;
+	default:
+		ri->n++;
 	}
 
 	return AE_OK;
@@ -52,71 +51,26 @@ static acpi_status acpi_platform_count_r
 static acpi_status acpi_platform_add_resources(struct acpi_resource *res,
 					       void *data)
 {
-	struct acpi_resource_fixed_memory32 *acpi_mem;
-	struct acpi_resource_address32 *acpi_add32;
-	struct acpi_resource_extended_irq *acpi_xirq;
-	struct acpi_resource_irq *acpi_irq;
 	struct resource_info *ri = data;
 	struct resource *r;
-	int irq, i;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		acpi_mem = &res->data.fixed_memory32;
-		r = &ri->res[ri->cur++];
-
-		r->start = acpi_mem->address;
-		r->end = r->start + acpi_mem->address_length - 1;
-		r->flags = IORESOURCE_MEM;
-
-		dev_dbg(ri->dev, "Memory32Fixed %pR\n", r);
-		break;
-
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		acpi_add32 = &res->data.address32;
 
-		if (acpi_add32->resource_type == ACPI_IO_RANGE) {
-			r = &ri->res[ri->cur++];
-			r->start = acpi_add32->minimum;
-			r->end = r->start + acpi_add32->address_length - 1;
-			r->flags = IORESOURCE_IO;
-			dev_dbg(ri->dev, "Address32 %pR\n", r);
-		}
-		break;
-
-	case ACPI_RESOURCE_TYPE_IRQ:
-		acpi_irq = &res->data.irq;
-		r = &ri->res[ri->cur++];
-
-		irq = acpi_register_gsi(ri->dev,
-					acpi_irq->interrupts[0],
-					acpi_irq->triggering,
-					acpi_irq->polarity);
-
-		r->start = r->end = irq;
-		r->flags = IORESOURCE_IRQ;
-
-		dev_dbg(ri->dev, "IRQ %pR\n", r);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		acpi_xirq = &res->data.extended_irq;
-
-		for (i = 0; i < acpi_xirq->interrupt_count; i++, ri->cur++) {
-			r = &ri->res[ri->cur];
-			irq = acpi_register_gsi(ri->dev,
-						acpi_xirq->interrupts[i],
-						acpi_xirq->triggering,
-						acpi_xirq->polarity);
+	r = ri->res + ri->cur;
+	if (acpi_dev_resource_memory(res, r)
+	    || acpi_dev_resource_io(res, r)
+	    || acpi_dev_resource_address_space(res, r)
+	    || acpi_dev_resource_ext_address_space(res, r)) {
+		ri->cur++;
+		return AE_OK;
+	}
+	if (acpi_dev_resource_interrupt(res, 0, r)) {
+		int i;
 
-			r->start = r->end = irq;
-			r->flags = IORESOURCE_IRQ;
+		r++;
+		for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
+			r++;
 
-			dev_dbg(ri->dev, "Interrupt %pR\n", r);
-		}
-		break;
+		ri->cur += i;
 	}
-
 	return AE_OK;
 }
 
@@ -165,9 +119,6 @@ struct platform_device *acpi_create_plat
 		goto out;
 	}
 
-	if (WARN_ON(ri.n != ri.cur))
-		goto out;
-
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
 	 * attached to it, that physical device should be the parent of the
@@ -189,7 +140,7 @@ struct platform_device *acpi_create_plat
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
 	pdev = platform_device_register_resndata(parent, dev_name(&adev->dev),
-						 -1, ri.res, ri.n, NULL, 0);
+						 -1, ri.res, ri.cur, NULL, 0);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));


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

* [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
  2012-11-12 12:00   ` [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
  2012-11-12 12:01   ` [PATCH 2/3] ACPI / platform: Use common ACPI device resource parsing routines Rafael J. Wysocki
@ 2012-11-12 12:02   ` Rafael J. Wysocki
  2012-11-12 14:46     ` Mika Westerberg
  2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
  3 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-12 12:02 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Currently, whoever wants to use ACPI device resources has to call
acpi_walk_resources() to browse the buffer returned by the _CRS
method for the given device and create filters passed to that
routine to apply to the individual resource items.  This generally
is cumbersome, time-consuming and inefficient.  Moreover, it may
be problematic if resource conflicts need to be resolved, because
the different users of _CRS will need to do that in a consistent
way.

For this reason, add code to the ACPI core to execute _CRS once,
when the struct acpi_device object is created for a given device
node, and attach a list of ACPI resources returned by _CRS to that
object for future processing.

Convert the ACPI code that creates platform device objects to using
the new resources list instead of executing acpi_walk_resources() by
itself, which makes it much more straightforward and easier to
follow.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_platform.c |   90 ++++++++++++-------------------------------
 drivers/acpi/resource.c      |   12 +++++
 drivers/acpi/scan.c          |   56 ++++++++++++++++++++++++++
 include/acpi/acpi_bus.h      |    6 ++
 include/linux/acpi.h         |    1 
 5 files changed, 102 insertions(+), 63 deletions(-)

Index: linux/include/acpi/acpi_bus.h
===================================================================
--- linux.orig/include/acpi/acpi_bus.h
+++ linux/include/acpi/acpi_bus.h
@@ -259,6 +259,11 @@ struct acpi_device_physical_node {
 	struct device *dev;
 };
 
+struct acpi_resource_list_entry {
+	struct list_head node;
+	struct acpi_resource resource;
+};
+
 /* set maximum of physical nodes to 32 for expansibility */
 #define ACPI_MAX_PHYSICAL_NODE	32
 
@@ -268,6 +273,7 @@ struct acpi_device {
 	acpi_handle handle;		/* no handle for fixed hardware */
 	struct acpi_device *parent;
 	struct list_head children;
+	struct list_head resources;	/* Device resources. */
 	struct list_head node;
 	struct list_head wakeup_list;
 	struct acpi_device_status status;
Index: linux/drivers/acpi/scan.c
===================================================================
--- linux.orig/drivers/acpi/scan.c
+++ linux/drivers/acpi/scan.c
@@ -382,6 +382,52 @@ static void acpi_device_remove_files(str
 			ACPI Bus operations
    -------------------------------------------------------------------------- */
 
+static void acpi_bus_drop_resources(struct acpi_device *adev)
+{
+	struct acpi_resource_list_entry *entry, *s;
+
+	list_for_each_entry_safe(entry, s, &adev->resources, node) {
+		list_del(&entry->node);
+		kfree(entry);
+	}
+}
+
+static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
+					 void *context)
+{
+	struct list_head *list = context;
+	struct acpi_resource_list_entry *entry;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return AE_NO_MEMORY;
+
+	entry->resource = *res;
+	INIT_LIST_HEAD(&entry->node);
+	list_add_tail(&entry->node, list);
+	return AE_OK;
+}
+
+static int acpi_bus_get_resources(struct acpi_device *adev)
+{
+	acpi_status status;
+	acpi_handle not_used;
+	int ret = 0;
+
+	status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, &not_used);
+	if (ACPI_FAILURE(status))
+		return 0;
+
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_bus_add_resource, &adev->resources);
+	if (ACPI_FAILURE(status)) {
+		acpi_bus_drop_resources(adev);
+		ret = status == AE_NO_MEMORY ? -ENOMEM : -EIO;
+	}
+
+	return ret;
+}
+
 static const struct acpi_device_id *__acpi_match_device(
 	struct acpi_device *device, const struct acpi_device_id *ids)
 {
@@ -681,6 +727,7 @@ static void acpi_device_unregister(struc
 
 	acpi_device_remove_files(device);
 	device_unregister(&device->dev);
+	acpi_bus_drop_resources(device);
 }
 
 /* --------------------------------------------------------------------------
@@ -1412,6 +1459,15 @@ static int acpi_add_single_object(struct
 	acpi_device_set_id(device);
 
 	/*
+	 * Device Resources
+	 * ----------------
+	 */
+	INIT_LIST_HEAD(&device->resources);
+	result = acpi_bus_get_resources(device);
+	if (result)
+		goto end;
+
+	/*
 	 * Power Management
 	 * ----------------
 	 */
Index: linux/drivers/acpi/resource.c
===================================================================
--- linux.orig/drivers/acpi/resource.c
+++ linux/drivers/acpi/resource.c
@@ -391,3 +391,15 @@ bool acpi_dev_resource_interrupt(struct
 	return true;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
+
+unsigned int acpi_dev_resource_count(struct acpi_resource *ares)
+{
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
+		return ares->data.irq.interrupt_count;
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		return ares->data.extended_irq.interrupt_count;
+	}
+	return 1;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_count);
Index: linux/drivers/acpi/acpi_platform.c
===================================================================
--- linux.orig/drivers/acpi/acpi_platform.c
+++ linux/drivers/acpi/acpi_platform.c
@@ -19,59 +19,26 @@
 
 ACPI_MODULE_NAME("platform");
 
-struct resource_info {
-	struct device *dev;
-	struct resource *res;
-	size_t n, cur;
-};
-
-static acpi_status acpi_platform_count_resources(struct acpi_resource *res,
-						 void *data)
+static unsigned int acpi_platform_add_resource(struct acpi_resource *res,
+					       struct resource *r)
 {
-	struct acpi_resource_extended_irq *acpi_xirq;
-	struct acpi_resource_irq *acpi_irq;
-	struct resource_info *ri = data;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		acpi_irq = &res->data.irq;
-		ri->n += acpi_irq->interrupt_count;
-		break;
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		acpi_xirq = &res->data.extended_irq;
-		ri->n += acpi_xirq->interrupt_count;
-		break;
-	default:
-		ri->n++;
-	}
-
-	return AE_OK;
-}
-
-static acpi_status acpi_platform_add_resources(struct acpi_resource *res,
-					       void *data)
-{
-	struct resource_info *ri = data;
-	struct resource *r;
-
-	r = ri->res + ri->cur;
 	if (acpi_dev_resource_memory(res, r)
 	    || acpi_dev_resource_io(res, r)
 	    || acpi_dev_resource_address_space(res, r)
-	    || acpi_dev_resource_ext_address_space(res, r)) {
-		ri->cur++;
-		return AE_OK;
-	}
+	    || acpi_dev_resource_ext_address_space(res, r))
+		return 1;
+
 	if (acpi_dev_resource_interrupt(res, 0, r)) {
-		int i;
+		unsigned int i;
 
 		r++;
 		for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
 			r++;
 
-		ri->cur += i;
+		return i;
 	}
-	return AE_OK;
+
+	return 0;
 }
 
 /**
@@ -89,35 +56,32 @@ struct platform_device *acpi_create_plat
 	struct platform_device *pdev = NULL;
 	struct acpi_device *acpi_parent;
 	struct device *parent = NULL;
-	struct resource_info ri;
-	acpi_status status;
+	struct acpi_resource_list_entry *entry;
+	struct resource *resources;
+	unsigned int count;
 
 	/* If the ACPI node already has a physical device attached, skip it. */
 	if (adev->physical_node_count)
 		return NULL;
 
-	memset(&ri, 0, sizeof(ri));
-	/* First, count the resources. */
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_count_resources, &ri);
-	if (ACPI_FAILURE(status) || !ri.n)
+	count = 0;
+	list_for_each_entry(entry, &adev->resources, node)
+		count += acpi_dev_resource_count(&entry->resource);
+
+	if (!count)
 		return NULL;
 
 	/* Next, allocate memory for all the resources and populate it. */
-	ri.dev = &adev->dev;
-	ri.res = kzalloc(ri.n * sizeof(struct resource), GFP_KERNEL);
-	if (!ri.res) {
-		dev_err(&adev->dev,
-			"failed to allocate memory for resources\n");
+	resources = kzalloc(count * sizeof(struct resource), GFP_KERNEL);
+	if (!resources) {
+		dev_err(&adev->dev, "No memory for resources\n");
 		return NULL;
 	}
 
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_add_resources, &ri);
-	if (ACPI_FAILURE(status)) {
-		dev_err(&adev->dev, "failed to walk resources\n");
-		goto out;
-	}
+	count = 0;
+	list_for_each_entry(entry, &adev->resources, node)
+		count += acpi_platform_add_resource(&entry->resource,
+						    resources + count);
 
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
@@ -139,8 +103,9 @@ struct platform_device *acpi_create_plat
 		}
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
+
 	pdev = platform_device_register_resndata(parent, dev_name(&adev->dev),
-						 -1, ri.res, ri.cur, NULL, 0);
+						 -1, resources, count, NULL, 0);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));
@@ -150,8 +115,7 @@ struct platform_device *acpi_create_plat
 			dev_name(&pdev->dev));
 	}
 
- out:
-	kfree(ri.res);
+	kfree(resources);
 	return pdev;
 }
 
Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -260,6 +260,7 @@ bool acpi_dev_resource_ext_address_space
 unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 				 struct resource *res);
+unsigned int acpi_dev_resource_count(struct acpi_resource *ares);
 
 int acpi_check_resource_conflict(const struct resource *res);
 

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

* Re: [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core
  2012-11-12 12:00   ` [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
@ 2012-11-12 13:27     ` Mika Westerberg
  2012-11-12 20:25       ` [Update][PATCH " Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-12 13:27 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

On Mon, Nov 12, 2012 at 01:00:26PM +0100, Rafael J. Wysocki wrote:
> +/**
> + * acpi_dev_irq_flags - Determine IRQ resource flags.
> + * @triggering: Triggering type as provided by ACPI.
> + * @polarity: Interrupt polarity as provided by ACPI.
> + * @shareable: Whether or not the interrupt is shareable.
> + */
> +unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
> +{
> +	unsigned long flags = IORESOURCE_IRQ;
> +
> +	if (triggering == ACPI_LEVEL_SENSITIVE)
> +		flags = polarity == ACPI_ACTIVE_LOW ?
> +			IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;

This wants to have '|=' instead of '='.

> +	else
> +		flags = polarity == ACPI_ACTIVE_LOW ?
> +			IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;

Ditto.

> +
> +	if (shareable == ACPI_SHARED)
> +		flags |= IORESOURCE_IRQ_SHAREABLE;
> +
> +	return flags;
> +}
> +EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-12 12:02   ` [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects Rafael J. Wysocki
@ 2012-11-12 14:46     ` Mika Westerberg
  2012-11-12 21:03       ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-12 14:46 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

On Mon, Nov 12, 2012 at 01:02:11PM +0100, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> Currently, whoever wants to use ACPI device resources has to call
> acpi_walk_resources() to browse the buffer returned by the _CRS
> method for the given device and create filters passed to that
> routine to apply to the individual resource items.  This generally
> is cumbersome, time-consuming and inefficient.  Moreover, it may
> be problematic if resource conflicts need to be resolved, because
> the different users of _CRS will need to do that in a consistent
> way.
> 
> For this reason, add code to the ACPI core to execute _CRS once,
> when the struct acpi_device object is created for a given device
> node, and attach a list of ACPI resources returned by _CRS to that
> object for future processing.
> 
> Convert the ACPI code that creates platform device objects to using
> the new resources list instead of executing acpi_walk_resources() by
> itself, which makes it much more straightforward and easier to
> follow.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  drivers/acpi/acpi_platform.c |   90 ++++++++++++-------------------------------
>  drivers/acpi/resource.c      |   12 +++++
>  drivers/acpi/scan.c          |   56 ++++++++++++++++++++++++++
>  include/acpi/acpi_bus.h      |    6 ++
>  include/linux/acpi.h         |    1 
>  5 files changed, 102 insertions(+), 63 deletions(-)
> 
> Index: linux/include/acpi/acpi_bus.h
> ===================================================================
> --- linux.orig/include/acpi/acpi_bus.h
> +++ linux/include/acpi/acpi_bus.h
> @@ -259,6 +259,11 @@ struct acpi_device_physical_node {
>  	struct device *dev;
>  };
>  
> +struct acpi_resource_list_entry {
> +	struct list_head node;
> +	struct acpi_resource resource;
> +};
> +
>  /* set maximum of physical nodes to 32 for expansibility */
>  #define ACPI_MAX_PHYSICAL_NODE	32
>  
> @@ -268,6 +273,7 @@ struct acpi_device {
>  	acpi_handle handle;		/* no handle for fixed hardware */
>  	struct acpi_device *parent;
>  	struct list_head children;
> +	struct list_head resources;	/* Device resources. */
>  	struct list_head node;
>  	struct list_head wakeup_list;
>  	struct acpi_device_status status;
> Index: linux/drivers/acpi/scan.c
> ===================================================================
> --- linux.orig/drivers/acpi/scan.c
> +++ linux/drivers/acpi/scan.c
> @@ -382,6 +382,52 @@ static void acpi_device_remove_files(str
>  			ACPI Bus operations
>     -------------------------------------------------------------------------- */
>  
> +static void acpi_bus_drop_resources(struct acpi_device *adev)
> +{
> +	struct acpi_resource_list_entry *entry, *s;
> +
> +	list_for_each_entry_safe(entry, s, &adev->resources, node) {
> +		list_del(&entry->node);
> +		kfree(entry);
> +	}
> +}
> +
> +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> +					 void *context)
> +{
> +	struct list_head *list = context;
> +	struct acpi_resource_list_entry *entry;
> +
> +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> +	if (!entry)
> +		return AE_NO_MEMORY;
> +
> +	entry->resource = *res;

This does not work well with all resource types - specifically those that
contain pointers, like acpi_resource_gpio and acpi_resource_source.

The memory for the resources gets freed once acpi_walk_resources() is done.

> +	INIT_LIST_HEAD(&entry->node);
> +	list_add_tail(&entry->node, list);
> +	return AE_OK;
> +}

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

* [Update][PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core
  2012-11-12 13:27     ` Mika Westerberg
@ 2012-11-12 20:25       ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-12 20:25 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

On Monday, November 12, 2012 03:27:39 PM Mika Westerberg wrote:
> On Mon, Nov 12, 2012 at 01:00:26PM +0100, Rafael J. Wysocki wrote:
> > +/**
> > + * acpi_dev_irq_flags - Determine IRQ resource flags.
> > + * @triggering: Triggering type as provided by ACPI.
> > + * @polarity: Interrupt polarity as provided by ACPI.
> > + * @shareable: Whether or not the interrupt is shareable.
> > + */
> > +unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
> > +{
> > +	unsigned long flags = IORESOURCE_IRQ;
> > +
> > +	if (triggering == ACPI_LEVEL_SENSITIVE)
> > +		flags = polarity == ACPI_ACTIVE_LOW ?
> > +			IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
> 
> This wants to have '|=' instead of '='.
> 
> > +	else
> > +		flags = polarity == ACPI_ACTIVE_LOW ?
> > +			IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
> 
> Ditto.

It definitely does, but I fixed it slightly differently.  Updated patch follows.

Thanks,
Rafael


---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: ACPI: Move device resources interpretation code from PNP to ACPI core

Move some code used for parsing ACPI device resources from the PNP
subsystem to the ACPI core, so that other bus types (platform, SPI,
I2C) can use the same routines for parsing resources in a consistent
way, without duplicating code.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/Makefile          |    1 
 drivers/acpi/resource.c        |  393 +++++++++++++++++++++++++++++++++++++++++
 drivers/pnp/base.h             |    2 
 drivers/pnp/pnpacpi/rsparser.c |  296 +++---------------------------
 drivers/pnp/resource.c         |   16 +
 include/linux/acpi.h           |   10 +
 6 files changed, 454 insertions(+), 264 deletions(-)

Index: linux/drivers/acpi/resource.c
===================================================================
--- /dev/null
+++ linux/drivers/acpi/resource.c
@@ -0,0 +1,393 @@
+/*
+ * drivers/acpi/resource.c - ACPI device resources interpretation.
+ *
+ * Copyright (C) 2012, Intel Corp.
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_X86
+#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+#else
+#define valid_IRQ(i) (true)
+#endif
+
+static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect,
+						bool window)
+{
+	unsigned long flags = IORESOURCE_MEM;
+
+	if (len == 0)
+		flags |= IORESOURCE_DISABLED;
+
+	if (write_protect == ACPI_READ_WRITE_MEMORY)
+		flags |= IORESOURCE_MEM_WRITEABLE;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
+				     u8 write_protect)
+{
+	res->start = start;
+	res->end = start + len - 1;
+	res->flags = acpi_dev_memresource_flags(len, write_protect, false);
+}
+
+/**
+ * acpi_dev_resource_memory - Extract ACPI memory resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents a memory resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_memory24 *memory24;
+	struct acpi_resource_memory32 *memory32;
+	struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+		memory24 = &ares->data.memory24;
+		acpi_dev_get_memresource(res, memory24->minimum,
+					 memory24->address_length,
+					 memory24->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+		memory32 = &ares->data.memory32;
+		acpi_dev_get_memresource(res, memory32->minimum,
+					 memory32->address_length,
+					 memory32->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		fixed_memory32 = &ares->data.fixed_memory32;
+		acpi_dev_get_memresource(res, fixed_memory32->address,
+					 fixed_memory32->address_length,
+					 fixed_memory32->write_protect);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
+
+static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode,
+					      bool window)
+{
+	int flags = IORESOURCE_IO;
+
+	if (io_decode == ACPI_DECODE_16)
+		flags |= IORESOURCE_IO_16BIT_ADDR;
+
+	if (start > end || end >= 0x10003)
+		flags |= IORESOURCE_DISABLED;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
+				    u8 io_decode)
+{
+	u64 end = start + len - 1;
+
+	res->start = start;
+	res->end = end;
+	res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false);
+}
+
+/**
+ * acpi_dev_resource_io - Extract ACPI I/O resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an I/O resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_io *io;
+	struct acpi_resource_fixed_io *fixed_io;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IO:
+		io = &ares->data.io;
+		acpi_dev_get_ioresource(res, io->minimum,
+					io->address_length,
+					io->io_decode);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+		fixed_io = &ares->data.fixed_io;
+		acpi_dev_get_ioresource(res, fixed_io->address,
+					fixed_io->address_length,
+					ACPI_DECODE_10);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
+
+/**
+ * acpi_dev_resource_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an address space resource
+ * and if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res)
+{
+	acpi_status status;
+	struct acpi_resource_address64 addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+		break;
+	default:
+		return false;
+	}
+
+	status = acpi_resource_to_address64(ares, &addr);
+	if (ACPI_FAILURE(status))
+		return true;
+
+	res->start = addr.minimum;
+	res->end = addr.maximum;
+	window = addr.producer_consumer == ACPI_PRODUCER;
+
+	switch(addr.resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = addr.maximum - addr.minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+						addr.info.mem.write_protect,
+						window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = addr.granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(addr.minimum,
+						       addr.maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
+
+/**
+ * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an extended address space
+ * resource and if that's the case, use the information in it to populate the
+ * generic resource object pointed to by @res.
+ */
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res)
+{
+	struct acpi_resource_extended_address64 *ext_addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
+		return false;
+
+	ext_addr = &ares->data.ext_address64;
+
+	res->start = ext_addr->minimum;
+	res->end = ext_addr->maximum;
+	window = ext_addr->producer_consumer == ACPI_PRODUCER;
+
+	switch(ext_addr->resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = ext_addr->maximum - ext_addr->minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+					ext_addr->info.mem.write_protect,
+					window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = ext_addr->granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(ext_addr->minimum,
+						       ext_addr->maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
+
+/**
+ * acpi_dev_irq_flags - Determine IRQ resource flags.
+ * @triggering: Triggering type as provided by ACPI.
+ * @polarity: Interrupt polarity as provided by ACPI.
+ * @shareable: Whether or not the interrupt is shareable.
+ */
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
+{
+	unsigned long flags;
+
+	if (triggering == ACPI_LEVEL_SENSITIVE)
+		flags = polarity == ACPI_ACTIVE_LOW ?
+			IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
+	else
+		flags = polarity == ACPI_ACTIVE_LOW ?
+			IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
+
+	if (shareable == ACPI_SHARED)
+		flags |= IORESOURCE_IRQ_SHAREABLE;
+
+	return flags | IORESOURCE_IRQ;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
+
+static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
+{
+	res->start = gsi;
+	res->end = gsi;
+	res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED;
+}
+
+static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+				     u8 triggering, u8 polarity, u8 shareable)
+{
+	int irq, p, t;
+
+	if (!valid_IRQ(gsi)) {
+		acpi_dev_irqresource_disabled(res, gsi);
+		return;
+	}
+
+	/*
+	 * In IO-APIC mode, use overrided attribute. Two reasons:
+	 * 1. BIOS bug in DSDT
+	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
+	 */
+	if (!acpi_get_override_irq(gsi, &t, &p)) {
+		u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+		u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+		if (triggering != trig || polarity != pol) {
+			pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
+				   t ? "edge" : "level", p ? "low" : "high");
+			triggering = trig;
+			polarity = pol;
+		}
+	}
+
+	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
+	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+	if (irq >= 0) {
+		res->start = irq;
+		res->end = irq;
+	} else {
+		acpi_dev_irqresource_disabled(res, gsi);
+	}
+}
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)).  If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly.  If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res)
+{
+	struct acpi_resource_irq *irq;
+	struct acpi_resource_extended_irq *ext_irq;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
+		/*
+		 * Per spec, only one interrupt per descriptor is allowed in
+		 * _CRS, but some firmware violates this, so parse them all.
+		 */
+		irq = &ares->data.irq;
+		if (index >= irq->interrupt_count) {
+			acpi_dev_irqresource_disabled(res, 0);
+			return false;
+		}
+		acpi_dev_get_irqresource(res, irq->interrupts[index],
+					 irq->triggering, irq->polarity,
+					 irq->sharable);
+		break;
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		ext_irq = &ares->data.extended_irq;
+		if (index >= ext_irq->interrupt_count) {
+			acpi_dev_irqresource_disabled(res, 0);
+			return false;
+		}
+		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+					 ext_irq->triggering, ext_irq->polarity,
+					 ext_irq->sharable);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
Index: linux/drivers/acpi/Makefile
===================================================================
--- linux.orig/drivers/acpi/Makefile
+++ linux/drivers/acpi/Makefile
@@ -33,6 +33,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 #
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
+acpi-y				+= resource.o
 acpi-y				+= processor_core.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
Index: linux/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- linux.orig/drivers/pnp/pnpacpi/rsparser.c
+++ linux/drivers/pnp/pnpacpi/rsparser.c
@@ -28,37 +28,6 @@
 #include "../base.h"
 #include "pnpacpi.h"
 
-#ifdef CONFIG_IA64
-#define valid_IRQ(i) (1)
-#else
-#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
-#endif
-
-/*
- * Allocated Resources
- */
-static int irq_flags(int triggering, int polarity, int shareable)
-{
-	int flags;
-
-	if (triggering == ACPI_LEVEL_SENSITIVE) {
-		if (polarity == ACPI_ACTIVE_LOW)
-			flags = IORESOURCE_IRQ_LOWLEVEL;
-		else
-			flags = IORESOURCE_IRQ_HIGHLEVEL;
-	} else {
-		if (polarity == ACPI_ACTIVE_LOW)
-			flags = IORESOURCE_IRQ_LOWEDGE;
-		else
-			flags = IORESOURCE_IRQ_HIGHEDGE;
-	}
-
-	if (shareable == ACPI_SHARED)
-		flags |= IORESOURCE_IRQ_SHAREABLE;
-
-	return flags;
-}
-
 static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
 			     int *polarity, int *shareable)
 {
@@ -94,45 +63,6 @@ static void decode_irq_flags(struct pnp_
 		*shareable = ACPI_EXCLUSIVE;
 }
 
-static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
-						u32 gsi, int triggering,
-						int polarity, int shareable)
-{
-	int irq, flags;
-	int p, t;
-
-	if (!valid_IRQ(gsi)) {
-		pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
-		return;
-	}
-
-	/*
-	 * in IO-APIC mode, use overrided attribute. Two reasons:
-	 * 1. BIOS bug in DSDT
-	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
-	 */
-	if (!acpi_get_override_irq(gsi, &t, &p)) {
-		t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
-		p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
-
-		if (triggering != t || polarity != p) {
-			dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
-				gsi, t ? "edge":"level", p ? "low":"high");
-			triggering = t;
-			polarity = p;
-		}
-	}
-
-	flags = irq_flags(triggering, polarity, shareable);
-	irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
-	if (irq >= 0)
-		pcibios_penalize_isa_irq(irq, 1);
-	else
-		flags |= IORESOURCE_DISABLED;
-
-	pnp_add_irq_resource(dev, irq, flags);
-}
-
 static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
 		     int transfer)
 {
@@ -177,21 +107,16 @@ static int dma_flags(struct pnp_dev *dev
 	return flags;
 }
 
-static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
-					       u64 len, int io_decode,
-					       int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
+/*
+ * Allocated Resources
+ */
 
-	if (io_decode == ACPI_DECODE_16)
-		flags |= IORESOURCE_IO_16BIT_ADDR;
-	if (len == 0 || end >= 0x10003)
-		flags |= IORESOURCE_DISABLED;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
+static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r)
+{
+	if (!(r->flags & IORESOURCE_DISABLED))
+		pcibios_penalize_isa_irq(r->start, 1);
 
-	pnp_add_io_resource(dev, start, end, flags);
+	pnp_add_resource(dev, r);
 }
 
 /*
@@ -249,130 +174,49 @@ static void pnpacpi_parse_allocated_vend
 	}
 }
 
-static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
-						u64 start, u64 len,
-						int write_protect, int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
-
-	if (len == 0)
-		flags |= IORESOURCE_DISABLED;
-	if (write_protect == ACPI_READ_WRITE_MEMORY)
-		flags |= IORESOURCE_MEM_WRITEABLE;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
-
-	pnp_add_mem_resource(dev, start, end, flags);
-}
-
-static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
-						u64 start, u64 len)
-{
-	u64 end = start + len - 1;
-
-	pnp_add_bus_resource(dev, start, end);
-}
-
-static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
-						  struct acpi_resource *res)
-{
-	struct acpi_resource_address64 addr, *p = &addr;
-	acpi_status status;
-	int window;
-	u64 len;
-
-	status = acpi_resource_to_address64(res, p);
-	if (!ACPI_SUCCESS(status)) {
-		dev_warn(&dev->dev, "failed to convert resource type %d\n",
-			 res->type);
-		return;
-	}
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
-static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
-						      struct acpi_resource *res)
-{
-	struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
-	int window;
-	u64 len;
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
 					      void *data)
 {
 	struct pnp_dev *dev = data;
-	struct acpi_resource_irq *irq;
 	struct acpi_resource_dma *dma;
-	struct acpi_resource_io *io;
-	struct acpi_resource_fixed_io *fixed_io;
 	struct acpi_resource_vendor_typed *vendor_typed;
-	struct acpi_resource_memory24 *memory24;
-	struct acpi_resource_memory32 *memory32;
-	struct acpi_resource_fixed_memory32 *fixed_memory32;
-	struct acpi_resource_extended_irq *extended_irq;
+	struct resource r;
 	int i, flags;
 
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		/*
-		 * Per spec, only one interrupt per descriptor is allowed in
-		 * _CRS, but some firmware violates this, so parse them all.
-		 */
-		irq = &res->data.irq;
-		if (irq->interrupt_count == 0)
-			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
-		else {
-			for (i = 0; i < irq->interrupt_count; i++) {
-				pnpacpi_parse_allocated_irqresource(dev,
-					irq->interrupts[i],
-					irq->triggering,
-					irq->polarity,
-				    irq->sharable);
-			}
+	if (acpi_dev_resource_memory(res, &r)
+	    || acpi_dev_resource_io(res, &r)
+	    || acpi_dev_resource_address_space(res, &r)
+	    || acpi_dev_resource_ext_address_space(res, &r)) {
+		pnp_add_resource(dev, &r);
+		return AE_OK;
+	}
+
+	r.flags = 0;
+	if (acpi_dev_resource_interrupt(res, 0, &r)) {
+		pnpacpi_add_irqresource(dev, &r);
+		for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++)
+			pnpacpi_add_irqresource(dev, &r);
 
+		if (i > 1) {
 			/*
 			 * The IRQ encoder puts a single interrupt in each
 			 * descriptor, so if a _CRS descriptor has more than
 			 * one interrupt, we won't be able to re-encode it.
 			 */
-			if (pnp_can_write(dev) && irq->interrupt_count > 1) {
+			if (pnp_can_write(dev)) {
 				dev_warn(&dev->dev, "multiple interrupts in "
 					 "_CRS descriptor; configuration can't "
 					 "be changed\n");
 				dev->capabilities &= ~PNP_WRITE;
 			}
 		}
-		break;
+		return AE_OK;
+	} else if (r.flags & IORESOURCE_DISABLED) {
+		pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
+		return AE_OK;
+	}
 
+	switch (res->type) {
 	case ACPI_RESOURCE_TYPE_DMA:
 		dma = &res->data.dma;
 		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
@@ -383,26 +227,10 @@ static acpi_status pnpacpi_allocated_res
 		pnp_add_dma_resource(dev, dma->channels[0], flags);
 		break;
 
-	case ACPI_RESOURCE_TYPE_IO:
-		io = &res->data.io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			io->minimum,
-			io->address_length,
-			io->io_decode, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 		break;
 
-	case ACPI_RESOURCE_TYPE_FIXED_IO:
-		fixed_io = &res->data.fixed_io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			fixed_io->address,
-			fixed_io->address_length,
-			ACPI_DECODE_10, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_VENDOR:
 		vendor_typed = &res->data.vendor_typed;
 		pnpacpi_parse_allocated_vendor(dev, vendor_typed);
@@ -411,66 +239,6 @@ static acpi_status pnpacpi_allocated_res
 	case ACPI_RESOURCE_TYPE_END_TAG:
 		break;
 
-	case ACPI_RESOURCE_TYPE_MEMORY24:
-		memory24 = &res->data.memory24;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory24->minimum,
-			memory24->address_length,
-			memory24->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_MEMORY32:
-		memory32 = &res->data.memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory32->minimum,
-			memory32->address_length,
-			memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		fixed_memory32 = &res->data.fixed_memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			fixed_memory32->address,
-			fixed_memory32->address_length,
-			fixed_memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS16:
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-	case ACPI_RESOURCE_TYPE_ADDRESS64:
-		pnpacpi_parse_allocated_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
-		pnpacpi_parse_allocated_ext_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		extended_irq = &res->data.extended_irq;
-
-		if (extended_irq->interrupt_count == 0)
-			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
-		else {
-			for (i = 0; i < extended_irq->interrupt_count; i++) {
-				pnpacpi_parse_allocated_irqresource(dev,
-					extended_irq->interrupts[i],
-					extended_irq->triggering,
-					extended_irq->polarity,
-					extended_irq->sharable);
-			}
-
-			/*
-			 * The IRQ encoder puts a single interrupt in each
-			 * descriptor, so if a _CRS descriptor has more than
-			 * one interrupt, we won't be able to re-encode it.
-			 */
-			if (pnp_can_write(dev) &&
-			    extended_irq->interrupt_count > 1) {
-				dev_warn(&dev->dev, "multiple interrupts in "
-					 "_CRS descriptor; configuration can't "
-					 "be changed\n");
-				dev->capabilities &= ~PNP_WRITE;
-			}
-		}
-		break;
-
 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 		break;
 
@@ -531,7 +299,7 @@ static __init void pnpacpi_parse_irq_opt
 		if (p->interrupts[i])
 			__set_bit(p->interrupts[i], map.bits);
 
-	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
@@ -555,7 +323,7 @@ static __init void pnpacpi_parse_ext_irq
 		}
 	}
 
-	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
Index: linux/drivers/pnp/base.h
===================================================================
--- linux.orig/drivers/pnp/base.h
+++ linux/drivers/pnp/base.h
@@ -159,6 +159,8 @@ struct pnp_resource {
 
 void pnp_free_resource(struct pnp_resource *pnp_res);
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res);
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags);
 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
Index: linux/drivers/pnp/resource.c
===================================================================
--- linux.orig/drivers/pnp/resource.c
+++ linux/drivers/pnp/resource.c
@@ -503,6 +503,22 @@ static struct pnp_resource *pnp_new_reso
 	return pnp_res;
 }
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res)
+{
+	struct pnp_resource *pnp_res;
+
+	pnp_res = pnp_new_resource(dev);
+	if (!pnp_res) {
+		dev_err(&dev->dev, "can't add resource %pR\n", res);
+		return NULL;
+	}
+
+	pnp_res->res = *res;
+	dev_dbg(&dev->dev, "%pR\n", res);
+	return pnp_res;
+}
+
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags)
 {
Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -251,6 +251,16 @@ extern int pnpacpi_disabled;
 
 #define PXM_INVAL	(-1)
 
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res);
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res);
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res);
+
 int acpi_check_resource_conflict(const struct resource *res);
 
 int acpi_check_region(resource_size_t start, resource_size_t n,


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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-12 14:46     ` Mika Westerberg
@ 2012-11-12 21:03       ` Rafael J. Wysocki
  2012-11-13  7:12         ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-12 21:03 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Monday, November 12, 2012 04:46:21 PM Mika Westerberg wrote:
> On Mon, Nov 12, 2012 at 01:02:11PM +0100, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > 
> > Currently, whoever wants to use ACPI device resources has to call
> > acpi_walk_resources() to browse the buffer returned by the _CRS
> > method for the given device and create filters passed to that
> > routine to apply to the individual resource items.  This generally
> > is cumbersome, time-consuming and inefficient.  Moreover, it may
> > be problematic if resource conflicts need to be resolved, because
> > the different users of _CRS will need to do that in a consistent
> > way.
> > 
> > For this reason, add code to the ACPI core to execute _CRS once,
> > when the struct acpi_device object is created for a given device
> > node, and attach a list of ACPI resources returned by _CRS to that
> > object for future processing.
> > 
> > Convert the ACPI code that creates platform device objects to using
> > the new resources list instead of executing acpi_walk_resources() by
> > itself, which makes it much more straightforward and easier to
> > follow.
> > 
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >  drivers/acpi/acpi_platform.c |   90 ++++++++++++-------------------------------
> >  drivers/acpi/resource.c      |   12 +++++
> >  drivers/acpi/scan.c          |   56 ++++++++++++++++++++++++++
> >  include/acpi/acpi_bus.h      |    6 ++
> >  include/linux/acpi.h         |    1 
> >  5 files changed, 102 insertions(+), 63 deletions(-)
> > 
> > Index: linux/include/acpi/acpi_bus.h
> > ===================================================================
> > --- linux.orig/include/acpi/acpi_bus.h
> > +++ linux/include/acpi/acpi_bus.h
> > @@ -259,6 +259,11 @@ struct acpi_device_physical_node {
> >  	struct device *dev;
> >  };
> >  
> > +struct acpi_resource_list_entry {
> > +	struct list_head node;
> > +	struct acpi_resource resource;
> > +};
> > +
> >  /* set maximum of physical nodes to 32 for expansibility */
> >  #define ACPI_MAX_PHYSICAL_NODE	32
> >  
> > @@ -268,6 +273,7 @@ struct acpi_device {
> >  	acpi_handle handle;		/* no handle for fixed hardware */
> >  	struct acpi_device *parent;
> >  	struct list_head children;
> > +	struct list_head resources;	/* Device resources. */
> >  	struct list_head node;
> >  	struct list_head wakeup_list;
> >  	struct acpi_device_status status;
> > Index: linux/drivers/acpi/scan.c
> > ===================================================================
> > --- linux.orig/drivers/acpi/scan.c
> > +++ linux/drivers/acpi/scan.c
> > @@ -382,6 +382,52 @@ static void acpi_device_remove_files(str
> >  			ACPI Bus operations
> >     -------------------------------------------------------------------------- */
> >  
> > +static void acpi_bus_drop_resources(struct acpi_device *adev)
> > +{
> > +	struct acpi_resource_list_entry *entry, *s;
> > +
> > +	list_for_each_entry_safe(entry, s, &adev->resources, node) {
> > +		list_del(&entry->node);
> > +		kfree(entry);
> > +	}
> > +}
> > +
> > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > +					 void *context)
> > +{
> > +	struct list_head *list = context;
> > +	struct acpi_resource_list_entry *entry;
> > +
> > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > +	if (!entry)
> > +		return AE_NO_MEMORY;
> > +
> > +	entry->resource = *res;
> 
> This does not work well with all resource types - specifically those that
> contain pointers, like acpi_resource_gpio and acpi_resource_source.

Good point.

Well, this pretty much means we can't copy those things.

> The memory for the resources gets freed once acpi_walk_resources() is done.

I know that.

Having to evaluate _CRS and creating a buffer, converting the output into
ACPI resources and so on every time we need to look into the device's current
resources is totally inefficient.  We _need_ to cache the _CRS output.

Now, because of the pointers in certain types of resources, we can't
make copies of the resource objects used by acpi_walk_resources() which
makes that function totally unuseful to us.

I suppose we can just do acpi_get_current_resources() and play with the
buffer returned by it.  That won't be nice, but still better than what we
have.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-12 21:03       ` Rafael J. Wysocki
@ 2012-11-13  7:12         ` Mika Westerberg
  2012-11-13 12:06           ` [Replacement][PATCH 3/3] Rafael J. Wysocki
  2012-11-13 16:34             ` Moore, Robert
  0 siblings, 2 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-13  7:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > > +					 void *context)
> > > +{
> > > +	struct list_head *list = context;
> > > +	struct acpi_resource_list_entry *entry;
> > > +
> > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > +	if (!entry)
> > > +		return AE_NO_MEMORY;
> > > +
> > > +	entry->resource = *res;
> > 
> > This does not work well with all resource types - specifically those that
> > contain pointers, like acpi_resource_gpio and acpi_resource_source.
> 
> Good point.
> 
> Well, this pretty much means we can't copy those things.

Yeah. I only noticed this yesterday when I tested the GPIO translation in a
custom driver (since it uses the acpi_resource_gpio).

> > The memory for the resources gets freed once acpi_walk_resources() is done.
> 
> I know that.
> 
> Having to evaluate _CRS and creating a buffer, converting the output into
> ACPI resources and so on every time we need to look into the device's current
> resources is totally inefficient.  We _need_ to cache the _CRS output.

I agree and besides having adev->resources is much easier to use than
calling acpi_walk_resources() everytime.

> Now, because of the pointers in certain types of resources, we can't
> make copies of the resource objects used by acpi_walk_resources() which
> makes that function totally unuseful to us.
>
> I suppose we can just do acpi_get_current_resources() and play with the
> buffer returned by it.  That won't be nice, but still better than what we
> have.

I don't know any better option.

Thanks.

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

* [Replacement][PATCH 3/3]
  2012-11-13  7:12         ` Mika Westerberg
@ 2012-11-13 12:06           ` Rafael J. Wysocki
  2012-11-13 14:16             ` Mika Westerberg
  2012-11-13 16:34             ` Moore, Robert
  1 sibling, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 12:06 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Tuesday, November 13, 2012 09:12:09 AM Mika Westerberg wrote:
> On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > > > +					 void *context)
> > > > +{
> > > > +	struct list_head *list = context;
> > > > +	struct acpi_resource_list_entry *entry;
> > > > +
> > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > +	if (!entry)
> > > > +		return AE_NO_MEMORY;
> > > > +
> > > > +	entry->resource = *res;
> > > 
> > > This does not work well with all resource types - specifically those that
> > > contain pointers, like acpi_resource_gpio and acpi_resource_source.
> > 
> > Good point.
> > 
> > Well, this pretty much means we can't copy those things.
> 
> Yeah. I only noticed this yesterday when I tested the GPIO translation in a
> custom driver (since it uses the acpi_resource_gpio).
> 
> > > The memory for the resources gets freed once acpi_walk_resources() is done.
> > 
> > I know that.
> > 
> > Having to evaluate _CRS and creating a buffer, converting the output into
> > ACPI resources and so on every time we need to look into the device's current
> > resources is totally inefficient.  We _need_ to cache the _CRS output.
> 
> I agree and besides having adev->resources is much easier to use than
> calling acpi_walk_resources() everytime.
> 
> > Now, because of the pointers in certain types of resources, we can't
> > make copies of the resource objects used by acpi_walk_resources() which
> > makes that function totally unuseful to us.
> >
> > I suppose we can just do acpi_get_current_resources() and play with the
> > buffer returned by it.  That won't be nice, but still better than what we
> > have.
> 
> I don't know any better option.

Well, a better option would be to convince ACPICA to provide us different
interfaces. :-)

We might actually try to do that in the future, but for now we still need
_CRS to be evaluated centrally rather than by every interested party in
isolation.  So below is a replacement for my original [3/3] patch that
approaches the problem from a different angle (on top of [1/3] and
updated [2/3] sent yesterday).  Please let me know what you think.

Thanks,
Rafael


---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: ACPI: Centralized processing of ACPI device resources

Currently, whoever wants to use ACPI device resources has to call
acpi_walk_resources() to browse the buffer returned by the _CRS
method for the given device and create filters passed to that
routine to apply to the individual resource items.  This generally
is cumbersome, time-consuming and inefficient.  Moreover, it may
be problematic if resource conflicts need to be resolved, because
the different users of _CRS will need to do that in a consistent
way.  However, if there are resource conflicts, the ACPI core
should be able to resolve them centrally instead of relying on
various users of acpi_walk_resources() to handle them correctly
together.

For this reason, introduce a new function, acpi_dev_get_resources(),
that can be used by subsystems to obtain a list of struct resource
objects corresponding to the ACPI device resources returned by
_CRS and, if necessary, to apply additional preprocessing routine
to the ACPI resources before converting them to the struct resource
format.

Make the ACPI code that creates platform device objects use
acpi_dev_get_resources() for resource processing instead of executing
acpi_walk_resources() twice by itself, which causes it to be much
more straightforward and easier to follow.

In the future, acpi_dev_get_resources() can be extended to meet
the needs of the ACPI PNP subsystem and other users of _CRS in
the kernel.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_platform.c |   94 +++++-------------------------
 drivers/acpi/resource.c      |  132 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h         |   10 +++
 3 files changed, 159 insertions(+), 77 deletions(-)

Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -261,6 +261,16 @@ unsigned long acpi_dev_irq_flags(u8 trig
 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 				 struct resource *res);
 
+struct resource_list_entry {
+	struct list_head node;
+	struct resource res;
+};
+
+void acpi_dev_free_resource_list(struct list_head *list);
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+			   int (*preproc)(struct acpi_resource *, void *),
+			   void *preproc_data);
+
 int acpi_check_resource_conflict(const struct resource *res);
 
 int acpi_check_region(resource_size_t start, resource_size_t n,
Index: linux/drivers/acpi/resource.c
===================================================================
--- linux.orig/drivers/acpi/resource.c
+++ linux/drivers/acpi/resource.c
@@ -26,6 +26,7 @@
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_X86
 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
@@ -391,3 +392,134 @@ bool acpi_dev_resource_interrupt(struct
 	return true;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
+
+/**
+ * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
+ * @list: The head of the resource list to free.
+ */
+void acpi_dev_free_resource_list(struct list_head *list)
+{
+	struct resource_list_entry *rentry, *re;
+
+	list_for_each_entry_safe(rentry, re, list, node) {
+		list_del(&rentry->node);
+		kfree(rentry);
+	}
+}
+EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
+
+struct res_proc_context {
+	struct list_head *list;
+	int (*preproc)(struct acpi_resource *, void *);
+	void *preproc_data;
+	int count;
+	int error;
+};
+
+static acpi_status acpi_dev_new_resource_entry(struct resource *r,
+					       struct res_proc_context *c)
+{
+	struct resource_list_entry *rentry;
+
+	rentry = kmalloc(sizeof(*rentry), GFP_KERNEL);
+	if (!rentry) {
+		c->error = -ENOMEM;
+		return AE_NO_MEMORY;
+	}
+	INIT_LIST_HEAD(&rentry->node);
+	rentry->res = *r;
+	list_add_tail(&rentry->node, c->list);
+	c->count++;
+	return AE_OK;
+}
+
+static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
+					     void *context)
+{
+	struct res_proc_context *c = context;
+	struct resource r;
+	int i;
+
+	if (c->preproc) {
+		int ret;
+
+		ret = c->preproc(ares, c->preproc_data);
+		if (ret < 0) {
+			c->error = ret;
+			return AE_ABORT_METHOD;
+		} else if (ret > 0) {
+			return AE_OK;
+		}
+	}
+
+	if (acpi_dev_resource_memory(ares, &r)
+	    || acpi_dev_resource_io(ares, &r)
+	    || acpi_dev_resource_address_space(ares, &r)
+	    || acpi_dev_resource_ext_address_space(ares, &r))
+		return acpi_dev_new_resource_entry(&r, c);
+
+	for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) {
+		acpi_status status;
+
+		status = acpi_dev_new_resource_entry(&r, c);
+		if (ACPI_FAILURE(status))
+			return status;
+	}
+
+	return AE_OK;
+}
+
+/**
+ * acpi_dev_get_resources - Get current resources of a device.
+ * @adev: ACPI device node to get the resources for.
+ * @list: Head of the resultant list of resources (must be empty).
+ * @preproc: The caller's preprocessing routine.
+ * @preproc_data: Pointer passed to the caller's preprocessing routine.
+ *
+ * Evaluate the _CRS method for the given device node and process its output by
+ * (1) executing the @preproc() rountine provided by the caller, passing the
+ * resource pointer and @preproc_data to it as arguments, for each ACPI resource
+ * returned and (2) converting all of the returned ACPI resources into struct
+ * resource objects if possible.  If the return value of @preproc() in step (1)
+ * is different from 0, step (2) is not applied to the given ACPI resource and
+ * if that value is negative, the whole processing is aborted and that value is
+ * returned as the final error code.
+ *
+ * The resultant struct resource objects are put on the list pointed to by
+ * @list, that must be empty initially, as members of struct resource_list_entry
+ * objects.  Callers of this routine should use %acpi_dev_free_resource_list() to
+ * free that list.
+ *
+ * The number of resources in the output list is returned on success, an error
+ * code reflecting the error condition is returned otherwise.
+ */
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+			   int (*preproc)(struct acpi_resource *, void *),
+			   void *preproc_data)
+{
+	struct res_proc_context c;
+	acpi_handle not_used;
+	acpi_status status;
+
+	if (!adev || !adev->handle || !list_empty(list))
+		return -EINVAL;
+
+	status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, &not_used);
+	if (ACPI_FAILURE(status))
+		return 0;
+
+	c.list = list;
+	c.preproc = preproc;
+	c.preproc_data = preproc_data;
+	c.count = 0;
+	c.error = 0;
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_dev_process_resource, &c);
+	if (ACPI_FAILURE(status)) {
+		acpi_dev_free_resource_list(list);
+		return c.error ? c.error : -EIO;
+	}
+
+	return c.count;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
Index: linux/drivers/acpi/acpi_platform.c
===================================================================
--- linux.orig/drivers/acpi/acpi_platform.c
+++ linux/drivers/acpi/acpi_platform.c
@@ -19,61 +19,6 @@
 
 ACPI_MODULE_NAME("platform");
 
-struct resource_info {
-	struct device *dev;
-	struct resource *res;
-	size_t n, cur;
-};
-
-static acpi_status acpi_platform_count_resources(struct acpi_resource *res,
-						 void *data)
-{
-	struct acpi_resource_extended_irq *acpi_xirq;
-	struct acpi_resource_irq *acpi_irq;
-	struct resource_info *ri = data;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		acpi_irq = &res->data.irq;
-		ri->n += acpi_irq->interrupt_count;
-		break;
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		acpi_xirq = &res->data.extended_irq;
-		ri->n += acpi_xirq->interrupt_count;
-		break;
-	default:
-		ri->n++;
-	}
-
-	return AE_OK;
-}
-
-static acpi_status acpi_platform_add_resources(struct acpi_resource *res,
-					       void *data)
-{
-	struct resource_info *ri = data;
-	struct resource *r;
-
-	r = ri->res + ri->cur;
-	if (acpi_dev_resource_memory(res, r)
-	    || acpi_dev_resource_io(res, r)
-	    || acpi_dev_resource_address_space(res, r)
-	    || acpi_dev_resource_ext_address_space(res, r)) {
-		ri->cur++;
-		return AE_OK;
-	}
-	if (acpi_dev_resource_interrupt(res, 0, r)) {
-		int i;
-
-		r++;
-		for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
-			r++;
-
-		ri->cur += i;
-	}
-	return AE_OK;
-}
-
 /**
  * acpi_create_platform_device - Create platform device for ACPI device node
  * @adev: ACPI device node to create a platform device for.
@@ -89,35 +34,31 @@ struct platform_device *acpi_create_plat
 	struct platform_device *pdev = NULL;
 	struct acpi_device *acpi_parent;
 	struct device *parent = NULL;
-	struct resource_info ri;
-	acpi_status status;
+	struct resource_list_entry *rentry;
+	struct list_head resource_list;
+	struct resource *resources;
+	int count;
 
 	/* If the ACPI node already has a physical device attached, skip it. */
 	if (adev->physical_node_count)
 		return NULL;
 
-	memset(&ri, 0, sizeof(ri));
-	/* First, count the resources. */
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_count_resources, &ri);
-	if (ACPI_FAILURE(status) || !ri.n)
+	INIT_LIST_HEAD(&resource_list);
+	count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+	if (count <= 0)
 		return NULL;
 
-	/* Next, allocate memory for all the resources and populate it. */
-	ri.dev = &adev->dev;
-	ri.res = kzalloc(ri.n * sizeof(struct resource), GFP_KERNEL);
-	if (!ri.res) {
-		dev_err(&adev->dev,
-			"failed to allocate memory for resources\n");
+	resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
+	if (!resources) {
+		dev_err(&adev->dev, "No memory for resources\n");
+		acpi_dev_free_resource_list(&resource_list);
 		return NULL;
 	}
+	count = 0;
+	list_for_each_entry(rentry, &resource_list, node)
+		resources[count++] = rentry->res;
 
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_add_resources, &ri);
-	if (ACPI_FAILURE(status)) {
-		dev_err(&adev->dev, "failed to walk resources\n");
-		goto out;
-	}
+	acpi_dev_free_resource_list(&resource_list);
 
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
@@ -140,7 +81,7 @@ struct platform_device *acpi_create_plat
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
 	pdev = platform_device_register_resndata(parent, dev_name(&adev->dev),
-						 -1, ri.res, ri.cur, NULL, 0);
+						 -1, resources, count, NULL, 0);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));
@@ -150,8 +91,7 @@ struct platform_device *acpi_create_plat
 			dev_name(&pdev->dev));
 	}
 
- out:
-	kfree(ri.res);
+	kfree(resources);
 	return pdev;
 }
 



-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [Replacement][PATCH 3/3]
  2012-11-13 12:06           ` [Replacement][PATCH 3/3] Rafael J. Wysocki
@ 2012-11-13 14:16             ` Mika Westerberg
  2012-11-13 15:15               ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-13 14:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Tue, Nov 13, 2012 at 01:06:59PM +0100, Rafael J. Wysocki wrote:
> > I don't know any better option.
> 
> Well, a better option would be to convince ACPICA to provide us different
> interfaces. :-)

Heh, indeed.

> We might actually try to do that in the future, but for now we still need
> _CRS to be evaluated centrally rather than by every interested party in
> isolation.  So below is a replacement for my original [3/3] patch that
> approaches the problem from a different angle (on top of [1/3] and
> updated [2/3] sent yesterday).  Please let me know what you think.
> 
> Thanks,
> Rafael
> 
> 
> ---
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Subject: ACPI: Centralized processing of ACPI device resources
> 
> Currently, whoever wants to use ACPI device resources has to call
> acpi_walk_resources() to browse the buffer returned by the _CRS
> method for the given device and create filters passed to that
> routine to apply to the individual resource items.  This generally
> is cumbersome, time-consuming and inefficient.  Moreover, it may
> be problematic if resource conflicts need to be resolved, because
> the different users of _CRS will need to do that in a consistent
> way.  However, if there are resource conflicts, the ACPI core
> should be able to resolve them centrally instead of relying on
> various users of acpi_walk_resources() to handle them correctly
> together.
> 
> For this reason, introduce a new function, acpi_dev_get_resources(),
> that can be used by subsystems to obtain a list of struct resource
> objects corresponding to the ACPI device resources returned by
> _CRS and, if necessary, to apply additional preprocessing routine
> to the ACPI resources before converting them to the struct resource
> format.
> 
> Make the ACPI code that creates platform device objects use
> acpi_dev_get_resources() for resource processing instead of executing
> acpi_walk_resources() twice by itself, which causes it to be much
> more straightforward and easier to follow.
> 
> In the future, acpi_dev_get_resources() can be extended to meet
> the needs of the ACPI PNP subsystem and other users of _CRS in
> the kernel.
> 
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

I found one problem which resulted failure (see below) but once that was
fixed devices were enumerated correctly. I tested this also with modified
SPI/I2C/GPIO patches and they also work as expected on my test machine.

Nice work, thanks.

> ---
>  drivers/acpi/acpi_platform.c |   94 +++++-------------------------
>  drivers/acpi/resource.c      |  132 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/acpi.h         |   10 +++
>  3 files changed, 159 insertions(+), 77 deletions(-)
> 
> Index: linux/include/linux/acpi.h
> ===================================================================
> --- linux.orig/include/linux/acpi.h
> +++ linux/include/linux/acpi.h
> @@ -261,6 +261,16 @@ unsigned long acpi_dev_irq_flags(u8 trig
>  bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
>  				 struct resource *res);
>  
> +struct resource_list_entry {
> +	struct list_head node;
> +	struct resource res;
> +};
> +
> +void acpi_dev_free_resource_list(struct list_head *list);
> +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
> +			   int (*preproc)(struct acpi_resource *, void *),
> +			   void *preproc_data);
> +
>  int acpi_check_resource_conflict(const struct resource *res);
>  
>  int acpi_check_region(resource_size_t start, resource_size_t n,
> Index: linux/drivers/acpi/resource.c
> ===================================================================
> --- linux.orig/drivers/acpi/resource.c
> +++ linux/drivers/acpi/resource.c
> @@ -26,6 +26,7 @@
>  #include <linux/device.h>
>  #include <linux/export.h>
>  #include <linux/ioport.h>
> +#include <linux/slab.h>
>  
>  #ifdef CONFIG_X86
>  #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
> @@ -391,3 +392,134 @@ bool acpi_dev_resource_interrupt(struct
>  	return true;
>  }
>  EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
> +
> +/**
> + * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
> + * @list: The head of the resource list to free.
> + */
> +void acpi_dev_free_resource_list(struct list_head *list)
> +{
> +	struct resource_list_entry *rentry, *re;
> +
> +	list_for_each_entry_safe(rentry, re, list, node) {
> +		list_del(&rentry->node);
> +		kfree(rentry);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
> +
> +struct res_proc_context {
> +	struct list_head *list;
> +	int (*preproc)(struct acpi_resource *, void *);
> +	void *preproc_data;
> +	int count;
> +	int error;
> +};
> +
> +static acpi_status acpi_dev_new_resource_entry(struct resource *r,
> +					       struct res_proc_context *c)
> +{
> +	struct resource_list_entry *rentry;
> +
> +	rentry = kmalloc(sizeof(*rentry), GFP_KERNEL);
> +	if (!rentry) {
> +		c->error = -ENOMEM;
> +		return AE_NO_MEMORY;
> +	}
> +	INIT_LIST_HEAD(&rentry->node);
> +	rentry->res = *r;
> +	list_add_tail(&rentry->node, c->list);
> +	c->count++;
> +	return AE_OK;
> +}
> +
> +static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
> +					     void *context)
> +{
> +	struct res_proc_context *c = context;
> +	struct resource r;

We should initialize this to zero, otherwise insert_resource() will fail as
parent, sibling etc. pointers are garbage.

> +	int i;
> +
> +	if (c->preproc) {
> +		int ret;
> +
> +		ret = c->preproc(ares, c->preproc_data);
> +		if (ret < 0) {
> +			c->error = ret;
> +			return AE_ABORT_METHOD;
> +		} else if (ret > 0) {
> +			return AE_OK;
> +		}
> +	}
> +
> +	if (acpi_dev_resource_memory(ares, &r)
> +	    || acpi_dev_resource_io(ares, &r)
> +	    || acpi_dev_resource_address_space(ares, &r)
> +	    || acpi_dev_resource_ext_address_space(ares, &r))
> +		return acpi_dev_new_resource_entry(&r, c);
> +
> +	for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) {
> +		acpi_status status;
> +
> +		status = acpi_dev_new_resource_entry(&r, c);
> +		if (ACPI_FAILURE(status))
> +			return status;
> +	}
> +
> +	return AE_OK;
> +}
> +
> +/**
> + * acpi_dev_get_resources - Get current resources of a device.
> + * @adev: ACPI device node to get the resources for.
> + * @list: Head of the resultant list of resources (must be empty).
> + * @preproc: The caller's preprocessing routine.
> + * @preproc_data: Pointer passed to the caller's preprocessing routine.
> + *
> + * Evaluate the _CRS method for the given device node and process its output by
> + * (1) executing the @preproc() rountine provided by the caller, passing the
> + * resource pointer and @preproc_data to it as arguments, for each ACPI resource
> + * returned and (2) converting all of the returned ACPI resources into struct
> + * resource objects if possible.  If the return value of @preproc() in step (1)
> + * is different from 0, step (2) is not applied to the given ACPI resource and
> + * if that value is negative, the whole processing is aborted and that value is
> + * returned as the final error code.
> + *
> + * The resultant struct resource objects are put on the list pointed to by
> + * @list, that must be empty initially, as members of struct resource_list_entry
> + * objects.  Callers of this routine should use %acpi_dev_free_resource_list() to
> + * free that list.
> + *
> + * The number of resources in the output list is returned on success, an error
> + * code reflecting the error condition is returned otherwise.
> + */
> +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
> +			   int (*preproc)(struct acpi_resource *, void *),
> +			   void *preproc_data)

Could we change this so that you can pass NULL list as well (provided that
the preproc is given)?

This is useful in case when we try to find the SPI/I2C device handle based
on the ACPI serial bus resource address. In that case we are not interested
in any other resources (and hence there is no need to allocate memory for
them etc.)

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

* Re: [Replacement][PATCH 3/3]
  2012-11-13 14:16             ` Mika Westerberg
@ 2012-11-13 15:15               ` Rafael J. Wysocki
  2012-11-13 15:18                 ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 15:15 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Tuesday, November 13, 2012 04:16:42 PM Mika Westerberg wrote:
> On Tue, Nov 13, 2012 at 01:06:59PM +0100, Rafael J. Wysocki wrote:
> > > I don't know any better option.
> > 
> > Well, a better option would be to convince ACPICA to provide us different
> > interfaces. :-)
> 
> Heh, indeed.
> 
> > We might actually try to do that in the future, but for now we still need
> > _CRS to be evaluated centrally rather than by every interested party in
> > isolation.  So below is a replacement for my original [3/3] patch that
> > approaches the problem from a different angle (on top of [1/3] and
> > updated [2/3] sent yesterday).  Please let me know what you think.
> > 
> > Thanks,
> > Rafael
> > 
> > 
> > ---
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > Subject: ACPI: Centralized processing of ACPI device resources
> > 
> > Currently, whoever wants to use ACPI device resources has to call
> > acpi_walk_resources() to browse the buffer returned by the _CRS
> > method for the given device and create filters passed to that
> > routine to apply to the individual resource items.  This generally
> > is cumbersome, time-consuming and inefficient.  Moreover, it may
> > be problematic if resource conflicts need to be resolved, because
> > the different users of _CRS will need to do that in a consistent
> > way.  However, if there are resource conflicts, the ACPI core
> > should be able to resolve them centrally instead of relying on
> > various users of acpi_walk_resources() to handle them correctly
> > together.
> > 
> > For this reason, introduce a new function, acpi_dev_get_resources(),
> > that can be used by subsystems to obtain a list of struct resource
> > objects corresponding to the ACPI device resources returned by
> > _CRS and, if necessary, to apply additional preprocessing routine
> > to the ACPI resources before converting them to the struct resource
> > format.
> > 
> > Make the ACPI code that creates platform device objects use
> > acpi_dev_get_resources() for resource processing instead of executing
> > acpi_walk_resources() twice by itself, which causes it to be much
> > more straightforward and easier to follow.
> > 
> > In the future, acpi_dev_get_resources() can be extended to meet
> > the needs of the ACPI PNP subsystem and other users of _CRS in
> > the kernel.
> > 
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> I found one problem which resulted failure (see below) but once that was
> fixed devices were enumerated correctly. I tested this also with modified
> SPI/I2C/GPIO patches and they also work as expected on my test machine.
> 
> Nice work, thanks.

Well, thanks! :-)

> > ---
> >  drivers/acpi/acpi_platform.c |   94 +++++-------------------------
> >  drivers/acpi/resource.c      |  132 +++++++++++++++++++++++++++++++++++++++++++
> >  include/linux/acpi.h         |   10 +++
> >  3 files changed, 159 insertions(+), 77 deletions(-)
> > 
> > Index: linux/include/linux/acpi.h
> > ===================================================================
> > --- linux.orig/include/linux/acpi.h
> > +++ linux/include/linux/acpi.h
> > @@ -261,6 +261,16 @@ unsigned long acpi_dev_irq_flags(u8 trig
> >  bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
> >  				 struct resource *res);
> >  
> > +struct resource_list_entry {
> > +	struct list_head node;
> > +	struct resource res;
> > +};
> > +
> > +void acpi_dev_free_resource_list(struct list_head *list);
> > +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
> > +			   int (*preproc)(struct acpi_resource *, void *),
> > +			   void *preproc_data);
> > +
> >  int acpi_check_resource_conflict(const struct resource *res);
> >  
> >  int acpi_check_region(resource_size_t start, resource_size_t n,
> > Index: linux/drivers/acpi/resource.c
> > ===================================================================
> > --- linux.orig/drivers/acpi/resource.c
> > +++ linux/drivers/acpi/resource.c
> > @@ -26,6 +26,7 @@
> >  #include <linux/device.h>
> >  #include <linux/export.h>
> >  #include <linux/ioport.h>
> > +#include <linux/slab.h>
> >  
> >  #ifdef CONFIG_X86
> >  #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
> > @@ -391,3 +392,134 @@ bool acpi_dev_resource_interrupt(struct
> >  	return true;
> >  }
> >  EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
> > +
> > +/**
> > + * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
> > + * @list: The head of the resource list to free.
> > + */
> > +void acpi_dev_free_resource_list(struct list_head *list)
> > +{
> > +	struct resource_list_entry *rentry, *re;
> > +
> > +	list_for_each_entry_safe(rentry, re, list, node) {
> > +		list_del(&rentry->node);
> > +		kfree(rentry);
> > +	}
> > +}
> > +EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
> > +
> > +struct res_proc_context {
> > +	struct list_head *list;
> > +	int (*preproc)(struct acpi_resource *, void *);
> > +	void *preproc_data;
> > +	int count;
> > +	int error;
> > +};
> > +
> > +static acpi_status acpi_dev_new_resource_entry(struct resource *r,
> > +					       struct res_proc_context *c)
> > +{
> > +	struct resource_list_entry *rentry;
> > +
> > +	rentry = kmalloc(sizeof(*rentry), GFP_KERNEL);
> > +	if (!rentry) {
> > +		c->error = -ENOMEM;
> > +		return AE_NO_MEMORY;
> > +	}
> > +	INIT_LIST_HEAD(&rentry->node);
> > +	rentry->res = *r;
> > +	list_add_tail(&rentry->node, c->list);
> > +	c->count++;
> > +	return AE_OK;
> > +}
> > +
> > +static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
> > +					     void *context)
> > +{
> > +	struct res_proc_context *c = context;
> > +	struct resource r;
> 
> We should initialize this to zero, otherwise insert_resource() will fail as
> parent, sibling etc. pointers are garbage.

Ah, sorry for overlooking that.

I'll resend the whole [1-3/3] series later today with this bug fixed (hopefully).

> > +	int i;
> > +
> > +	if (c->preproc) {
> > +		int ret;
> > +
> > +		ret = c->preproc(ares, c->preproc_data);
> > +		if (ret < 0) {
> > +			c->error = ret;
> > +			return AE_ABORT_METHOD;
> > +		} else if (ret > 0) {
> > +			return AE_OK;
> > +		}
> > +	}
> > +
> > +	if (acpi_dev_resource_memory(ares, &r)
> > +	    || acpi_dev_resource_io(ares, &r)
> > +	    || acpi_dev_resource_address_space(ares, &r)
> > +	    || acpi_dev_resource_ext_address_space(ares, &r))
> > +		return acpi_dev_new_resource_entry(&r, c);
> > +
> > +	for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) {
> > +		acpi_status status;
> > +
> > +		status = acpi_dev_new_resource_entry(&r, c);
> > +		if (ACPI_FAILURE(status))
> > +			return status;
> > +	}
> > +
> > +	return AE_OK;
> > +}
> > +
> > +/**
> > + * acpi_dev_get_resources - Get current resources of a device.
> > + * @adev: ACPI device node to get the resources for.
> > + * @list: Head of the resultant list of resources (must be empty).
> > + * @preproc: The caller's preprocessing routine.
> > + * @preproc_data: Pointer passed to the caller's preprocessing routine.
> > + *
> > + * Evaluate the _CRS method for the given device node and process its output by
> > + * (1) executing the @preproc() rountine provided by the caller, passing the
> > + * resource pointer and @preproc_data to it as arguments, for each ACPI resource
> > + * returned and (2) converting all of the returned ACPI resources into struct
> > + * resource objects if possible.  If the return value of @preproc() in step (1)
> > + * is different from 0, step (2) is not applied to the given ACPI resource and
> > + * if that value is negative, the whole processing is aborted and that value is
> > + * returned as the final error code.
> > + *
> > + * The resultant struct resource objects are put on the list pointed to by
> > + * @list, that must be empty initially, as members of struct resource_list_entry
> > + * objects.  Callers of this routine should use %acpi_dev_free_resource_list() to
> > + * free that list.
> > + *
> > + * The number of resources in the output list is returned on success, an error
> > + * code reflecting the error condition is returned otherwise.
> > + */
> > +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
> > +			   int (*preproc)(struct acpi_resource *, void *),
> > +			   void *preproc_data)
> 
> Could we change this so that you can pass NULL list as well (provided that
> the preproc is given)?
> 
> This is useful in case when we try to find the SPI/I2C device handle based
> on the ACPI serial bus resource address. In that case we are not interested
> in any other resources (and hence there is no need to allocate memory for
> them etc.)

I'd prefer to have a separate helper function for that, if that's not a
problem.  It should be clear when we ask for resources of a given device
and when we only want to poke things like that.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [Replacement][PATCH 3/3]
  2012-11-13 15:15               ` Rafael J. Wysocki
@ 2012-11-13 15:18                 ` Mika Westerberg
  2012-11-13 15:28                   ` Rafael J. Wysocki
  0 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-13 15:18 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Tue, Nov 13, 2012 at 04:15:51PM +0100, Rafael J. Wysocki wrote:
> > Could we change this so that you can pass NULL list as well (provided that
> > the preproc is given)?
> > 
> > This is useful in case when we try to find the SPI/I2C device handle based
> > on the ACPI serial bus resource address. In that case we are not interested
> > in any other resources (and hence there is no need to allocate memory for
> > them etc.)
> 
> I'd prefer to have a separate helper function for that, if that's not a
> problem.  It should be clear when we ask for resources of a given device
> and when we only want to poke things like that.

It's not a problem, we can have a separate helper for that.

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

* Re: [Replacement][PATCH 3/3]
  2012-11-13 15:18                 ` Mika Westerberg
@ 2012-11-13 15:28                   ` Rafael J. Wysocki
  2012-11-13 15:37                     ` Mika Westerberg
  0 siblings, 1 reply; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 15:28 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Tuesday, November 13, 2012 05:18:13 PM Mika Westerberg wrote:
> On Tue, Nov 13, 2012 at 04:15:51PM +0100, Rafael J. Wysocki wrote:
> > > Could we change this so that you can pass NULL list as well (provided that
> > > the preproc is given)?
> > > 
> > > This is useful in case when we try to find the SPI/I2C device handle based
> > > on the ACPI serial bus resource address. In that case we are not interested
> > > in any other resources (and hence there is no need to allocate memory for
> > > them etc.)
> > 
> > I'd prefer to have a separate helper function for that, if that's not a
> > problem.  It should be clear when we ask for resources of a given device
> > and when we only want to poke things like that.
> 
> It's not a problem, we can have a separate helper for that.

OK

I suppose you can introduce such a helper in the GPIO patch, then? :-)

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [Replacement][PATCH 3/3]
  2012-11-13 15:28                   ` Rafael J. Wysocki
@ 2012-11-13 15:37                     ` Mika Westerberg
  0 siblings, 0 replies; 127+ messages in thread
From: Mika Westerberg @ 2012-11-13 15:37 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Moore, Robert

On Tue, Nov 13, 2012 at 04:28:50PM +0100, Rafael J. Wysocki wrote:
> On Tuesday, November 13, 2012 05:18:13 PM Mika Westerberg wrote:
> > On Tue, Nov 13, 2012 at 04:15:51PM +0100, Rafael J. Wysocki wrote:
> > > > Could we change this so that you can pass NULL list as well (provided that
> > > > the preproc is given)?
> > > > 
> > > > This is useful in case when we try to find the SPI/I2C device handle based
> > > > on the ACPI serial bus resource address. In that case we are not interested
> > > > in any other resources (and hence there is no need to allocate memory for
> > > > them etc.)
> > > 
> > > I'd prefer to have a separate helper function for that, if that's not a
> > > problem.  It should be clear when we ask for resources of a given device
> > > and when we only want to poke things like that.
> > 
> > It's not a problem, we can have a separate helper for that.
> 
> OK
> 
> I suppose you can introduce such a helper in the GPIO patch, then? :-)

Actually we don't need that at all - we just need to return 1 from the
preproc function and acpi_dev_get_resources() will skip creating the normal
resources (altough we still need to pass valid resource_list but that is
not a problem).

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-13  7:12         ` Mika Westerberg
@ 2012-11-13 16:34             ` Moore, Robert
  2012-11-13 16:34             ` Moore, Robert
  1 sibling, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-13 16:34 UTC (permalink / raw)
  To: Mika Westerberg, Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, Wysocki, Rafael J,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Zheng, Lv

> I suppose we can just do acpi_get_current_resources() and play with 
> the buffer returned by it.  That won't be nice, but still better than 
> what we have.

A couple of the reasons we created the ACPICA resource manager was to:
1) Simplify host access to the various resource fields, especially packed flags.
2) Avoid alignment issues, especially on machines that don't support misaligned transfers.

If there are issues with the current resource manager, we can discuss them. But I would hope that you really don't want to be fussing around with the raw data coming back from the AML. It is not pretty and we have gone to some lengths to make the entire conversion table-driven to minimize bugs and simplify maintenance.

Bob


> -----Original Message-----
> From: Mika Westerberg [mailto:mika.westerberg@linux.intel.com]
> Sent: Monday, November 12, 2012 11:12 PM
> To: Rafael J. Wysocki
> Cc: mathias.nyman@linux.intel.com; linux-acpi@vger.kernel.org; linux-
> kernel@vger.kernel.org; lenb@kernel.org; Wysocki, Rafael J;
> broonie@opensource.wolfsonmicro.com; grant.likely@secretlab.ca;
> linus.walleij@linaro.org; khali@linux-fr.org; Bjorn Helgaas; Moore, Robert
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > > > +					 void *context)
> > > > +{
> > > > +	struct list_head *list = context;
> > > > +	struct acpi_resource_list_entry *entry;
> > > > +
> > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > +	if (!entry)
> > > > +		return AE_NO_MEMORY;
> > > > +
> > > > +	entry->resource = *res;
> > >
> > > This does not work well with all resource types - specifically those
> > > that contain pointers, like acpi_resource_gpio and
> acpi_resource_source.
> >
> > Good point.
> >
> > Well, this pretty much means we can't copy those things.
> 
> Yeah. I only noticed this yesterday when I tested the GPIO translation in
> a custom driver (since it uses the acpi_resource_gpio).
> 
> > > The memory for the resources gets freed once acpi_walk_resources() is
> done.
> >
> > I know that.
> >
> > Having to evaluate _CRS and creating a buffer, converting the output
> > into ACPI resources and so on every time we need to look into the
> > device's current resources is totally inefficient.  We _need_ to cache
> the _CRS output.
> 
> I agree and besides having adev->resources is much easier to use than
> calling acpi_walk_resources() everytime.
> 
> > Now, because of the pointers in certain types of resources, we can't
> > make copies of the resource objects used by acpi_walk_resources()
> > which makes that function totally unuseful to us.
> >
> > I suppose we can just do acpi_get_current_resources() and play with
> > the buffer returned by it.  That won't be nice, but still better than
> > what we have.
> 
> I don't know any better option.
> 
> Thanks.

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-13 16:34             ` Moore, Robert
  0 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-13 16:34 UTC (permalink / raw)
  To: Mika Westerberg, Rafael J. Wysocki
  Cc: mathias.nyman, linux-acpi, linux-kernel, lenb, Wysocki, Rafael J,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas,
	Zheng, Lv

> I suppose we can just do acpi_get_current_resources() and play with 
> the buffer returned by it.  That won't be nice, but still better than 
> what we have.

A couple of the reasons we created the ACPICA resource manager was to:
1) Simplify host access to the various resource fields, especially packed flags.
2) Avoid alignment issues, especially on machines that don't support misaligned transfers.

If there are issues with the current resource manager, we can discuss them. But I would hope that you really don't want to be fussing around with the raw data coming back from the AML. It is not pretty and we have gone to some lengths to make the entire conversion table-driven to minimize bugs and simplify maintenance.

Bob


> -----Original Message-----
> From: Mika Westerberg [mailto:mika.westerberg@linux.intel.com]
> Sent: Monday, November 12, 2012 11:12 PM
> To: Rafael J. Wysocki
> Cc: mathias.nyman@linux.intel.com; linux-acpi@vger.kernel.org; linux-
> kernel@vger.kernel.org; lenb@kernel.org; Wysocki, Rafael J;
> broonie@opensource.wolfsonmicro.com; grant.likely@secretlab.ca;
> linus.walleij@linaro.org; khali@linux-fr.org; Bjorn Helgaas; Moore, Robert
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > > > +					 void *context)
> > > > +{
> > > > +	struct list_head *list = context;
> > > > +	struct acpi_resource_list_entry *entry;
> > > > +
> > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > +	if (!entry)
> > > > +		return AE_NO_MEMORY;
> > > > +
> > > > +	entry->resource = *res;
> > >
> > > This does not work well with all resource types - specifically those
> > > that contain pointers, like acpi_resource_gpio and
> acpi_resource_source.
> >
> > Good point.
> >
> > Well, this pretty much means we can't copy those things.
> 
> Yeah. I only noticed this yesterday when I tested the GPIO translation in
> a custom driver (since it uses the acpi_resource_gpio).
> 
> > > The memory for the resources gets freed once acpi_walk_resources() is
> done.
> >
> > I know that.
> >
> > Having to evaluate _CRS and creating a buffer, converting the output
> > into ACPI resources and so on every time we need to look into the
> > device's current resources is totally inefficient.  We _need_ to cache
> the _CRS output.
> 
> I agree and besides having adev->resources is much easier to use than
> calling acpi_walk_resources() everytime.
> 
> > Now, because of the pointers in certain types of resources, we can't
> > make copies of the resource objects used by acpi_walk_resources()
> > which makes that function totally unuseful to us.
> >
> > I suppose we can just do acpi_get_current_resources() and play with
> > the buffer returned by it.  That won't be nice, but still better than
> > what we have.
> 
> I don't know any better option.
> 
> Thanks.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-13 16:34             ` Moore, Robert
@ 2012-11-13 20:44               ` Rafael J. Wysocki
  -1 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 20:44 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Tuesday, November 13, 2012 04:34:07 PM Moore, Robert wrote:
> > I suppose we can just do acpi_get_current_resources() and play with 
> > the buffer returned by it.  That won't be nice, but still better than 
> > what we have.
> 
> A couple of the reasons we created the ACPICA resource manager was to:
> 1) Simplify host access to the various resource fields, especially packed flags.
> 2) Avoid alignment issues, especially on machines that don't support misaligned transfers.

That's fine.

> If there are issues with the current resource manager, we can discuss them.
> But I would hope that you really don't want to be fussing around with the raw
> data coming back from the AML.

No, I don't. :-)

I'd like to be able to do more things with struct acpi_resource objects.

Pretty much the output of acpi_get_current_resources() is what I'm
interested in, but there doesn't seem to be any convenient way to access
things in the return buffer from the outside of ACPICA now.

> It is not pretty and we have gone to some lengths to make the entire
> conversion table-driven to minimize bugs and simplify maintenance.

OK

So what I would like to have, in general terms, is something like
acpi_walk_resources() split into three parts:

 (1) One that processes the _CRS output and creates a list of
     struct acpi_resource objects for us to play with.  I suppose
     it's OK if that's just a buffer filled with resource objects,
     but a linked list might be more convenient.

 (2) One that allows us to access (read/write) resources in the
     list returned by (1).  We don't need to open code walking
     the list and I probably wouldn't event want to do that.  What
     we need is to be able to walk the same list for a number of
     times and possibly to modify values in the resource objects
     if there are conflicts.

 (3) One allowing us to free the list returned by (1) if not needed
     any more.

And it would be great if we could take the list returned by (1),
modify the resources in it and feed it back to _SRS (after conversion
back to the format that _SRS understands).

Thanks,
Rafael


> > -----Original Message-----
> > From: Mika Westerberg [mailto:mika.westerberg@linux.intel.com]
> > Sent: Monday, November 12, 2012 11:12 PM
> > To: Rafael J. Wysocki
> > Cc: mathias.nyman@linux.intel.com; linux-acpi@vger.kernel.org; linux-
> > kernel@vger.kernel.org; lenb@kernel.org; Wysocki, Rafael J;
> > broonie@opensource.wolfsonmicro.com; grant.likely@secretlab.ca;
> > linus.walleij@linaro.org; khali@linux-fr.org; Bjorn Helgaas; Moore, Robert
> > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> > objects
> > 
> > On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > > > > +					 void *context)
> > > > > +{
> > > > > +	struct list_head *list = context;
> > > > > +	struct acpi_resource_list_entry *entry;
> > > > > +
> > > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > > +	if (!entry)
> > > > > +		return AE_NO_MEMORY;
> > > > > +
> > > > > +	entry->resource = *res;
> > > >
> > > > This does not work well with all resource types - specifically those
> > > > that contain pointers, like acpi_resource_gpio and
> > acpi_resource_source.
> > >
> > > Good point.
> > >
> > > Well, this pretty much means we can't copy those things.
> > 
> > Yeah. I only noticed this yesterday when I tested the GPIO translation in
> > a custom driver (since it uses the acpi_resource_gpio).
> > 
> > > > The memory for the resources gets freed once acpi_walk_resources() is
> > done.
> > >
> > > I know that.
> > >
> > > Having to evaluate _CRS and creating a buffer, converting the output
> > > into ACPI resources and so on every time we need to look into the
> > > device's current resources is totally inefficient.  We _need_ to cache
> > the _CRS output.
> > 
> > I agree and besides having adev->resources is much easier to use than
> > calling acpi_walk_resources() everytime.
> > 
> > > Now, because of the pointers in certain types of resources, we can't
> > > make copies of the resource objects used by acpi_walk_resources()
> > > which makes that function totally unuseful to us.
> > >
> > > I suppose we can just do acpi_get_current_resources() and play with
> > > the buffer returned by it.  That won't be nice, but still better than
> > > what we have.
> > 
> > I don't know any better option.
> > 
> > Thanks.
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-13 20:44               ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 20:44 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Tuesday, November 13, 2012 04:34:07 PM Moore, Robert wrote:
> > I suppose we can just do acpi_get_current_resources() and play with 
> > the buffer returned by it.  That won't be nice, but still better than 
> > what we have.
> 
> A couple of the reasons we created the ACPICA resource manager was to:
> 1) Simplify host access to the various resource fields, especially packed flags.
> 2) Avoid alignment issues, especially on machines that don't support misaligned transfers.

That's fine.

> If there are issues with the current resource manager, we can discuss them.
> But I would hope that you really don't want to be fussing around with the raw
> data coming back from the AML.

No, I don't. :-)

I'd like to be able to do more things with struct acpi_resource objects.

Pretty much the output of acpi_get_current_resources() is what I'm
interested in, but there doesn't seem to be any convenient way to access
things in the return buffer from the outside of ACPICA now.

> It is not pretty and we have gone to some lengths to make the entire
> conversion table-driven to minimize bugs and simplify maintenance.

OK

So what I would like to have, in general terms, is something like
acpi_walk_resources() split into three parts:

 (1) One that processes the _CRS output and creates a list of
     struct acpi_resource objects for us to play with.  I suppose
     it's OK if that's just a buffer filled with resource objects,
     but a linked list might be more convenient.

 (2) One that allows us to access (read/write) resources in the
     list returned by (1).  We don't need to open code walking
     the list and I probably wouldn't event want to do that.  What
     we need is to be able to walk the same list for a number of
     times and possibly to modify values in the resource objects
     if there are conflicts.

 (3) One allowing us to free the list returned by (1) if not needed
     any more.

And it would be great if we could take the list returned by (1),
modify the resources in it and feed it back to _SRS (after conversion
back to the format that _SRS understands).

Thanks,
Rafael


> > -----Original Message-----
> > From: Mika Westerberg [mailto:mika.westerberg@linux.intel.com]
> > Sent: Monday, November 12, 2012 11:12 PM
> > To: Rafael J. Wysocki
> > Cc: mathias.nyman@linux.intel.com; linux-acpi@vger.kernel.org; linux-
> > kernel@vger.kernel.org; lenb@kernel.org; Wysocki, Rafael J;
> > broonie@opensource.wolfsonmicro.com; grant.likely@secretlab.ca;
> > linus.walleij@linaro.org; khali@linux-fr.org; Bjorn Helgaas; Moore, Robert
> > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> > objects
> > 
> > On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource *res,
> > > > > +					 void *context)
> > > > > +{
> > > > > +	struct list_head *list = context;
> > > > > +	struct acpi_resource_list_entry *entry;
> > > > > +
> > > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > > +	if (!entry)
> > > > > +		return AE_NO_MEMORY;
> > > > > +
> > > > > +	entry->resource = *res;
> > > >
> > > > This does not work well with all resource types - specifically those
> > > > that contain pointers, like acpi_resource_gpio and
> > acpi_resource_source.
> > >
> > > Good point.
> > >
> > > Well, this pretty much means we can't copy those things.
> > 
> > Yeah. I only noticed this yesterday when I tested the GPIO translation in
> > a custom driver (since it uses the acpi_resource_gpio).
> > 
> > > > The memory for the resources gets freed once acpi_walk_resources() is
> > done.
> > >
> > > I know that.
> > >
> > > Having to evaluate _CRS and creating a buffer, converting the output
> > > into ACPI resources and so on every time we need to look into the
> > > device's current resources is totally inefficient.  We _need_ to cache
> > the _CRS output.
> > 
> > I agree and besides having adev->resources is much easier to use than
> > calling acpi_walk_resources() everytime.
> > 
> > > Now, because of the pointers in certain types of resources, we can't
> > > make copies of the resource objects used by acpi_walk_resources()
> > > which makes that function totally unuseful to us.
> > >
> > > I suppose we can just do acpi_get_current_resources() and play with
> > > the buffer returned by it.  That won't be nice, but still better than
> > > what we have.
> > 
> > I don't know any better option.
> > 
> > Thanks.
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources
  2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
                     ` (2 preceding siblings ...)
  2012-11-12 12:02   ` [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects Rafael J. Wysocki
@ 2012-11-13 20:51   ` Rafael J. Wysocki
  2012-11-13 20:55     ` [PATCH 1/3 rev 2] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
                       ` (3 more replies)
  3 siblings, 4 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 20:51 UTC (permalink / raw)
  To: linux-acpi
  Cc: Mika Westerberg, mathias.nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas

On Monday, November 12, 2012 12:51:32 PM Rafael J. Wysocki wrote:
> On Saturday, November 03, 2012 09:46:30 AM Mika Westerberg wrote:
> > Hi,
> > 
> > With ACPI 5 we can now describe how devices are connected to their bus
> > using new resources: SPISerialBus and I2CSerialBus. Also it is now possible
> > to add GPIO connections for the devices with the help of GpioIO and GpioInt
> > resources.
> > 
> > This series adds support for these new resources.
> > 
> > The series based on the ACPI 5 enumeration support patches that are available
> > on Rafael's linux-next branch:
> > 
> > 	git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next	
> > 
> > Specifically patches from this thread:
> > 
> > 	https://lkml.org/lkml/2012/10/31/154
> > 
> > Since these patches depend on the above patches on Rafael's linux-next branch
> > I suggest that these be merged via that branch, if there are no objections.
> > 
> > The series follows the Device Tree way so that it would be easy to add ACPI
> > support for the existing SPI and I2C drivers if one is familiar how the
> > corresponding DT support is done.
> > 
> > For GPIO we introduce a function that maps between ACPI GPIO numbers and Linux
> > ones - acpi_get_gpio().
> > 
> > SPI slave devices gets enumerated automatically if the master device has
> > master->dev.acpi_handle set (this is analogous to master->dev.of_mode). The
> > platform bus code in Rafael's branch assigns the ACPI handle to the master
> > device.
> > 
> > I2C slave devices can be enumerated by calling acpi_i2c_register_devices() in
> > the adapter driver.
> 
> Following the previous discussion, the patches below move some ACPI resources
> parsing code from drivers/pnp/pnpacpi/rsparser.c to a new file
> drivers/acpi/resource.c and reformat it so that it can be used by other
> subsystems (patch [1/3]), convert the new ACPI platform devices creation
> code to use the routines in drivers/acpi/resource.c instead of doing its
> own resource parsing (patch [2/3]) and make the ACPI namespace scan attach
> a list of _CRS resources to each struct acpi_device it creates, where
> applicable (patch [3/3] - the ACPI platform device code is converted to use
> that instead of executing _CRS by itself via acpi_walk_resources()).
> 
> The patchset is on top of the current linux-pm.git/linux-next branch and
> has been tested somewhat.  Please let me know if you find any problems in it.

Updated series, taking the Mika's feedback into account, follows.  There are
bug fixes in [1/3], [2/3] is unchanged and the new [3/3] is a replacement, done
in a different way because of some ACPICA limitations I didn't realize before.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* [PATCH 1/3 rev 2] ACPI: Move device resources interpretation code from PNP to ACPI core
  2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
@ 2012-11-13 20:55     ` Rafael J. Wysocki
  2012-11-13 20:55     ` [PATCH 2/3 rev 2] ACPI / platform: Use common ACPI device resource parsing routines Rafael J. Wysocki
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 20:55 UTC (permalink / raw)
  To: linux-acpi
  Cc: Mika Westerberg, mathias.nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Move some code used for parsing ACPI device resources from the PNP
subsystem to the ACPI core, so that other bus types (platform, SPI,
I2C) can use the same routines for parsing resources in a consistent
way, without duplicating code.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/Makefile          |    1 
 drivers/acpi/resource.c        |  393 +++++++++++++++++++++++++++++++++++++++++
 drivers/pnp/base.h             |    2 
 drivers/pnp/pnpacpi/rsparser.c |  296 +++---------------------------
 drivers/pnp/resource.c         |   16 +
 include/linux/acpi.h           |   10 +
 6 files changed, 454 insertions(+), 264 deletions(-)

Index: linux/drivers/acpi/resource.c
===================================================================
--- /dev/null
+++ linux/drivers/acpi/resource.c
@@ -0,0 +1,393 @@
+/*
+ * drivers/acpi/resource.c - ACPI device resources interpretation.
+ *
+ * Copyright (C) 2012, Intel Corp.
+ * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_X86
+#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
+#else
+#define valid_IRQ(i) (true)
+#endif
+
+static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect,
+						bool window)
+{
+	unsigned long flags = IORESOURCE_MEM;
+
+	if (len == 0)
+		flags |= IORESOURCE_DISABLED;
+
+	if (write_protect == ACPI_READ_WRITE_MEMORY)
+		flags |= IORESOURCE_MEM_WRITEABLE;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len,
+				     u8 write_protect)
+{
+	res->start = start;
+	res->end = start + len - 1;
+	res->flags = acpi_dev_memresource_flags(len, write_protect, false);
+}
+
+/**
+ * acpi_dev_resource_memory - Extract ACPI memory resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents a memory resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_memory24 *memory24;
+	struct acpi_resource_memory32 *memory32;
+	struct acpi_resource_fixed_memory32 *fixed_memory32;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_MEMORY24:
+		memory24 = &ares->data.memory24;
+		acpi_dev_get_memresource(res, memory24->minimum,
+					 memory24->address_length,
+					 memory24->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_MEMORY32:
+		memory32 = &ares->data.memory32;
+		acpi_dev_get_memresource(res, memory32->minimum,
+					 memory32->address_length,
+					 memory32->write_protect);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		fixed_memory32 = &ares->data.fixed_memory32;
+		acpi_dev_get_memresource(res, fixed_memory32->address,
+					 fixed_memory32->address_length,
+					 fixed_memory32->write_protect);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_memory);
+
+static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode,
+					      bool window)
+{
+	int flags = IORESOURCE_IO;
+
+	if (io_decode == ACPI_DECODE_16)
+		flags |= IORESOURCE_IO_16BIT_ADDR;
+
+	if (start > end || end >= 0x10003)
+		flags |= IORESOURCE_DISABLED;
+
+	if (window)
+		flags |= IORESOURCE_WINDOW;
+
+	return flags;
+}
+
+static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len,
+				    u8 io_decode)
+{
+	u64 end = start + len - 1;
+
+	res->start = start;
+	res->end = end;
+	res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false);
+}
+
+/**
+ * acpi_dev_resource_io - Extract ACPI I/O resource information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an I/O resource and
+ * if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res)
+{
+	struct acpi_resource_io *io;
+	struct acpi_resource_fixed_io *fixed_io;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IO:
+		io = &ares->data.io;
+		acpi_dev_get_ioresource(res, io->minimum,
+					io->address_length,
+					io->io_decode);
+		break;
+	case ACPI_RESOURCE_TYPE_FIXED_IO:
+		fixed_io = &ares->data.fixed_io;
+		acpi_dev_get_ioresource(res, fixed_io->address,
+					fixed_io->address_length,
+					ACPI_DECODE_10);
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_io);
+
+/**
+ * acpi_dev_resource_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an address space resource
+ * and if that's the case, use the information in it to populate the generic
+ * resource object pointed to by @res.
+ */
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res)
+{
+	acpi_status status;
+	struct acpi_resource_address64 addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_ADDRESS16:
+	case ACPI_RESOURCE_TYPE_ADDRESS32:
+	case ACPI_RESOURCE_TYPE_ADDRESS64:
+		break;
+	default:
+		return false;
+	}
+
+	status = acpi_resource_to_address64(ares, &addr);
+	if (ACPI_FAILURE(status))
+		return true;
+
+	res->start = addr.minimum;
+	res->end = addr.maximum;
+	window = addr.producer_consumer == ACPI_PRODUCER;
+
+	switch(addr.resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = addr.maximum - addr.minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+						addr.info.mem.write_protect,
+						window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = addr.granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(addr.minimum,
+						       addr.maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space);
+
+/**
+ * acpi_dev_resource_ext_address_space - Extract ACPI address space information.
+ * @ares: Input ACPI resource object.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an extended address space
+ * resource and if that's the case, use the information in it to populate the
+ * generic resource object pointed to by @res.
+ */
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res)
+{
+	struct acpi_resource_extended_address64 *ext_addr;
+	bool window;
+	u64 len;
+	u8 io_decode;
+
+	if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64)
+		return false;
+
+	ext_addr = &ares->data.ext_address64;
+
+	res->start = ext_addr->minimum;
+	res->end = ext_addr->maximum;
+	window = ext_addr->producer_consumer == ACPI_PRODUCER;
+
+	switch(ext_addr->resource_type) {
+	case ACPI_MEMORY_RANGE:
+		len = ext_addr->maximum - ext_addr->minimum + 1;
+		res->flags = acpi_dev_memresource_flags(len,
+					ext_addr->info.mem.write_protect,
+					window);
+		break;
+	case ACPI_IO_RANGE:
+		io_decode = ext_addr->granularity == 0xfff ?
+				ACPI_DECODE_10 : ACPI_DECODE_16;
+		res->flags = acpi_dev_ioresource_flags(ext_addr->minimum,
+						       ext_addr->maximum,
+						       io_decode, window);
+		break;
+	case ACPI_BUS_NUMBER_RANGE:
+		res->flags = IORESOURCE_BUS;
+		break;
+	default:
+		res->flags = 0;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space);
+
+/**
+ * acpi_dev_irq_flags - Determine IRQ resource flags.
+ * @triggering: Triggering type as provided by ACPI.
+ * @polarity: Interrupt polarity as provided by ACPI.
+ * @shareable: Whether or not the interrupt is shareable.
+ */
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable)
+{
+	unsigned long flags;
+
+	if (triggering == ACPI_LEVEL_SENSITIVE)
+		flags = polarity == ACPI_ACTIVE_LOW ?
+			IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL;
+	else
+		flags = polarity == ACPI_ACTIVE_LOW ?
+			IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE;
+
+	if (shareable == ACPI_SHARED)
+		flags |= IORESOURCE_IRQ_SHAREABLE;
+
+	return flags | IORESOURCE_IRQ;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_irq_flags);
+
+static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi)
+{
+	res->start = gsi;
+	res->end = gsi;
+	res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED;
+}
+
+static void acpi_dev_get_irqresource(struct resource *res, u32 gsi,
+				     u8 triggering, u8 polarity, u8 shareable)
+{
+	int irq, p, t;
+
+	if (!valid_IRQ(gsi)) {
+		acpi_dev_irqresource_disabled(res, gsi);
+		return;
+	}
+
+	/*
+	 * In IO-APIC mode, use overrided attribute. Two reasons:
+	 * 1. BIOS bug in DSDT
+	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
+	 */
+	if (!acpi_get_override_irq(gsi, &t, &p)) {
+		u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
+		u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
+
+		if (triggering != trig || polarity != pol) {
+			pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi,
+				   t ? "edge" : "level", p ? "low" : "high");
+			triggering = trig;
+			polarity = pol;
+		}
+	}
+
+	res->flags = acpi_dev_irq_flags(triggering, polarity, shareable);
+	irq = acpi_register_gsi(NULL, gsi, triggering, polarity);
+	if (irq >= 0) {
+		res->start = irq;
+		res->end = irq;
+	} else {
+		acpi_dev_irqresource_disabled(res, gsi);
+	}
+}
+
+/**
+ * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information.
+ * @ares: Input ACPI resource object.
+ * @index: Index into the array of GSIs represented by the resource.
+ * @res: Output generic resource object.
+ *
+ * Check if the given ACPI resource object represents an interrupt resource
+ * and @index does not exceed the resource's interrupt count (true is returned
+ * in that case regardless of the results of the other checks)).  If that's the
+ * case, register the GSI corresponding to @index from the array of interrupts
+ * represented by the resource and populate the generic resource object pointed
+ * to by @res accordingly.  If the registration of the GSI is not successful,
+ * IORESOURCE_DISABLED will be set it that object's flags.
+ */
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res)
+{
+	struct acpi_resource_irq *irq;
+	struct acpi_resource_extended_irq *ext_irq;
+
+	switch (ares->type) {
+	case ACPI_RESOURCE_TYPE_IRQ:
+		/*
+		 * Per spec, only one interrupt per descriptor is allowed in
+		 * _CRS, but some firmware violates this, so parse them all.
+		 */
+		irq = &ares->data.irq;
+		if (index >= irq->interrupt_count) {
+			acpi_dev_irqresource_disabled(res, 0);
+			return false;
+		}
+		acpi_dev_get_irqresource(res, irq->interrupts[index],
+					 irq->triggering, irq->polarity,
+					 irq->sharable);
+		break;
+	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
+		ext_irq = &ares->data.extended_irq;
+		if (index >= ext_irq->interrupt_count) {
+			acpi_dev_irqresource_disabled(res, 0);
+			return false;
+		}
+		acpi_dev_get_irqresource(res, ext_irq->interrupts[index],
+					 ext_irq->triggering, ext_irq->polarity,
+					 ext_irq->sharable);
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
Index: linux/drivers/acpi/Makefile
===================================================================
--- linux.orig/drivers/acpi/Makefile
+++ linux/drivers/acpi/Makefile
@@ -33,6 +33,7 @@ acpi-$(CONFIG_ACPI_SLEEP)	+= proc.o
 #
 acpi-y				+= bus.o glue.o
 acpi-y				+= scan.o
+acpi-y				+= resource.o
 acpi-y				+= processor_core.o
 acpi-y				+= ec.o
 acpi-$(CONFIG_ACPI_DOCK)	+= dock.o
Index: linux/drivers/pnp/pnpacpi/rsparser.c
===================================================================
--- linux.orig/drivers/pnp/pnpacpi/rsparser.c
+++ linux/drivers/pnp/pnpacpi/rsparser.c
@@ -28,37 +28,6 @@
 #include "../base.h"
 #include "pnpacpi.h"
 
-#ifdef CONFIG_IA64
-#define valid_IRQ(i) (1)
-#else
-#define valid_IRQ(i) (((i) != 0) && ((i) != 2))
-#endif
-
-/*
- * Allocated Resources
- */
-static int irq_flags(int triggering, int polarity, int shareable)
-{
-	int flags;
-
-	if (triggering == ACPI_LEVEL_SENSITIVE) {
-		if (polarity == ACPI_ACTIVE_LOW)
-			flags = IORESOURCE_IRQ_LOWLEVEL;
-		else
-			flags = IORESOURCE_IRQ_HIGHLEVEL;
-	} else {
-		if (polarity == ACPI_ACTIVE_LOW)
-			flags = IORESOURCE_IRQ_LOWEDGE;
-		else
-			flags = IORESOURCE_IRQ_HIGHEDGE;
-	}
-
-	if (shareable == ACPI_SHARED)
-		flags |= IORESOURCE_IRQ_SHAREABLE;
-
-	return flags;
-}
-
 static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering,
 			     int *polarity, int *shareable)
 {
@@ -94,45 +63,6 @@ static void decode_irq_flags(struct pnp_
 		*shareable = ACPI_EXCLUSIVE;
 }
 
-static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev,
-						u32 gsi, int triggering,
-						int polarity, int shareable)
-{
-	int irq, flags;
-	int p, t;
-
-	if (!valid_IRQ(gsi)) {
-		pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED);
-		return;
-	}
-
-	/*
-	 * in IO-APIC mode, use overrided attribute. Two reasons:
-	 * 1. BIOS bug in DSDT
-	 * 2. BIOS uses IO-APIC mode Interrupt Source Override
-	 */
-	if (!acpi_get_override_irq(gsi, &t, &p)) {
-		t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
-		p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
-
-		if (triggering != t || polarity != p) {
-			dev_warn(&dev->dev, "IRQ %d override to %s, %s\n",
-				gsi, t ? "edge":"level", p ? "low":"high");
-			triggering = t;
-			polarity = p;
-		}
-	}
-
-	flags = irq_flags(triggering, polarity, shareable);
-	irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity);
-	if (irq >= 0)
-		pcibios_penalize_isa_irq(irq, 1);
-	else
-		flags |= IORESOURCE_DISABLED;
-
-	pnp_add_irq_resource(dev, irq, flags);
-}
-
 static int dma_flags(struct pnp_dev *dev, int type, int bus_master,
 		     int transfer)
 {
@@ -177,21 +107,16 @@ static int dma_flags(struct pnp_dev *dev
 	return flags;
 }
 
-static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start,
-					       u64 len, int io_decode,
-					       int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
+/*
+ * Allocated Resources
+ */
 
-	if (io_decode == ACPI_DECODE_16)
-		flags |= IORESOURCE_IO_16BIT_ADDR;
-	if (len == 0 || end >= 0x10003)
-		flags |= IORESOURCE_DISABLED;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
+static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r)
+{
+	if (!(r->flags & IORESOURCE_DISABLED))
+		pcibios_penalize_isa_irq(r->start, 1);
 
-	pnp_add_io_resource(dev, start, end, flags);
+	pnp_add_resource(dev, r);
 }
 
 /*
@@ -249,130 +174,49 @@ static void pnpacpi_parse_allocated_vend
 	}
 }
 
-static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev,
-						u64 start, u64 len,
-						int write_protect, int window)
-{
-	int flags = 0;
-	u64 end = start + len - 1;
-
-	if (len == 0)
-		flags |= IORESOURCE_DISABLED;
-	if (write_protect == ACPI_READ_WRITE_MEMORY)
-		flags |= IORESOURCE_MEM_WRITEABLE;
-	if (window)
-		flags |= IORESOURCE_WINDOW;
-
-	pnp_add_mem_resource(dev, start, end, flags);
-}
-
-static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev,
-						u64 start, u64 len)
-{
-	u64 end = start + len - 1;
-
-	pnp_add_bus_resource(dev, start, end);
-}
-
-static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev,
-						  struct acpi_resource *res)
-{
-	struct acpi_resource_address64 addr, *p = &addr;
-	acpi_status status;
-	int window;
-	u64 len;
-
-	status = acpi_resource_to_address64(res, p);
-	if (!ACPI_SUCCESS(status)) {
-		dev_warn(&dev->dev, "failed to convert resource type %d\n",
-			 res->type);
-		return;
-	}
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
-static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev,
-						      struct acpi_resource *res)
-{
-	struct acpi_resource_extended_address64 *p = &res->data.ext_address64;
-	int window;
-	u64 len;
-
-	/* Windows apparently computes length rather than using _LEN */
-	len = p->maximum - p->minimum + 1;
-	window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0;
-
-	if (p->resource_type == ACPI_MEMORY_RANGE)
-		pnpacpi_parse_allocated_memresource(dev, p->minimum, len,
-			p->info.mem.write_protect, window);
-	else if (p->resource_type == ACPI_IO_RANGE)
-		pnpacpi_parse_allocated_ioresource(dev, p->minimum, len,
-			p->granularity == 0xfff ? ACPI_DECODE_10 :
-				ACPI_DECODE_16, window);
-	else if (p->resource_type == ACPI_BUS_NUMBER_RANGE)
-		pnpacpi_parse_allocated_busresource(dev, p->minimum, len);
-}
-
 static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
 					      void *data)
 {
 	struct pnp_dev *dev = data;
-	struct acpi_resource_irq *irq;
 	struct acpi_resource_dma *dma;
-	struct acpi_resource_io *io;
-	struct acpi_resource_fixed_io *fixed_io;
 	struct acpi_resource_vendor_typed *vendor_typed;
-	struct acpi_resource_memory24 *memory24;
-	struct acpi_resource_memory32 *memory32;
-	struct acpi_resource_fixed_memory32 *fixed_memory32;
-	struct acpi_resource_extended_irq *extended_irq;
+	struct resource r;
 	int i, flags;
 
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		/*
-		 * Per spec, only one interrupt per descriptor is allowed in
-		 * _CRS, but some firmware violates this, so parse them all.
-		 */
-		irq = &res->data.irq;
-		if (irq->interrupt_count == 0)
-			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
-		else {
-			for (i = 0; i < irq->interrupt_count; i++) {
-				pnpacpi_parse_allocated_irqresource(dev,
-					irq->interrupts[i],
-					irq->triggering,
-					irq->polarity,
-				    irq->sharable);
-			}
+	if (acpi_dev_resource_memory(res, &r)
+	    || acpi_dev_resource_io(res, &r)
+	    || acpi_dev_resource_address_space(res, &r)
+	    || acpi_dev_resource_ext_address_space(res, &r)) {
+		pnp_add_resource(dev, &r);
+		return AE_OK;
+	}
+
+	r.flags = 0;
+	if (acpi_dev_resource_interrupt(res, 0, &r)) {
+		pnpacpi_add_irqresource(dev, &r);
+		for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++)
+			pnpacpi_add_irqresource(dev, &r);
 
+		if (i > 1) {
 			/*
 			 * The IRQ encoder puts a single interrupt in each
 			 * descriptor, so if a _CRS descriptor has more than
 			 * one interrupt, we won't be able to re-encode it.
 			 */
-			if (pnp_can_write(dev) && irq->interrupt_count > 1) {
+			if (pnp_can_write(dev)) {
 				dev_warn(&dev->dev, "multiple interrupts in "
 					 "_CRS descriptor; configuration can't "
 					 "be changed\n");
 				dev->capabilities &= ~PNP_WRITE;
 			}
 		}
-		break;
+		return AE_OK;
+	} else if (r.flags & IORESOURCE_DISABLED) {
+		pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
+		return AE_OK;
+	}
 
+	switch (res->type) {
 	case ACPI_RESOURCE_TYPE_DMA:
 		dma = &res->data.dma;
 		if (dma->channel_count > 0 && dma->channels[0] != (u8) -1)
@@ -383,26 +227,10 @@ static acpi_status pnpacpi_allocated_res
 		pnp_add_dma_resource(dev, dma->channels[0], flags);
 		break;
 
-	case ACPI_RESOURCE_TYPE_IO:
-		io = &res->data.io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			io->minimum,
-			io->address_length,
-			io->io_decode, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_START_DEPENDENT:
 	case ACPI_RESOURCE_TYPE_END_DEPENDENT:
 		break;
 
-	case ACPI_RESOURCE_TYPE_FIXED_IO:
-		fixed_io = &res->data.fixed_io;
-		pnpacpi_parse_allocated_ioresource(dev,
-			fixed_io->address,
-			fixed_io->address_length,
-			ACPI_DECODE_10, 0);
-		break;
-
 	case ACPI_RESOURCE_TYPE_VENDOR:
 		vendor_typed = &res->data.vendor_typed;
 		pnpacpi_parse_allocated_vendor(dev, vendor_typed);
@@ -411,66 +239,6 @@ static acpi_status pnpacpi_allocated_res
 	case ACPI_RESOURCE_TYPE_END_TAG:
 		break;
 
-	case ACPI_RESOURCE_TYPE_MEMORY24:
-		memory24 = &res->data.memory24;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory24->minimum,
-			memory24->address_length,
-			memory24->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_MEMORY32:
-		memory32 = &res->data.memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			memory32->minimum,
-			memory32->address_length,
-			memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		fixed_memory32 = &res->data.fixed_memory32;
-		pnpacpi_parse_allocated_memresource(dev,
-			fixed_memory32->address,
-			fixed_memory32->address_length,
-			fixed_memory32->write_protect, 0);
-		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS16:
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-	case ACPI_RESOURCE_TYPE_ADDRESS64:
-		pnpacpi_parse_allocated_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
-		pnpacpi_parse_allocated_ext_address_space(dev, res);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		extended_irq = &res->data.extended_irq;
-
-		if (extended_irq->interrupt_count == 0)
-			pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED);
-		else {
-			for (i = 0; i < extended_irq->interrupt_count; i++) {
-				pnpacpi_parse_allocated_irqresource(dev,
-					extended_irq->interrupts[i],
-					extended_irq->triggering,
-					extended_irq->polarity,
-					extended_irq->sharable);
-			}
-
-			/*
-			 * The IRQ encoder puts a single interrupt in each
-			 * descriptor, so if a _CRS descriptor has more than
-			 * one interrupt, we won't be able to re-encode it.
-			 */
-			if (pnp_can_write(dev) &&
-			    extended_irq->interrupt_count > 1) {
-				dev_warn(&dev->dev, "multiple interrupts in "
-					 "_CRS descriptor; configuration can't "
-					 "be changed\n");
-				dev->capabilities &= ~PNP_WRITE;
-			}
-		}
-		break;
-
 	case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
 		break;
 
@@ -531,7 +299,7 @@ static __init void pnpacpi_parse_irq_opt
 		if (p->interrupts[i])
 			__set_bit(p->interrupts[i], map.bits);
 
-	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
@@ -555,7 +323,7 @@ static __init void pnpacpi_parse_ext_irq
 		}
 	}
 
-	flags = irq_flags(p->triggering, p->polarity, p->sharable);
+	flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable);
 	pnp_register_irq_resource(dev, option_flags, &map, flags);
 }
 
Index: linux/drivers/pnp/base.h
===================================================================
--- linux.orig/drivers/pnp/base.h
+++ linux/drivers/pnp/base.h
@@ -159,6 +159,8 @@ struct pnp_resource {
 
 void pnp_free_resource(struct pnp_resource *pnp_res);
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res);
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags);
 struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
Index: linux/drivers/pnp/resource.c
===================================================================
--- linux.orig/drivers/pnp/resource.c
+++ linux/drivers/pnp/resource.c
@@ -503,6 +503,22 @@ static struct pnp_resource *pnp_new_reso
 	return pnp_res;
 }
 
+struct pnp_resource *pnp_add_resource(struct pnp_dev *dev,
+				      struct resource *res)
+{
+	struct pnp_resource *pnp_res;
+
+	pnp_res = pnp_new_resource(dev);
+	if (!pnp_res) {
+		dev_err(&dev->dev, "can't add resource %pR\n", res);
+		return NULL;
+	}
+
+	pnp_res->res = *res;
+	dev_dbg(&dev->dev, "%pR\n", res);
+	return pnp_res;
+}
+
 struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
 					  int flags)
 {
Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -251,6 +251,16 @@ extern int pnpacpi_disabled;
 
 #define PXM_INVAL	(-1)
 
+bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res);
+bool acpi_dev_resource_address_space(struct acpi_resource *ares,
+				     struct resource *res);
+bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares,
+					 struct resource *res);
+unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable);
+bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
+				 struct resource *res);
+
 int acpi_check_resource_conflict(const struct resource *res);
 
 int acpi_check_region(resource_size_t start, resource_size_t n,

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

* [PATCH 2/3 rev 2] ACPI / platform: Use common ACPI device resource parsing routines
  2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
  2012-11-13 20:55     ` [PATCH 1/3 rev 2] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
@ 2012-11-13 20:55     ` Rafael J. Wysocki
  2012-11-13 20:56     ` [PATCH 3/3 rev 2] ACPI: Centralized processing of ACPI device resources Rafael J. Wysocki
  2012-11-14  9:52     ` [PATCH 0/3 rev 2] Centralized parsing " Mika Westerberg
  3 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 20:55 UTC (permalink / raw)
  To: linux-acpi
  Cc: Mika Westerberg, mathias.nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Use common routines in drivers/acpi/resource.c to parse ACPI device
resources while creating platform device objects.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_platform.c |   89 +++++++++----------------------------------
 1 file changed, 20 insertions(+), 69 deletions(-)

Index: linux/drivers/acpi/acpi_platform.c
===================================================================
--- linux.orig/drivers/acpi/acpi_platform.c
+++ linux/drivers/acpi/acpi_platform.c
@@ -29,21 +29,20 @@ static acpi_status acpi_platform_count_r
 						 void *data)
 {
 	struct acpi_resource_extended_irq *acpi_xirq;
+	struct acpi_resource_irq *acpi_irq;
 	struct resource_info *ri = data;
 
 	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
 	case ACPI_RESOURCE_TYPE_IRQ:
-		ri->n++;
+		acpi_irq = &res->data.irq;
+		ri->n += acpi_irq->interrupt_count;
 		break;
 	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
 		acpi_xirq = &res->data.extended_irq;
 		ri->n += acpi_xirq->interrupt_count;
 		break;
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		if (res->data.address32.resource_type == ACPI_IO_RANGE)
-			ri->n++;
-		break;
+	default:
+		ri->n++;
 	}
 
 	return AE_OK;
@@ -52,71 +51,26 @@ static acpi_status acpi_platform_count_r
 static acpi_status acpi_platform_add_resources(struct acpi_resource *res,
 					       void *data)
 {
-	struct acpi_resource_fixed_memory32 *acpi_mem;
-	struct acpi_resource_address32 *acpi_add32;
-	struct acpi_resource_extended_irq *acpi_xirq;
-	struct acpi_resource_irq *acpi_irq;
 	struct resource_info *ri = data;
 	struct resource *r;
-	int irq, i;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		acpi_mem = &res->data.fixed_memory32;
-		r = &ri->res[ri->cur++];
-
-		r->start = acpi_mem->address;
-		r->end = r->start + acpi_mem->address_length - 1;
-		r->flags = IORESOURCE_MEM;
-
-		dev_dbg(ri->dev, "Memory32Fixed %pR\n", r);
-		break;
-
-	case ACPI_RESOURCE_TYPE_ADDRESS32:
-		acpi_add32 = &res->data.address32;
 
-		if (acpi_add32->resource_type == ACPI_IO_RANGE) {
-			r = &ri->res[ri->cur++];
-			r->start = acpi_add32->minimum;
-			r->end = r->start + acpi_add32->address_length - 1;
-			r->flags = IORESOURCE_IO;
-			dev_dbg(ri->dev, "Address32 %pR\n", r);
-		}
-		break;
-
-	case ACPI_RESOURCE_TYPE_IRQ:
-		acpi_irq = &res->data.irq;
-		r = &ri->res[ri->cur++];
-
-		irq = acpi_register_gsi(ri->dev,
-					acpi_irq->interrupts[0],
-					acpi_irq->triggering,
-					acpi_irq->polarity);
-
-		r->start = r->end = irq;
-		r->flags = IORESOURCE_IRQ;
-
-		dev_dbg(ri->dev, "IRQ %pR\n", r);
-		break;
-
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		acpi_xirq = &res->data.extended_irq;
-
-		for (i = 0; i < acpi_xirq->interrupt_count; i++, ri->cur++) {
-			r = &ri->res[ri->cur];
-			irq = acpi_register_gsi(ri->dev,
-						acpi_xirq->interrupts[i],
-						acpi_xirq->triggering,
-						acpi_xirq->polarity);
+	r = ri->res + ri->cur;
+	if (acpi_dev_resource_memory(res, r)
+	    || acpi_dev_resource_io(res, r)
+	    || acpi_dev_resource_address_space(res, r)
+	    || acpi_dev_resource_ext_address_space(res, r)) {
+		ri->cur++;
+		return AE_OK;
+	}
+	if (acpi_dev_resource_interrupt(res, 0, r)) {
+		int i;
 
-			r->start = r->end = irq;
-			r->flags = IORESOURCE_IRQ;
+		r++;
+		for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
+			r++;
 
-			dev_dbg(ri->dev, "Interrupt %pR\n", r);
-		}
-		break;
+		ri->cur += i;
 	}
-
 	return AE_OK;
 }
 
@@ -165,9 +119,6 @@ struct platform_device *acpi_create_plat
 		goto out;
 	}
 
-	if (WARN_ON(ri.n != ri.cur))
-		goto out;
-
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
 	 * attached to it, that physical device should be the parent of the
@@ -189,7 +140,7 @@ struct platform_device *acpi_create_plat
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
 	pdev = platform_device_register_resndata(parent, dev_name(&adev->dev),
-						 -1, ri.res, ri.n, NULL, 0);
+						 -1, ri.res, ri.cur, NULL, 0);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));

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

* [PATCH 3/3 rev 2] ACPI: Centralized processing of ACPI device resources
  2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
  2012-11-13 20:55     ` [PATCH 1/3 rev 2] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
  2012-11-13 20:55     ` [PATCH 2/3 rev 2] ACPI / platform: Use common ACPI device resource parsing routines Rafael J. Wysocki
@ 2012-11-13 20:56     ` Rafael J. Wysocki
  2012-11-14  9:52     ` [PATCH 0/3 rev 2] Centralized parsing " Mika Westerberg
  3 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 20:56 UTC (permalink / raw)
  To: linux-acpi
  Cc: Mika Westerberg, mathias.nyman, linux-kernel, lenb,
	rafael.j.wysocki, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Currently, whoever wants to use ACPI device resources has to call
acpi_walk_resources() to browse the buffer returned by the _CRS
method for the given device and create filters passed to that
routine to apply to the individual resource items.  This generally
is cumbersome, time-consuming and inefficient.  Moreover, it may
be problematic if resource conflicts need to be resolved, because
the different users of _CRS will need to do that in a consistent
way.  However, if there are resource conflicts, the ACPI core
should be able to resolve them centrally instead of relying on
various users of acpi_walk_resources() to handle them correctly
together.

For this reason, introduce a new function, acpi_dev_get_resources(),
that can be used by subsystems to obtain a list of struct resource
objects corresponding to the ACPI device resources returned by
_CRS and, if necessary, to apply additional preprocessing routine
to the ACPI resources before converting them to the struct resource
format.

Make the ACPI code that creates platform device objects use
acpi_dev_get_resources() for resource processing instead of executing
acpi_walk_resources() twice by itself, which causes it to be much
more straightforward and easier to follow.

In the future, acpi_dev_get_resources() can be extended to meet
the needs of the ACPI PNP subsystem and other users of _CRS in
the kernel.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpi_platform.c |   94 +++++-------------------------
 drivers/acpi/resource.c      |  134 +++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h         |   10 +++
 3 files changed, 161 insertions(+), 77 deletions(-)

Index: linux/include/linux/acpi.h
===================================================================
--- linux.orig/include/linux/acpi.h
+++ linux/include/linux/acpi.h
@@ -261,6 +261,16 @@ unsigned long acpi_dev_irq_flags(u8 trig
 bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index,
 				 struct resource *res);
 
+struct resource_list_entry {
+	struct list_head node;
+	struct resource res;
+};
+
+void acpi_dev_free_resource_list(struct list_head *list);
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+			   int (*preproc)(struct acpi_resource *, void *),
+			   void *preproc_data);
+
 int acpi_check_resource_conflict(const struct resource *res);
 
 int acpi_check_region(resource_size_t start, resource_size_t n,
Index: linux/drivers/acpi/resource.c
===================================================================
--- linux.orig/drivers/acpi/resource.c
+++ linux/drivers/acpi/resource.c
@@ -26,6 +26,7 @@
 #include <linux/device.h>
 #include <linux/export.h>
 #include <linux/ioport.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_X86
 #define valid_IRQ(i) (((i) != 0) && ((i) != 2))
@@ -391,3 +392,136 @@ bool acpi_dev_resource_interrupt(struct
 	return true;
 }
 EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt);
+
+/**
+ * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources().
+ * @list: The head of the resource list to free.
+ */
+void acpi_dev_free_resource_list(struct list_head *list)
+{
+	struct resource_list_entry *rentry, *re;
+
+	list_for_each_entry_safe(rentry, re, list, node) {
+		list_del(&rentry->node);
+		kfree(rentry);
+	}
+}
+EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list);
+
+struct res_proc_context {
+	struct list_head *list;
+	int (*preproc)(struct acpi_resource *, void *);
+	void *preproc_data;
+	int count;
+	int error;
+};
+
+static acpi_status acpi_dev_new_resource_entry(struct resource *r,
+					       struct res_proc_context *c)
+{
+	struct resource_list_entry *rentry;
+
+	rentry = kmalloc(sizeof(*rentry), GFP_KERNEL);
+	if (!rentry) {
+		c->error = -ENOMEM;
+		return AE_NO_MEMORY;
+	}
+	INIT_LIST_HEAD(&rentry->node);
+	rentry->res = *r;
+	list_add_tail(&rentry->node, c->list);
+	c->count++;
+	return AE_OK;
+}
+
+static acpi_status acpi_dev_process_resource(struct acpi_resource *ares,
+					     void *context)
+{
+	struct res_proc_context *c = context;
+	struct resource r;
+	int i;
+
+	if (c->preproc) {
+		int ret;
+
+		ret = c->preproc(ares, c->preproc_data);
+		if (ret < 0) {
+			c->error = ret;
+			return AE_ABORT_METHOD;
+		} else if (ret > 0) {
+			return AE_OK;
+		}
+	}
+
+	memset(&r, 0, sizeof(r));
+
+	if (acpi_dev_resource_memory(ares, &r)
+	    || acpi_dev_resource_io(ares, &r)
+	    || acpi_dev_resource_address_space(ares, &r)
+	    || acpi_dev_resource_ext_address_space(ares, &r))
+		return acpi_dev_new_resource_entry(&r, c);
+
+	for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) {
+		acpi_status status;
+
+		status = acpi_dev_new_resource_entry(&r, c);
+		if (ACPI_FAILURE(status))
+			return status;
+	}
+
+	return AE_OK;
+}
+
+/**
+ * acpi_dev_get_resources - Get current resources of a device.
+ * @adev: ACPI device node to get the resources for.
+ * @list: Head of the resultant list of resources (must be empty).
+ * @preproc: The caller's preprocessing routine.
+ * @preproc_data: Pointer passed to the caller's preprocessing routine.
+ *
+ * Evaluate the _CRS method for the given device node and process its output by
+ * (1) executing the @preproc() rountine provided by the caller, passing the
+ * resource pointer and @preproc_data to it as arguments, for each ACPI resource
+ * returned and (2) converting all of the returned ACPI resources into struct
+ * resource objects if possible.  If the return value of @preproc() in step (1)
+ * is different from 0, step (2) is not applied to the given ACPI resource and
+ * if that value is negative, the whole processing is aborted and that value is
+ * returned as the final error code.
+ *
+ * The resultant struct resource objects are put on the list pointed to by
+ * @list, that must be empty initially, as members of struct resource_list_entry
+ * objects.  Callers of this routine should use %acpi_dev_free_resource_list() to
+ * free that list.
+ *
+ * The number of resources in the output list is returned on success, an error
+ * code reflecting the error condition is returned otherwise.
+ */
+int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list,
+			   int (*preproc)(struct acpi_resource *, void *),
+			   void *preproc_data)
+{
+	struct res_proc_context c;
+	acpi_handle not_used;
+	acpi_status status;
+
+	if (!adev || !adev->handle || !list_empty(list))
+		return -EINVAL;
+
+	status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, &not_used);
+	if (ACPI_FAILURE(status))
+		return 0;
+
+	c.list = list;
+	c.preproc = preproc;
+	c.preproc_data = preproc_data;
+	c.count = 0;
+	c.error = 0;
+	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
+				     acpi_dev_process_resource, &c);
+	if (ACPI_FAILURE(status)) {
+		acpi_dev_free_resource_list(list);
+		return c.error ? c.error : -EIO;
+	}
+
+	return c.count;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
Index: linux/drivers/acpi/acpi_platform.c
===================================================================
--- linux.orig/drivers/acpi/acpi_platform.c
+++ linux/drivers/acpi/acpi_platform.c
@@ -19,61 +19,6 @@
 
 ACPI_MODULE_NAME("platform");
 
-struct resource_info {
-	struct device *dev;
-	struct resource *res;
-	size_t n, cur;
-};
-
-static acpi_status acpi_platform_count_resources(struct acpi_resource *res,
-						 void *data)
-{
-	struct acpi_resource_extended_irq *acpi_xirq;
-	struct acpi_resource_irq *acpi_irq;
-	struct resource_info *ri = data;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_IRQ:
-		acpi_irq = &res->data.irq;
-		ri->n += acpi_irq->interrupt_count;
-		break;
-	case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
-		acpi_xirq = &res->data.extended_irq;
-		ri->n += acpi_xirq->interrupt_count;
-		break;
-	default:
-		ri->n++;
-	}
-
-	return AE_OK;
-}
-
-static acpi_status acpi_platform_add_resources(struct acpi_resource *res,
-					       void *data)
-{
-	struct resource_info *ri = data;
-	struct resource *r;
-
-	r = ri->res + ri->cur;
-	if (acpi_dev_resource_memory(res, r)
-	    || acpi_dev_resource_io(res, r)
-	    || acpi_dev_resource_address_space(res, r)
-	    || acpi_dev_resource_ext_address_space(res, r)) {
-		ri->cur++;
-		return AE_OK;
-	}
-	if (acpi_dev_resource_interrupt(res, 0, r)) {
-		int i;
-
-		r++;
-		for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++)
-			r++;
-
-		ri->cur += i;
-	}
-	return AE_OK;
-}
-
 /**
  * acpi_create_platform_device - Create platform device for ACPI device node
  * @adev: ACPI device node to create a platform device for.
@@ -89,35 +34,31 @@ struct platform_device *acpi_create_plat
 	struct platform_device *pdev = NULL;
 	struct acpi_device *acpi_parent;
 	struct device *parent = NULL;
-	struct resource_info ri;
-	acpi_status status;
+	struct resource_list_entry *rentry;
+	struct list_head resource_list;
+	struct resource *resources;
+	int count;
 
 	/* If the ACPI node already has a physical device attached, skip it. */
 	if (adev->physical_node_count)
 		return NULL;
 
-	memset(&ri, 0, sizeof(ri));
-	/* First, count the resources. */
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_count_resources, &ri);
-	if (ACPI_FAILURE(status) || !ri.n)
+	INIT_LIST_HEAD(&resource_list);
+	count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
+	if (count <= 0)
 		return NULL;
 
-	/* Next, allocate memory for all the resources and populate it. */
-	ri.dev = &adev->dev;
-	ri.res = kzalloc(ri.n * sizeof(struct resource), GFP_KERNEL);
-	if (!ri.res) {
-		dev_err(&adev->dev,
-			"failed to allocate memory for resources\n");
+	resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL);
+	if (!resources) {
+		dev_err(&adev->dev, "No memory for resources\n");
+		acpi_dev_free_resource_list(&resource_list);
 		return NULL;
 	}
+	count = 0;
+	list_for_each_entry(rentry, &resource_list, node)
+		resources[count++] = rentry->res;
 
-	status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS,
-				     acpi_platform_add_resources, &ri);
-	if (ACPI_FAILURE(status)) {
-		dev_err(&adev->dev, "failed to walk resources\n");
-		goto out;
-	}
+	acpi_dev_free_resource_list(&resource_list);
 
 	/*
 	 * If the ACPI node has a parent and that parent has a physical device
@@ -140,7 +81,7 @@ struct platform_device *acpi_create_plat
 		mutex_unlock(&acpi_parent->physical_node_lock);
 	}
 	pdev = platform_device_register_resndata(parent, dev_name(&adev->dev),
-						 -1, ri.res, ri.cur, NULL, 0);
+						 -1, resources, count, NULL, 0);
 	if (IS_ERR(pdev)) {
 		dev_err(&adev->dev, "platform device creation failed: %ld\n",
 			PTR_ERR(pdev));
@@ -150,8 +91,7 @@ struct platform_device *acpi_create_plat
 			dev_name(&pdev->dev));
 	}
 
- out:
-	kfree(ri.res);
+	kfree(resources);
 	return pdev;
 }
 

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-13 20:44               ` Rafael J. Wysocki
@ 2012-11-13 22:06                 ` Moore, Robert
  -1 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-13 22:06 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

I may not quite understand what you are asking for, but I will try. It seems like we already have much of what you want/need, so maybe I'm missing something.



> So what I would like to have, in general terms, is something like
> acpi_walk_resources() split into three parts:
> 
>  (1) One that processes the _CRS output and creates a list of
>      struct acpi_resource objects for us to play with.  I suppose
>      it's OK if that's just a buffer filled with resource objects,
>      but a linked list might be more convenient.
> 

This sounds like AcpiGetCurrentResources. It executes _CRS and formats the data into acpi_resource objects.



>  (2) One that allows us to access (read/write) resources in the
>      list returned by (1).  We don't need to open code walking
>      the list and I probably wouldn't event want to do that.  What
>      we need is to be able to walk the same list for a number of
>      times and possibly to modify values in the resource objects
>      if there are conflicts.

This sounds like AcpiWalkResources. I suppose a possible issue is that currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI method on behalf of the caller. It might make more sense to allow the caller to pass in the resource buffer returned from a call to _CRS, etc.


> 
>  (3) One allowing us to free the list returned by (1) if not needed
>      any more.
> 

AcpiGetCurrentResources: Currently, everything is returned in a single buffer to minimize the number of allocations. A buffer you can free when you are done with it.

I think I saw where you mentioned that you cannot copy this buffer because of internal pointers to other areas of the buffer. Yes. However, we can build linked lists all day if you really want them :-)


> And it would be great if we could take the list returned by (1), modify
> the resources in it and feed it back to _SRS (after conversion back to the
> format that _SRS understands).
> 

AcpiSetCurrentResources.

The AML debugger already has a command that illustrates the use of the various resource interfaces, see dbcmds.c

> Thanks,
> Rafael

Bob





> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Tuesday, November 13, 2012 12:44 PM
> To: Moore, Robert
> Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> Bjorn Helgaas; Zheng, Lv
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Tuesday, November 13, 2012 04:34:07 PM Moore, Robert wrote:
> > > I suppose we can just do acpi_get_current_resources() and play with
> > > the buffer returned by it.  That won't be nice, but still better
> > > than what we have.
> >
> > A couple of the reasons we created the ACPICA resource manager was to:
> > 1) Simplify host access to the various resource fields, especially
> packed flags.
> > 2) Avoid alignment issues, especially on machines that don't support
> misaligned transfers.
> 
> That's fine.
> 
> > If there are issues with the current resource manager, we can discuss
> them.
> > But I would hope that you really don't want to be fussing around with
> > the raw data coming back from the AML.
> 
> No, I don't. :-)
> 
> I'd like to be able to do more things with struct acpi_resource objects.
> 
> Pretty much the output of acpi_get_current_resources() is what I'm
> interested in, but there doesn't seem to be any convenient way to access
> things in the return buffer from the outside of ACPICA now.
> 
> > It is not pretty and we have gone to some lengths to make the entire
> > conversion table-driven to minimize bugs and simplify maintenance.
> 
> OK
> 
> So what I would like to have, in general terms, is something like
> acpi_walk_resources() split into three parts:
> 
>  (1) One that processes the _CRS output and creates a list of
>      struct acpi_resource objects for us to play with.  I suppose
>      it's OK if that's just a buffer filled with resource objects,
>      but a linked list might be more convenient.
> 
>  (2) One that allows us to access (read/write) resources in the
>      list returned by (1).  We don't need to open code walking
>      the list and I probably wouldn't event want to do that.  What
>      we need is to be able to walk the same list for a number of
>      times and possibly to modify values in the resource objects
>      if there are conflicts.
> 
>  (3) One allowing us to free the list returned by (1) if not needed
>      any more.
> 
> And it would be great if we could take the list returned by (1), modify
> the resources in it and feed it back to _SRS (after conversion back to the
> format that _SRS understands).
> 
> Thanks,
> Rafael
> 
> 
> > > -----Original Message-----
> > > From: Mika Westerberg [mailto:mika.westerberg@linux.intel.com]
> > > Sent: Monday, November 12, 2012 11:12 PM
> > > To: Rafael J. Wysocki
> > > Cc: mathias.nyman@linux.intel.com; linux-acpi@vger.kernel.org;
> > > linux- kernel@vger.kernel.org; lenb@kernel.org; Wysocki, Rafael J;
> > > broonie@opensource.wolfsonmicro.com; grant.likely@secretlab.ca;
> > > linus.walleij@linaro.org; khali@linux-fr.org; Bjorn Helgaas; Moore,
> > > Robert
> > > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device
> > > node objects
> > >
> > > On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource
> *res,
> > > > > > +					 void *context)
> > > > > > +{
> > > > > > +	struct list_head *list = context;
> > > > > > +	struct acpi_resource_list_entry *entry;
> > > > > > +
> > > > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > > > +	if (!entry)
> > > > > > +		return AE_NO_MEMORY;
> > > > > > +
> > > > > > +	entry->resource = *res;
> > > > >
> > > > > This does not work well with all resource types - specifically
> > > > > those that contain pointers, like acpi_resource_gpio and
> > > acpi_resource_source.
> > > >
> > > > Good point.
> > > >
> > > > Well, this pretty much means we can't copy those things.
> > >
> > > Yeah. I only noticed this yesterday when I tested the GPIO
> > > translation in a custom driver (since it uses the acpi_resource_gpio).
> > >
> > > > > The memory for the resources gets freed once
> > > > > acpi_walk_resources() is
> > > done.
> > > >
> > > > I know that.
> > > >
> > > > Having to evaluate _CRS and creating a buffer, converting the
> > > > output into ACPI resources and so on every time we need to look
> > > > into the device's current resources is totally inefficient.  We
> > > > _need_ to cache
> > > the _CRS output.
> > >
> > > I agree and besides having adev->resources is much easier to use
> > > than calling acpi_walk_resources() everytime.
> > >
> > > > Now, because of the pointers in certain types of resources, we
> > > > can't make copies of the resource objects used by
> > > > acpi_walk_resources() which makes that function totally unuseful to
> us.
> > > >
> > > > I suppose we can just do acpi_get_current_resources() and play
> > > > with the buffer returned by it.  That won't be nice, but still
> > > > better than what we have.
> > >
> > > I don't know any better option.
> > >
> > > Thanks.
> >
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-13 22:06                 ` Moore, Robert
  0 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-13 22:06 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 7618 bytes --]

I may not quite understand what you are asking for, but I will try. It seems like we already have much of what you want/need, so maybe I'm missing something.



> So what I would like to have, in general terms, is something like
> acpi_walk_resources() split into three parts:
> 
>  (1) One that processes the _CRS output and creates a list of
>      struct acpi_resource objects for us to play with.  I suppose
>      it's OK if that's just a buffer filled with resource objects,
>      but a linked list might be more convenient.
> 

This sounds like AcpiGetCurrentResources. It executes _CRS and formats the data into acpi_resource objects.



>  (2) One that allows us to access (read/write) resources in the
>      list returned by (1).  We don't need to open code walking
>      the list and I probably wouldn't event want to do that.  What
>      we need is to be able to walk the same list for a number of
>      times and possibly to modify values in the resource objects
>      if there are conflicts.

This sounds like AcpiWalkResources. I suppose a possible issue is that currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI method on behalf of the caller. It might make more sense to allow the caller to pass in the resource buffer returned from a call to _CRS, etc.


> 
>  (3) One allowing us to free the list returned by (1) if not needed
>      any more.
> 

AcpiGetCurrentResources: Currently, everything is returned in a single buffer to minimize the number of allocations. A buffer you can free when you are done with it.

I think I saw where you mentioned that you cannot copy this buffer because of internal pointers to other areas of the buffer. Yes. However, we can build linked lists all day if you really want them :-)


> And it would be great if we could take the list returned by (1), modify
> the resources in it and feed it back to _SRS (after conversion back to the
> format that _SRS understands).
> 

AcpiSetCurrentResources.

The AML debugger already has a command that illustrates the use of the various resource interfaces, see dbcmds.c

> Thanks,
> Rafael

Bob





> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Tuesday, November 13, 2012 12:44 PM
> To: Moore, Robert
> Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> Bjorn Helgaas; Zheng, Lv
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Tuesday, November 13, 2012 04:34:07 PM Moore, Robert wrote:
> > > I suppose we can just do acpi_get_current_resources() and play with
> > > the buffer returned by it.  That won't be nice, but still better
> > > than what we have.
> >
> > A couple of the reasons we created the ACPICA resource manager was to:
> > 1) Simplify host access to the various resource fields, especially
> packed flags.
> > 2) Avoid alignment issues, especially on machines that don't support
> misaligned transfers.
> 
> That's fine.
> 
> > If there are issues with the current resource manager, we can discuss
> them.
> > But I would hope that you really don't want to be fussing around with
> > the raw data coming back from the AML.
> 
> No, I don't. :-)
> 
> I'd like to be able to do more things with struct acpi_resource objects.
> 
> Pretty much the output of acpi_get_current_resources() is what I'm
> interested in, but there doesn't seem to be any convenient way to access
> things in the return buffer from the outside of ACPICA now.
> 
> > It is not pretty and we have gone to some lengths to make the entire
> > conversion table-driven to minimize bugs and simplify maintenance.
> 
> OK
> 
> So what I would like to have, in general terms, is something like
> acpi_walk_resources() split into three parts:
> 
>  (1) One that processes the _CRS output and creates a list of
>      struct acpi_resource objects for us to play with.  I suppose
>      it's OK if that's just a buffer filled with resource objects,
>      but a linked list might be more convenient.
> 
>  (2) One that allows us to access (read/write) resources in the
>      list returned by (1).  We don't need to open code walking
>      the list and I probably wouldn't event want to do that.  What
>      we need is to be able to walk the same list for a number of
>      times and possibly to modify values in the resource objects
>      if there are conflicts.
> 
>  (3) One allowing us to free the list returned by (1) if not needed
>      any more.
> 
> And it would be great if we could take the list returned by (1), modify
> the resources in it and feed it back to _SRS (after conversion back to the
> format that _SRS understands).
> 
> Thanks,
> Rafael
> 
> 
> > > -----Original Message-----
> > > From: Mika Westerberg [mailto:mika.westerberg@linux.intel.com]
> > > Sent: Monday, November 12, 2012 11:12 PM
> > > To: Rafael J. Wysocki
> > > Cc: mathias.nyman@linux.intel.com; linux-acpi@vger.kernel.org;
> > > linux- kernel@vger.kernel.org; lenb@kernel.org; Wysocki, Rafael J;
> > > broonie@opensource.wolfsonmicro.com; grant.likely@secretlab.ca;
> > > linus.walleij@linaro.org; khali@linux-fr.org; Bjorn Helgaas; Moore,
> > > Robert
> > > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device
> > > node objects
> > >
> > > On Mon, Nov 12, 2012 at 10:03:56PM +0100, Rafael J. Wysocki wrote:
> > > > > > +static acpi_status acpi_bus_add_resource(struct acpi_resource
> *res,
> > > > > > +					 void *context)
> > > > > > +{
> > > > > > +	struct list_head *list = context;
> > > > > > +	struct acpi_resource_list_entry *entry;
> > > > > > +
> > > > > > +	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> > > > > > +	if (!entry)
> > > > > > +		return AE_NO_MEMORY;
> > > > > > +
> > > > > > +	entry->resource = *res;
> > > > >
> > > > > This does not work well with all resource types - specifically
> > > > > those that contain pointers, like acpi_resource_gpio and
> > > acpi_resource_source.
> > > >
> > > > Good point.
> > > >
> > > > Well, this pretty much means we can't copy those things.
> > >
> > > Yeah. I only noticed this yesterday when I tested the GPIO
> > > translation in a custom driver (since it uses the acpi_resource_gpio).
> > >
> > > > > The memory for the resources gets freed once
> > > > > acpi_walk_resources() is
> > > done.
> > > >
> > > > I know that.
> > > >
> > > > Having to evaluate _CRS and creating a buffer, converting the
> > > > output into ACPI resources and so on every time we need to look
> > > > into the device's current resources is totally inefficient.  We
> > > > _need_ to cache
> > > the _CRS output.
> > >
> > > I agree and besides having adev->resources is much easier to use
> > > than calling acpi_walk_resources() everytime.
> > >
> > > > Now, because of the pointers in certain types of resources, we
> > > > can't make copies of the resource objects used by
> > > > acpi_walk_resources() which makes that function totally unuseful to
> us.
> > > >
> > > > I suppose we can just do acpi_get_current_resources() and play
> > > > with the buffer returned by it.  That won't be nice, but still
> > > > better than what we have.
> > >
> > > I don't know any better option.
> > >
> > > Thanks.
> >
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-13 22:06                 ` Moore, Robert
@ 2012-11-13 22:56                   ` Rafael J. Wysocki
  -1 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 22:56 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> I may not quite understand what you are asking for, but I will try.
> It seems like we already have much of what you want/need, so maybe
> I'm missing something.

I think all of the necessary pieces are there.

> > So what I would like to have, in general terms, is something like
> > acpi_walk_resources() split into three parts:
> > 
> >  (1) One that processes the _CRS output and creates a list of
> >      struct acpi_resource objects for us to play with.  I suppose
> >      it's OK if that's just a buffer filled with resource objects,
> >      but a linked list might be more convenient.
> > 
> 
> This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> the data into acpi_resource objects.

Yes, it does.  However, it is not completely clear to me if/how the caller is
supposed to prepare the buffer object pointed to by the second arg.

If the buffer is initialized by AcpiGetCurrentResources, then that's what
I need for (1).

> >  (2) One that allows us to access (read/write) resources in the
> >      list returned by (1).  We don't need to open code walking
> >      the list and I probably wouldn't event want to do that.  What
> >      we need is to be able to walk the same list for a number of
> >      times and possibly to modify values in the resource objects
> >      if there are conflicts.
> 
> This sounds like AcpiWalkResources. I suppose a possible issue is that
> currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> method on behalf of the caller.

Yes, that exactly is the problem.

> It might make more sense to allow the caller to pass in the resource buffer
> returned from a call to _CRS, etc.

Yes! :-)

> > 
> >  (3) One allowing us to free the list returned by (1) if not needed
> >      any more.
> > 
> 
> AcpiGetCurrentResources: Currently, everything is returned in a single buffer
> to minimize the number of allocations. A buffer you can free when you are
> done with it.

I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it for the
ACPICA's internal use only?

Besides, I would prefer to be able to pass just "buffer" for freeing, without
having to touch its internals.  No big deal, but it would be nicer. :-) 

> I think I saw where you mentioned that you cannot copy this buffer because
> of internal pointers to other areas of the buffer. Yes. However, we can build
> linked lists all day if you really want them :-)

I really won't care if I can pass a resource buffer to a "walker" routine. :-)

> > And it would be great if we could take the list returned by (1), modify
> > the resources in it and feed it back to _SRS (after conversion back to the
> > format that _SRS understands).
> > 
> 
> AcpiSetCurrentResources.
> 
> The AML debugger already has a command that illustrates the use of the
> various resource interfaces, see dbcmds.c

I will.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-13 22:56                   ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-13 22:56 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> I may not quite understand what you are asking for, but I will try.
> It seems like we already have much of what you want/need, so maybe
> I'm missing something.

I think all of the necessary pieces are there.

> > So what I would like to have, in general terms, is something like
> > acpi_walk_resources() split into three parts:
> > 
> >  (1) One that processes the _CRS output and creates a list of
> >      struct acpi_resource objects for us to play with.  I suppose
> >      it's OK if that's just a buffer filled with resource objects,
> >      but a linked list might be more convenient.
> > 
> 
> This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> the data into acpi_resource objects.

Yes, it does.  However, it is not completely clear to me if/how the caller is
supposed to prepare the buffer object pointed to by the second arg.

If the buffer is initialized by AcpiGetCurrentResources, then that's what
I need for (1).

> >  (2) One that allows us to access (read/write) resources in the
> >      list returned by (1).  We don't need to open code walking
> >      the list and I probably wouldn't event want to do that.  What
> >      we need is to be able to walk the same list for a number of
> >      times and possibly to modify values in the resource objects
> >      if there are conflicts.
> 
> This sounds like AcpiWalkResources. I suppose a possible issue is that
> currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> method on behalf of the caller.

Yes, that exactly is the problem.

> It might make more sense to allow the caller to pass in the resource buffer
> returned from a call to _CRS, etc.

Yes! :-)

> > 
> >  (3) One allowing us to free the list returned by (1) if not needed
> >      any more.
> > 
> 
> AcpiGetCurrentResources: Currently, everything is returned in a single buffer
> to minimize the number of allocations. A buffer you can free when you are
> done with it.

I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it for the
ACPICA's internal use only?

Besides, I would prefer to be able to pass just "buffer" for freeing, without
having to touch its internals.  No big deal, but it would be nicer. :-) 

> I think I saw where you mentioned that you cannot copy this buffer because
> of internal pointers to other areas of the buffer. Yes. However, we can build
> linked lists all day if you really want them :-)

I really won't care if I can pass a resource buffer to a "walker" routine. :-)

> > And it would be great if we could take the list returned by (1), modify
> > the resources in it and feed it back to _SRS (after conversion back to the
> > format that _SRS understands).
> > 
> 
> AcpiSetCurrentResources.
> 
> The AML debugger already has a command that illustrates the use of the
> various resource interfaces, see dbcmds.c

I will.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-13 22:56                   ` Rafael J. Wysocki
@ 2012-11-14  2:23                     ` Moore, Robert
  -1 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-14  2:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

Rafael,

I sounds like with a few changes, we can enhance this mechanism to be more useful to you and others. Some comments below. I need to look at the code in question a bit more, but I see no insurmountable issues.

Bob


> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Tuesday, November 13, 2012 2:57 PM
> To: Moore, Robert
> Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> Bjorn Helgaas; Zheng, Lv
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > I may not quite understand what you are asking for, but I will try.
> > It seems like we already have much of what you want/need, so maybe I'm
> > missing something.
> 
> I think all of the necessary pieces are there.
> 
> > > So what I would like to have, in general terms, is something like
> > > acpi_walk_resources() split into three parts:
> > >
> > >  (1) One that processes the _CRS output and creates a list of
> > >      struct acpi_resource objects for us to play with.  I suppose
> > >      it's OK if that's just a buffer filled with resource objects,
> > >      but a linked list might be more convenient.
> > >
> >
> > This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> > the data into acpi_resource objects.
> 
> Yes, it does.  However, it is not completely clear to me if/how the caller
> is supposed to prepare the buffer object pointed to by the second arg.
> 
> If the buffer is initialized by AcpiGetCurrentResources, then that's what
> I need for (1).


It looks to me that at least AcpiGetCurrentResources does not actually ever allocate a buffer for the resource template, it expects the caller to eventually provide one of at least the size of the returned resource template.

This is really quite a bit out-of-date as far as the memory allocation model. It should also support the option to just allocate the buffer of the appropriate size before returning it to the caller.




> 
> > >  (2) One that allows us to access (read/write) resources in the
> > >      list returned by (1).  We don't need to open code walking
> > >      the list and I probably wouldn't event want to do that.  What
> > >      we need is to be able to walk the same list for a number of
> > >      times and possibly to modify values in the resource objects
> > >      if there are conflicts.
> >
> > This sounds like AcpiWalkResources. I suppose a possible issue is that
> > currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> > method on behalf of the caller.
> 
> Yes, that exactly is the problem.
> 
> > It might make more sense to allow the caller to pass in the resource
> > buffer returned from a call to _CRS, etc.
> 
> Yes! :-)


I'll take a closer look at this tomorrow.




> 
> > >
> > >  (3) One allowing us to free the list returned by (1) if not needed
> > >      any more.
> > >
> >
> > AcpiGetCurrentResources: Currently, everything is returned in a single
> > buffer to minimize the number of allocations. A buffer you can free
> > when you are done with it.
> 
> I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it
> for the ACPICA's internal use only?
> 
> Besides, I would prefer to be able to pass just "buffer" for freeing,
> without having to touch its internals.  No big deal, but it would be
> nicer. :-)


The ACPI_BUFFER type is in fact a public type that is meant to return both the buffer and the (actual) length. You will find many instances of ACPI_FREE(buffer.pointer) within existing linux code, since it also used for objects returned by control method execution/object evaluation.


> 
> > I think I saw where you mentioned that you cannot copy this buffer
> > because of internal pointers to other areas of the buffer. Yes.
> > However, we can build linked lists all day if you really want them :-)
> 
> I really won't care if I can pass a resource buffer to a "walker" routine.
> :-)
> 
> > > And it would be great if we could take the list returned by (1),
> > > modify the resources in it and feed it back to _SRS (after
> > > conversion back to the format that _SRS understands).
> > >
> >
> > AcpiSetCurrentResources.
> >
> > The AML debugger already has a command that illustrates the use of the
> > various resource interfaces, see dbcmds.c
> 
> I will.
> 
> Thanks,
> Rafael
> 
> 
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-14  2:23                     ` Moore, Robert
  0 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-14  2:23 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4853 bytes --]

Rafael,

I sounds like with a few changes, we can enhance this mechanism to be more useful to you and others. Some comments below. I need to look at the code in question a bit more, but I see no insurmountable issues.

Bob


> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Tuesday, November 13, 2012 2:57 PM
> To: Moore, Robert
> Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> Bjorn Helgaas; Zheng, Lv
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > I may not quite understand what you are asking for, but I will try.
> > It seems like we already have much of what you want/need, so maybe I'm
> > missing something.
> 
> I think all of the necessary pieces are there.
> 
> > > So what I would like to have, in general terms, is something like
> > > acpi_walk_resources() split into three parts:
> > >
> > >  (1) One that processes the _CRS output and creates a list of
> > >      struct acpi_resource objects for us to play with.  I suppose
> > >      it's OK if that's just a buffer filled with resource objects,
> > >      but a linked list might be more convenient.
> > >
> >
> > This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> > the data into acpi_resource objects.
> 
> Yes, it does.  However, it is not completely clear to me if/how the caller
> is supposed to prepare the buffer object pointed to by the second arg.
> 
> If the buffer is initialized by AcpiGetCurrentResources, then that's what
> I need for (1).


It looks to me that at least AcpiGetCurrentResources does not actually ever allocate a buffer for the resource template, it expects the caller to eventually provide one of at least the size of the returned resource template.

This is really quite a bit out-of-date as far as the memory allocation model. It should also support the option to just allocate the buffer of the appropriate size before returning it to the caller.




> 
> > >  (2) One that allows us to access (read/write) resources in the
> > >      list returned by (1).  We don't need to open code walking
> > >      the list and I probably wouldn't event want to do that.  What
> > >      we need is to be able to walk the same list for a number of
> > >      times and possibly to modify values in the resource objects
> > >      if there are conflicts.
> >
> > This sounds like AcpiWalkResources. I suppose a possible issue is that
> > currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> > method on behalf of the caller.
> 
> Yes, that exactly is the problem.
> 
> > It might make more sense to allow the caller to pass in the resource
> > buffer returned from a call to _CRS, etc.
> 
> Yes! :-)


I'll take a closer look at this tomorrow.




> 
> > >
> > >  (3) One allowing us to free the list returned by (1) if not needed
> > >      any more.
> > >
> >
> > AcpiGetCurrentResources: Currently, everything is returned in a single
> > buffer to minimize the number of allocations. A buffer you can free
> > when you are done with it.
> 
> I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it
> for the ACPICA's internal use only?
> 
> Besides, I would prefer to be able to pass just "buffer" for freeing,
> without having to touch its internals.  No big deal, but it would be
> nicer. :-)


The ACPI_BUFFER type is in fact a public type that is meant to return both the buffer and the (actual) length. You will find many instances of ACPI_FREE(buffer.pointer) within existing linux code, since it also used for objects returned by control method execution/object evaluation.


> 
> > I think I saw where you mentioned that you cannot copy this buffer
> > because of internal pointers to other areas of the buffer. Yes.
> > However, we can build linked lists all day if you really want them :-)
> 
> I really won't care if I can pass a resource buffer to a "walker" routine.
> :-)
> 
> > > And it would be great if we could take the list returned by (1),
> > > modify the resources in it and feed it back to _SRS (after
> > > conversion back to the format that _SRS understands).
> > >
> >
> > AcpiSetCurrentResources.
> >
> > The AML debugger already has a command that illustrates the use of the
> > various resource interfaces, see dbcmds.c
> 
> I will.
> 
> Thanks,
> Rafael
> 
> 
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-14  2:23                     ` Moore, Robert
@ 2012-11-14  9:18                       ` Rafael J. Wysocki
  -1 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-14  9:18 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Wednesday, November 14, 2012 02:23:51 AM Moore, Robert wrote:
> Rafael,
> 
> I sounds like with a few changes, we can enhance this mechanism to
> be more useful to you and others. Some comments below. I need to look
> at the code in question a bit more, but I see no insurmountable issues.

Great, thanks!
 

> > -----Original Message-----
> > From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> > Sent: Tuesday, November 13, 2012 2:57 PM
> > To: Moore, Robert
> > Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> > acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> > Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> > grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> > Bjorn Helgaas; Zheng, Lv
> > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> > objects
> > 
> > On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > > I may not quite understand what you are asking for, but I will try.
> > > It seems like we already have much of what you want/need, so maybe I'm
> > > missing something.
> > 
> > I think all of the necessary pieces are there.
> > 
> > > > So what I would like to have, in general terms, is something like
> > > > acpi_walk_resources() split into three parts:
> > > >
> > > >  (1) One that processes the _CRS output and creates a list of
> > > >      struct acpi_resource objects for us to play with.  I suppose
> > > >      it's OK if that's just a buffer filled with resource objects,
> > > >      but a linked list might be more convenient.
> > > >
> > >
> > > This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> > > the data into acpi_resource objects.
> > 
> > Yes, it does.  However, it is not completely clear to me if/how the caller
> > is supposed to prepare the buffer object pointed to by the second arg.
> > 
> > If the buffer is initialized by AcpiGetCurrentResources, then that's what
> > I need for (1).
> 
> 
> It looks to me that at least AcpiGetCurrentResources does not actually ever
> allocate a buffer for the resource template, it expects the caller to
> eventually provide one of at least the size of the returned resource template.
> 
> This is really quite a bit out-of-date as far as the memory allocation model.
> It should also support the option to just allocate the buffer of the appropriate
> size before returning it to the caller.

Yes, that would be really useful.

Ideally, I'd like to be able to pass a pointer to an uninitialized buffer
structure to it (or to a wrapper around it) and get a buffer full of
struct acpi_resource objects (if _CRS returns any) back from it. :-)


> > > >  (2) One that allows us to access (read/write) resources in the
> > > >      list returned by (1).  We don't need to open code walking
> > > >      the list and I probably wouldn't event want to do that.  What
> > > >      we need is to be able to walk the same list for a number of
> > > >      times and possibly to modify values in the resource objects
> > > >      if there are conflicts.
> > >
> > > This sounds like AcpiWalkResources. I suppose a possible issue is that
> > > currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> > > method on behalf of the caller.
> > 
> > Yes, that exactly is the problem.
> > 
> > > It might make more sense to allow the caller to pass in the resource
> > > buffer returned from a call to _CRS, etc.
> > 
> > Yes! :-)
> 
> 
> I'll take a closer look at this tomorrow.

Cool, thanks!


> > > >  (3) One allowing us to free the list returned by (1) if not needed
> > > >      any more.
> > > >
> > >
> > > AcpiGetCurrentResources: Currently, everything is returned in a single
> > > buffer to minimize the number of allocations. A buffer you can free
> > > when you are done with it.
> > 
> > I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it
> > for the ACPICA's internal use only?
> > 
> > Besides, I would prefer to be able to pass just "buffer" for freeing,
> > without having to touch its internals.  No big deal, but it would be
> > nicer. :-)
> 
> 
> The ACPI_BUFFER type is in fact a public type that is meant to return both the
> buffer and the (actual) length. You will find many instances of
> ACPI_FREE(buffer.pointer) within existing linux code, since it also used for
> objects returned by control method execution/object evaluation.

Well, I suppose I only wanted to say that acpi_free_buffer(buffer) would look
a bit more straightforward than ACPI_FREE(buffer.pointer). :-)

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-14  9:18                       ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-14  9:18 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Wednesday, November 14, 2012 02:23:51 AM Moore, Robert wrote:
> Rafael,
> 
> I sounds like with a few changes, we can enhance this mechanism to
> be more useful to you and others. Some comments below. I need to look
> at the code in question a bit more, but I see no insurmountable issues.

Great, thanks!
 

> > -----Original Message-----
> > From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> > Sent: Tuesday, November 13, 2012 2:57 PM
> > To: Moore, Robert
> > Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> > acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> > Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> > grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> > Bjorn Helgaas; Zheng, Lv
> > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> > objects
> > 
> > On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > > I may not quite understand what you are asking for, but I will try.
> > > It seems like we already have much of what you want/need, so maybe I'm
> > > missing something.
> > 
> > I think all of the necessary pieces are there.
> > 
> > > > So what I would like to have, in general terms, is something like
> > > > acpi_walk_resources() split into three parts:
> > > >
> > > >  (1) One that processes the _CRS output and creates a list of
> > > >      struct acpi_resource objects for us to play with.  I suppose
> > > >      it's OK if that's just a buffer filled with resource objects,
> > > >      but a linked list might be more convenient.
> > > >
> > >
> > > This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> > > the data into acpi_resource objects.
> > 
> > Yes, it does.  However, it is not completely clear to me if/how the caller
> > is supposed to prepare the buffer object pointed to by the second arg.
> > 
> > If the buffer is initialized by AcpiGetCurrentResources, then that's what
> > I need for (1).
> 
> 
> It looks to me that at least AcpiGetCurrentResources does not actually ever
> allocate a buffer for the resource template, it expects the caller to
> eventually provide one of at least the size of the returned resource template.
> 
> This is really quite a bit out-of-date as far as the memory allocation model.
> It should also support the option to just allocate the buffer of the appropriate
> size before returning it to the caller.

Yes, that would be really useful.

Ideally, I'd like to be able to pass a pointer to an uninitialized buffer
structure to it (or to a wrapper around it) and get a buffer full of
struct acpi_resource objects (if _CRS returns any) back from it. :-)


> > > >  (2) One that allows us to access (read/write) resources in the
> > > >      list returned by (1).  We don't need to open code walking
> > > >      the list and I probably wouldn't event want to do that.  What
> > > >      we need is to be able to walk the same list for a number of
> > > >      times and possibly to modify values in the resource objects
> > > >      if there are conflicts.
> > >
> > > This sounds like AcpiWalkResources. I suppose a possible issue is that
> > > currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> > > method on behalf of the caller.
> > 
> > Yes, that exactly is the problem.
> > 
> > > It might make more sense to allow the caller to pass in the resource
> > > buffer returned from a call to _CRS, etc.
> > 
> > Yes! :-)
> 
> 
> I'll take a closer look at this tomorrow.

Cool, thanks!


> > > >  (3) One allowing us to free the list returned by (1) if not needed
> > > >      any more.
> > > >
> > >
> > > AcpiGetCurrentResources: Currently, everything is returned in a single
> > > buffer to minimize the number of allocations. A buffer you can free
> > > when you are done with it.
> > 
> > I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it
> > for the ACPICA's internal use only?
> > 
> > Besides, I would prefer to be able to pass just "buffer" for freeing,
> > without having to touch its internals.  No big deal, but it would be
> > nicer. :-)
> 
> 
> The ACPI_BUFFER type is in fact a public type that is meant to return both the
> buffer and the (actual) length. You will find many instances of
> ACPI_FREE(buffer.pointer) within existing linux code, since it also used for
> objects returned by control method execution/object evaluation.

Well, I suppose I only wanted to say that acpi_free_buffer(buffer) would look
a bit more straightforward than ACPI_FREE(buffer.pointer). :-)

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-14  9:18                       ` Rafael J. Wysocki
@ 2012-11-14  9:32                         ` Rafael J. Wysocki
  -1 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-14  9:32 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Wednesday, November 14, 2012 10:18:46 AM Rafael J. Wysocki wrote:
> On Wednesday, November 14, 2012 02:23:51 AM Moore, Robert wrote:
> > Rafael,
> > 
> > I sounds like with a few changes, we can enhance this mechanism to
> > be more useful to you and others. Some comments below. I need to look
> > at the code in question a bit more, but I see no insurmountable issues.
> 
> Great, thanks!
>  
> 
> > > -----Original Message-----
> > > From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> > > Sent: Tuesday, November 13, 2012 2:57 PM
> > > To: Moore, Robert
> > > Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> > > acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> > > Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> > > grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> > > Bjorn Helgaas; Zheng, Lv
> > > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> > > objects
> > > 
> > > On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > > > I may not quite understand what you are asking for, but I will try.
> > > > It seems like we already have much of what you want/need, so maybe I'm
> > > > missing something.
> > > 
> > > I think all of the necessary pieces are there.
> > > 
> > > > > So what I would like to have, in general terms, is something like
> > > > > acpi_walk_resources() split into three parts:
> > > > >
> > > > >  (1) One that processes the _CRS output and creates a list of
> > > > >      struct acpi_resource objects for us to play with.  I suppose
> > > > >      it's OK if that's just a buffer filled with resource objects,
> > > > >      but a linked list might be more convenient.
> > > > >
> > > >
> > > > This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> > > > the data into acpi_resource objects.
> > > 
> > > Yes, it does.  However, it is not completely clear to me if/how the caller
> > > is supposed to prepare the buffer object pointed to by the second arg.
> > > 
> > > If the buffer is initialized by AcpiGetCurrentResources, then that's what
> > > I need for (1).
> > 
> > 
> > It looks to me that at least AcpiGetCurrentResources does not actually ever
> > allocate a buffer for the resource template, it expects the caller to
> > eventually provide one of at least the size of the returned resource template.
> > 
> > This is really quite a bit out-of-date as far as the memory allocation model.
> > It should also support the option to just allocate the buffer of the appropriate
> > size before returning it to the caller.
> 
> Yes, that would be really useful.
> 
> Ideally, I'd like to be able to pass a pointer to an uninitialized buffer
> structure to it (or to a wrapper around it) and get a buffer full of
> struct acpi_resource objects (if _CRS returns any) back from it. :-)

Of course, I can add such a wrapper in the Linux-specific code just fine.


> > > > >  (2) One that allows us to access (read/write) resources in the
> > > > >      list returned by (1).  We don't need to open code walking
> > > > >      the list and I probably wouldn't event want to do that.  What
> > > > >      we need is to be able to walk the same list for a number of
> > > > >      times and possibly to modify values in the resource objects
> > > > >      if there are conflicts.
> > > >
> > > > This sounds like AcpiWalkResources. I suppose a possible issue is that
> > > > currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> > > > method on behalf of the caller.
> > > 
> > > Yes, that exactly is the problem.
> > > 
> > > > It might make more sense to allow the caller to pass in the resource
> > > > buffer returned from a call to _CRS, etc.
> > > 
> > > Yes! :-)
> > 
> > 
> > I'll take a closer look at this tomorrow.
> 
> Cool, thanks!
> 
> 
> > > > >  (3) One allowing us to free the list returned by (1) if not needed
> > > > >      any more.
> > > > >
> > > >
> > > > AcpiGetCurrentResources: Currently, everything is returned in a single
> > > > buffer to minimize the number of allocations. A buffer you can free
> > > > when you are done with it.
> > > 
> > > I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it
> > > for the ACPICA's internal use only?
> > > 
> > > Besides, I would prefer to be able to pass just "buffer" for freeing,
> > > without having to touch its internals.  No big deal, but it would be
> > > nicer. :-)
> > 
> > 
> > The ACPI_BUFFER type is in fact a public type that is meant to return both the
> > buffer and the (actual) length. You will find many instances of
> > ACPI_FREE(buffer.pointer) within existing linux code, since it also used for
> > objects returned by control method execution/object evaluation.
> 
> Well, I suppose I only wanted to say that acpi_free_buffer(buffer) would look
> a bit more straightforward than ACPI_FREE(buffer.pointer). :-)

And I can define acpi_free_buffer() in the Linux-specific code too.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-14  9:32                         ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-14  9:32 UTC (permalink / raw)
  To: Moore, Robert
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

On Wednesday, November 14, 2012 10:18:46 AM Rafael J. Wysocki wrote:
> On Wednesday, November 14, 2012 02:23:51 AM Moore, Robert wrote:
> > Rafael,
> > 
> > I sounds like with a few changes, we can enhance this mechanism to
> > be more useful to you and others. Some comments below. I need to look
> > at the code in question a bit more, but I see no insurmountable issues.
> 
> Great, thanks!
>  
> 
> > > -----Original Message-----
> > > From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> > > Sent: Tuesday, November 13, 2012 2:57 PM
> > > To: Moore, Robert
> > > Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> > > acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> > > Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> > > grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> > > Bjorn Helgaas; Zheng, Lv
> > > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> > > objects
> > > 
> > > On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > > > I may not quite understand what you are asking for, but I will try.
> > > > It seems like we already have much of what you want/need, so maybe I'm
> > > > missing something.
> > > 
> > > I think all of the necessary pieces are there.
> > > 
> > > > > So what I would like to have, in general terms, is something like
> > > > > acpi_walk_resources() split into three parts:
> > > > >
> > > > >  (1) One that processes the _CRS output and creates a list of
> > > > >      struct acpi_resource objects for us to play with.  I suppose
> > > > >      it's OK if that's just a buffer filled with resource objects,
> > > > >      but a linked list might be more convenient.
> > > > >
> > > >
> > > > This sounds like AcpiGetCurrentResources. It executes _CRS and formats
> > > > the data into acpi_resource objects.
> > > 
> > > Yes, it does.  However, it is not completely clear to me if/how the caller
> > > is supposed to prepare the buffer object pointed to by the second arg.
> > > 
> > > If the buffer is initialized by AcpiGetCurrentResources, then that's what
> > > I need for (1).
> > 
> > 
> > It looks to me that at least AcpiGetCurrentResources does not actually ever
> > allocate a buffer for the resource template, it expects the caller to
> > eventually provide one of at least the size of the returned resource template.
> > 
> > This is really quite a bit out-of-date as far as the memory allocation model.
> > It should also support the option to just allocate the buffer of the appropriate
> > size before returning it to the caller.
> 
> Yes, that would be really useful.
> 
> Ideally, I'd like to be able to pass a pointer to an uninitialized buffer
> structure to it (or to a wrapper around it) and get a buffer full of
> struct acpi_resource objects (if _CRS returns any) back from it. :-)

Of course, I can add such a wrapper in the Linux-specific code just fine.


> > > > >  (2) One that allows us to access (read/write) resources in the
> > > > >      list returned by (1).  We don't need to open code walking
> > > > >      the list and I probably wouldn't event want to do that.  What
> > > > >      we need is to be able to walk the same list for a number of
> > > > >      times and possibly to modify values in the resource objects
> > > > >      if there are conflicts.
> > > >
> > > > This sounds like AcpiWalkResources. I suppose a possible issue is that
> > > > currently, AcpiWalkResources actually invokes the _CRS, _PRS, or _AEI
> > > > method on behalf of the caller.
> > > 
> > > Yes, that exactly is the problem.
> > > 
> > > > It might make more sense to allow the caller to pass in the resource
> > > > buffer returned from a call to _CRS, etc.
> > > 
> > > Yes! :-)
> > 
> > 
> > I'll take a closer look at this tomorrow.
> 
> Cool, thanks!
> 
> 
> > > > >  (3) One allowing us to free the list returned by (1) if not needed
> > > > >      any more.
> > > > >
> > > >
> > > > AcpiGetCurrentResources: Currently, everything is returned in a single
> > > > buffer to minimize the number of allocations. A buffer you can free
> > > > when you are done with it.
> > > 
> > > I suppose I should use ACPI_FREE(buffer.pointer) for that, but isn't it
> > > for the ACPICA's internal use only?
> > > 
> > > Besides, I would prefer to be able to pass just "buffer" for freeing,
> > > without having to touch its internals.  No big deal, but it would be
> > > nicer. :-)
> > 
> > 
> > The ACPI_BUFFER type is in fact a public type that is meant to return both the
> > buffer and the (actual) length. You will find many instances of
> > ACPI_FREE(buffer.pointer) within existing linux code, since it also used for
> > objects returned by control method execution/object evaluation.
> 
> Well, I suppose I only wanted to say that acpi_free_buffer(buffer) would look
> a bit more straightforward than ACPI_FREE(buffer.pointer). :-)

And I can define acpi_free_buffer() in the Linux-specific code too.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources
  2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
                       ` (2 preceding siblings ...)
  2012-11-13 20:56     ` [PATCH 3/3 rev 2] ACPI: Centralized processing of ACPI device resources Rafael J. Wysocki
@ 2012-11-14  9:52     ` Mika Westerberg
  2012-11-14 10:08       ` Rafael J. Wysocki
  3 siblings, 1 reply; 127+ messages in thread
From: Mika Westerberg @ 2012-11-14  9:52 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-acpi, mathias.nyman, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

On Tue, Nov 13, 2012 at 09:51:39PM +0100, Rafael J. Wysocki wrote:
> Updated series, taking the Mika's feedback into account, follows.  There are
> bug fixes in [1/3], [2/3] is unchanged and the new [3/3] is a replacement, done
> in a different way because of some ACPICA limitations I didn't realize before.

I've now tested this series on my ACPI 5 enabled test machine and
everything works fine - I can see the platform devices and that they have
the ACPI handle attached.

For the whole series,

Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>

(testing has been limited on one ACPI 5 machine, though).

I guess I can start preparing the GPIO/SPI/I2C patches soon ;-)

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

* Re: [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources
  2012-11-14  9:52     ` [PATCH 0/3 rev 2] Centralized parsing " Mika Westerberg
@ 2012-11-14 10:08       ` Rafael J. Wysocki
  0 siblings, 0 replies; 127+ messages in thread
From: Rafael J. Wysocki @ 2012-11-14 10:08 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-acpi, mathias.nyman, linux-kernel, lenb, rafael.j.wysocki,
	broonie, grant.likely, linus.walleij, khali, Bjorn Helgaas

On Wednesday, November 14, 2012 11:52:32 AM Mika Westerberg wrote:
> On Tue, Nov 13, 2012 at 09:51:39PM +0100, Rafael J. Wysocki wrote:
> > Updated series, taking the Mika's feedback into account, follows.  There are
> > bug fixes in [1/3], [2/3] is unchanged and the new [3/3] is a replacement, done
> > in a different way because of some ACPICA limitations I didn't realize before.
> 
> I've now tested this series on my ACPI 5 enabled test machine and
> everything works fine - I can see the platform devices and that they have
> the ACPI handle attached.
> 
> For the whole series,
> 
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> (testing has been limited on one ACPI 5 machine, though).

OK, thanks!

> I guess I can start preparing the GPIO/SPI/I2C patches soon ;-)

Yes, please. :-)

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
  2012-11-14  9:32                         ` Rafael J. Wysocki
@ 2012-11-14 14:20                           ` Moore, Robert
  -1 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-14 14:20 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

> And I can define acpi_free_buffer() in the Linux-specific code too.
> 
> Thanks,
> Rafael

I'll be glad to add an ACPI_FREE_BUFFER macro, although we've had complaints over the years that ACPICA uses too many macros. (Not so many complaints in the last 5 years, however.)

Bob


> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Wednesday, November 14, 2012 1:33 AM
> To: Moore, Robert
> Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> Bjorn Helgaas; Zheng, Lv
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Wednesday, November 14, 2012 10:18:46 AM Rafael J. Wysocki wrote:
> > On Wednesday, November 14, 2012 02:23:51 AM Moore, Robert wrote:
> > > Rafael,
> > >
> > > I sounds like with a few changes, we can enhance this mechanism to
> > > be more useful to you and others. Some comments below. I need to
> > > look at the code in question a bit more, but I see no insurmountable
> issues.
> >
> > Great, thanks!
> >
> >
> > > > -----Original Message-----
> > > > From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> > > > Sent: Tuesday, November 13, 2012 2:57 PM
> > > > To: Moore, Robert
> > > > Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> > > > acpi@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > lenb@kernel.org; Wysocki, Rafael J;
> > > > broonie@opensource.wolfsonmicro.com;
> > > > grant.likely@secretlab.ca; linus.walleij@linaro.org;
> > > > khali@linux-fr.org; Bjorn Helgaas; Zheng, Lv
> > > > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device
> > > > node objects
> > > >
> > > > On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > > > > I may not quite understand what you are asking for, but I will
> try.
> > > > > It seems like we already have much of what you want/need, so
> > > > > maybe I'm missing something.
> > > >
> > > > I think all of the necessary pieces are there.
> > > >
> > > > > > So what I would like to have, in general terms, is something
> > > > > > like
> > > > > > acpi_walk_resources() split into three parts:
> > > > > >
> > > > > >  (1) One that processes the _CRS output and creates a list of
> > > > > >      struct acpi_resource objects for us to play with.  I
> suppose
> > > > > >      it's OK if that's just a buffer filled with resource
> objects,
> > > > > >      but a linked list might be more convenient.
> > > > > >
> > > > >
> > > > > This sounds like AcpiGetCurrentResources. It executes _CRS and
> > > > > formats the data into acpi_resource objects.
> > > >
> > > > Yes, it does.  However, it is not completely clear to me if/how
> > > > the caller is supposed to prepare the buffer object pointed to by
> the second arg.
> > > >
> > > > If the buffer is initialized by AcpiGetCurrentResources, then
> > > > that's what I need for (1).
> > >
> > >
> > > It looks to me that at least AcpiGetCurrentResources does not
> > > actually ever allocate a buffer for the resource template, it
> > > expects the caller to eventually provide one of at least the size of
> the returned resource template.
> > >
> > > This is really quite a bit out-of-date as far as the memory allocation
> model.
> > > It should also support the option to just allocate the buffer of the
> > > appropriate size before returning it to the caller.
> >
> > Yes, that would be really useful.
> >
> > Ideally, I'd like to be able to pass a pointer to an uninitialized
> > buffer structure to it (or to a wrapper around it) and get a buffer
> > full of struct acpi_resource objects (if _CRS returns any) back from
> > it. :-)
> 
> Of course, I can add such a wrapper in the Linux-specific code just fine.
> 
> 
> > > > > >  (2) One that allows us to access (read/write) resources in the
> > > > > >      list returned by (1).  We don't need to open code walking
> > > > > >      the list and I probably wouldn't event want to do that.
> What
> > > > > >      we need is to be able to walk the same list for a number of
> > > > > >      times and possibly to modify values in the resource objects
> > > > > >      if there are conflicts.
> > > > >
> > > > > This sounds like AcpiWalkResources. I suppose a possible issue
> > > > > is that currently, AcpiWalkResources actually invokes the _CRS,
> > > > > _PRS, or _AEI method on behalf of the caller.
> > > >
> > > > Yes, that exactly is the problem.
> > > >
> > > > > It might make more sense to allow the caller to pass in the
> > > > > resource buffer returned from a call to _CRS, etc.
> > > >
> > > > Yes! :-)
> > >
> > >
> > > I'll take a closer look at this tomorrow.
> >
> > Cool, thanks!
> >
> >
> > > > > >  (3) One allowing us to free the list returned by (1) if not
> needed
> > > > > >      any more.
> > > > > >
> > > > >
> > > > > AcpiGetCurrentResources: Currently, everything is returned in a
> > > > > single buffer to minimize the number of allocations. A buffer
> > > > > you can free when you are done with it.
> > > >
> > > > I suppose I should use ACPI_FREE(buffer.pointer) for that, but
> > > > isn't it for the ACPICA's internal use only?
> > > >
> > > > Besides, I would prefer to be able to pass just "buffer" for
> > > > freeing, without having to touch its internals.  No big deal, but
> > > > it would be nicer. :-)
> > >
> > >
> > > The ACPI_BUFFER type is in fact a public type that is meant to
> > > return both the buffer and the (actual) length. You will find many
> > > instances of
> > > ACPI_FREE(buffer.pointer) within existing linux code, since it also
> > > used for objects returned by control method execution/object
> evaluation.
> >
> > Well, I suppose I only wanted to say that acpi_free_buffer(buffer)
> > would look a bit more straightforward than ACPI_FREE(buffer.pointer).
> > :-)
> 
> And I can define acpi_free_buffer() in the Linux-specific code too.
> 
> Thanks,
> Rafael
> 
> 
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.

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

* RE: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects
@ 2012-11-14 14:20                           ` Moore, Robert
  0 siblings, 0 replies; 127+ messages in thread
From: Moore, Robert @ 2012-11-14 14:20 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Mika Westerberg, mathias.nyman, linux-acpi, linux-kernel, lenb,
	Wysocki, Rafael J, broonie, grant.likely, linus.walleij, khali,
	Bjorn Helgaas, Zheng, Lv

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 6303 bytes --]

> And I can define acpi_free_buffer() in the Linux-specific code too.
> 
> Thanks,
> Rafael

I'll be glad to add an ACPI_FREE_BUFFER macro, although we've had complaints over the years that ACPICA uses too many macros. (Not so many complaints in the last 5 years, however.)

Bob


> -----Original Message-----
> From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> Sent: Wednesday, November 14, 2012 1:33 AM
> To: Moore, Robert
> Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> acpi@vger.kernel.org; linux-kernel@vger.kernel.org; lenb@kernel.org;
> Wysocki, Rafael J; broonie@opensource.wolfsonmicro.com;
> grant.likely@secretlab.ca; linus.walleij@linaro.org; khali@linux-fr.org;
> Bjorn Helgaas; Zheng, Lv
> Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device node
> objects
> 
> On Wednesday, November 14, 2012 10:18:46 AM Rafael J. Wysocki wrote:
> > On Wednesday, November 14, 2012 02:23:51 AM Moore, Robert wrote:
> > > Rafael,
> > >
> > > I sounds like with a few changes, we can enhance this mechanism to
> > > be more useful to you and others. Some comments below. I need to
> > > look at the code in question a bit more, but I see no insurmountable
> issues.
> >
> > Great, thanks!
> >
> >
> > > > -----Original Message-----
> > > > From: Rafael J. Wysocki [mailto:rjw@sisk.pl]
> > > > Sent: Tuesday, November 13, 2012 2:57 PM
> > > > To: Moore, Robert
> > > > Cc: Mika Westerberg; mathias.nyman@linux.intel.com; linux-
> > > > acpi@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > lenb@kernel.org; Wysocki, Rafael J;
> > > > broonie@opensource.wolfsonmicro.com;
> > > > grant.likely@secretlab.ca; linus.walleij@linaro.org;
> > > > khali@linux-fr.org; Bjorn Helgaas; Zheng, Lv
> > > > Subject: Re: [PATCH 3/3] ACPI: Evaluate _CRS while creating device
> > > > node objects
> > > >
> > > > On Tuesday, November 13, 2012 10:06:03 PM Moore, Robert wrote:
> > > > > I may not quite understand what you are asking for, but I will
> try.
> > > > > It seems like we already have much of what you want/need, so
> > > > > maybe I'm missing something.
> > > >
> > > > I think all of the necessary pieces are there.
> > > >
> > > > > > So what I would like to have, in general terms, is something
> > > > > > like
> > > > > > acpi_walk_resources() split into three parts:
> > > > > >
> > > > > >  (1) One that processes the _CRS output and creates a list of
> > > > > >      struct acpi_resource objects for us to play with.  I
> suppose
> > > > > >      it's OK if that's just a buffer filled with resource
> objects,
> > > > > >      but a linked list might be more convenient.
> > > > > >
> > > > >
> > > > > This sounds like AcpiGetCurrentResources. It executes _CRS and
> > > > > formats the data into acpi_resource objects.
> > > >
> > > > Yes, it does.  However, it is not completely clear to me if/how
> > > > the caller is supposed to prepare the buffer object pointed to by
> the second arg.
> > > >
> > > > If the buffer is initialized by AcpiGetCurrentResources, then
> > > > that's what I need for (1).
> > >
> > >
> > > It looks to me that at least AcpiGetCurrentResources does not
> > > actually ever allocate a buffer for the resource template, it
> > > expects the caller to eventually provide one of at least the size of
> the returned resource template.
> > >
> > > This is really quite a bit out-of-date as far as the memory allocation
> model.
> > > It should also support the option to just allocate the buffer of the
> > > appropriate size before returning it to the caller.
> >
> > Yes, that would be really useful.
> >
> > Ideally, I'd like to be able to pass a pointer to an uninitialized
> > buffer structure to it (or to a wrapper around it) and get a buffer
> > full of struct acpi_resource objects (if _CRS returns any) back from
> > it. :-)
> 
> Of course, I can add such a wrapper in the Linux-specific code just fine.
> 
> 
> > > > > >  (2) One that allows us to access (read/write) resources in the
> > > > > >      list returned by (1).  We don't need to open code walking
> > > > > >      the list and I probably wouldn't event want to do that.
> What
> > > > > >      we need is to be able to walk the same list for a number of
> > > > > >      times and possibly to modify values in the resource objects
> > > > > >      if there are conflicts.
> > > > >
> > > > > This sounds like AcpiWalkResources. I suppose a possible issue
> > > > > is that currently, AcpiWalkResources actually invokes the _CRS,
> > > > > _PRS, or _AEI method on behalf of the caller.
> > > >
> > > > Yes, that exactly is the problem.
> > > >
> > > > > It might make more sense to allow the caller to pass in the
> > > > > resource buffer returned from a call to _CRS, etc.
> > > >
> > > > Yes! :-)
> > >
> > >
> > > I'll take a closer look at this tomorrow.
> >
> > Cool, thanks!
> >
> >
> > > > > >  (3) One allowing us to free the list returned by (1) if not
> needed
> > > > > >      any more.
> > > > > >
> > > > >
> > > > > AcpiGetCurrentResources: Currently, everything is returned in a
> > > > > single buffer to minimize the number of allocations. A buffer
> > > > > you can free when you are done with it.
> > > >
> > > > I suppose I should use ACPI_FREE(buffer.pointer) for that, but
> > > > isn't it for the ACPICA's internal use only?
> > > >
> > > > Besides, I would prefer to be able to pass just "buffer" for
> > > > freeing, without having to touch its internals.  No big deal, but
> > > > it would be nicer. :-)
> > >
> > >
> > > The ACPI_BUFFER type is in fact a public type that is meant to
> > > return both the buffer and the (actual) length. You will find many
> > > instances of
> > > ACPI_FREE(buffer.pointer) within existing linux code, since it also
> > > used for objects returned by control method execution/object
> evaluation.
> >
> > Well, I suppose I only wanted to say that acpi_free_buffer(buffer)
> > would look a bit more straightforward than ACPI_FREE(buffer.pointer).
> > :-)
> 
> And I can define acpi_free_buffer() in the Linux-specific code too.
> 
> Thanks,
> Rafael
> 
> 
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

end of thread, other threads:[~2012-11-14 14:20 UTC | newest]

Thread overview: 127+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-03  7:46 [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Mika Westerberg
2012-11-03  7:46 ` [PATCH 1/3] gpio / ACPI: add ACPI support Mika Westerberg
2012-11-05 11:53   ` Linus Walleij
2012-11-05 12:14     ` Mathias Nyman
2012-11-05 12:46       ` Rafael J. Wysocki
2012-11-05 13:11         ` Linus Walleij
2012-11-05 13:19           ` Rafael J. Wysocki
2012-11-05 13:28             ` Linus Walleij
2012-11-05 13:50               ` Rafael J. Wysocki
2012-11-05 14:40                 ` Linus Walleij
2012-11-06  9:39                   ` Mika Westerberg
2012-11-06 10:15                     ` Linus Walleij
2012-11-07  8:54                       ` Mika Westerberg
2012-11-08 15:55   ` Grant Likely
2012-11-08 19:38     ` Mika Westerberg
2012-11-09 14:11       ` Mathias Nyman
2012-11-09 14:18         ` Grant Likely
2012-11-09 15:05           ` Mathias Nyman
2012-11-09 15:46             ` Grant Likely
2012-11-11  9:50               ` Mika Westerberg
2012-11-03  7:46 ` [PATCH 2/3] spi / ACPI: add ACPI enumeration support Mika Westerberg
2012-11-03 19:42   ` Bjorn Helgaas
2012-11-03 20:13     ` Mika Westerberg
2012-11-03 20:59       ` Rafael J. Wysocki
2012-11-05 10:31         ` Rafael J. Wysocki
2012-11-05 10:56           ` Mika Westerberg
2012-11-05 10:56             ` Mark Brown
2012-11-05 12:02               ` Mika Westerberg
2012-11-05 12:23                 ` Jean Delvare
2012-11-05 12:59                   ` Rafael J. Wysocki
2012-11-05 13:15                     ` Mika Westerberg
2012-11-05 13:20                       ` Linus Walleij
2012-11-05 13:43                         ` Mika Westerberg
2012-11-05 14:03                         ` Jean Delvare
2012-11-05 14:19                           ` Rafael J. Wysocki
2012-11-05 14:53                             ` Mika Westerberg
2012-11-05 15:19                               ` Jean Delvare
2012-11-05 17:12                                 ` Mika Westerberg
2012-11-05 17:43                                   ` Bjorn Helgaas
2012-11-05 18:08                                     ` Mika Westerberg
2012-11-05 17:49                                   ` Jean Delvare
2012-11-05 20:42                           ` Linus Walleij
2012-11-06  8:11                 ` Mark Brown
2012-11-05 16:54           ` Bjorn Helgaas
2012-11-06 13:43             ` Rafael J. Wysocki
2012-11-06 20:35               ` Bjorn Helgaas
2012-11-06 22:28                 ` Rafael J. Wysocki
2012-11-06 22:36                   ` Rafael J. Wysocki
2012-11-07  9:58                     ` Mika Westerberg
2012-11-07 11:14                       ` Rafael J. Wysocki
2012-11-07 13:05                         ` Mika Westerberg
2012-11-08  0:46                           ` Rafael J. Wysocki
2012-11-08 20:20                             ` Mika Westerberg
2012-11-08 20:54                               ` Rafael J. Wysocki
2012-11-08 18:05                       ` Grant Likely
2012-11-08 21:06                         ` Rafael J. Wysocki
2012-11-08 21:34                           ` Grant Likely
2012-11-05 10:54       ` Mark Brown
2012-11-03 20:39     ` Rafael J. Wysocki
2012-11-05 16:54       ` Bjorn Helgaas
2012-11-06 13:16         ` Rafael J. Wysocki
2012-11-06 20:53           ` Bjorn Helgaas
2012-11-06 22:18             ` Rafael J. Wysocki
2012-11-07  9:56               ` Mika Westerberg
2012-11-08 19:32                 ` Bjorn Helgaas
2012-11-08 20:04                   ` Mika Westerberg
2012-11-09 15:11                     ` Bjorn Helgaas
2012-11-09 15:45                       ` Grant Likely
2012-11-09 16:35                         ` Bjorn Helgaas
2012-11-09 16:43                           ` Grant Likely
2012-11-09 16:48                             ` Mark Brown
2012-11-09 16:53                             ` Bjorn Helgaas
2012-11-10 11:10                               ` Rafael J. Wysocki
2012-11-10 11:16                                 ` Grant Likely
2012-11-10 17:14                                 ` Bjorn Helgaas
2012-11-10 19:40                                   ` Rafael J. Wysocki
2012-11-05 10:54   ` Mark Brown
2012-11-05 11:03     ` Mika Westerberg
2012-11-05 11:13       ` Mark Brown
2012-11-08 18:48   ` Grant Likely
2012-11-09  3:50     ` Mika Westerberg
2012-11-03  7:46 ` [PATCH 3/3] i2c " Mika Westerberg
2012-11-03 21:52   ` Jean Delvare
2012-11-04  7:23     ` Mika Westerberg
2012-11-04  8:50       ` Jean Delvare
2012-11-04 10:50         ` Mika Westerberg
2012-11-08 18:58   ` Grant Likely
2012-11-09  3:51     ` Mika Westerberg
2012-11-04 18:29 ` [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C Linus Walleij
2012-11-05  9:23   ` Mika Westerberg
2012-11-12 11:51 ` [PATCH 0/3] Centralized parsing of ACPI device resources (was: Re: [PATCH 0/3] ACPI 5 support for GPIO, SPI and I2C) Rafael J. Wysocki
2012-11-12 12:00   ` [PATCH 1/3] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
2012-11-12 13:27     ` Mika Westerberg
2012-11-12 20:25       ` [Update][PATCH " Rafael J. Wysocki
2012-11-12 12:01   ` [PATCH 2/3] ACPI / platform: Use common ACPI device resource parsing routines Rafael J. Wysocki
2012-11-12 12:02   ` [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects Rafael J. Wysocki
2012-11-12 14:46     ` Mika Westerberg
2012-11-12 21:03       ` Rafael J. Wysocki
2012-11-13  7:12         ` Mika Westerberg
2012-11-13 12:06           ` [Replacement][PATCH 3/3] Rafael J. Wysocki
2012-11-13 14:16             ` Mika Westerberg
2012-11-13 15:15               ` Rafael J. Wysocki
2012-11-13 15:18                 ` Mika Westerberg
2012-11-13 15:28                   ` Rafael J. Wysocki
2012-11-13 15:37                     ` Mika Westerberg
2012-11-13 16:34           ` [PATCH 3/3] ACPI: Evaluate _CRS while creating device node objects Moore, Robert
2012-11-13 16:34             ` Moore, Robert
2012-11-13 20:44             ` Rafael J. Wysocki
2012-11-13 20:44               ` Rafael J. Wysocki
2012-11-13 22:06               ` Moore, Robert
2012-11-13 22:06                 ` Moore, Robert
2012-11-13 22:56                 ` Rafael J. Wysocki
2012-11-13 22:56                   ` Rafael J. Wysocki
2012-11-14  2:23                   ` Moore, Robert
2012-11-14  2:23                     ` Moore, Robert
2012-11-14  9:18                     ` Rafael J. Wysocki
2012-11-14  9:18                       ` Rafael J. Wysocki
2012-11-14  9:32                       ` Rafael J. Wysocki
2012-11-14  9:32                         ` Rafael J. Wysocki
2012-11-14 14:20                         ` Moore, Robert
2012-11-14 14:20                           ` Moore, Robert
2012-11-13 20:51   ` [PATCH 0/3 rev 2] Centralized parsing of ACPI device resources Rafael J. Wysocki
2012-11-13 20:55     ` [PATCH 1/3 rev 2] ACPI: Move device resources interpretation code from PNP to ACPI core Rafael J. Wysocki
2012-11-13 20:55     ` [PATCH 2/3 rev 2] ACPI / platform: Use common ACPI device resource parsing routines Rafael J. Wysocki
2012-11-13 20:56     ` [PATCH 3/3 rev 2] ACPI: Centralized processing of ACPI device resources Rafael J. Wysocki
2012-11-14  9:52     ` [PATCH 0/3 rev 2] Centralized parsing " Mika Westerberg
2012-11-14 10:08       ` Rafael J. Wysocki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.