CONFIG_ARCH_HI3xxx=y
CONFIG_ARCH_KEYSTONE=y
CONFIG_ARCH_MXC=y
-CONFIG_MACH_IMX51_DT=y
+CONFIG_SOC_IMX51=y
CONFIG_SOC_IMX53=y
CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
CONFIG_POWER_RESET_SUN6I=y
CONFIG_SENSORS_LM90=y
CONFIG_THERMAL=y
- CONFIG_DOVE_THERMAL=y
CONFIG_ARMADA_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_ORION_WATCHDOG=y
CONFIG_SUNXI_WATCHDOG=y
CONFIG_MFD_AS3722=y
+ CONFIG_MFD_BCM590XX=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_SPI=y
CONFIG_MFD_MAX8907=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_AB8500=y
CONFIG_REGULATOR_AS3722=y
+ CONFIG_REGULATOR_BCM590XX=y
CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_MAX8907=y
CONFIG_REGULATOR_PALMAS=y
obj-y += system-controller.o mvebu-soc-id.o
ifeq ($(CONFIG_MACH_MVEBU_V7),y)
- obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o
+ obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
-obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
endif
obj-$(CONFIG_MACH_DOVE) += dove.o
obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o
+obj-$(CONFIG_MACH_NETXBIG) += netxbig.o
#include <linux/mbus.h>
#include <linux/signal.h>
#include <linux/slab.h>
+ #include <linux/irqchip.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
return 1;
}
- static void __init mvebu_timer_and_clk_init(void)
+ static void __init mvebu_init_irq(void)
{
- of_clk_init(NULL);
- clocksource_of_init();
+ irqchip_init();
mvebu_scu_enable();
coherency_init();
BUG_ON(mvebu_mbus_dt_init(coherency_available()));
+ }
+
+ static void __init external_abort_quirk(void)
+ {
+ u32 dev, rev;
- if (of_machine_is_compatible("marvell,armada375"))
- hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
- "imprecise external abort");
+ if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
+ return;
+
+ hook_fault_code(16 + 6, armada_375_external_abort_wa, SIGBUS, 0,
+ "imprecise external abort");
}
static void __init i2c_quirk(void)
{
struct device_node *np;
u32 dev, rev;
+ int res;
- if (mvebu_get_soc_id(&dev, &rev) == 0 && rev > ARMADA_375_Z1_REV)
+ /*
+ * The early SoC Z1 revision needs a quirk to be applied in order
+ * for the thermal controller to work properly. This quirk breaks
+ * the thermal support if applied on a SoC that doesn't need it,
+ * so we enforce the SoC revision to be known.
+ */
+ res = mvebu_get_soc_id(&dev, &rev);
+ if (res < 0 || (res == 0 && rev > ARMADA_375_Z1_REV))
return;
for_each_compatible_node(np, NULL, "marvell,armada375-thermal") {
/*
* The thermal controller needs some quirk too, so let's change
- * the compatible string to reflect this.
+ * the compatible string to reflect this and allow the driver
+ * the take the necessary action.
*/
prop = kzalloc(sizeof(*prop), GFP_KERNEL);
prop->name = kstrdup("compatible", GFP_KERNEL);
{
if (of_machine_is_compatible("plathome,openblocks-ax3-4"))
i2c_quirk();
- if (of_machine_is_compatible("marvell,a375-db"))
+ if (of_machine_is_compatible("marvell,a375-db")) {
+ external_abort_quirk();
thermal_quirk();
+ }
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
.l2c_aux_mask = ~0,
.smp = smp_ops(armada_xp_smp_ops),
.init_machine = mvebu_dt_init,
- .init_time = mvebu_timer_and_clk_init,
+ .init_irq = mvebu_init_irq,
.restart = mvebu_restart,
.dt_compat = armada_370_xp_dt_compat,
MACHINE_END
DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
- .init_time = mvebu_timer_and_clk_init,
+ .init_irq = mvebu_init_irq,
.init_machine = mvebu_dt_init,
.restart = mvebu_restart,
.dt_compat = armada_375_dt_compat,
DT_MACHINE_START(ARMADA_38X_DT, "Marvell Armada 380/385 (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
- .init_time = mvebu_timer_and_clk_init,
+ .init_irq = mvebu_init_irq,
.restart = mvebu_restart,
.dt_compat = armada_38x_dt_compat,
MACHINE_END
extern void ll_disable_coherency(void);
extern void ll_enable_coherency(void);
+ extern void armada_370_xp_cpu_resume(void);
+
static struct platform_device armada_xp_cpuidle_device = {
.name = "cpuidle-armada-370-xp",
};
writel(reg, pmsu_mp_base + L2C_NFABRIC_PM_CTL);
}
- static void armada_370_xp_cpu_resume(void)
- {
- asm volatile("bl ll_add_cpu_to_smp_group\n\t"
- "bl ll_enable_coherency\n\t"
- "b cpu_resume\n\t");
- }
-
/* No locking is needed because we only access per-CPU registers */
-void armada_370_xp_pmsu_idle_prepare(bool deepidle)
+int armada_370_xp_pmsu_idle_enter(unsigned long deepidle)
{
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
u32 reg;
if (pmsu_mp_base == NULL)
- return;
+ return -EINVAL;
/*
* Adjust the PMSU configuration to wait for WFI signal, enable
reg = readl(pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
reg |= PMSU_CPU_POWER_DOWN_DIS_SNP_Q_SKIP;
writel(reg, pmsu_mp_base + PMSU_CPU_POWER_DOWN_CONTROL(hw_cpu));
-}
-
-static noinline int do_armada_370_xp_cpu_suspend(unsigned long deepidle)
-{
- armada_370_xp_pmsu_idle_prepare(deepidle);
v7_exit_coherency_flush(all);
static int armada_370_xp_cpu_suspend(unsigned long deepidle)
{
- return cpu_suspend(deepidle, do_armada_370_xp_cpu_suspend);
+ return cpu_suspend(deepidle, armada_370_xp_pmsu_idle_enter);
}
/* No locking is needed because we only access per-CPU registers */
-static noinline void armada_370_xp_pmsu_idle_restore(void)
+void armada_370_xp_pmsu_idle_exit(void)
{
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
u32 reg;
unsigned int hw_cpu = cpu_logical_map(smp_processor_id());
mvebu_pmsu_set_cpu_boot_addr(hw_cpu, armada_370_xp_cpu_resume);
} else if (action == CPU_PM_EXIT) {
- armada_370_xp_pmsu_idle_restore();
+ armada_370_xp_pmsu_idle_exit();
}
return NOTIFY_OK;
.notifier_call = armada_370_xp_cpu_pm_notify,
};
-int __init armada_370_xp_cpu_pm_init(void)
+static int __init armada_370_xp_cpu_pm_init(void)
{
struct device_node *np;
#include <linux/clk-provider.h>
#include <linux/clocksource.h>
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/of_address.h>
+ #include <linux/of_irq.h>
+ #include <linux/of_platform.h>
+ #include <linux/io.h>
+ #include <linux/reboot.h>
#include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+ #include <asm/system_misc.h>
+
+ #define SUN4I_WATCHDOG_CTRL_REG 0x00
+ #define SUN4I_WATCHDOG_CTRL_RESTART BIT(0)
+ #define SUN4I_WATCHDOG_MODE_REG 0x04
+ #define SUN4I_WATCHDOG_MODE_ENABLE BIT(0)
+ #define SUN4I_WATCHDOG_MODE_RESET_ENABLE BIT(1)
+
+ #define SUN6I_WATCHDOG1_IRQ_REG 0x00
+ #define SUN6I_WATCHDOG1_CTRL_REG 0x10
+ #define SUN6I_WATCHDOG1_CTRL_RESTART BIT(0)
+ #define SUN6I_WATCHDOG1_CONFIG_REG 0x14
+ #define SUN6I_WATCHDOG1_CONFIG_RESTART BIT(0)
+ #define SUN6I_WATCHDOG1_CONFIG_IRQ BIT(1)
+ #define SUN6I_WATCHDOG1_MODE_REG 0x18
+ #define SUN6I_WATCHDOG1_MODE_ENABLE BIT(0)
+
+ static void __iomem *wdt_base;
+
+ static void sun4i_restart(enum reboot_mode mode, const char *cmd)
+ {
+ if (!wdt_base)
+ return;
+
+ /* Enable timer and set reset bit in the watchdog */
+ writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE,
+ wdt_base + SUN4I_WATCHDOG_MODE_REG);
+
+ /*
+ * Restart the watchdog. The default (and lowest) interval
+ * value for the watchdog is 0.5s.
+ */
+ writel(SUN4I_WATCHDOG_CTRL_RESTART, wdt_base + SUN4I_WATCHDOG_CTRL_REG);
+
+ while (1) {
+ mdelay(5);
+ writel(SUN4I_WATCHDOG_MODE_ENABLE | SUN4I_WATCHDOG_MODE_RESET_ENABLE,
+ wdt_base + SUN4I_WATCHDOG_MODE_REG);
+ }
+ }
+
+ static struct of_device_id sunxi_restart_ids[] = {
+ { .compatible = "allwinner,sun4i-a10-wdt" },
+ { /*sentinel*/ }
+ };
+
+ static void sunxi_setup_restart(void)
+ {
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, sunxi_restart_ids);
+ if (WARN(!np, "unable to setup watchdog restart"))
+ return;
+
+ wdt_base = of_iomap(np, 0);
+ WARN(!wdt_base, "failed to map watchdog base address");
+ }
+
+ static void __init sunxi_dt_init(void)
+ {
+ sunxi_setup_restart();
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ }
static const char * const sunxi_board_dt_compat[] = {
"allwinner,sun4i-a10",
};
DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
+ .init_machine = sunxi_dt_init,
.dt_compat = sunxi_board_dt_compat,
+ .restart = sun4i_restart,
MACHINE_END
static const char * const sun6i_board_dt_compat[] = {
};
DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family")
+ .init_machine = sunxi_dt_init,
.dt_compat = sun7i_board_dt_compat,
+ .restart = sun4i_restart,
MACHINE_END
+
+static const char * const sun8i_board_dt_compat[] = {
+ "allwinner,sun8i-a23",
+ NULL,
+};
+
+DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
+ .dt_compat = sun8i_board_dt_compat,
+MACHINE_END