diff options
Diffstat (limited to 'arch/arm/mach-mvebu/system-controller.c')
| -rw-r--r-- | arch/arm/mach-mvebu/system-controller.c | 44 | 
1 files changed, 34 insertions, 10 deletions
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c index f875124ff4f..0c5524ac75b 100644 --- a/arch/arm/mach-mvebu/system-controller.c +++ b/arch/arm/mach-mvebu/system-controller.c @@ -1,5 +1,5 @@  /* - * System controller support for Armada 370 and XP platforms. + * System controller support for Armada 370, 375 and XP platforms.   *   * Copyright (C) 2012 Marvell   * @@ -11,7 +11,7 @@   * License version 2.  This program is licensed "as is" without any   * warranty of any kind, whether express or implied.   * - * The Armada 370 and Armada XP SoCs both have a range of + * The Armada 370, 375 and Armada XP SoCs have a range of   * miscellaneous registers, that do not belong to a particular device,   * but rather provide system-level features. This basic   * system-controller driver provides a device tree binding for those @@ -27,6 +27,7 @@  #include <linux/of_address.h>  #include <linux/io.h>  #include <linux/reboot.h> +#include "common.h"  static void __iomem *system_controller_base; @@ -36,30 +37,43 @@ struct mvebu_system_controller {  	u32 rstoutn_mask_reset_out_en;  	u32 system_soft_reset; + +	u32 resume_boot_addr;  };  static struct mvebu_system_controller *mvebu_sc; -const struct mvebu_system_controller armada_370_xp_system_controller = { +static const struct mvebu_system_controller armada_370_xp_system_controller = {  	.rstoutn_mask_offset = 0x60,  	.system_soft_reset_offset = 0x64,  	.rstoutn_mask_reset_out_en = 0x1,  	.system_soft_reset = 0x1,  }; -const struct mvebu_system_controller orion_system_controller = { +static const struct mvebu_system_controller armada_375_system_controller = { +	.rstoutn_mask_offset = 0x54, +	.system_soft_reset_offset = 0x58, +	.rstoutn_mask_reset_out_en = 0x1, +	.system_soft_reset = 0x1, +	.resume_boot_addr = 0xd4, +}; + +static const struct mvebu_system_controller orion_system_controller = {  	.rstoutn_mask_offset = 0x108,  	.system_soft_reset_offset = 0x10c,  	.rstoutn_mask_reset_out_en = 0x4,  	.system_soft_reset = 0x1,  }; -static struct of_device_id of_system_controller_table[] = { +static const struct of_device_id of_system_controller_table[] = {  	{  		.compatible = "marvell,orion-system-controller",  		.data = (void *) &orion_system_controller,  	}, {  		.compatible = "marvell,armada-370-xp-system-controller",  		.data = (void *) &armada_370_xp_system_controller, +	}, { +		.compatible = "marvell,armada-375-system-controller", +		.data = (void *) &armada_375_system_controller,  	},  	{ /* end of list */ },  }; @@ -87,20 +101,30 @@ void mvebu_restart(enum reboot_mode mode, const char *cmd)  		;  } +#ifdef CONFIG_SMP +void mvebu_system_controller_set_cpu_boot_addr(void *boot_addr) +{ +	BUG_ON(system_controller_base == NULL); +	BUG_ON(mvebu_sc->resume_boot_addr == 0); +	writel(virt_to_phys(boot_addr), system_controller_base + +	       mvebu_sc->resume_boot_addr); +} +#endif +  static int __init mvebu_system_controller_init(void)  { +	const struct of_device_id *match;  	struct device_node *np; -	np = of_find_matching_node(NULL, of_system_controller_table); +	np = of_find_matching_node_and_match(NULL, of_system_controller_table, +					     &match);  	if (np) { -		const struct of_device_id *match = -		    of_match_node(of_system_controller_table, np); -		BUG_ON(!match);  		system_controller_base = of_iomap(np, 0);  		mvebu_sc = (struct mvebu_system_controller *)match->data; +		of_node_put(np);  	}  	return 0;  } -arch_initcall(mvebu_system_controller_init); +early_initcall(mvebu_system_controller_init);  | 
