Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1573584 > unrolled thread
| Started by | Rob Herring <robh@kernel.org> |
|---|---|
| First post | 2017-02-04 04:40 +0100 |
| Last post | 2017-02-04 11:50 +0100 |
| Articles | 17 — 7 participants |
Back to article view | Back to linux.kernel
[PATCH 0/5] DRM OF graph clean-up Rob Herring <robh@kernel.org> - 2017-02-04 04:40 +0100
[PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Rob Herring <robh@kernel.org> - 2017-02-04 04:40 +0100
Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Liviu Dudau <liviu.dudau@arm.com> - 2017-02-06 11:20 +0100
Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Rob Herring <robh@kernel.org> - 2017-02-06 17:30 +0100
Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Philipp Zabel <p.zabel@pengutronix.de> - 2017-02-06 11:50 +0100
Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Rob Herring <robh@kernel.org> - 2017-02-06 18:00 +0100
Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Philipp Zabel <p.zabel@pengutronix.de> - 2017-02-06 18:50 +0100
Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge Frank Rowand <frowand.list@gmail.com> - 2017-02-10 21:00 +0100
[PATCH 1/5] of: introduce of_graph_get_remote_node Rob Herring <robh@kernel.org> - 2017-02-04 04:40 +0100
Re: [PATCH 1/5] of: introduce of_graph_get_remote_node Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> - 2017-02-04 17:20 +0100
Re: [PATCH 1/5] of: introduce of_graph_get_remote_node Daniel Vetter <daniel@ffwll.ch> - 2017-02-06 10:00 +0100
Re: [PATCH 1/5] of: introduce of_graph_get_remote_node Rob Herring <robh@kernel.org> - 2017-02-06 14:50 +0100
Re: [PATCH 1/5] of: introduce of_graph_get_remote_node Philipp Zabel <p.zabel@pengutronix.de> - 2017-02-06 11:40 +0100
Re: [PATCH 1/5] of: introduce of_graph_get_remote_node Rob Herring <robh@kernel.org> - 2017-02-06 15:00 +0100
Re: [PATCH 1/5] of: introduce of_graph_get_remote_node Philipp Zabel <p.zabel@pengutronix.de> - 2017-02-06 15:10 +0100
[PATCH 5/5] drm: omap: use common OF graph helpers Rob Herring <robh@kernel.org> - 2017-02-04 04:40 +0100
Re: [PATCH 0/5] DRM OF graph clean-up Russell King - ARM Linux <linux@armlinux.org.uk> - 2017-02-04 11:50 +0100
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-04 04:40 +0100 |
| Subject | [PATCH 0/5] DRM OF graph clean-up |
| Message-ID | <t6ZmF-32o-3@gated-at.bofh.it> |
I've been unhappy with the OF graph API for some time and decided to do something about it. The problem is drivers have to do too much of the graph parsing and walking themselves. This has led to the same pattern duplicated over and over. This series adds 2 new helpers and adapts DRM drivers to use them. It only adds one new graph helper, but reduces the use of the others which I hope to remove at some point. But we're not there yet. There's a few other things I'd like to clean-up. The Armada and Rockchip drivers remain oddballs with their own graph parsing. I can't see how the armada driver even can work. There's nothing to instantiate the armada-drm device either in DT or the kernel. The omapdrm driver still has some custom helpers similar to the common ones, but still slightly different. It got to be more changes than I wanted to make to address. Build tested only (and probably not every last driver). Rob Rob Herring (5): of: introduce of_graph_get_remote_node drm: of: introduce drm_of_find_panel_or_bridge drm: convert drivers to use of_graph_get_remote_node drm: convert drivers to use drm_of_find_panel_or_bridge drm: omap: use common OF graph helpers drivers/gpu/drm/arm/hdlcd_drv.c | 22 +---- drivers/gpu/drm/arm/malidp_drv.c | 29 +------ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c | 64 +++----------- drivers/gpu/drm/bridge/adv7511/adv7533.c | 12 +-- drivers/gpu/drm/bridge/dumb-vga-dac.c | 15 +--- drivers/gpu/drm/bridge/nxp-ptn3460.c | 16 +--- drivers/gpu/drm/bridge/parade-ps8622.c | 16 +--- drivers/gpu/drm/bridge/tc358767.c | 27 +----- drivers/gpu/drm/bridge/ti-tfp410.c | 15 ++-- drivers/gpu/drm/drm_of.c | 50 +++++++++++ drivers/gpu/drm/exynos/exynos_dp.c | 35 +++----- drivers/gpu/drm/exynos/exynos_drm_dpi.c | 16 +--- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 13 +-- drivers/gpu/drm/exynos/exynos_drm_mic.c | 27 +----- drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c | 49 ++++------- drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 27 +----- drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c | 30 +------ drivers/gpu/drm/imx/imx-ldb.c | 28 ++----- drivers/gpu/drm/imx/parallel-display.c | 35 +------- drivers/gpu/drm/mediatek/mtk_dpi.c | 12 +-- drivers/gpu/drm/mediatek/mtk_dsi.c | 23 ++--- drivers/gpu/drm/mediatek/mtk_hdmi.c | 26 +----- drivers/gpu/drm/meson/meson_drv.c | 12 +-- drivers/gpu/drm/meson/meson_venc_cvbs.c | 19 +---- drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 28 +------ drivers/gpu/drm/mxsfb/mxsfb_out.c | 36 ++------ drivers/gpu/drm/omapdrm/dss/dpi.c | 2 +- drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +- drivers/gpu/drm/omapdrm/dss/dss-of.c | 102 +---------------------- drivers/gpu/drm/omapdrm/dss/dss.c | 61 +++----------- drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 +- drivers/gpu/drm/omapdrm/dss/hdmi5.c | 2 +- drivers/gpu/drm/omapdrm/dss/omapdss.h | 11 --- drivers/gpu/drm/omapdrm/dss/venc.c | 3 +- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 26 +----- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 18 ++-- drivers/gpu/drm/sun4i/sun4i_rgb.c | 17 ++-- drivers/gpu/drm/sun4i/sun4i_tcon.c | 90 ++------------------ drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 11 +-- drivers/gpu/drm/tilcdc/tilcdc_external.c | 66 ++------------- drivers/gpu/drm/vc4/vc4_dpi.c | 15 +--- drivers/of/base.c | 28 +++++++ include/drm/drm_of.h | 13 +++ include/linux/of_graph.h | 8 ++ 45 files changed, 272 insertions(+), 891 deletions(-) -- 2.10.1
[toc] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-04 04:40 +0100 |
| Subject | [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t6ZmG-32o-9@gated-at.bofh.it> |
| In reply to | #1573584 |
Many drivers have a common pattern of searching the OF graph for either an
attached panel or bridge and then finding the DRM struct for the panel
or bridge. Also, most drivers need to handle deferred probing when the
DRM device is not yet instantiated. Create a common function,
drm_of_find_panel_or_bridge, to find the connected node and the
associated DRM panel or bridge device.
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/gpu/drm/drm_of.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
include/drm/drm_of.h | 13 +++++++++++++
2 files changed, 63 insertions(+)
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 47848ed8ca48..b29ce2f52113 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -3,7 +3,9 @@
#include <linux/list.h>
#include <linux/of_graph.h>
#include <drm/drmP.h>
+#include <drm/drm_bridge.h>
#include <drm/drm_crtc.h>
+#include <drm/drm_panel.h>
#include <drm/drm_of.h>
static void drm_release_of(struct device *dev, void *data)
@@ -207,3 +209,51 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
return -EINVAL;
}
EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
+
+/*
+ * drm_of_find_panel_or_bridge - return connected panel or bridge device
+ * @np: device tree node containing encoder input ports
+ * @panel: pointer to hold returned drm_panel
+ * @bridge: pointer to hold returned drm_bridge
+ *
+ * Given a DT node's port and endpoint number, find the connected node and
+ * return either the associated struct drm_panel or drm_bridge device.
+ *
+ * Returns zero if successful, or one of the standard error codes if it fails.
+ */
+int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge)
+{
+ int ret = -ENODEV;
+ struct device_node *remote;
+
+ remote = of_graph_get_remote_node(np, port, endpoint);
+ if (!remote)
+ return -ENODEV;
+
+ if (bridge)
+ *bridge = NULL;
+
+ if (panel) {
+ *panel = of_drm_find_panel(remote);
+ if (*panel) {
+ ret = 0;
+ goto out_put;
+ }
+ ret = -EPROBE_DEFER;
+ }
+
+ if (bridge) {
+ *bridge = of_drm_find_bridge(remote);
+ if (*bridge)
+ ret = 0;
+ else
+ ret = -EPROBE_DEFER;
+ }
+out_put:
+ of_node_put(remote);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index 26a64805cc15..f86507f0599b 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -8,6 +8,8 @@ struct component_match;
struct device;
struct drm_device;
struct drm_encoder;
+struct drm_panel;
+struct drm_bridge;
struct device_node;
#ifdef CONFIG_OF
@@ -23,6 +25,10 @@ extern int drm_of_component_probe(struct device *dev,
extern int drm_of_encoder_active_endpoint(struct device_node *node,
struct drm_encoder *encoder,
struct of_endpoint *endpoint);
+extern int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge);
#else
static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
struct device_node *port)
@@ -52,6 +58,13 @@ static inline int drm_of_encoder_active_endpoint(struct device_node *node,
{
return -EINVAL;
}
+static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
+ int port, int endpoint,
+ struct drm_panel **panel,
+ struct drm_bridge **bridge)
+{
+ return -EINVAL;
+}
#endif
static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Liviu Dudau <liviu.dudau@arm.com> |
|---|---|
| Date | 2017-02-06 11:20 +0100 |
| Subject | Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t7OyS-3E0-7@gated-at.bofh.it> |
| In reply to | #1573585 |
On Fri, Feb 03, 2017 at 09:36:32PM -0600, Rob Herring wrote:
> Many drivers have a common pattern of searching the OF graph for either an
> attached panel or bridge and then finding the DRM struct for the panel
> or bridge. Also, most drivers need to handle deferred probing when the
> DRM device is not yet instantiated. Create a common function,
> drm_of_find_panel_or_bridge, to find the connected node and the
> associated DRM panel or bridge device.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> drivers/gpu/drm/drm_of.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
> include/drm/drm_of.h | 13 +++++++++++++
> 2 files changed, 63 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index 47848ed8ca48..b29ce2f52113 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -3,7 +3,9 @@
> #include <linux/list.h>
> #include <linux/of_graph.h>
> #include <drm/drmP.h>
> +#include <drm/drm_bridge.h>
> #include <drm/drm_crtc.h>
> +#include <drm/drm_panel.h>
> #include <drm/drm_of.h>
>
> static void drm_release_of(struct device *dev, void *data)
> @@ -207,3 +209,51 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
> return -EINVAL;
> }
> EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
> +
> +/*
> + * drm_of_find_panel_or_bridge - return connected panel or bridge device
> + * @np: device tree node containing encoder input ports
> + * @panel: pointer to hold returned drm_panel
> + * @bridge: pointer to hold returned drm_bridge
> + *
> + * Given a DT node's port and endpoint number, find the connected node and
> + * return either the associated struct drm_panel or drm_bridge device.
> + *
> + * Returns zero if successful, or one of the standard error codes if it fails.
> + */
> +int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge)
> +{
> + int ret = -ENODEV;
Given that you never return 'ret' with -ENODEV can I suggest that you initialise 'ret'
with -EPROBE_DEFER and then you can get rid of the two assignments further down?
Otherwise, looks good to me.
Best regards,
Liviu
> + struct device_node *remote;
> +
> + remote = of_graph_get_remote_node(np, port, endpoint);
> + if (!remote)
> + return -ENODEV;
> +
> + if (bridge)
> + *bridge = NULL;
> +
> + if (panel) {
> + *panel = of_drm_find_panel(remote);
> + if (*panel) {
> + ret = 0;
> + goto out_put;
> + }
> + ret = -EPROBE_DEFER;
> + }
> +
> + if (bridge) {
> + *bridge = of_drm_find_bridge(remote);
> + if (*bridge)
> + ret = 0;
> + else
> + ret = -EPROBE_DEFER;
> + }
> +out_put:
> + of_node_put(remote);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
> diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
> index 26a64805cc15..f86507f0599b 100644
> --- a/include/drm/drm_of.h
> +++ b/include/drm/drm_of.h
> @@ -8,6 +8,8 @@ struct component_match;
> struct device;
> struct drm_device;
> struct drm_encoder;
> +struct drm_panel;
> +struct drm_bridge;
> struct device_node;
>
> #ifdef CONFIG_OF
> @@ -23,6 +25,10 @@ extern int drm_of_component_probe(struct device *dev,
> extern int drm_of_encoder_active_endpoint(struct device_node *node,
> struct drm_encoder *encoder,
> struct of_endpoint *endpoint);
> +extern int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge);
> #else
> static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
> struct device_node *port)
> @@ -52,6 +58,13 @@ static inline int drm_of_encoder_active_endpoint(struct device_node *node,
> {
> return -EINVAL;
> }
> +static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge)
> +{
> + return -EINVAL;
> +}
> #endif
>
> static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,
> --
> 2.10.1
>
--
====================
| I would like to |
| fix the world, |
| but they're not |
| giving me the |
\ source code! /
---------------
¯\_(ツ)_/¯
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-06 17:30 +0100 |
| Subject | Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t7UkW-7hD-21@gated-at.bofh.it> |
| In reply to | #1574523 |
On Mon, Feb 6, 2017 at 4:18 AM, Liviu Dudau <liviu.dudau@arm.com> wrote:
> On Fri, Feb 03, 2017 at 09:36:32PM -0600, Rob Herring wrote:
>> Many drivers have a common pattern of searching the OF graph for either an
>> attached panel or bridge and then finding the DRM struct for the panel
>> or bridge. Also, most drivers need to handle deferred probing when the
>> DRM device is not yet instantiated. Create a common function,
>> drm_of_find_panel_or_bridge, to find the connected node and the
>> associated DRM panel or bridge device.
>>
>> Signed-off-by: Rob Herring <robh@kernel.org>
>> ---
>> drivers/gpu/drm/drm_of.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
>> include/drm/drm_of.h | 13 +++++++++++++
>> 2 files changed, 63 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
>> index 47848ed8ca48..b29ce2f52113 100644
>> --- a/drivers/gpu/drm/drm_of.c
>> +++ b/drivers/gpu/drm/drm_of.c
>> @@ -3,7 +3,9 @@
>> #include <linux/list.h>
>> #include <linux/of_graph.h>
>> #include <drm/drmP.h>
>> +#include <drm/drm_bridge.h>
>> #include <drm/drm_crtc.h>
>> +#include <drm/drm_panel.h>
>> #include <drm/drm_of.h>
>>
>> static void drm_release_of(struct device *dev, void *data)
>> @@ -207,3 +209,51 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
>> return -EINVAL;
>> }
>> EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
>> +
>> +/*
>> + * drm_of_find_panel_or_bridge - return connected panel or bridge device
>> + * @np: device tree node containing encoder input ports
>> + * @panel: pointer to hold returned drm_panel
>> + * @bridge: pointer to hold returned drm_bridge
>> + *
>> + * Given a DT node's port and endpoint number, find the connected node and
>> + * return either the associated struct drm_panel or drm_bridge device.
>> + *
>> + * Returns zero if successful, or one of the standard error codes if it fails.
>> + */
>> +int drm_of_find_panel_or_bridge(const struct device_node *np,
>> + int port, int endpoint,
>> + struct drm_panel **panel,
>> + struct drm_bridge **bridge)
>> +{
>> + int ret = -ENODEV;
>
> Given that you never return 'ret' with -ENODEV can I suggest that you initialise 'ret'
> with -EPROBE_DEFER and then you can get rid of the two assignments further down?
But I can if both panel and bridge are NULL. I'm going with Philipp's
suggestion of -EINVAL here.
Rob
[toc] | [prev] | [next] | [standalone]
| From | Philipp Zabel <p.zabel@pengutronix.de> |
|---|---|
| Date | 2017-02-06 11:50 +0100 |
| Subject | Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t7P1U-3Pt-3@gated-at.bofh.it> |
| In reply to | #1573585 |
On Fri, 2017-02-03 at 21:36 -0600, Rob Herring wrote:
> Many drivers have a common pattern of searching the OF graph for either an
> attached panel or bridge and then finding the DRM struct for the panel
> or bridge. Also, most drivers need to handle deferred probing when the
> DRM device is not yet instantiated. Create a common function,
> drm_of_find_panel_or_bridge, to find the connected node and the
> associated DRM panel or bridge device.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> drivers/gpu/drm/drm_of.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
> include/drm/drm_of.h | 13 +++++++++++++
> 2 files changed, 63 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index 47848ed8ca48..b29ce2f52113 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -3,7 +3,9 @@
> #include <linux/list.h>
> #include <linux/of_graph.h>
> #include <drm/drmP.h>
> +#include <drm/drm_bridge.h>
> #include <drm/drm_crtc.h>
> +#include <drm/drm_panel.h>
> #include <drm/drm_of.h>
>
> static void drm_release_of(struct device *dev, void *data)
> @@ -207,3 +209,51 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
> return -EINVAL;
> }
> EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
> +
> +/*
> + * drm_of_find_panel_or_bridge - return connected panel or bridge device
> + * @np: device tree node containing encoder input ports
> + * @panel: pointer to hold returned drm_panel
> + * @bridge: pointer to hold returned drm_bridge
> + *
> + * Given a DT node's port and endpoint number, find the connected node and
> + * return either the associated struct drm_panel or drm_bridge device.
Add a commend that at least one of panel, bridge must be set?
> + * Returns zero if successful, or one of the standard error codes if it fails.
> + */
> +int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge)
> +{
> + int ret = -ENODEV;
This is only returned if !panel && !bridge. I'd consider this invalid
usage of this function, so maybe use -EINVAL?
> + struct device_node *remote;
> +
> + remote = of_graph_get_remote_node(np, port, endpoint);
> + if (!remote)
> + return -ENODEV;
> +
> + if (bridge)
> + *bridge = NULL;
I would move this ^ ...
> + if (panel) {
> + *panel = of_drm_find_panel(remote);
> + if (*panel) {
... here.
> + ret = 0;
> + goto out_put;
> + }
> + ret = -EPROBE_DEFER;
> + }
> +
> + if (bridge) {
> + *bridge = of_drm_find_bridge(remote);
> + if (*bridge)
> + ret = 0;
> + else
> + ret = -EPROBE_DEFER;
> + }
> +out_put:
> + of_node_put(remote);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
> diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
> index 26a64805cc15..f86507f0599b 100644
> --- a/include/drm/drm_of.h
> +++ b/include/drm/drm_of.h
> @@ -8,6 +8,8 @@ struct component_match;
> struct device;
> struct drm_device;
> struct drm_encoder;
> +struct drm_panel;
> +struct drm_bridge;
> struct device_node;
>
> #ifdef CONFIG_OF
> @@ -23,6 +25,10 @@ extern int drm_of_component_probe(struct device *dev,
> extern int drm_of_encoder_active_endpoint(struct device_node *node,
> struct drm_encoder *encoder,
> struct of_endpoint *endpoint);
> +extern int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge);
> #else
> static inline uint32_t drm_of_find_possible_crtcs(struct drm_device *dev,
> struct device_node *port)
> @@ -52,6 +58,13 @@ static inline int drm_of_encoder_active_endpoint(struct device_node *node,
> {
> return -EINVAL;
> }
> +static inline int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge)
> +{
> + return -EINVAL;
> +}
> #endif
>
> static inline int drm_of_encoder_active_endpoint_id(struct device_node *node,
regards
Philipp
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-06 18:00 +0100 |
| Subject | Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t7UNZ-7sP-27@gated-at.bofh.it> |
| In reply to | #1574552 |
On Mon, Feb 06, 2017 at 11:42:48AM +0100, Philipp Zabel wrote:
> On Fri, 2017-02-03 at 21:36 -0600, Rob Herring wrote:
> > Many drivers have a common pattern of searching the OF graph for either an
> > attached panel or bridge and then finding the DRM struct for the panel
> > or bridge. Also, most drivers need to handle deferred probing when the
> > DRM device is not yet instantiated. Create a common function,
> > drm_of_find_panel_or_bridge, to find the connected node and the
> > associated DRM panel or bridge device.
[...]
> > +int drm_of_find_panel_or_bridge(const struct device_node *np,
> > + int port, int endpoint,
> > + struct drm_panel **panel,
> > + struct drm_bridge **bridge)
> > +{
> > + int ret = -ENODEV;
>
> This is only returned if !panel && !bridge. I'd consider this invalid
> usage of this function, so maybe use -EINVAL?
Yes.
> > + struct device_node *remote;
> > +
> > + remote = of_graph_get_remote_node(np, port, endpoint);
> > + if (!remote)
> > + return -ENODEV;
> > +
> > + if (bridge)
> > + *bridge = NULL;
>
> I would move this ^ ...
>
> > + if (panel) {
> > + *panel = of_drm_find_panel(remote);
> > + if (*panel) {
>
> ... here.
Okay.
> > + ret = 0;
> > + goto out_put;
> > + }
> > + ret = -EPROBE_DEFER;
> > + }
> > +
> > + if (bridge) {
> > + *bridge = of_drm_find_bridge(remote);
> > + if (*bridge)
> > + ret = 0;
> > + else
> > + ret = -EPROBE_DEFER;
> > + }
> > +out_put:
> > + of_node_put(remote);
> > + return ret;
> > +}
I've ended up re-writing things a bit getting rid of the goto and the
result looks like this:
int drm_of_find_panel_or_bridge(const struct device_node *np,
int port, int endpoint,
struct drm_panel **panel,
struct drm_bridge **bridge)
{
int ret = -EPROBE_DEFER;
struct device_node *remote;
if (!panel && !bridge)
return -EINVAL;
remote = of_graph_get_remote_node(np, port, endpoint);
if (!remote)
return -ENODEV;
if (panel) {
*panel = of_drm_find_panel(remote);
if (*panel) {
if (bridge)
*bridge = NULL;
ret = 0;
}
}
/* No panel found yet, check for a bridge next. */
if (ret && bridge) {
*bridge = of_drm_find_bridge(remote);
if (*bridge)
ret = 0;
}
of_node_put(remote);
return ret;
}
[toc] | [prev] | [next] | [standalone]
| From | Philipp Zabel <p.zabel@pengutronix.de> |
|---|---|
| Date | 2017-02-06 18:50 +0100 |
| Subject | Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t7VAm-87K-21@gated-at.bofh.it> |
| In reply to | #1574992 |
On Mon, 2017-02-06 at 10:53 -0600, Rob Herring wrote:
> On Mon, Feb 06, 2017 at 11:42:48AM +0100, Philipp Zabel wrote:
> > On Fri, 2017-02-03 at 21:36 -0600, Rob Herring wrote:
> > > Many drivers have a common pattern of searching the OF graph for either an
> > > attached panel or bridge and then finding the DRM struct for the panel
> > > or bridge. Also, most drivers need to handle deferred probing when the
> > > DRM device is not yet instantiated. Create a common function,
> > > drm_of_find_panel_or_bridge, to find the connected node and the
> > > associated DRM panel or bridge device.
>
> [...]
>
> > > +int drm_of_find_panel_or_bridge(const struct device_node *np,
> > > + int port, int endpoint,
> > > + struct drm_panel **panel,
> > > + struct drm_bridge **bridge)
> > > +{
> > > + int ret = -ENODEV;
> >
> > This is only returned if !panel && !bridge. I'd consider this invalid
> > usage of this function, so maybe use -EINVAL?
>
> Yes.
>
> > > + struct device_node *remote;
> > > +
> > > + remote = of_graph_get_remote_node(np, port, endpoint);
> > > + if (!remote)
> > > + return -ENODEV;
> > > +
> > > + if (bridge)
> > > + *bridge = NULL;
> >
> > I would move this ^ ...
> >
> > > + if (panel) {
> > > + *panel = of_drm_find_panel(remote);
> > > + if (*panel) {
> >
> > ... here.
>
> Okay.
>
> > > + ret = 0;
> > > + goto out_put;
> > > + }
> > > + ret = -EPROBE_DEFER;
> > > + }
> > > +
> > > + if (bridge) {
> > > + *bridge = of_drm_find_bridge(remote);
> > > + if (*bridge)
> > > + ret = 0;
> > > + else
> > > + ret = -EPROBE_DEFER;
> > > + }
> > > +out_put:
> > > + of_node_put(remote);
> > > + return ret;
> > > +}
>
> I've ended up re-writing things a bit getting rid of the goto and the
> result looks like this:
Looks good to me.
> int drm_of_find_panel_or_bridge(const struct device_node *np,
> int port, int endpoint,
> struct drm_panel **panel,
> struct drm_bridge **bridge)
> {
> int ret = -EPROBE_DEFER;
> struct device_node *remote;
>
> if (!panel && !bridge)
> return -EINVAL;
>
> remote = of_graph_get_remote_node(np, port, endpoint);
> if (!remote)
> return -ENODEV;
>
> if (panel) {
> *panel = of_drm_find_panel(remote);
> if (*panel) {
> if (bridge)
> *bridge = NULL;
With the goto out_put gone, I'm conflicted whether I find this clearer
here, or ...
> ret = 0;
> }
> }
>
> /* No panel found yet, check for a bridge next. */
> if (ret && bridge) {
> *bridge = of_drm_find_bridge(remote);
> if (*bridge)
> ret = 0;
> }
... even down here:
if (bridge) {
if (ret) {
/* No panel found yet, check for a bridge next. */
*bridge = of_drm_find_bridge(remote)
if (*bridge)
ret = 0;
} else {
*bridge = NULL;
}
}
That way bridge doesn't have to be checked twice and all the
modification of *bridge is in the same block.
>
> of_node_put(remote);
> return ret;
> }
Either way,
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
[toc] | [prev] | [next] | [standalone]
| From | Frank Rowand <frowand.list@gmail.com> |
|---|---|
| Date | 2017-02-10 21:00 +0100 |
| Subject | Re: [PATCH 2/5] drm: of: introduce drm_of_find_panel_or_bridge |
| Message-ID | <t9pwm-7Pl-13@gated-at.bofh.it> |
| In reply to | #1573585 |
On 02/03/17 19:36, Rob Herring wrote:
> Many drivers have a common pattern of searching the OF graph for either an
> attached panel or bridge and then finding the DRM struct for the panel
> or bridge. Also, most drivers need to handle deferred probing when the
> DRM device is not yet instantiated. Create a common function,
> drm_of_find_panel_or_bridge, to find the connected node and the
> associated DRM panel or bridge device.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> drivers/gpu/drm/drm_of.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++
> include/drm/drm_of.h | 13 +++++++++++++
> 2 files changed, 63 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index 47848ed8ca48..b29ce2f52113 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -3,7 +3,9 @@
> #include <linux/list.h>
> #include <linux/of_graph.h>
> #include <drm/drmP.h>
> +#include <drm/drm_bridge.h>
> #include <drm/drm_crtc.h>
> +#include <drm/drm_panel.h>
> #include <drm/drm_of.h>
>
> static void drm_release_of(struct device *dev, void *data)
> @@ -207,3 +209,51 @@ int drm_of_encoder_active_endpoint(struct device_node *node,
> return -EINVAL;
> }
> EXPORT_SYMBOL_GPL(drm_of_encoder_active_endpoint);
> +
> +/*
> + * drm_of_find_panel_or_bridge - return connected panel or bridge device
> + * @np: device tree node containing encoder input ports
@port: ....
@endpoint: ....
> + * @panel: pointer to hold returned drm_panel
> + * @bridge: pointer to hold returned drm_bridge
> + *
> + * Given a DT node's port and endpoint number, find the connected node and
> + * return either the associated struct drm_panel or drm_bridge device.
> + *
> + * Returns zero if successful, or one of the standard error codes if it fails.
> + */
> +int drm_of_find_panel_or_bridge(const struct device_node *np,
> + int port, int endpoint,
> + struct drm_panel **panel,
> + struct drm_bridge **bridge)
> +{
< snip >
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-04 04:40 +0100 |
| Subject | [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t6ZmF-32o-7@gated-at.bofh.it> |
| In reply to | #1573584 |
The OF graph API leaves too much of the graph walking to clients when
in many cases the driver doesn't care about accessing the port or
endpoint nodes. The drivers typically just want the device connected via
a particular graph connection. of_graph_get_remote_node provides this
functionality.
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/of/base.c | 28 ++++++++++++++++++++++++++++
include/linux/of_graph.h | 8 ++++++++
2 files changed, 36 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index d4bea3c797d6..ea18ab16b92c 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2469,3 +2469,31 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
return of_get_next_parent(np);
}
EXPORT_SYMBOL(of_graph_get_remote_port);
+
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+ int port, int endpoint)
+{
+ struct device_node *endpoint_node, *remote;
+
+ endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
+ if (!endpoint_node) {
+ pr_debug("no valid endpoint (%d, %d) for node %s\n",
+ port, endpoint, node->full_name);
+ return NULL;
+ }
+
+ remote = of_graph_get_remote_port_parent(endpoint_node);
+ of_node_put(endpoint);
+ if (!remote) {
+ pr_debug("no valid remote node\n");
+ return NULL;
+ }
+
+ if (!of_device_is_available(remote)) {
+ pr_debug("not available for remote node\n");
+ return NULL;
+ }
+
+ return remote;
+}
+EXPORT_SYMBOL(of_graph_get_remote_node);
diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
index bb3a5a2cd570..7b71d3e09209 100644
--- a/include/linux/of_graph.h
+++ b/include/linux/of_graph.h
@@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs(
struct device_node *of_graph_get_remote_port_parent(
const struct device_node *node);
struct device_node *of_graph_get_remote_port(const struct device_node *node);
+struct device_node *of_graph_get_remote_node(const struct device_node *node,
+ int port, int endpoint);
#else
static inline int of_graph_parse_endpoint(const struct device_node *node,
@@ -89,6 +91,12 @@ static inline struct device_node *of_graph_get_remote_port(
{
return NULL;
}
+static inline struct device_node *of_graph_get_remote_node(
+ const struct device_node *node,
+ int port, int endpoint)
+{
+ return NULL;
+}
#endif /* CONFIG_OF */
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com> |
|---|---|
| Date | 2017-02-04 17:20 +0100 |
| Subject | Re: [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t7bea-2Tv-15@gated-at.bofh.it> |
| In reply to | #1573587 |
Hi Rob,
On 02/04/2017 05:36 AM, Rob Herring wrote:
> The OF graph API leaves too much of the graph walking to clients when
> in many cases the driver doesn't care about accessing the port or
> endpoint nodes. The drivers typically just want the device connected via
> a particular graph connection. of_graph_get_remote_node provides this
> functionality.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> drivers/of/base.c | 28 ++++++++++++++++++++++++++++
> include/linux/of_graph.h | 8 ++++++++
> 2 files changed, 36 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d4bea3c797d6..ea18ab16b92c 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2469,3 +2469,31 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
> return of_get_next_parent(np);
> }
> EXPORT_SYMBOL(of_graph_get_remote_port);
> +
> +struct device_node *of_graph_get_remote_node(const struct device_node *node,
> + int port, int endpoint)
it would be nice to add a short comment that a returned device
node is expected to be dereferenced with of_node_put().
> +{
> + struct device_node *endpoint_node, *remote;
> +
> + endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
> + if (!endpoint_node) {
> + pr_debug("no valid endpoint (%d, %d) for node %s\n",
> + port, endpoint, node->full_name);
> + return NULL;
> + }
> +
> + remote = of_graph_get_remote_port_parent(endpoint_node);
> + of_node_put(endpoint);
Typo, here it should be of_node_put(endpoint_node);
> + if (!remote) {
> + pr_debug("no valid remote node\n");
> + return NULL;
> + }
> +
> + if (!of_device_is_available(remote)) {
> + pr_debug("not available for remote node\n");
> + return NULL;
> + }
> +
> + return remote;
> +}
> +EXPORT_SYMBOL(of_graph_get_remote_node);
--
With best wishes,
Vladimir
[toc] | [prev] | [next] | [standalone]
| From | Daniel Vetter <daniel@ffwll.ch> |
|---|---|
| Date | 2017-02-06 10:00 +0100 |
| Subject | Re: [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t7Njs-2A1-11@gated-at.bofh.it> |
| In reply to | #1573587 |
On Fri, Feb 03, 2017 at 09:36:31PM -0600, Rob Herring wrote:
> The OF graph API leaves too much of the graph walking to clients when
> in many cases the driver doesn't care about accessing the port or
> endpoint nodes. The drivers typically just want the device connected via
> a particular graph connection. of_graph_get_remote_node provides this
> functionality.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
Just a quick procedural comment: drm-misc for 4.11 is closed already, but
if we can get this core patch into 4.11 still then that would avoid
cross-tree sync pains in 4.12 ...
-Daniel
> ---
> drivers/of/base.c | 28 ++++++++++++++++++++++++++++
> include/linux/of_graph.h | 8 ++++++++
> 2 files changed, 36 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d4bea3c797d6..ea18ab16b92c 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2469,3 +2469,31 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
> return of_get_next_parent(np);
> }
> EXPORT_SYMBOL(of_graph_get_remote_port);
> +
> +struct device_node *of_graph_get_remote_node(const struct device_node *node,
> + int port, int endpoint)
> +{
> + struct device_node *endpoint_node, *remote;
> +
> + endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
> + if (!endpoint_node) {
> + pr_debug("no valid endpoint (%d, %d) for node %s\n",
> + port, endpoint, node->full_name);
> + return NULL;
> + }
> +
> + remote = of_graph_get_remote_port_parent(endpoint_node);
> + of_node_put(endpoint);
> + if (!remote) {
> + pr_debug("no valid remote node\n");
> + return NULL;
> + }
> +
> + if (!of_device_is_available(remote)) {
> + pr_debug("not available for remote node\n");
> + return NULL;
> + }
> +
> + return remote;
> +}
> +EXPORT_SYMBOL(of_graph_get_remote_node);
> diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
> index bb3a5a2cd570..7b71d3e09209 100644
> --- a/include/linux/of_graph.h
> +++ b/include/linux/of_graph.h
> @@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs(
> struct device_node *of_graph_get_remote_port_parent(
> const struct device_node *node);
> struct device_node *of_graph_get_remote_port(const struct device_node *node);
> +struct device_node *of_graph_get_remote_node(const struct device_node *node,
> + int port, int endpoint);
> #else
>
> static inline int of_graph_parse_endpoint(const struct device_node *node,
> @@ -89,6 +91,12 @@ static inline struct device_node *of_graph_get_remote_port(
> {
> return NULL;
> }
> +static inline struct device_node *of_graph_get_remote_node(
> + const struct device_node *node,
> + int port, int endpoint)
> +{
> + return NULL;
> +}
>
> #endif /* CONFIG_OF */
>
> --
> 2.10.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-06 14:50 +0100 |
| Subject | Re: [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t7RQ8-5AW-89@gated-at.bofh.it> |
| In reply to | #1574467 |
On Mon, Feb 6, 2017 at 2:50 AM, Daniel Vetter <daniel@ffwll.ch> wrote: > On Fri, Feb 03, 2017 at 09:36:31PM -0600, Rob Herring wrote: >> The OF graph API leaves too much of the graph walking to clients when >> in many cases the driver doesn't care about accessing the port or >> endpoint nodes. The drivers typically just want the device connected via >> a particular graph connection. of_graph_get_remote_node provides this >> functionality. >> >> Signed-off-by: Rob Herring <robh@kernel.org> > > Just a quick procedural comment: drm-misc for 4.11 is closed already, but > if we can get this core patch into 4.11 still then that would avoid > cross-tree sync pains in 4.12 ... Right, I was thinking the same thing. Rob
[toc] | [prev] | [next] | [standalone]
| From | Philipp Zabel <p.zabel@pengutronix.de> |
|---|---|
| Date | 2017-02-06 11:40 +0100 |
| Subject | Re: [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t7OSe-3KY-19@gated-at.bofh.it> |
| In reply to | #1573587 |
Hi Rob,
thanks for this clean-up series! I was not aware how far the duplication
has spread over time.
On Fri, 2017-02-03 at 21:36 -0600, Rob Herring wrote:
> The OF graph API leaves too much of the graph walking to clients when
> in many cases the driver doesn't care about accessing the port or
> endpoint nodes. The drivers typically just want the device connected via
> a particular graph connection. of_graph_get_remote_node provides this
> functionality.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> drivers/of/base.c | 28 ++++++++++++++++++++++++++++
> include/linux/of_graph.h | 8 ++++++++
> 2 files changed, 36 insertions(+)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index d4bea3c797d6..ea18ab16b92c 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -2469,3 +2469,31 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node)
> return of_get_next_parent(np);
> }
> EXPORT_SYMBOL(of_graph_get_remote_port);
> +
> +struct device_node *of_graph_get_remote_node(const struct device_node *node,
> + int port, int endpoint)
I think this should have a documentation comment, similar to the
of_graph_get_endpoint_by_regs one, as it is not really clear from the
function name that the returned device node is the parent (or
grandparent) device node containing the remote port to the specified
node & port & endpoint.
Also it might be interesting to the user that -1 is a wildcard value for
port / endpoint.
> +{
> + struct device_node *endpoint_node, *remote;
> +
> + endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
> + if (!endpoint_node) {
> + pr_debug("no valid endpoint (%d, %d) for node %s\n",
> + port, endpoint, node->full_name);
> + return NULL;
> + }
> +
> + remote = of_graph_get_remote_port_parent(endpoint_node);
> + of_node_put(endpoint);
Vladimir pointed this out already. With that fixed and the missing doc
comment added,
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
> + if (!remote) {
> + pr_debug("no valid remote node\n");
> + return NULL;
> + }
> +
> + if (!of_device_is_available(remote)) {
> + pr_debug("not available for remote node\n");
> + return NULL;
> + }
> +
> + return remote;
> +}
> +EXPORT_SYMBOL(of_graph_get_remote_node);
> diff --git a/include/linux/of_graph.h b/include/linux/of_graph.h
> index bb3a5a2cd570..7b71d3e09209 100644
> --- a/include/linux/of_graph.h
> +++ b/include/linux/of_graph.h
> @@ -51,6 +51,8 @@ struct device_node *of_graph_get_endpoint_by_regs(
> struct device_node *of_graph_get_remote_port_parent(
> const struct device_node *node);
> struct device_node *of_graph_get_remote_port(const struct device_node *node);
> +struct device_node *of_graph_get_remote_node(const struct device_node *node,
> + int port, int endpoint);
> #else
>
> static inline int of_graph_parse_endpoint(const struct device_node *node,
> @@ -89,6 +91,12 @@ static inline struct device_node *of_graph_get_remote_port(
> {
> return NULL;
> }
> +static inline struct device_node *of_graph_get_remote_node(
> + const struct device_node *node,
> + int port, int endpoint)
> +{
> + return NULL;
> +}
>
> #endif /* CONFIG_OF */
regards
Philipp
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-06 15:00 +0100 |
| Subject | Re: [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t7RZO-5F5-67@gated-at.bofh.it> |
| In reply to | #1574543 |
On Mon, Feb 6, 2017 at 4:32 AM, Philipp Zabel <p.zabel@pengutronix.de> wrote: > Hi Rob, > > thanks for this clean-up series! I was not aware how far the duplication > has spread over time. > > On Fri, 2017-02-03 at 21:36 -0600, Rob Herring wrote: >> The OF graph API leaves too much of the graph walking to clients when >> in many cases the driver doesn't care about accessing the port or >> endpoint nodes. The drivers typically just want the device connected via >> a particular graph connection. of_graph_get_remote_node provides this >> functionality. >> >> Signed-off-by: Rob Herring <robh@kernel.org> >> --- >> drivers/of/base.c | 28 ++++++++++++++++++++++++++++ >> include/linux/of_graph.h | 8 ++++++++ >> 2 files changed, 36 insertions(+) >> >> diff --git a/drivers/of/base.c b/drivers/of/base.c >> index d4bea3c797d6..ea18ab16b92c 100644 >> --- a/drivers/of/base.c >> +++ b/drivers/of/base.c >> @@ -2469,3 +2469,31 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node) >> return of_get_next_parent(np); >> } >> EXPORT_SYMBOL(of_graph_get_remote_port); >> + >> +struct device_node *of_graph_get_remote_node(const struct device_node *node, >> + int port, int endpoint) > > I think this should have a documentation comment, similar to the > of_graph_get_endpoint_by_regs one, as it is not really clear from the > function name that the returned device node is the parent (or > grandparent) device node containing the remote port to the specified > node & port & endpoint. > Also it might be interesting to the user that -1 is a wildcard value for > port / endpoint. I really want to not allow using a wildcard here. Drivers should know what port they want (or iterate over all of them). It didn't look like any drivers were depending on the wildcard, but were just using -1 for "no reg property" when really that should 0. Of course, I may have missed something. I guess I could enforce port/endpoint > 0 here as there's no existing users. Rob
[toc] | [prev] | [next] | [standalone]
| From | Philipp Zabel <p.zabel@pengutronix.de> |
|---|---|
| Date | 2017-02-06 15:10 +0100 |
| Subject | Re: [PATCH 1/5] of: introduce of_graph_get_remote_node |
| Message-ID | <t7S9s-5XR-27@gated-at.bofh.it> |
| In reply to | #1574780 |
On Mon, 2017-02-06 at 07:54 -0600, Rob Herring wrote: > On Mon, Feb 6, 2017 at 4:32 AM, Philipp Zabel <p.zabel@pengutronix.de> wrote: > > Hi Rob, > > > > thanks for this clean-up series! I was not aware how far the duplication > > has spread over time. > > > > On Fri, 2017-02-03 at 21:36 -0600, Rob Herring wrote: > >> The OF graph API leaves too much of the graph walking to clients when > >> in many cases the driver doesn't care about accessing the port or > >> endpoint nodes. The drivers typically just want the device connected via > >> a particular graph connection. of_graph_get_remote_node provides this > >> functionality. > >> > >> Signed-off-by: Rob Herring <robh@kernel.org> > >> --- > >> drivers/of/base.c | 28 ++++++++++++++++++++++++++++ > >> include/linux/of_graph.h | 8 ++++++++ > >> 2 files changed, 36 insertions(+) > >> > >> diff --git a/drivers/of/base.c b/drivers/of/base.c > >> index d4bea3c797d6..ea18ab16b92c 100644 > >> --- a/drivers/of/base.c > >> +++ b/drivers/of/base.c > >> @@ -2469,3 +2469,31 @@ struct device_node *of_graph_get_remote_port(const struct device_node *node) > >> return of_get_next_parent(np); > >> } > >> EXPORT_SYMBOL(of_graph_get_remote_port); > >> + > >> +struct device_node *of_graph_get_remote_node(const struct device_node *node, > >> + int port, int endpoint) > > > > I think this should have a documentation comment, similar to the > > of_graph_get_endpoint_by_regs one, as it is not really clear from the > > function name that the returned device node is the parent (or > > grandparent) device node containing the remote port to the specified > > node & port & endpoint. > > Also it might be interesting to the user that -1 is a wildcard value for > > port / endpoint. > > I really want to not allow using a wildcard here. Drivers should know > what port they want (or iterate over all of them). It didn't look like > any drivers were depending on the wildcard, but were just using -1 for > "no reg property" when really that should 0. Of course, I may have > missed something. > > I guess I could enforce port/endpoint > 0 here as there's no existing users. That sounds reasonable. If it works for all users, enforcing >= 0 should be fine, but in that case I'd change the parameters to be unsigned. regards Philipp
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-02-04 04:40 +0100 |
| Subject | [PATCH 5/5] drm: omap: use common OF graph helpers |
| Message-ID | <t6ZmG-32o-13@gated-at.bofh.it> |
| In reply to | #1573584 |
The OMAP driver has its own OF graph helpers that are similar to the
common helpers. This commit replaces most of the calls with the common
helpers. There's still a couple of custom helpers left, but the driver
needs more extensive changes to get rid of them.
In dss_init_ports, we invert the loop, looping through the known ports
and matching them to DT nodes rather than looping thru DT nodes and
matching them to the ports.
Signed-off-by: Rob Herring <robh@kernel.org>
---
drivers/gpu/drm/omapdrm/dss/dpi.c | 2 +-
drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
drivers/gpu/drm/omapdrm/dss/dss-of.c | 102 +---------------------------------
drivers/gpu/drm/omapdrm/dss/dss.c | 61 +++++---------------
drivers/gpu/drm/omapdrm/dss/hdmi4.c | 3 +-
drivers/gpu/drm/omapdrm/dss/hdmi5.c | 2 +-
drivers/gpu/drm/omapdrm/dss/omapdss.h | 11 ----
drivers/gpu/drm/omapdrm/dss/venc.c | 3 +-
8 files changed, 23 insertions(+), 163 deletions(-)
diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c b/drivers/gpu/drm/omapdrm/dss/dpi.c
index e75162d26ac0..e5bb494d4689 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -855,7 +855,7 @@ int dpi_init_port(struct platform_device *pdev, struct device_node *port)
if (!dpi)
return -ENOMEM;
- ep = omapdss_of_get_next_endpoint(port, NULL);
+ ep = of_get_next_child(port, NULL);
if (!ep)
return 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c
index f060bda31235..a9235b9fdaaf 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5091,7 +5091,7 @@ static int dsi_probe_of(struct platform_device *pdev)
struct device_node *ep;
struct omap_dsi_pin_config pin_cfg;
- ep = omapdss_of_get_first_endpoint(node);
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
if (!ep)
return 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c b/drivers/gpu/drm/omapdrm/dss/dss-of.c
index dfd4e9621e3b..eb520ab45ddd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss-of.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss-of.c
@@ -16,77 +16,12 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/seq_file.h>
#include "omapdss.h"
#include "dss.h"
-struct device_node *
-omapdss_of_get_next_port(const struct device_node *parent,
- struct device_node *prev)
-{
- struct device_node *port = NULL;
-
- if (!parent)
- return NULL;
-
- if (!prev) {
- struct device_node *ports;
- /*
- * It's the first call, we have to find a port subnode
- * within this node or within an optional 'ports' node.
- */
- ports = of_get_child_by_name(parent, "ports");
- if (ports)
- parent = ports;
-
- port = of_get_child_by_name(parent, "port");
-
- /* release the 'ports' node */
- of_node_put(ports);
- } else {
- struct device_node *ports;
-
- ports = of_get_parent(prev);
- if (!ports)
- return NULL;
-
- do {
- port = of_get_next_child(ports, prev);
- if (!port) {
- of_node_put(ports);
- return NULL;
- }
- prev = port;
- } while (of_node_cmp(port->name, "port") != 0);
-
- of_node_put(ports);
- }
-
- return port;
-}
-EXPORT_SYMBOL_GPL(omapdss_of_get_next_port);
-
-struct device_node *
-omapdss_of_get_next_endpoint(const struct device_node *parent,
- struct device_node *prev)
-{
- struct device_node *ep = NULL;
-
- if (!parent)
- return NULL;
-
- do {
- ep = of_get_next_child(parent, prev);
- if (!ep)
- return NULL;
- prev = ep;
- } while (of_node_cmp(ep->name, "endpoint") != 0);
-
- return ep;
-}
-EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
-
struct device_node *dss_of_port_get_parent_device(struct device_node *port)
{
struct device_node *np;
@@ -123,37 +58,6 @@ u32 dss_of_port_get_port_number(struct device_node *port)
return reg;
}
-static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
-{
- struct device_node *np;
-
- np = of_parse_phandle(node, "remote-endpoint", 0);
- if (!np)
- return NULL;
-
- np = of_get_next_parent(np);
-
- return np;
-}
-
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent)
-{
- struct device_node *port, *ep;
-
- port = omapdss_of_get_next_port(parent, NULL);
-
- if (!port)
- return NULL;
-
- ep = omapdss_of_get_next_endpoint(port, NULL);
-
- of_node_put(port);
-
- return ep;
-}
-EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint);
-
struct omap_dss_device *
omapdss_of_find_source_for_first_ep(struct device_node *node)
{
@@ -161,11 +65,11 @@ omapdss_of_find_source_for_first_ep(struct device_node *node)
struct device_node *src_port;
struct omap_dss_device *src;
- ep = omapdss_of_get_first_endpoint(node);
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
if (!ep)
return ERR_PTR(-EINVAL);
- src_port = omapdss_of_get_remote_port(ep);
+ src_port = of_graph_get_remote_port(ep);
if (!src_port) {
of_node_put(ep);
return ERR_PTR(-EINVAL);
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 14887d5b02e5..2734c401d9fa 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -38,6 +38,7 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/regulator/consumer.h>
#include <linux/suspend.h>
#include <linux/component.h>
@@ -1043,32 +1044,14 @@ static int dss_init_ports(struct platform_device *pdev)
{
struct device_node *parent = pdev->dev.of_node;
struct device_node *port;
- int r;
-
- if (parent == NULL)
- return 0;
+ int i;
- port = omapdss_of_get_next_port(parent, NULL);
- if (!port)
- return 0;
-
- if (dss.feat->num_ports == 0)
- return 0;
-
- do {
- enum omap_display_type port_type;
- u32 reg;
-
- r = of_property_read_u32(port, "reg", ®);
- if (r)
- reg = 0;
-
- if (reg >= dss.feat->num_ports)
+ for (i = 0; i < dss.feat->num_ports; i++) {
+ port = of_graph_get_port_by_id(parent, i);
+ if (!port)
continue;
- port_type = dss.feat->ports[reg];
-
- switch (port_type) {
+ switch (dss.feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI:
dpi_init_port(pdev, port);
break;
@@ -1078,7 +1061,7 @@ static int dss_init_ports(struct platform_device *pdev)
default:
break;
}
- } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
+ }
return 0;
}
@@ -1087,32 +1070,14 @@ static void dss_uninit_ports(struct platform_device *pdev)
{
struct device_node *parent = pdev->dev.of_node;
struct device_node *port;
+ int i;
- if (parent == NULL)
- return;
-
- port = omapdss_of_get_next_port(parent, NULL);
- if (!port)
- return;
-
- if (dss.feat->num_ports == 0)
- return;
-
- do {
- enum omap_display_type port_type;
- u32 reg;
- int r;
-
- r = of_property_read_u32(port, "reg", ®);
- if (r)
- reg = 0;
-
- if (reg >= dss.feat->num_ports)
+ for (i = 0; i < dss.feat->num_ports; i++) {
+ port = of_graph_get_port_by_id(parent, i);
+ if (!port)
continue;
- port_type = dss.feat->ports[reg];
-
- switch (port_type) {
+ switch (dss.feat->ports[i]) {
case OMAP_DISPLAY_TYPE_DPI:
dpi_uninit_port(port);
break;
@@ -1122,7 +1087,7 @@ static void dss_uninit_ports(struct platform_device *pdev)
default:
break;
}
- } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
+ }
}
static int dss_video_pll_probe(struct platform_device *pdev)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index e7162c16de2e..87c53034c634 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -34,6 +34,7 @@
#include <linux/regulator/consumer.h>
#include <linux/component.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <sound/omap-hdmi-audio.h>
#include "omapdss.h"
@@ -546,7 +547,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
struct device_node *ep;
int r;
- ep = omapdss_of_get_first_endpoint(node);
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
if (!ep)
return 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 678dfb02764a..1d14a4ac9902 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -572,7 +572,7 @@ static int hdmi_probe_of(struct platform_device *pdev)
struct device_node *ep;
int r;
- ep = omapdss_of_get_first_endpoint(node);
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
if (!ep)
return 0;
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index b420dde8c0fb..acf4e520baaf 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -830,17 +830,6 @@ static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev)
return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
}
-struct device_node *
-omapdss_of_get_next_port(const struct device_node *parent,
- struct device_node *prev);
-
-struct device_node *
-omapdss_of_get_next_endpoint(const struct device_node *parent,
- struct device_node *prev);
-
-struct device_node *
-omapdss_of_get_first_endpoint(const struct device_node *parent);
-
struct omap_dss_device *
omapdss_of_find_source_for_first_ep(struct device_node *node);
diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c b/drivers/gpu/drm/omapdrm/dss/venc.c
index d74f7fcc2e46..19d14957f566 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -35,6 +35,7 @@
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
+#include <linux/of_graph.h>
#include <linux/component.h>
#include "omapdss.h"
@@ -818,7 +819,7 @@ static int venc_probe_of(struct platform_device *pdev)
u32 channels;
int r;
- ep = omapdss_of_get_first_endpoint(node);
+ ep = of_graph_get_endpoint_by_regs(node, 0, 0);
if (!ep)
return 0;
--
2.10.1
[toc] | [prev] | [next] | [standalone]
| From | Russell King - ARM Linux <linux@armlinux.org.uk> |
|---|---|
| Date | 2017-02-04 11:50 +0100 |
| Message-ID | <t764O-7Fv-13@gated-at.bofh.it> |
| In reply to | #1573584 |
On Fri, Feb 03, 2017 at 09:36:30PM -0600, Rob Herring wrote: > The Armada and Rockchip drivers remain oddballs with their own graph > parsing. I can't see how the armada driver even can work. There's > nothing to instantiate the armada-drm device either in DT or the kernel. Correct, that's sitting out of tree because it requires either legacy code in arch/arm/mach-dove at the moment, or stuff for DT. Each time that I looked at the DT reserved memory stuff I've ended up giving up as it always seemed to be half complete, and the documentation was confusing (seemingly referring to things that weren't merged.) Maybe that's changed today, but I've not had a chance to look at it again. -- RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up according to speedtest.net.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web