Re: [PATCH 2/6] soc/tegra: pmc: Fix early initialisation of PMC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 28/06/16 11:38, Jon Hunter wrote:
> During early initialisation, the available power partitions for a given
> device is configured as well as the polarity of the PMC interrupt. Both
> of which should only be configured if there is a valid device node for
> the PMC device. This is because the soc data used for configuring the
> power partitions is only available if a device node for the PMC is found
> and the code to configure the interrupt polarity uses the device node
> pointer directly.
> 
> Some early device-tree images may not have this device node and so fix
> this by ensuring the device node pointer is valid when configuring these
> items.
> 
> Signed-off-by: Jon Hunter <jonathanh@xxxxxxxxxx>
> ---
>  drivers/soc/tegra/pmc.c | 34 ++++++++++++++++++----------------
>  1 file changed, 18 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
> index 52a9e9703668..2e031c4ad547 100644
> --- a/drivers/soc/tegra/pmc.c
> +++ b/drivers/soc/tegra/pmc.c
> @@ -1550,27 +1550,29 @@ static int __init tegra_pmc_early_init(void)
>  		return -ENXIO;
>  	}
>  
> -	/* Create a bit-map of the available and valid partitions */
> -	for (i = 0; i < pmc->soc->num_powergates; i++)
> -		if (pmc->soc->powergates[i])
> -			set_bit(i, pmc->powergates_available);
> -
>  	mutex_init(&pmc->powergates_lock);
>  
> -	/*
> -	 * Invert the interrupt polarity if a PMC device tree node exists and
> -	 * contains the nvidia,invert-interrupt property.
> -	 */
> -	invert = of_property_read_bool(np, "nvidia,invert-interrupt");
> +	if (np) {
> +		/* Create a bit-map of the available and valid partitions */
> +		for (i = 0; i < pmc->soc->num_powergates; i++)
> +			if (pmc->soc->powergates[i])
> +				set_bit(i, pmc->powergates_available);
>  
> -	value = tegra_pmc_readl(PMC_CNTRL);
> +		/*
> +		 * Invert the interrupt polarity if a PMC device tree node
> +		 * exists and contains the nvidia,invert-interrupt property.
> +		 */
> +		invert = of_property_read_bool(np, "nvidia,invert-interrupt");
>  
> -	if (invert)
> -		value |= PMC_CNTRL_INTR_POLARITY;
> -	else
> -		value &= ~PMC_CNTRL_INTR_POLARITY;
> +		value = tegra_pmc_readl(PMC_CNTRL);
>  
> -	tegra_pmc_writel(value, PMC_CNTRL);
> +		if (invert)
> +			value |= PMC_CNTRL_INTR_POLARITY;
> +		else
> +			value &= ~PMC_CNTRL_INTR_POLARITY;
> +
> +		tegra_pmc_writel(value, PMC_CNTRL);
> +	}
>  
>  	return 0;
>  }

By the way, the more I think about this, if there is no valid 'pmc'
node in the device-tree blob, then I wonder if we should even bother
mapping the pmc address space at all? The reason being, if there is
no 'pmc' node then we cannot look-up the SoC data and so all the
public PMC APIs are pretty useless AFAICT. I wonder if we should do
something like ...

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index e09c7ed385f6..34d1385d7ef0 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1510,7 +1510,6 @@ static int __init tegra_pmc_early_init(void)
 {
        const struct of_device_id *match;
        struct device_node *np;
-       struct resource regs;
        unsigned int i;
        bool invert;
        u32 value;
@@ -1520,73 +1519,47 @@ static int __init tegra_pmc_early_init(void)
        np = of_find_matching_node_and_match(NULL, tegra_pmc_match, &match);
        if (!np) {
                /*
-                * Fall back to legacy initialization for 32-bit ARM only. All
-                * 64-bit ARM device tree files for Tegra are required to have
-                * a PMC node.
-                *
-                * This is for backwards-compatibility with old device trees
-                * that didn't contain a PMC node. Note that in this case the
-                * SoC data can't be matched and therefore powergating is
-                * disabled.
+                * All 64-bit ARM device tree files for Tegra are required to
+                * have a PMC node. For old 32-bit Tegra device trees that
+                * don't contain a PMC node, the SoC data can't be matched
+                * and therefore powergating is disabled.
                 */
-               if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) {
+               if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra())
                        pr_warn("DT node not found, powergating disabled\n");
 
-                       regs.start = 0x7000e400;
-                       regs.end = 0x7000e7ff;
-                       regs.flags = IORESOURCE_MEM;
-
-                       pr_warn("Using memory region %pR\n", &regs);
-               } else {
-                       /*
-                        * At this point we're not running on Tegra, so play
-                        * nice with multi-platform kernels.
-                        */
-                       return 0;
-               }
-       } else {
-               /*
-                * Extract information from the device tree if we've found a
-                * matching node.
-                */
-               if (of_address_to_resource(np, 0, &regs) < 0) {
-                       pr_err("failed to get PMC registers\n");
-                       return -ENXIO;
-               }
+               return 0;
        }
 
-       pmc->base = ioremap_nocache(regs.start, resource_size(&regs));
+       pmc->base = of_iomap(np, 0);
        if (!pmc->base) {
                pr_err("failed to map PMC registers\n");
                of_node_put(np);
                return -ENXIO;
        }

Cheers
Jon
 

-- 
nvpublic
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux