public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Grant Likely <grant.likely@linaro.org>
Cc: ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Darren Hart <darren.hart@intel.com>,
	Mika Westerberg <mika.westerberg@linux.intel.com>,
	Aaron Lu <aaron.lu@intel.com>, Arnd Bergmann <arnd@arndb.de>,
	devicetree@vger.kernel.org,
	Linus Walleij <linus.walleij@linaro.org>,
	Alexandre Courbot <gnurou@gmail.com>,
	Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Bryan Wu <cooloney@gmail.com>
Subject: [PATCH v6 03/12] ACPI: Allow drivers to match using Device Tree compatible property
Date: Tue, 21 Oct 2014 23:19:20 +0200	[thread overview]
Message-ID: <1637143.FRLeu7Fjhe@vostro.rjw.lan> (raw)
In-Reply-To: <13750506.S2yVlRRDa2@vostro.rjw.lan>

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

We have lots of existing Device Tree enabled drivers and allocating
separate _HID for each is not feasible. Instead we allocate special _HID
"PRP0001" that means that the match should be done using Device Tree
compatible property using driver's .of_match_table instead if the driver
is missing .acpi_match_table.

If there is a need to distinguish from where the device is enumerated
(DT/ACPI) driver can check dev->of_node or ACPI_COMPATION(dev).

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---

Changes from v5:
- Package () { "compatible", "blah" } is now regarded as a valid compatible
  property definition and is equivalent to
  Package () { "compatible", Package () { "blah" } }

Grant, I've dropped the Reviewed-by from you due to the modifications, please
have another look at the code.

---
 drivers/acpi/property.c |   39 ++++++++++++++++++
 drivers/acpi/scan.c     |  104 +++++++++++++++++++++++++++++++++++++++++++-----
 include/acpi/acpi_bus.h |    1 
 include/linux/acpi.h    |    8 ---
 4 files changed, 136 insertions(+), 16 deletions(-)

Index: linux-pm/drivers/acpi/property.c
===================================================================
--- linux-pm.orig/drivers/acpi/property.c
+++ linux-pm/drivers/acpi/property.c
@@ -76,6 +76,42 @@ static bool acpi_properties_format_valid
 	return true;
 }
 
+static void acpi_init_of_compatible(struct acpi_device *adev)
+{
+	const union acpi_object *of_compatible;
+	struct acpi_hardware_id *hwid;
+	bool acpi_of = false;
+	int ret;
+
+	/*
+	 * Check if the special PRP0001 ACPI ID is present and in that
+	 * case we fill in Device Tree compatible properties for this
+	 * device.
+	 */
+	list_for_each_entry(hwid, &adev->pnp.ids, list) {
+		if (!strcmp(hwid->id, "PRP0001")) {
+			acpi_of = true;
+			break;
+		}
+	}
+
+	if (!acpi_of)
+		return;
+
+	ret = acpi_dev_get_property_array(adev, "compatible", ACPI_TYPE_STRING,
+					  &of_compatible);
+	if (ret) {
+		ret = acpi_dev_get_property(adev, "compatible",
+					    ACPI_TYPE_STRING, &of_compatible);
+		if (ret) {
+			acpi_handle_warn(adev->handle,
+					 "PRP0001 requires compatible property\n");
+			return;
+		}
+	}
+	adev->data.of_compatible = of_compatible;
+}
+
 void acpi_init_properties(struct acpi_device *adev)
 {
 	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
@@ -119,6 +155,8 @@ void acpi_init_properties(struct acpi_de
 
 		adev->data.pointer = buf.pointer;
 		adev->data.properties = properties;
+
+		acpi_init_of_compatible(adev);
 		return;
 	}
 
@@ -130,6 +168,7 @@ void acpi_init_properties(struct acpi_de
 void acpi_free_properties(struct acpi_device *adev)
 {
 	ACPI_FREE((void *)adev->data.pointer);
+	adev->data.of_compatible = NULL;
 	adev->data.pointer = NULL;
 	adev->data.properties = NULL;
 }
Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -124,17 +124,56 @@ static int create_modalias(struct acpi_d
 	if (list_empty(&acpi_dev->pnp.ids))
 		return 0;
 
-	len = snprintf(modalias, size, "acpi:");
-	size -= len;
+	/*
+	 * If the device has PRP0001 we expose DT compatible modalias
+	 * instead in form of of:NnameTCcompatible.
+	 */
+	if (acpi_dev->data.of_compatible) {
+		struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+		const union acpi_object *of_compatible, *obj;
+		int i, nval;
+		char *c;
+
+		acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
+		/* DT strings are all in lower case */
+		for (c = buf.pointer; *c != '\0'; c++)
+			*c = tolower(*c);
+
+		len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
+		ACPI_FREE(buf.pointer);
+
+		of_compatible = acpi_dev->data.of_compatible;
+		if (of_compatible->type == ACPI_TYPE_PACKAGE) {
+			nval = of_compatible->package.count;
+			obj = of_compatible->package.elements;
+		} else { /* Must be ACPI_TYPE_STRING. */
+			nval = 1;
+			obj = of_compatible;
+		}
+		for (i = 0; i < nval; i++, obj++) {
+			count = snprintf(&modalias[len], size, "C%s",
+					 obj->string.pointer);
+			if (count < 0)
+				return -EINVAL;
+			if (count >= size)
+				return -ENOMEM;
+
+			len += count;
+			size -= count;
+		}
+	} else {
+		len = snprintf(modalias, size, "acpi:");
+		size -= len;
 
-	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
-		count = snprintf(&modalias[len], size, "%s:", id->id);
-		if (count < 0)
-			return -EINVAL;
-		if (count >= size)
-			return -ENOMEM;
-		len += count;
-		size -= count;
+		list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
+			count = snprintf(&modalias[len], size, "%s:", id->id);
+			if (count < 0)
+				return -EINVAL;
+			if (count >= size)
+				return -ENOMEM;
+			len += count;
+			size -= count;
+		}
 	}
 
 	modalias[len] = '\0';
@@ -864,6 +903,51 @@ int acpi_match_device_ids(struct acpi_de
 }
 EXPORT_SYMBOL(acpi_match_device_ids);
 
+/* Performs match against special "PRP0001" shoehorn ACPI ID */
+static bool acpi_of_driver_match_device(struct device *dev,
+					const struct device_driver *drv)
+{
+	const union acpi_object *of_compatible, *obj;
+	struct acpi_device *adev;
+	int i, nval;
+
+	adev = ACPI_COMPANION(dev);
+	if (!adev)
+		return false;
+
+	of_compatible = adev->data.of_compatible;
+	if (!drv->of_match_table || !of_compatible)
+		return false;
+
+	if (of_compatible->type == ACPI_TYPE_PACKAGE) {
+		nval = of_compatible->package.count;
+		obj = of_compatible->package.elements;
+	} else { /* Must be ACPI_TYPE_STRING. */
+		nval = 1;
+		obj = of_compatible;
+	}
+	/* Now we can look for the driver DT compatible strings */
+	for (i = 0; i < nval; i++, obj++) {
+		const struct of_device_id *id;
+
+		for (id = drv->of_match_table; id->compatible[0]; id++)
+			if (!strcasecmp(obj->string.pointer, id->compatible))
+				return true;
+	}
+
+	return false;
+}
+
+bool acpi_driver_match_device(struct device *dev,
+			      const struct device_driver *drv)
+{
+	if (!drv->acpi_match_table)
+		return acpi_of_driver_match_device(dev, drv);
+
+	return !!acpi_match_device(drv->acpi_match_table, dev);
+}
+EXPORT_SYMBOL_GPL(acpi_driver_match_device);
+
 static void acpi_free_power_resources_lists(struct acpi_device *device)
 {
 	int i;
Index: linux-pm/include/acpi/acpi_bus.h
===================================================================
--- linux-pm.orig/include/acpi/acpi_bus.h
+++ linux-pm/include/acpi/acpi_bus.h
@@ -341,6 +341,7 @@ struct acpi_device_physical_node {
 struct acpi_device_data {
 	const union acpi_object *pointer;
 	const union acpi_object *properties;
+	const union acpi_object *of_compatible;
 };
 
 /* Device */
Index: linux-pm/include/linux/acpi.h
===================================================================
--- linux-pm.orig/include/linux/acpi.h
+++ linux-pm/include/linux/acpi.h
@@ -424,12 +424,8 @@ extern int acpi_nvs_for_each_region(int
 const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
 					       const struct device *dev);
 
-static inline bool acpi_driver_match_device(struct device *dev,
-					    const struct device_driver *drv)
-{
-	return !!acpi_match_device(drv->acpi_match_table, dev);
-}
-
+extern bool acpi_driver_match_device(struct device *dev,
+				     const struct device_driver *drv);
 int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
 int acpi_device_modalias(struct device *, char *, int);
 

  parent reply	other threads:[~2014-10-21 21:19 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-21 21:08 [PATCH v6 00/12] Add ACPI _DSD and unified device properties support Rafael J. Wysocki
2014-10-21 21:09 ` [PATCH v6 01/12] ACPI: Add support for device specific properties Rafael J. Wysocki
2014-10-21 21:15 ` [PATCH v6 02/12] Driver core: Unified device properties interface for platform firmware Rafael J. Wysocki
2014-11-03 15:40   ` Grant Likely
2014-11-03 22:04     ` Rafael J. Wysocki
     [not found]       ` <3645687.BsyGDrJDrU-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-11-04 17:01         ` Grant Likely
     [not found]           ` <CACxGe6uv0TmoZivL3ESw+oRW-OjqakLP4KBnDrwJXzQ2ku8ZLA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-04 21:29             ` Rafael J. Wysocki
2014-11-04 15:51   ` Grant Likely
     [not found]     ` <20141104155112.6FC67C423D0-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2014-11-04 16:20       ` Rafael J. Wysocki
     [not found]   ` <2127128.VT1Iq03xz1-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-11-04 16:38     ` [Update][PATCH " Rafael J. Wysocki
2014-10-21 21:19 ` Rafael J. Wysocki [this message]
2014-10-21 21:19 ` [PATCH v6 04/12] misc: at25: Make use of device property API Rafael J. Wysocki
2014-11-04 14:18   ` Grant Likely
     [not found]     ` <20141104141826.36F8AC408F6-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
2014-11-04 14:38       ` Mika Westerberg
2014-11-04 15:04         ` Grant Likely
2014-11-04 16:19           ` Rafael J. Wysocki
     [not found]             ` <4645043.WOkgNMSUuO-sKB8Sp2ER+y1GS7QM15AGw@public.gmane.org>
2014-11-04 16:07               ` Mika Westerberg
2014-10-21 21:20 ` [PATCH v6 05/12] gpio / ACPI: Add support for _DSD device properties Rafael J. Wysocki
2014-10-21 21:21 ` [PATCH v6 06/12] gpio: sch: Consolidate core and resume banks Rafael J. Wysocki
2014-10-21 21:21 ` [PATCH v6 07/12] leds: leds-gpio: Add support for GPIO descriptors Rafael J. Wysocki
2014-10-21 21:22 ` [PATCH v6 08/12] input: gpio_keys_polled: " Rafael J. Wysocki
2014-10-21 21:29 ` [PATCH v6 09/12] Driver core: Unified interface for firmware node properties Rafael J. Wysocki
2014-11-04 16:43   ` [Update][PATCH " Rafael J. Wysocki
2014-10-21 21:33 ` [PATCH v6 10/12] gpio: Support for unified device properties interface Rafael J. Wysocki
2014-10-21 21:35 ` [PATCH v6 11/12] leds: leds-gpio: Make use of device property API Rafael J. Wysocki
2014-10-21 21:37 ` [PATCH v6 12/12] input: gpio_keys_polled: " Rafael J. Wysocki
2014-10-24 22:10 ` [PATCH v6 00/12] Add ACPI _DSD and unified device properties support Rafael J. Wysocki
2014-11-04 15:49   ` Grant Likely
2014-11-04 16:20     ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1637143.FRLeu7Fjhe@vostro.rjw.lan \
    --to=rjw@rjwysocki.net \
    --cc=aaron.lu@intel.com \
    --cc=arnd@arndb.de \
    --cc=cooloney@gmail.com \
    --cc=darren.hart@intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=gnurou@gmail.com \
    --cc=grant.likely@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox