浏览代码

Merge branch 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson

* 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
  ux500: allow 5500 and 8500 to be built together
  ux500: modem_irq is only for 5500
  ux500: dynamic SOC detection
  ux500: rename MOP board Kconfig
  ux500: remove build-time changing macros
Linus Torvalds 14 年之前
父节点
当前提交
e773202e22

+ 4 - 0
arch/arm/configs/u8500_defconfig

@@ -9,6 +9,10 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_U8500=y
+CONFIG_UX500_SOC_DB5500=y
+CONFIG_UX500_SOC_DB8500=y
+CONFIG_MACH_U8500=y
+CONFIG_MACH_U5500=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_PREEMPT=y

+ 14 - 12
arch/arm/mach-ux500/Kconfig

@@ -7,28 +7,30 @@ config UX500_SOC_COMMON
 	select HAS_MTU
 	select NOMADIK_GPIO
 
-config UX500_SOC_DB8500
-	bool
+menu "Ux500 SoC"
 
 config UX500_SOC_DB5500
-	bool
+	bool "DB5500"
+
+config UX500_SOC_DB8500
+	bool "DB8500"
+
+endmenu
 
-choice
-	prompt "Ux500 target platform"
-	default MACH_U8500_MOP
+menu "Ux500 target platform"
 
-config MACH_U8500_MOP
+config MACH_U8500
 	bool "U8500 Development platform"
-	select UX500_SOC_DB8500
+	depends on UX500_SOC_DB8500
 	help
 	  Include support for the mop500 development platform.
 
 config MACH_U5500
 	bool "U5500 Development platform"
-	select UX500_SOC_DB5500
+	depends on UX500_SOC_DB5500
 	help
 	  Include support for the U5500 development platform.
-endchoice
+endmenu
 
 config UX500_DEBUG_UART
 	int "Ux500 UART to use for low-level debug"
@@ -39,14 +41,14 @@ config UX500_DEBUG_UART
 
 config U5500_MODEM_IRQ
 	bool "Modem IRQ support"
-	depends on MACH_U5500
+	depends on UX500_SOC_DB5500
 	default y
 	help
 	  Add support for handling IRQ:s from modem side
 
 config U5500_MBOX
 	bool "Mailbox support"
-	depends on MACH_U5500 && U5500_MODEM_IRQ
+	depends on U5500_MODEM_IRQ
 	default y
 	help
 	  Add support for U5500 mailbox communication with modem side

+ 3 - 2
arch/arm/mach-ux500/Makefile

@@ -2,10 +2,11 @@
 # Makefile for the linux kernel, U8500 machine.
 #
 
-obj-y				:= clock.o cpu.o devices.o devices-common.o
+obj-y				:= clock.o cpu.o devices.o devices-common.o \
+				   id.o
 obj-$(CONFIG_UX500_SOC_DB5500)	+= cpu-db5500.o dma-db5500.o
 obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o devices-db8500.o prcmu.o
-obj-$(CONFIG_MACH_U8500_MOP)	+= board-mop500.o board-mop500-sdi.o \
+obj-$(CONFIG_MACH_U8500)	+= board-mop500.o board-mop500-sdi.o \
 				board-mop500-keypads.o
 obj-$(CONFIG_MACH_U5500)	+= board-u5500.o board-u5500-sdi.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o

+ 10 - 4
arch/arm/mach-ux500/clock.c

@@ -136,8 +136,7 @@ EXPORT_SYMBOL(clk_disable);
  */
 static unsigned long clk_mtu_get_rate(struct clk *clk)
 {
-	void __iomem *addr = __io_address(UX500_PRCMU_BASE)
-		+ PRCM_TCR;
+	void __iomem *addr;
 	u32 tcr;
 	int mtu = (int) clk->data;
 	/*
@@ -149,13 +148,20 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
 	unsigned long mturate;
 	unsigned long retclk;
 
+	if (cpu_is_u5500())
+		addr = __io_address(U5500_PRCMU_BASE);
+	else if (cpu_is_u8500())
+		addr = __io_address(U8500_PRCMU_BASE);
+	else
+		ux500_unknown_soc();
+
 	/*
 	 * On a startup, always conifgure the TCR to the doze mode;
 	 * bootloaders do it for us. Do this in the kernel too.
 	 */
-	writel(PRCM_TCR_DOZE_MODE, addr);
+	writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR);
 
-	tcr = readl(addr);
+	tcr = readl(addr + PRCM_TCR);
 
 	/* Get the rate from the parent as a default */
 	if (clk->parent_periph)

+ 18 - 0
arch/arm/mach-ux500/cpu-db5500.c

@@ -21,7 +21,20 @@
 
 #include "devices-db5500.h"
 
+static struct map_desc u5500_uart_io_desc[] __initdata = {
+	__IO_DEV_DESC(U5500_UART0_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_UART2_BASE, SZ_4K),
+};
+
 static struct map_desc u5500_io_desc[] __initdata = {
+	__IO_DEV_DESC(U5500_GIC_CPU_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_TWD_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_SCU_BASE, SZ_4K),
+	__IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K),
+
 	__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
 	__IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
 	__IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
@@ -143,6 +156,11 @@ static void __init db5500_add_gpios(void)
 
 void __init u5500_map_io(void)
 {
+	/*
+	 * Map the UARTs early so that the DEBUG_LL stuff continues to work.
+	 */
+	iotable_init(u5500_uart_io_desc, ARRAY_SIZE(u5500_uart_io_desc));
+
 	ux500_map_io();
 
 	iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));

+ 24 - 81
arch/arm/mach-ux500/cpu-db8500.c

@@ -29,13 +29,31 @@ static struct platform_device *platform_devs[] __initdata = {
 };
 
 /* minimum static i/o mapping required to boot U8500 platforms */
+static struct map_desc u8500_uart_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_UART0_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
+};
+
 static struct map_desc u8500_io_desc[] __initdata = {
+	__IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
+
+	__IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K),
+	__IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K),
+
 	__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
 	__IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
-	__MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M),
 };
 
 static struct map_desc u8500_ed_io_desc[] __initdata = {
@@ -52,71 +70,13 @@ static struct map_desc u8500_v2_io_desc[] __initdata = {
 	__IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
 };
 
-/*
- * Functions to differentiate between later ASICs
- * We look into the end of the ROM to locate the hardcoded ASIC ID.
- * This is only needed to differentiate between minor revisions and
- * process variants of an ASIC, the major revisions are encoded in
- * the cpuid.
- */
-#define U8500_ASIC_ID_LOC_ED_V1	(U8500_BOOT_ROM_BASE + 0x1FFF4)
-#define U8500_ASIC_ID_LOC_V2	(U8500_BOOT_ROM_BASE + 0x1DBF4)
-#define U8500_ASIC_REV_ED	0x01
-#define U8500_ASIC_REV_V10	0xA0
-#define U8500_ASIC_REV_V11	0xA1
-#define U8500_ASIC_REV_V20	0xB0
-
-/**
- * struct db8500_asic_id - fields of the ASIC ID
- * @process: the manufacturing process, 0x40 is 40 nm
- *  0x00 is "standard"
- * @partnumber: hithereto 0x8500 for DB8500
- * @revision: version code in the series
- * This field definion is not formally defined but makes
- * sense.
- */
-struct db8500_asic_id {
-	u8 process;
-	u16 partnumber;
-	u8 revision;
-};
-
-/* This isn't going to change at runtime */
-static struct db8500_asic_id db8500_id;
-
-static void __init get_db8500_asic_id(void)
-{
-	u32 asicid;
-
-	if (cpu_is_u8500v1() || cpu_is_u8500ed())
-		asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1));
-	else if (cpu_is_u8500v2())
-		asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2));
-	else
-		BUG();
-
-	db8500_id.process = (asicid >> 24);
-	db8500_id.partnumber = (asicid >> 16) & 0xFFFFU;
-	db8500_id.revision = asicid & 0xFFU;
-}
-
-bool cpu_is_u8500v10(void)
-{
-	return (db8500_id.revision == U8500_ASIC_REV_V10);
-}
-
-bool cpu_is_u8500v11(void)
-{
-	return (db8500_id.revision == U8500_ASIC_REV_V11);
-}
-
-bool cpu_is_u8500v20(void)
-{
-	return (db8500_id.revision == U8500_ASIC_REV_V20);
-}
-
 void __init u8500_map_io(void)
 {
+	/*
+	 * Map the UARTs early so that the DEBUG_LL stuff continues to work.
+	 */
+	iotable_init(u8500_uart_io_desc, ARRAY_SIZE(u8500_uart_io_desc));
+
 	ux500_map_io();
 
 	iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
@@ -127,9 +87,6 @@ void __init u8500_map_io(void)
 		iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
 	else if (cpu_is_u8500v2())
 		iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
-
-	/* Read out the ASIC ID as early as we can */
-	get_db8500_asic_id();
 }
 
 static resource_size_t __initdata db8500_gpio_base[] = {
@@ -159,20 +116,6 @@ static void __init db8500_add_gpios(void)
  */
 void __init u8500_init_devices(void)
 {
-	/* Display some ASIC boilerplate */
-	pr_info("DB8500: process: %02x, revision ID: 0x%02x\n",
-		db8500_id.process, db8500_id.revision);
-	if (cpu_is_u8500ed())
-		pr_info("DB8500: Early Drop (ED)\n");
-	else if (cpu_is_u8500v10())
-		pr_info("DB8500: version 1.0\n");
-	else if (cpu_is_u8500v11())
-		pr_info("DB8500: version 1.1\n");
-	else if (cpu_is_u8500v20())
-		pr_info("DB8500: version 2.0\n");
-	else
-		pr_warning("ASIC: UNKNOWN SILICON VERSION!\n");
-
 	if (cpu_is_u8500ed())
 		dma40_u8500ed_fixup();
 

+ 39 - 39
arch/arm/mach-ux500/cpu.c

@@ -23,37 +23,25 @@
 
 #include "clock.h"
 
-static struct map_desc ux500_io_desc[] __initdata = {
-	__IO_DEV_DESC(UX500_UART0_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_UART2_BASE, SZ_4K),
-
-	__IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_TWD_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_SCU_BASE, SZ_4K),
-
-	__IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K),
-
-	__IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K),
-	__IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K),
-
-	__IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K),
-};
-
-void __init ux500_map_io(void)
-{
-	iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
-}
+#ifdef CONFIG_CACHE_L2X0
+static void __iomem *l2x0_base;
+#endif
 
 void __init ux500_init_irq(void)
 {
-	gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE),
-		 __io_address(UX500_GIC_CPU_BASE));
+	void __iomem *dist_base;
+	void __iomem *cpu_base;
+
+	if (cpu_is_u5500()) {
+		dist_base = __io_address(U5500_GIC_DIST_BASE);
+		cpu_base = __io_address(U5500_GIC_CPU_BASE);
+	} else if (cpu_is_u8500()) {
+		dist_base = __io_address(U8500_GIC_DIST_BASE);
+		cpu_base = __io_address(U8500_GIC_CPU_BASE);
+	} else
+		ux500_unknown_soc();
+
+	gic_init(0, 29, dist_base, cpu_base);
 
 	/*
 	 * Init clocks here so that they are available for system timer
@@ -74,7 +62,8 @@ static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
 
 static inline void ux500_cache_sync(void)
 {
-	void __iomem *base = __io_address(UX500_L2CC_BASE);
+	void __iomem *base = l2x0_base;
+
 	writel_relaxed(0, base + L2X0_CACHE_SYNC);
 	ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
 }
@@ -96,20 +85,23 @@ static void ux500_l2x0_disable(void)
  */
 static void ux500_l2x0_inv_all(void)
 {
-	void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE);
+	void __iomem *base = l2x0_base;
 	uint32_t l2x0_way_mask = (1<<16) - 1;	/* Bitmask of active ways */
 
 	/* invalidate all ways */
-	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
-	ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
+	writel_relaxed(l2x0_way_mask, base + L2X0_INV_WAY);
+	ux500_cache_wait(base + L2X0_INV_WAY, l2x0_way_mask);
 	ux500_cache_sync();
 }
 
 static int ux500_l2x0_init(void)
 {
-	void __iomem *l2x0_base;
-
-	l2x0_base = __io_address(UX500_L2CC_BASE);
+	if (cpu_is_u5500())
+		l2x0_base = __io_address(U5500_L2CC_BASE);
+	else if (cpu_is_u8500())
+		l2x0_base = __io_address(U8500_L2CC_BASE);
+	else
+		ux500_unknown_soc();
 
 	/* 64KB way size, 8 way associativity, force WA */
 	l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
@@ -127,13 +119,21 @@ static void __init ux500_timer_init(void)
 {
 #ifdef CONFIG_LOCAL_TIMERS
 	/* Setup the local timer base */
-	twd_base = __io_address(UX500_TWD_BASE);
+	if (cpu_is_u5500())
+		twd_base = __io_address(U5500_TWD_BASE);
+	else if (cpu_is_u8500())
+		twd_base = __io_address(U8500_TWD_BASE);
+	else
+		ux500_unknown_soc();
 #endif
-	/* Setup the MTU base */
-	if (cpu_is_u8500ed())
+	if (cpu_is_u5500())
+		mtu_base = __io_address(U5500_MTU0_BASE);
+	else if (cpu_is_u8500ed())
 		mtu_base = __io_address(U8500_MTU0_BASE_ED);
+	else if (cpu_is_u8500())
+		mtu_base = __io_address(U8500_MTU0_BASE);
 	else
-		mtu_base = __io_address(UX500_MTU0_BASE);
+		ux500_unknown_soc();
 
 	nmdk_timer_init();
 }

+ 107 - 0
arch/arm/mach-ux500/id.c

@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+struct dbx500_asic_id dbx500_id;
+
+static unsigned int ux500_read_asicid(phys_addr_t addr)
+{
+	phys_addr_t base = addr & ~0xfff;
+	struct map_desc desc = {
+		.virtual	= IO_ADDRESS(base),
+		.pfn		= __phys_to_pfn(base),
+		.length		= SZ_16K,
+		.type		= MT_DEVICE,
+	};
+
+	iotable_init(&desc, 1);
+
+	/* As in devicemaps_init() */
+	local_flush_tlb_all();
+	flush_cache_all();
+
+	return readl(__io_address(addr));
+}
+
+static void ux500_print_soc_info(unsigned int asicid)
+{
+	unsigned int rev = dbx500_revision();
+
+	pr_info("DB%4x ", dbx500_partnumber());
+
+	if (rev == 0x01)
+		pr_cont("Early Drop");
+	else if (rev >= 0xA0)
+		pr_cont("v%d.%d" , (rev >> 4) - 0xA + 1, rev & 0xf);
+	else
+		pr_cont("Unknown");
+
+	pr_cont(" [%#010x]\n", asicid);
+}
+
+static unsigned int partnumber(unsigned int asicid)
+{
+	return (asicid >> 8) & 0xffff;
+}
+
+/*
+ * SOC		MIDR		ASICID ADDRESS		ASICID VALUE
+ * DB8500ed	0x410fc090	0x9001FFF4		0x00850001
+ * DB8500v1	0x411fc091	0x9001FFF4		0x008500A0
+ * DB8500v1.1	0x411fc091	0x9001FFF4		0x008500A1
+ * DB8500v2	0x412fc091	0x9001DBF4		0x008500B0
+ * DB5500v1	0x412fc091	0x9001FFF4		0x005500A0
+ */
+
+void __init ux500_map_io(void)
+{
+	unsigned int cpuid = read_cpuid_id();
+	unsigned int asicid = 0;
+	phys_addr_t addr = 0;
+
+	switch (cpuid) {
+	case 0x410fc090: /* DB8500ed */
+	case 0x411fc091: /* DB8500v1 */
+		addr = 0x9001FFF4;
+		break;
+
+	case 0x412fc091: /* DB8500v2 / DB5500v1 */
+		asicid = ux500_read_asicid(0x9001DBF4);
+		if (partnumber(asicid) == 0x8500)
+			/* DB8500v2 */
+			break;
+
+		/* DB5500v1 */
+		addr = 0x9001FFF4;
+		break;
+	}
+
+	if (addr)
+		asicid = ux500_read_asicid(addr);
+
+	if (!asicid) {
+		pr_err("Unable to identify SoC\n");
+		ux500_unknown_soc();
+	}
+
+	dbx500_id.process = asicid >> 24;
+	dbx500_id.partnumber = partnumber(asicid);
+	dbx500_id.revision = asicid & 0xff;
+
+	ux500_print_soc_info(asicid);
+}

+ 18 - 1
arch/arm/mach-ux500/include/mach/debug-macro.S

@@ -14,7 +14,24 @@
 #error Invalid Ux500 debug UART
 #endif
 
-#define __UX500_UART(n)	UX500_UART##n##_BASE
+/*
+ * DEBUG_LL only works if only one SOC is built in.  We don't use #else below
+ * in order to get "__UX500_UART redefined" warnings if more than one SOC is
+ * built, so that there's some hint during the build that something is wrong.
+ */
+
+#ifdef CONFIG_UX500_SOC_DB5500
+#define __UX500_UART(n)	U5500_UART##n##_BASE
+#endif
+
+#ifdef CONFIG_UX500_SOC_DB8500
+#define __UX500_UART(n)	U8500_UART##n##_BASE
+#endif
+
+#ifndef __UX500_UART
+#error Unknown SOC
+#endif
+
 #define UX500_UART(n)	__UX500_UART(n)
 #define UART_BASE	UX500_UART(CONFIG_UX500_DEBUG_UART)
 

+ 0 - 5
arch/arm/mach-ux500/include/mach/entry-macro.S

@@ -11,15 +11,10 @@
  * warranty of any kind, whether express or implied.
  */
 #include <mach/hardware.h>
-#define HAVE_GET_IRQNR_PREAMBLE
 #include <asm/hardware/entry-macro-gic.S>
 
 		.macro	disable_fiq
 		.endm
 
-		.macro  get_irqnr_preamble, base, tmp
-		ldr     \base, =IO_ADDRESS(UX500_GIC_CPU_BASE)
-		.endm
-
 		.macro  arch_ret_to_user, tmp1, tmp2
 		.endm

+ 1 - 107
arch/arm/mach-ux500/include/mach/hardware.h

@@ -29,118 +29,12 @@
 #include <mach/db8500-regs.h>
 #include <mach/db5500-regs.h>
 
-#ifdef CONFIG_UX500_SOC_DB8500
-#define UX500(periph)		U8500_##periph##_BASE
-#elif defined(CONFIG_UX500_SOC_DB5500)
-#define UX500(periph)		U5500_##periph##_BASE
-#endif
-
-#define UX500_BACKUPRAM0_BASE	UX500(BACKUPRAM0)
-#define UX500_BACKUPRAM1_BASE	UX500(BACKUPRAM1)
-#define UX500_B2R2_BASE		UX500(B2R2)
-
-#define UX500_CLKRST1_BASE	UX500(CLKRST1)
-#define UX500_CLKRST2_BASE	UX500(CLKRST2)
-#define UX500_CLKRST3_BASE	UX500(CLKRST3)
-#define UX500_CLKRST5_BASE	UX500(CLKRST5)
-#define UX500_CLKRST6_BASE	UX500(CLKRST6)
-
-#define UX500_DMA_BASE		UX500(DMA)
-#define UX500_FSMC_BASE		UX500(FSMC)
-
-#define UX500_GIC_CPU_BASE	UX500(GIC_CPU)
-#define UX500_GIC_DIST_BASE	UX500(GIC_DIST)
-
-#define UX500_I2C1_BASE		UX500(I2C1)
-#define UX500_I2C2_BASE		UX500(I2C2)
-#define UX500_I2C3_BASE		UX500(I2C3)
-
-#define UX500_L2CC_BASE		UX500(L2CC)
-#define UX500_MCDE_BASE		UX500(MCDE)
-#define UX500_MTU0_BASE		UX500(MTU0)
-#define UX500_MTU1_BASE		UX500(MTU1)
-#define UX500_PRCMU_BASE	UX500(PRCMU)
-
-#define UX500_RNG_BASE		UX500(RNG)
-#define UX500_RTC_BASE		UX500(RTC)
-
-#define UX500_SCU_BASE		UX500(SCU)
-
-#define UX500_SDI0_BASE		UX500(SDI0)
-#define UX500_SDI1_BASE		UX500(SDI1)
-#define UX500_SDI2_BASE		UX500(SDI2)
-#define UX500_SDI3_BASE		UX500(SDI3)
-#define UX500_SDI4_BASE		UX500(SDI4)
-
-#define UX500_SPI0_BASE		UX500(SPI0)
-#define UX500_SPI1_BASE		UX500(SPI1)
-#define UX500_SPI2_BASE		UX500(SPI2)
-#define UX500_SPI3_BASE		UX500(SPI3)
-
-#define UX500_SIA_BASE		UX500(SIA)
-#define UX500_SVA_BASE		UX500(SVA)
-
-#define UX500_TWD_BASE		UX500(TWD)
-
-#define UX500_UART0_BASE	UX500(UART0)
-#define UX500_UART1_BASE	UX500(UART1)
-#define UX500_UART2_BASE	UX500(UART2)
-
-#define UX500_USBOTG_BASE	UX500(USBOTG)
-
 /* ST-Ericsson modified pl022 id */
 #define SSP_PER_ID		0x01080022
 
 #ifndef __ASSEMBLY__
 
-#include <asm/cputype.h>
-
-static inline bool cpu_is_u8500(void)
-{
-#ifdef CONFIG_UX500_SOC_DB8500
-	return 1;
-#else
-	return 0;
-#endif
-}
-
-#define CPUID_DB8500ED	0x410fc090
-#define CPUID_DB8500V1	0x411fc091
-#define CPUID_DB8500V2	0x412fc091
-
-static inline bool cpu_is_u8500ed(void)
-{
-	return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED);
-}
-
-static inline bool cpu_is_u8500v1(void)
-{
-	return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1);
-}
-
-static inline bool cpu_is_u8500v2(void)
-{
-	return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2);
-}
-
-#ifdef CONFIG_UX500_SOC_DB8500
-bool cpu_is_u8500v10(void);
-bool cpu_is_u8500v11(void);
-bool cpu_is_u8500v20(void);
-#else
-static inline bool cpu_is_u8500v10(void) { return false; }
-static inline bool cpu_is_u8500v11(void) { return false; }
-static inline bool cpu_is_u8500v20(void) { return false; }
-#endif
-
-static inline bool cpu_is_u5500(void)
-{
-#ifdef CONFIG_UX500_SOC_DB5500
-	return 1;
-#else
-	return 0;
-#endif
-}
+#include <mach/id.h>
 
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
 

