[PATCH v2] of: Keep track of populated platform devices

Rob Herring robherring2 at gmail.com
Wed Apr 30 08:22:25 PDT 2014


On Wed, Apr 30, 2014 at 9:05 AM, Pawel Moll <pawel.moll at arm.com> wrote:
> In "Device Tree powered" systems, platform devices are usually
> massively populated with of_platform_populate() call, executed
> at some level of initcalls, either by generic architecture
> or by platform-specific code.
>
> There are situations though where certain devices must be
> created (and bound with drivers) before all the others.
> This presents a challenge, as devices created explicitly
> would be created again by of_platform_populate().
>
> This patch tries to solve that issue in a generic way,
> adding a "populated" flag for a DT node description.
> Once set, this device will never be created again via
> of_* API, so of_platform_populate() will skip such nodes
> (and its children) in a similar way to the non-available
> ones.
>
> Signed-off-by: Pawel Moll <pawel.moll at arm.com>

One pondering and one minor change below, otherwise:

Acked-by: Rob Herring <robh at kernel.org>


> ---
>
> Changes since v1:
>
> - added of_node_check_and_set_flag()... (atomic test and set)
> - ... used it to atomically mark a node...
> - ... clearing the bit on error path.
>
>  drivers/of/platform.c | 18 +++++++++++++-----
>  include/linux/of.h    |  7 +++++++
>  2 files changed, 20 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index 404d1da..b33927a 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -204,12 +204,13 @@ static struct platform_device *of_platform_device_create_pdata(
>  {
>         struct platform_device *dev;
>
> -       if (!of_device_is_available(np))
> +       if (!of_device_is_available(np) ||
> +                       of_node_check_and_set_flag(np, OF_POPULATED))
>                 return NULL;
>
>         dev = of_device_alloc(np, bus_id, parent);
>         if (!dev)
> -               return NULL;
> +               goto err_clear_flag;

I wonder if leaving it set would be the right behavior. I can't see
that we would want to process the node again. But this is the
exceptional case, so its probably not too important and can stay like
this.

>
>  #if defined(CONFIG_MICROBLAZE)
>         dev->archdata.dma_mask = 0xffffffffUL;
> @@ -227,10 +228,14 @@ static struct platform_device *of_platform_device_create_pdata(
>
>         if (of_device_add(dev) != 0) {
>                 platform_device_put(dev);
> -               return NULL;
> +               goto err_clear_flag;
>         }
>
>         return dev;
> +
> +err_clear_flag:
> +       of_node_clear_flag(np, OF_POPULATED);
> +       return NULL;
>  }
>
>  /**
> @@ -262,14 +267,15 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>
>         pr_debug("Creating amba device %s\n", node->full_name);
>
> -       if (!of_device_is_available(node))
> +       if (!of_device_is_available(node) ||
> +                       of_node_check_and_set_flag(node, OF_POPULATED))
>                 return NULL;
>
>         dev = amba_device_alloc(NULL, 0, 0);
>         if (!dev) {
>                 pr_err("%s(): amba_device_alloc() failed for %s\n",
>                        __func__, node->full_name);
> -               return NULL;
> +               goto err_clear_flag;
>         }
>
>         /* setup generic device info */
> @@ -309,6 +315,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
>
>  err_free:
>         amba_device_put(dev);
> +err_clear_flag:
> +       of_node_clear_flag(node, OF_POPULATED);
>         return NULL;
>  }
>  #else /* CONFIG_ARM_AMBA */
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 3bad8d1..534cab8 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -130,6 +130,12 @@ static inline int of_node_check_flag(struct device_node *n, unsigned long flag)
>         return test_bit(flag, &n->_flags);
>  }
>
> +static inline int of_node_check_and_set_flag(struct device_node *n,

Please keep the well known naming convention of the called function:
of_node_test_and_set_flag



More information about the linux-arm-kernel mailing list