Sending this as an RFC with one driver converted to see what people
think. The goal is to avoid having to run the match twice and be
similar to how platform_device_id works right now. If people agree
I can go through and send out patches for all the drivers doing
the duplicate search (~100 files).
Stephen Boyd (2):
of: Assign of_device_id to matching device_node
gpio/omap: Use of_node->id_entry directly
drivers/gpio/gpio-omap.c | 4 +---
drivers/of/device.c | 18 ++++++++++++++++++
include/linux/of.h | 1 +
include/linux/of_device.h | 12 ++----------
4 files changed, 22 insertions(+), 13 deletions(-)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
Now that the driver core is assigning the of_device_id that
matches to the of_node before calling probe we can skip this
duplicate search and just use of_node->id_entry directly.
Signed-off-by: Stephen Boyd <[email protected]>
---
drivers/gpio/gpio-omap.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 2050891..04ae7e7 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1083,8 +1083,6 @@ static void omap_gpio_chip_init(struct gpio_bank *bank)
irq_set_handler_data(bank->irq, bank);
}
-static const struct of_device_id omap_gpio_match[];
-
static int omap_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -1094,7 +1092,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
struct resource *res;
struct gpio_bank *bank;
- match = of_match_device(of_match_ptr(omap_gpio_match), dev);
+ match = pdev->dev.of_node->id_entry;
pdata = match ? match->data : dev->platform_data;
if (!pdata)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
Platform drivers have to match the compatible field twice if they
want to use the .data field of the of_device_id struct when their
driver matches multiple devicetree compatible fields. The first
match happens when the driver core probes for a matching
device and the second match typically happens during their probe
routine when the driver calls of_match_device() to get the
of_device_id that this device matches.
Skip this duplicate search by assigning the of_device_id to a new
id_entry pointer in the device_node struct when the driver core
matches up an of_device_id with a device_node. Drivers can then
get the entry pointer via dev->of_node->id_entry and access the
.data field to differentiate which device they matched.
Signed-off-by: Stephen Boyd <[email protected]>
---
drivers/of/device.c | 18 ++++++++++++++++++
include/linux/of.h | 1 +
include/linux/of_device.h | 12 ++----------
3 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/of/device.c b/drivers/of/device.c
index f685e55..f3eab88 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -27,6 +27,24 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
}
EXPORT_SYMBOL(of_match_device);
+/**
+ * of_driver_match_device - Tell if a driver's of_match_table matches a device.
+ * @drv: the device_driver structure to test
+ * @dev: the device structure to match against
+ */
+int of_driver_match_device(struct device *dev,
+ const struct device_driver *drv)
+{
+ const struct of_device_id *id;
+
+ id = of_match_device(drv->of_match_table, dev);
+ if (id)
+ dev->of_node->id_entry = id;
+
+ return id != NULL;
+}
+EXPORT_SYMBOL(of_driver_match_device);
+
struct platform_device *of_dev_get(struct platform_device *dev)
{
struct device *tmp;
diff --git a/include/linux/of.h b/include/linux/of.h
index 1fd08ca..6c847af 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -59,6 +59,7 @@ struct device_node {
struct proc_dir_entry *pde; /* this node's proc directory */
struct kref kref;
unsigned long _flags;
+ const struct of_device_id *id_entry;
void *data;
#if defined(CONFIG_SPARC)
const char *path_component_name;
diff --git a/include/linux/of_device.h b/include/linux/of_device.h
index 901b743..5b2a69a 100644
--- a/include/linux/of_device.h
+++ b/include/linux/of_device.h
@@ -14,16 +14,8 @@ extern const struct of_device_id *of_match_device(
const struct of_device_id *matches, const struct device *dev);
extern void of_device_make_bus_id(struct device *dev);
-/**
- * of_driver_match_device - Tell if a driver's of_match_table matches a device.
- * @drv: the device_driver structure to test
- * @dev: the device structure to match against
- */
-static inline int of_driver_match_device(struct device *dev,
- const struct device_driver *drv)
-{
- return of_match_device(drv->of_match_table, dev) != NULL;
-}
+extern int of_driver_match_device(struct device *dev,
+ const struct device_driver *drv);
extern struct platform_device *of_dev_get(struct platform_device *dev);
extern void of_dev_put(struct platform_device *dev);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
On Wed, May 22, 2013 at 3:40 PM, Stephen Boyd <[email protected]> wrote:
> Sending this as an RFC with one driver converted to see what people
> think. The goal is to avoid having to run the match twice and be
> similar to how platform_device_id works right now. If people agree
> I can go through and send out patches for all the drivers doing
> the duplicate search (~100 files).
>
See this commit:
commit b1608d69cb804e414d0887140ba08a9398e4e638
Author: Grant Likely <[email protected]>
Date: Wed May 18 11:19:24 2011 -0600
drivercore: revert addition of of_match to struct device
Commit b826291c, "drivercore/dt: add a match table pointer to struct
device" added an of_match pointer to struct device to cache the
of_match_table entry discovered at driver match time. This was unsafe
because matching is not an atomic operation with probing a driver. If
two or more drivers are attempted to be matched to a driver at the
same time, then the cached matching entry pointer could get
overwritten.
This patch reverts the of_match cache pointer and reworks all users to
call of_match_device() directly instead.
Signed-off-by: Grant Likely <[email protected]>