Commit d2207071 authored by Stephen Warren's avatar Stephen Warren

ARM: tegra: split tegra_pmc_init() in two

Tegra's board file currently initializes clocks much earlier than those
for most other ARM SoCs. The reason is:

* The PMC HW block is involved in the path of some interrupts (i.e. it
inverts, or not, the IRQ input pin dedicated to the PMIC).

* So, that part of the PMC must be initialized early so that the IRQ
polarity is correct.

* The PMC initialization is currently monolithic, and the PMC has some
clock inputs, so the init routine ends up calling of_clk_get_by_name(),
and hence clocks must be set up early too.

In order to defer clock initialization to the more typical location,
split out the portions of tegra_pmc_init() that are truly IRQ-related
into a separate tegra_pmc_init_irq(), which can be called from the
machine descriptor's .init_irq() function, and defer the rest until
the machine descriptor's .init_machine() function. This allows the
clock initiliazation to happen from the machine descriptor's
.init_time() function, as is typical.
Signed-off-by: default avatarStephen Warren <swarren@nvidia.com>
parent 272b98c6
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/clk-provider.h>
#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/cache-l2x0.h>
...@@ -61,8 +60,7 @@ u32 tegra_uart_config[4] = { ...@@ -61,8 +60,7 @@ u32 tegra_uart_config[4] = {
#ifdef CONFIG_OF #ifdef CONFIG_OF
void __init tegra_dt_init_irq(void) void __init tegra_dt_init_irq(void)
{ {
of_clk_init(NULL); tegra_pmc_init_irq();
tegra_pmc_init();
tegra_init_irq(); tegra_init_irq();
irqchip_init(); irqchip_init();
tegra_legacy_irq_syscore_init(); tegra_legacy_irq_syscore_init();
......
...@@ -285,13 +285,10 @@ static const struct of_device_id matches[] __initconst = { ...@@ -285,13 +285,10 @@ static const struct of_device_id matches[] __initconst = {
{ } { }
}; };
static void __init tegra_pmc_parse_dt(void) void __init tegra_pmc_init_irq(void)
{ {
struct device_node *np; struct device_node *np;
u32 prop; u32 val;
enum tegra_suspend_mode suspend_mode;
u32 core_good_time[2] = {0, 0};
u32 lp0_vec[2] = {0, 0};
np = of_find_matching_node(NULL, matches); np = of_find_matching_node(NULL, matches);
BUG_ON(!np); BUG_ON(!np);
...@@ -300,6 +297,26 @@ static void __init tegra_pmc_parse_dt(void) ...@@ -300,6 +297,26 @@ static void __init tegra_pmc_parse_dt(void)
tegra_pmc_invert_interrupt = of_property_read_bool(np, tegra_pmc_invert_interrupt = of_property_read_bool(np,
"nvidia,invert-interrupt"); "nvidia,invert-interrupt");
val = tegra_pmc_readl(PMC_CTRL);
if (tegra_pmc_invert_interrupt)
val |= PMC_CTRL_INTR_LOW;
else
val &= ~PMC_CTRL_INTR_LOW;
tegra_pmc_writel(val, PMC_CTRL);
}
void __init tegra_pmc_init(void)
{
struct device_node *np;
u32 prop;
enum tegra_suspend_mode suspend_mode;
u32 core_good_time[2] = {0, 0};
u32 lp0_vec[2] = {0, 0};
np = of_find_matching_node(NULL, matches);
BUG_ON(!np);
tegra_pclk = of_clk_get_by_name(np, "pclk"); tegra_pclk = of_clk_get_by_name(np, "pclk");
WARN_ON(IS_ERR(tegra_pclk)); WARN_ON(IS_ERR(tegra_pclk));
...@@ -365,17 +382,3 @@ static void __init tegra_pmc_parse_dt(void) ...@@ -365,17 +382,3 @@ static void __init tegra_pmc_parse_dt(void)
pmc_pm_data.suspend_mode = suspend_mode; pmc_pm_data.suspend_mode = suspend_mode;
} }
void __init tegra_pmc_init(void)
{
u32 val;
tegra_pmc_parse_dt();
val = tegra_pmc_readl(PMC_CTRL);
if (tegra_pmc_invert_interrupt)
val |= PMC_CTRL_INTR_LOW;
else
val &= ~PMC_CTRL_INTR_LOW;
tegra_pmc_writel(val, PMC_CTRL);
}
...@@ -39,6 +39,7 @@ bool tegra_pmc_cpu_is_powered(int cpuid); ...@@ -39,6 +39,7 @@ bool tegra_pmc_cpu_is_powered(int cpuid);
int tegra_pmc_cpu_power_on(int cpuid); int tegra_pmc_cpu_power_on(int cpuid);
int tegra_pmc_cpu_remove_clamping(int cpuid); int tegra_pmc_cpu_remove_clamping(int cpuid);
void tegra_pmc_init_irq(void);
void tegra_pmc_init(void); void tegra_pmc_init(void);
#endif #endif
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sys_soc.h> #include <linux/sys_soc.h>
#include <linux/usb/tegra_usb_phy.h> #include <linux/usb/tegra_usb_phy.h>
#include <linux/clk-provider.h>
#include <linux/clk/tegra.h> #include <linux/clk/tegra.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#include "common.h" #include "common.h"
#include "fuse.h" #include "fuse.h"
#include "iomap.h" #include "iomap.h"
#include "pmc.h"
static void __init tegra_dt_init(void) static void __init tegra_dt_init(void)
{ {
...@@ -51,6 +53,8 @@ static void __init tegra_dt_init(void) ...@@ -51,6 +53,8 @@ static void __init tegra_dt_init(void)
struct soc_device *soc_dev; struct soc_device *soc_dev;
struct device *parent = NULL; struct device *parent = NULL;
tegra_pmc_init();
tegra_clocks_apply_init_table(); tegra_clocks_apply_init_table();
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
...@@ -80,6 +84,12 @@ static void __init tegra_dt_init(void) ...@@ -80,6 +84,12 @@ static void __init tegra_dt_init(void)
of_platform_populate(NULL, of_default_bus_match_table, NULL, parent); of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
} }
static void __init tegra_dt_init_time(void)
{
of_clk_init(NULL);
clocksource_of_init();
}
static void __init paz00_init(void) static void __init paz00_init(void)
{ {
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)) if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
...@@ -119,7 +129,7 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") ...@@ -119,7 +129,7 @@ DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
.smp = smp_ops(tegra_smp_ops), .smp = smp_ops(tegra_smp_ops),
.init_early = tegra_init_early, .init_early = tegra_init_early,
.init_irq = tegra_dt_init_irq, .init_irq = tegra_dt_init_irq,
.init_time = clocksource_of_init, .init_time = tegra_dt_init_time,
.init_machine = tegra_dt_init, .init_machine = tegra_dt_init,
.init_late = tegra_dt_init_late, .init_late = tegra_dt_init_late,
.restart = tegra_assert_system_reset, .restart = tegra_assert_system_reset,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment