Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1247958 > unrolled thread
| Started by | Liviu Dudau <Liviu.Dudau@arm.com> |
|---|---|
| First post | 2015-10-15 18:20 +0200 |
| Last post | 2015-10-15 18:20 +0200 |
| Articles | 4 — 1 participant |
Back to article view | Back to linux.kernel
[RFC PATCH 0/4] drm: Cleanup probe function for component based masters. Liviu Dudau <Liviu.Dudau@arm.com> - 2015-10-15 18:20 +0200
[RFC PATCH 1/4] drm: Introduce generic probe function for component based masters. Liviu Dudau <Liviu.Dudau@arm.com> - 2015-10-15 18:20 +0200
[RFC PATCH 3/4] drm/rockchip: Convert the probe function to the generic drm_of_component_probe() Liviu Dudau <Liviu.Dudau@arm.com> - 2015-10-15 18:20 +0200
[RFC PATCH 4/4] drm/armada: Convert the probe function to the generic drm_of_component_probe() Liviu Dudau <Liviu.Dudau@arm.com> - 2015-10-15 18:20 +0200
| From | Liviu Dudau <Liviu.Dudau@arm.com> |
|---|---|
| Date | 2015-10-15 18:20 +0200 |
| Subject | [RFC PATCH 0/4] drm: Cleanup probe function for component based masters. |
| Message-ID | <qjTq2-3aG-29@gated-at.bofh.it> |
A few drivers in drivers/gpu/drm are component-enabled and use quite similar code sequences to probe for their encoder slaves at the remote end of the ports. Move the code into a "generic" function and remove it from the drivers. The end results is that drivers get a reference count fix (imx), more thorough error checking (imx again), setting the DMA coherent mask (armada) plus a decrease in the overall count of LoC. I'm looking for comments and testing of the patchset (only compile tested from my end as I don't have access to all the devices touched by the changes). My main interest is in finding out if -EINVAL is the correct code to return if dev->of_node == NULL (handy now, as it is different from the other possible error codes and used in armada to trigger old platform_data support. Also looking for thoughts on the correctness of the patch and if it possible to co-opt more drivers into using the function. Best regards, Liviu Liviu Dudau (4): drm: Introduce generic probe function for component based masters. drm/imx: Convert the probe function to the generic drm_of_component_probe() drm/rockchip: Convert the probe function to the generic drm_of_component_probe() drm/armada: Convert the probe function to the generic drm_of_component_probe() drivers/gpu/drm/armada/armada_drv.c | 83 +++++++++----------------- drivers/gpu/drm/drm_of.c | 92 +++++++++++++++++++++++++++++ drivers/gpu/drm/imx/imx-drm-core.c | 54 +---------------- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 84 ++------------------------ include/drm/drm_of.h | 12 ++++ 5 files changed, 138 insertions(+), 187 deletions(-) -- 2.6.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Liviu Dudau <Liviu.Dudau@arm.com> |
|---|---|
| Date | 2015-10-15 18:20 +0200 |
| Subject | [RFC PATCH 1/4] drm: Introduce generic probe function for component based masters. |
| Message-ID | <qjTq3-3aG-41@gated-at.bofh.it> |
| In reply to | #1247958 |
A lot of component based DRM drivers use a variant of the same code
as the probe function. They bind the crtc ports in the first iteration
and then scan through the child nodes and bind the encoders attached
to the remote endpoints. Factor the common code into a separate
function called drm_of_component_probe() in order to increase code
reuse.
Cc: David Airlie <airlied@linux.ie>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
drivers/gpu/drm/drm_of.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_of.h | 12 +++++++
2 files changed, 104 insertions(+)
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index be38840..cf16240 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -1,3 +1,4 @@
+#include <linux/component.h>
#include <linux/export.h>
#include <linux/list.h>
#include <linux/of_graph.h>
@@ -61,3 +62,94 @@ uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
return possible_crtcs;
}
EXPORT_SYMBOL(drm_of_find_possible_crtcs);
+
+/**
+ * drm_of_component_probe - Generic probe function for a component based master
+ * @dev: master device containing the OF node
+ * @compare_of: compare function used for matching components
+ * @master_ops: component master ops to be used
+ *
+ * Parse the platform device OF node and bind all the components associated
+ * with the master. Interface ports are added before the encoders in order to
+ * satisfy their .bind requirements
+ * See Documentation/devicetree/bindings/graph.txt for the bindings.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+int drm_of_component_probe(struct device *dev,
+ int (*compare_of)(struct device *, void *),
+ const struct component_master_ops *master_ops)
+{
+ struct device_node *ep, *port, *remote;
+ struct component_match *match = NULL;
+ int i, ret;
+
+ if (!dev->of_node)
+ return -EINVAL;
+
+ /*
+ * Bind the crtc's ports first, so that drm_of_find_possible_crtcs()
+ * called from encoder's .bind callbacks works as expected
+ */
+ for (i = 0; ; i++) {
+ port = of_parse_phandle(dev->of_node, "ports", i);
+ if (!port)
+ break;
+
+ if (!of_device_is_available(port->parent)) {
+ of_node_put(port);
+ continue;
+ }
+
+ component_match_add(dev, &match, compare_of, port);
+ of_node_put(port);
+ }
+
+ if (i == 0) {
+ dev_err(dev, "missing 'ports' property\n");
+ return -ENODEV;
+ }
+
+ if (!match) {
+ dev_err(dev, "no available port\n");
+ return -ENODEV;
+ }
+
+ /*
+ * For bound crtcs, bind the encoders attached to their remote endpoint
+ */
+ for (i = 0; ; i++) {
+ port = of_parse_phandle(dev->of_node, "ports", i);
+ if (!port)
+ break;
+
+ if (!of_device_is_available(port->parent)) {
+ of_node_put(port);
+ continue;
+ }
+
+ for_each_child_of_node(port, ep) {
+ remote = of_graph_get_remote_port_parent(ep);
+ if (!remote || !of_device_is_available(remote)) {
+ of_node_put(remote);
+ continue;
+ } else if (!of_device_is_available(remote->parent)) {
+ dev_warn(dev, "parent device of %s is not available\n",
+ remote->full_name);
+ of_node_put(remote);
+ continue;
+ }
+
+ component_match_add(dev, &match, compare_of, remote);
+ of_node_put(remote);
+ }
+ of_node_put(port);
+ }
+
+ ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
+ return component_master_add_with_match(dev, master_ops, match);
+}
+EXPORT_SYMBOL(drm_of_component_probe);
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index 2441f71..7c0c05b 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -1,18 +1,30 @@
#ifndef __DRM_OF_H__
#define __DRM_OF_H__
+struct component_master_ops;
+struct device;
struct drm_device;
struct device_node;
#ifdef CONFIG_OF
extern uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
struct device_node *port);
+extern int drm_of_component_probe(struct device *dev,
+ int (*compare_of)(struct device *, void *),
+ const struct component_master_ops *master_ops);
#else
static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
struct device_node *port)
{
return 0;
}
+
+static inline int drm_of_component_probe(struct device *dev,
+ int (*compare_of)(struct device *, void *),
+ const struct component_master_ops *master_ops)
+{
+ return -EINVAL;
+}
#endif
#endif /* __DRM_OF_H__ */
--
2.6.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Liviu Dudau <Liviu.Dudau@arm.com> |
|---|---|
| Date | 2015-10-15 18:20 +0200 |
| Subject | [RFC PATCH 3/4] drm/rockchip: Convert the probe function to the generic drm_of_component_probe() |
| Message-ID | <qjTq3-3aG-43@gated-at.bofh.it> |
| In reply to | #1247958 |
Use the generic drm_of_component_probe() function to probe for components.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 84 ++---------------------------
1 file changed, 5 insertions(+), 79 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 9a0c291..8cd6397 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -47,10 +47,6 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
int ret;
- ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
- if (ret)
- return ret;
-
dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
return arm_iommu_attach_device(dev, mapping);
@@ -416,29 +412,6 @@ static int compare_of(struct device *dev, void *data)
return dev->of_node == np;
}
-static void rockchip_add_endpoints(struct device *dev,
- struct component_match **match,
- struct device_node *port)
-{
- struct device_node *ep, *remote;
-
- for_each_child_of_node(port, ep) {
- remote = of_graph_get_remote_port_parent(ep);
- if (!remote || !of_device_is_available(remote)) {
- of_node_put(remote);
- continue;
- } else if (!of_device_is_available(remote->parent)) {
- dev_warn(dev, "parent device of %s is not available\n",
- remote->full_name);
- of_node_put(remote);
- continue;
- }
-
- component_match_add(dev, match, compare_of, remote);
- of_node_put(remote);
- }
-}
-
static int rockchip_drm_bind(struct device *dev)
{
struct drm_device *drm;
@@ -481,61 +454,14 @@ static const struct component_master_ops rockchip_drm_ops = {
static int rockchip_drm_platform_probe(struct platform_device *pdev)
{
- struct device *dev = &pdev->dev;
- struct component_match *match = NULL;
- struct device_node *np = dev->of_node;
- struct device_node *port;
- int i;
-
- if (!np)
- return -ENODEV;
- /*
- * Bind the crtc ports first, so that
- * drm_of_find_possible_crtcs called from encoder .bind callbacks
- * works as expected.
- */
- for (i = 0;; i++) {
- port = of_parse_phandle(np, "ports", i);
- if (!port)
- break;
-
- if (!of_device_is_available(port->parent)) {
- of_node_put(port);
- continue;
- }
+ int ret = drm_of_component_probe(&pdev->dev, compare_of,
+ &rockchip_drm_ops);
- component_match_add(dev, &match, compare_of, port->parent);
- of_node_put(port);
- }
-
- if (i == 0) {
- dev_err(dev, "missing 'ports' property\n");
+ /* keep compatibility with old code that was returning -ENODEV */
+ if (ret == -EINVAL)
return -ENODEV;
- }
-
- if (!match) {
- dev_err(dev, "No available vop found for display-subsystem.\n");
- return -ENODEV;
- }
- /*
- * For each bound crtc, bind the encoders attached to its
- * remote endpoint.
- */
- for (i = 0;; i++) {
- port = of_parse_phandle(np, "ports", i);
- if (!port)
- break;
-
- if (!of_device_is_available(port->parent)) {
- of_node_put(port);
- continue;
- }
- rockchip_add_endpoints(dev, &match, port);
- of_node_put(port);
- }
-
- return component_master_add_with_match(dev, &rockchip_drm_ops, match);
+ return ret;
}
static int rockchip_drm_platform_remove(struct platform_device *pdev)
--
2.6.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Liviu Dudau <Liviu.Dudau@arm.com> |
|---|---|
| Date | 2015-10-15 18:20 +0200 |
| Subject | [RFC PATCH 4/4] drm/armada: Convert the probe function to the generic drm_of_component_probe() |
| Message-ID | <qjTq4-3aG-57@gated-at.bofh.it> |
| In reply to | #1247958 |
The armada DRM driver keeps some old platform data compatibility in the
probe function that makes moving to the generic drm_of_component_probe()
a bit more complicated that it should. Refactor the probe function to do
the platform_data processing after the generic probe (and if that fails).
This way future cleanup can further remove support for it.
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
---
drivers/gpu/drm/armada/armada_drv.c | 83 +++++++++++++------------------------
1 file changed, 28 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 225034b..990080d 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -11,6 +11,7 @@
#include <linux/of_graph.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
+#include <drm/drm_of.h>
#include "armada_crtc.h"
#include "armada_drm.h"
#include "armada_gem.h"
@@ -370,47 +371,36 @@ static void armada_add_endpoints(struct device *dev,
}
}
-static int armada_drm_find_components(struct device *dev,
- struct component_match **match)
-{
- struct device_node *port;
- int i;
-
- if (dev->of_node) {
- struct device_node *np = dev->of_node;
-
- for (i = 0; ; i++) {
- port = of_parse_phandle(np, "ports", i);
- if (!port)
- break;
+static const struct component_master_ops armada_master_ops = {
+ .bind = armada_drm_bind,
+ .unbind = armada_drm_unbind,
+};
- component_match_add(dev, match, compare_of, port);
- of_node_put(port);
- }
+static int armada_drm_probe(struct platform_device *pdev)
+{
+ int ret;
- if (i == 0) {
- dev_err(dev, "missing 'ports' property\n");
- return -ENODEV;
- }
+ if (!is_componentized(&pdev->dev))
+ return drm_platform_init(&armada_drm_driver, pdev);
- for (i = 0; ; i++) {
- port = of_parse_phandle(np, "ports", i);
- if (!port)
- break;
+ ret = drm_of_component_probe(&pdev->dev, compare_dev_name,
+ &armada_master_ops);
+ if (ret != -EINVAL)
+ return ret;
- armada_add_endpoints(dev, match, port);
- of_node_put(port);
- }
- } else if (dev->platform_data) {
- char **devices = dev->platform_data;
+ if (pdev->dev.platform_data) {
+ struct component_match *match = NULL;
+ char **devices = pdev->dev.platform_data;
+ struct device_node *port;
struct device *d;
+ int i;
for (i = 0; devices[i]; i++)
- component_match_add(dev, match, compare_dev_name,
+ component_match_add(&pdev->dev, &match, compare_dev_name,
devices[i]);
if (i == 0) {
- dev_err(dev, "missing 'ports' property\n");
+ dev_err(&pdev->dev, "missing 'ports' property\n");
return -ENODEV;
}
@@ -419,35 +409,18 @@ static int armada_drm_find_components(struct device *dev,
devices[i]);
if (d && d->of_node) {
for_each_child_of_node(d->of_node, port)
- armada_add_endpoints(dev, match, port);
+ armada_add_endpoints(&pdev->dev,
+ &match, port);
}
put_device(d);
}
- }
-
- return 0;
-}
-
-static const struct component_master_ops armada_master_ops = {
- .bind = armada_drm_bind,
- .unbind = armada_drm_unbind,
-};
-static int armada_drm_probe(struct platform_device *pdev)
-{
- if (is_componentized(&pdev->dev)) {
- struct component_match *match = NULL;
- int ret;
-
- ret = armada_drm_find_components(&pdev->dev, &match);
- if (ret < 0)
- return ret;
-
- return component_master_add_with_match(&pdev->dev,
- &armada_master_ops, match);
- } else {
- return drm_platform_init(&armada_drm_driver, pdev);
+ ret = component_master_add_with_match(&pdev->dev,
+ &armada_master_ops,
+ match);
}
+
+ return ret;
}
static int armada_drm_remove(struct platform_device *pdev)
--
2.6.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web