+ 80 - 0
arch/arm/mach-ux500/include/mach/id.h

@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_UX500_ID
+#define __MACH_UX500_ID
+
+/**
+ * struct dbx500_asic_id - fields of the ASIC ID
+ * @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard"
+ * @partnumber: hithereto 0x8500 for DB8500
+ * @revision: version code in the series
+ */
+struct dbx500_asic_id {
+	u16	partnumber;
+	u8	revision;
+	u8	process;
+};
+
+extern struct dbx500_asic_id dbx500_id;
+
+static inline unsigned int __attribute_const__ dbx500_partnumber(void)
+{
+	return dbx500_id.partnumber;
+}
+
+static inline unsigned int __attribute_const__ dbx500_revision(void)
+{
+	return dbx500_id.revision;
+}
+
+/*
+ * SOCs
+ */
+
+static inline bool __attribute_const__ cpu_is_u8500(void)
+{
+	return dbx500_partnumber() == 0x8500;
+}
+
+static inline bool __attribute_const__ cpu_is_u5500(void)
+{
+	return dbx500_partnumber() == 0x5500;
+}
+
+/*
+ * 8500 revisions
+ */
+
+static inline bool __attribute_const__ cpu_is_u8500ed(void)
+{
+	return cpu_is_u8500() && dbx500_revision() == 0x00;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v1(void)
+{
+	return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v10(void)
+{
+	return cpu_is_u8500() && dbx500_revision() == 0xA0;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v11(void)
+{
+	return cpu_is_u8500() && dbx500_revision() == 0xA1;
+}
+
+static inline bool __attribute_const__ cpu_is_u8500v2(void)
+{
+	return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0);
+}
+
+#define ux500_unknown_soc()	BUG()
+
+#endif

+ 1 - 1
arch/arm/mach-ux500/include/mach/irqs.h

@@ -36,7 +36,7 @@
 /* This will be overridden by board-specific irq headers */
 #define IRQ_BOARD_END			IRQ_BOARD_START
 
-#ifdef CONFIG_MACH_U8500_MOP
+#ifdef CONFIG_MACH_U8500
 #include <mach/irqs-board-mop500.h>
 #endif
 

+ 1 - 1
arch/arm/mach-ux500/include/mach/setup.h

@@ -14,7 +14,7 @@
 #include <asm/mach/time.h>
 #include <linux/init.h>
 
-extern void __init ux500_map_io(void);
+void __init ux500_map_io(void);
 extern void __init u5500_map_io(void);
 extern void __init u8500_map_io(void);
 

+ 5 - 0
arch/arm/mach-ux500/modem-irq-db5500.c

@@ -12,6 +12,8 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 
+#include <mach/id.h>
+
 #define MODEM_INTCON_BASE_ADDR 0xBFFD3000
 #define MODEM_INTCON_SIZE 0xFFF
 
@@ -101,6 +103,9 @@ static int modem_irq_init(void)
 	static struct irq_chip  modem_irq_chip;
 	struct modem_irq *mi;
 
+	if (!cpu_is_u5500())
+		return -ENODEV;
+
 	pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n",
 		   IRQ_DB5500_MODEM);
 

+ 29 - 8
arch/arm/mach-ux500/platsmp.c

@@ -20,6 +20,7 @@
 #include <asm/cacheflush.h>
 #include <asm/smp_scu.h>
 #include <mach/hardware.h>
+#include <mach/setup.h>
 
 /*
  * control for which core is the next to come out of the secondary
@@ -40,6 +41,18 @@ static void write_pen_release(int val)
 	outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
 }
 
+static void __iomem *scu_base_addr(void)
+{
+	if (cpu_is_u5500())
+		return __io_address(U5500_SCU_BASE);
+	else if (cpu_is_u8500())
+		return __io_address(U8500_SCU_BASE);
+	else
+		ux500_unknown_soc();
+
+	return NULL;
+}
+
 static DEFINE_SPINLOCK(boot_lock);
 
 void __cpuinit platform_secondary_init(unsigned int cpu)
@@ -100,21 +113,28 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 
 static void __init wakeup_secondary(void)
 {
+	void __iomem *backupram;
+
+	if (cpu_is_u5500())
+		backupram = __io_address(U5500_BACKUPRAM0_BASE);
+	else if (cpu_is_u8500())
+		backupram = __io_address(U8500_BACKUPRAM0_BASE);
+	else
+		ux500_unknown_soc();
+
 	/*
 	 * write the address of secondary startup into the backup ram register
 	 * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
 	 * backup ram register at offset 0x1FF0, which is what boot rom code
 	 * is waiting for. This would wake up the secondary core from WFE
 	 */
-#define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4
+#define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4
 	__raw_writel(virt_to_phys(u8500_secondary_startup),
-		__io_address(UX500_BACKUPRAM0_BASE) +
-		U8500_CPU1_JUMPADDR_OFFSET);
+		     backupram + UX500_CPU1_JUMPADDR_OFFSET);
 
-#define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
+#define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
 	__raw_writel(0xA1FEED01,
-		__io_address(UX500_BACKUPRAM0_BASE) +
-		U8500_CPU1_WAKEMAGIC_OFFSET);
+		     backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
 
 	/* make sure write buffer is drained */
 	mb();
@@ -126,9 +146,10 @@ static void __init wakeup_secondary(void)
  */
 void __init smp_init_cpus(void)
 {
+	void __iomem *scu_base = scu_base_addr();
 	unsigned int i, ncores;
 
-	ncores = scu_get_core_count(__io_address(UX500_SCU_BASE));
+	ncores = scu_base ? scu_get_core_count(scu_base) : 1;
 
 	/* sanity check */
 	if (ncores > NR_CPUS) {
@@ -154,6 +175,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 	for (i = 0; i < max_cpus; i++)
 		set_cpu_present(i, true);
 
-	scu_enable(__io_address(UX500_SCU_BASE));
+	scu_enable(scu_base_addr());
 	wakeup_secondary();
 }