The body of the loop is taken from the exynos driver. It appears to also be useful in msm, and I've used it in vc4.
Signed-off-by: Eric Anholt eric@anholt.net ---
This is separated from converting exynos to use it, to let it land separately and not have to sync between trees.
drivers/base/component.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/component.h | 5 +++++ 2 files changed, 45 insertions(+)
diff --git a/drivers/base/component.c b/drivers/base/component.c index f748430..08167a3 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -16,6 +16,7 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/platform_device.h> #include <linux/slab.h>
struct component_match { @@ -283,6 +284,45 @@ void component_match_add(struct device *dev, struct component_match **matchptr, } EXPORT_SYMBOL(component_match_add);
+static int compare_dev(struct device *dev, void *data) +{ + return dev == (struct device *)data; +} + +/** + * component_match_add_platform_drivers - For each driver passed in, + * finds each device that probed with it and adds it as a component + * driver to the match list. + * @dev: master device for the components + * @match: pointer to the match structure pointer. For the first + * component_match_add(), this should be a pointer to a NULL + * pointer, which will get filled in by the call. + * @drivers: array of platform drivers whose devices should all be + * added to the match + * @count: number of platform drivers to match + */ +void component_match_add_platform_drivers(struct device *dev, + struct component_match **match, + struct platform_driver *const *drivers, + int count) +{ + int i; + + for (i = 0; i < count; i++) { + struct device_driver *drv = &drivers[i]->driver; + struct device *p = NULL, *d; + + while ((d = bus_find_device(&platform_bus_type, p, drv, + (void *)platform_bus_type.match))) { + put_device(p); + component_match_add(dev, match, compare_dev, d); + p = d; + } + put_device(p); + } +} +EXPORT_SYMBOL_GPL(component_match_add_platform_drivers); + int component_master_add_with_match(struct device *dev, const struct component_master_ops *ops, struct component_match *match) diff --git a/include/linux/component.h b/include/linux/component.h index c00dcc3..2d74420 100644 --- a/include/linux/component.h +++ b/include/linux/component.h @@ -2,6 +2,7 @@ #define COMPONENT_H
struct device; +struct platform_driver;
struct component_ops { int (*bind)(struct device *, struct device *, void *); @@ -35,5 +36,9 @@ int component_master_add_with_match(struct device *, const struct component_master_ops *, struct component_match *); void component_match_add(struct device *, struct component_match **, int (*compare)(struct device *, void *), void *compare_data); +void component_match_add_platform_drivers(struct device *dev, + struct component_match **match, + struct platform_driver *const *drivers, + int count);
#endif
Signed-off-by: Eric Anholt eric@anholt.net --- drivers/gpu/drm/exynos/exynos_drm_drv.c | 37 +++++++-------------------------- 1 file changed, 7 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 831d2e4..74826ec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -566,32 +566,6 @@ static struct platform_driver *const exynos_drm_drv_with_simple_dev[] = { }; #define PDEV_COUNT ARRAY_SIZE(exynos_drm_drv_with_simple_dev)
-static int compare_dev(struct device *dev, void *data) -{ - return dev == (struct device *)data; -} - -static struct component_match *exynos_drm_match_add(struct device *dev) -{ - struct component_match *match = NULL; - int i; - - for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) { - struct device_driver *drv = &exynos_drm_kms_drivers[i]->driver; - struct device *p = NULL, *d; - - while ((d = bus_find_device(&platform_bus_type, p, drv, - (void *)platform_bus_type.match))) { - put_device(p); - component_match_add(dev, &match, compare_dev, d); - p = d; - } - put_device(p); - } - - return match ?: ERR_PTR(-ENODEV); -} - static int exynos_drm_bind(struct device *dev) { return drm_platform_init(&exynos_drm_driver, to_platform_device(dev)); @@ -609,14 +583,17 @@ static const struct component_master_ops exynos_drm_ops = {
static int exynos_drm_platform_probe(struct platform_device *pdev) { - struct component_match *match; + struct component_match *match = NULL;
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
- match = exynos_drm_match_add(&pdev->dev); - if (IS_ERR(match)) - return PTR_ERR(match); + component_match_add_platform_drivers(&pdev->dev, &match, + exynos_drm_kms_drivers, + ARRAY_SIZE(exynos_drm_kms_drivers)); + + if (!match) + return -ENODEV;
return component_master_add_with_match(&pdev->dev, &exynos_drm_ops, match);
Hi Eric.
2015-09-28 Eric Anholt eric@anholt.net:
Signed-off-by: Eric Anholt eric@anholt.net
drivers/gpu/drm/exynos/exynos_drm_drv.c | 37 +++++++-------------------------- 1 file changed, 7 insertions(+), 30 deletions(-)
Can you kindly add a commit message as well?
Otherwise,
Reviewed-by: Gustavo Padovan gustavo.padovan@collabora.co.uk
Gustavo
Hi Eric,
2015-09-28 Eric Anholt eric@anholt.net:
The body of the loop is taken from the exynos driver. It appears to also be useful in msm, and I've used it in vc4.
Signed-off-by: Eric Anholt eric@anholt.net
This is separated from converting exynos to use it, to let it land separately and not have to sync between trees.
drivers/base/component.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/component.h | 5 +++++ 2 files changed, 45 insertions(+)
This looks good to me.
Reviewed-by: Gustavo Padovan gustavo.padovan@collabora.co.uk
Gustavo
dri-devel@lists.freedesktop.org