Re: [PATCH v3] platform: set of_node in platform_device_register_full()

From: Rafael J. Wysocki
Date: Fri Feb 22 2019 - 04:16:47 EST


On Thu, Feb 21, 2019 at 12:29 PM Mans Rullgard <mans@xxxxxxxxx> wrote:
>
> If the provided fwnode is an OF node, set dev.of_node as well.
>
> Also add an of_node_reused flag to struct platform_device_info and copy
> this to the new device. This is needed to avoid pinctrl settings being
> requested twice. See 4e75e1d7dac9 ("driver core: add helper to reuse a
> device-tree node") for a longer explanation.
>
> Some drivers are just shims that create extra "glue" devices with the
> DT device as parent and have the real driver bind to these. In these
> cases, the glue device needs to get a reference to the original DT node
> in order for the main driver to access properties and child nodes.
>
> For example, the sunxi-musb driver creates such a glue device using
> platform_device_register_full(). Consequently, devices attached to
> this USB interface don't get associated with DT nodes, if present,
> the way they do with EHCI.
>
> This change will allow sunxi-musb and similar drivers to easily
> propagate the DT node to child devices as required.
>
> Signed-off-by: Mans Rullgard <mans@xxxxxxxxx>

Generally

Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx>

but I'm a bit concerned about the existing users of
platform_device_register_full() who may pass a valid DT fwnode to it
and not expect of_node to be set. Arguably, they should expect it to
be set, but then there may be some fallout resulting from this change.

> ---
> Changes in v3:
> - handle of_node_reused
> ---
> drivers/base/platform.c | 2 ++
> include/linux/platform_device.h | 1 +
> 2 files changed, 3 insertions(+)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index dff82a3c2caa..7058ecea779a 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -512,6 +512,8 @@ struct platform_device *platform_device_register_full(
>
> pdev->dev.parent = pdevinfo->parent;
> pdev->dev.fwnode = pdevinfo->fwnode;
> + pdev->dev.of_node = of_node_get(to_of_node(pdev->dev.fwnode));
> + pdev->dev.of_node_reused = pdevinfo->of_node_reused;
>
> if (pdevinfo->dma_mask) {
> /*
> diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
> index 1a9f38f27f65..4a29fdf16806 100644
> --- a/include/linux/platform_device.h
> +++ b/include/linux/platform_device.h
> @@ -62,6 +62,7 @@ extern int platform_add_devices(struct platform_device **, int);
> struct platform_device_info {
> struct device *parent;
> struct fwnode_handle *fwnode;
> + bool of_node_reused;
>
> const char *name;
> int id;
> --
> 2.20.1
>