[RFC] early init and DT platform devices allocation/registration
Grant Likely
grant.likely at secretlab.ca
Wed Jun 26 03:52:33 EST 2013
On Tue, Jun 25, 2013 at 5:36 PM, Hiroshi Doyu <hdoyu at nvidia.com> wrote:
> Stephen Warren <swarren at wwwdotorg.org> wrote @ Tue, 25 Jun 2013 16:56:22 +0200:
>
>> >> How this problem is supposed to be solved in the kernel ?
>> >>
>> >> 1- drivers that are to be up and running at early_initcall time must not
>> >> rely on the device/driver model (but then they cannot use any API that
>> >> requires a struct device to function (eg regmap))
>> >> 2- the driver should allocate a platform device at early initcall from
>> >> a DT compatible node. Do not know how to deal with platform device
>> >> duplication though, since of_platform_populate() will create another
>> >> platform device when the node is parsed
>> >
>> > While I've resisted it in the past, I would be okay with adding struct
>> > device pointer in the device_node structure. I've resisted because I
>> > don't want drivers following the device_node pointer and making an
>> > assumption about what /kind/ of device is pointed to by it. However,
>> > this is an important use case and it makes it feasible to use an early
>> > platform device with of_platform_populate.
>>
>> Hiroshi (who I have CC'd here) has also been asking about this same
>> issue downstream. The issue for us is that we need to initialize an SMMU
>> driver before any devices that are translated by the SMMU. One option is
>> to force the register/probe of the SMMU driver explicitly, early in the
>> machine's .init_machine() callback, before of_platform_populate(), to
>> ensure the ordering. Then, we run into the same duplicate device issue,
>> and the change Grant mentions above would help solve this.
>
> Here's my workaround. I need to call of_detach_node() with OF_DYNAMIC
> to avoid duplicated device registration.
Gah! my eyes!
Don't do that. It is incredibly problematic. Look at inhibiting
duplicate device creation instead.
g.
>
> From f4d88b8521c278b41b72028d326c03cfd2e90af8 Mon Sep 17 00:00:00 2001
> From: Hiroshi Doyu <hdoyu at nvidia.com>
> Date: Fri, 14 Jun 2013 15:22:02 +0300
> Subject: [PATCH 1/1] ARM: tegra: Populate AHB/IOMMU earlier than others
>
> Populate AHB/IOMMU earlier than others. IOMMU depends on AHB. IOMMU
> needs to be instanciated earlier than others so that IOMMU can
> register other platform devices as IOMMU'able. Once IOMMU is
> populated, IOMMU/AHB nodes are detached to prevent another
> registeration.
>
> Signed-off-by: Hiroshi Doyu <hdoyu at nvidia.com>
> ---
> arch/arm/mach-tegra/Kconfig | 1 +
> arch/arm/mach-tegra/tegra.c | 24 ++++++++++++++++++++++++
> drivers/iommu/tegra-smmu.c | 3 +++
> 3 files changed, 28 insertions(+)
>
> diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
> index ef3a8da..79905fe 100644
> --- a/arch/arm/mach-tegra/Kconfig
> +++ b/arch/arm/mach-tegra/Kconfig
> @@ -15,6 +15,7 @@ config ARCH_TEGRA
> select SOC_BUS
> select SPARSE_IRQ
> select USE_OF
> + select OF_DYNAMIC
> help
> This enables support for NVIDIA Tegra based systems.
>
> diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
> index 0d1e412..0c494b5 100644
> --- a/arch/arm/mach-tegra/tegra.c
> +++ b/arch/arm/mach-tegra/tegra.c
> @@ -80,6 +80,28 @@ static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
> {}
> };
>
> +static void tegra_of_platform_populate_iommu(void)
> +{
> + int i;
> + struct platform_device *pdev;
> + const char * const dname[] = {"ahb", "iommu", };
> +
> + for (i = 0; i < ARRAY_SIZE(dname); i++) {
> + struct device_node *np;
> + char path[NAME_MAX];
> +
> + snprintf(path, sizeof(path), "/%s", dname[i]);
> + np = of_find_node_by_path(path);
> + if (!np)
> + break;
> +
> + pdev = of_platform_device_create(np, NULL, NULL);
> + of_node_put(np);
> + if (!pdev)
> + break;
> + }
> +}
> +
> static void __init tegra_dt_init(void)
> {
> struct soc_device_attribute *soc_dev_attr;
> @@ -107,6 +129,8 @@ static void __init tegra_dt_init(void)
>
> parent = soc_device_to_device(soc_dev);
>
> + tegra_of_platform_populate_iommu();
> +
> /*
> * Finished with the static registrations now; fill in the missing
> * devices
> diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
> index f6f120e..6c9de3f 100644
> --- a/drivers/iommu/tegra-smmu.c
> +++ b/drivers/iommu/tegra-smmu.c
> @@ -1238,6 +1238,9 @@ static int tegra_smmu_probe(struct platform_device *pdev)
> smmu_debugfs_create(smmu);
> smmu_handle = smmu;
> bus_set_iommu(&platform_bus_type, &smmu_iommu_ops);
> +
> + of_detach_node(dev->of_node);
> + of_detach_node(smmu->ahb);
> return 0;
> }
>
> --
> 1.8.1.5
>
More information about the devicetree-discuss
mailing list