Browse Source

Merge tag 'integrator-for-v3.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator into next/soc

From Linus Walleij:
Integrator patches for the v3.13 kernel cycle:
- Fix up the LED support
- Update the Integrator defconfig
- Remove ATAG boot path
- Move some stuff over to the device tree

* tag 'integrator-for-v3.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator:
  ARM: integrator: core module registers from compatible strings
  ARM: integrator: use devm_ioremap() to remap CM
  cpufreq: probe the Integrator cpufreq driver from DT
  ARM: integrator: move CM base into device tree
  ARM: integrator: decommission the <mach/irqs.h> header
  ARM: integrator: delete non-devicetree boot path
  ARM: integrator: print the Linux IRQ in LL_DEBUG code
  ARM: integrator: get the LM interrupts from DT
  ARM: integrator: update defconfig
  ARM: integrator: get the CM control register by proxy

Signed-off-by: Kevin Hilman <khilman@linaro.org>
Kevin Hilman 11 years ago
parent
commit
7bc13d78c6

+ 47 - 3
Documentation/devicetree/bindings/arm/arm-boards

@@ -9,9 +9,53 @@ Required properties (in root node):
 
 FPGA type interrupt controllers, see the versatile-fpga-irq binding doc.
 
-In the root node the Integrator/CP must have a /cpcon node pointing
-to the CP control registers, and the Integrator/AP must have a
-/syscon node pointing to the Integrator/AP system controller.
+Required nodes:
+
+- core-module: the root node to the Integrator platforms must have
+  a core-module with regs and the compatible string
+  "arm,core-module-integrator"
+
+  Required properties for the core module:
+  - regs: the location and size of the core module registers, one
+    range of 0x200 bytes.
+
+- syscon: the root node of the Integrator platforms must have a
+  system controller node pointong to the control registers,
+  with the compatible string
+  "arm,integrator-ap-syscon"
+  "arm,integrator-cp-syscon"
+  respectively.
+
+  Required properties for the system controller:
+  - regs: the location and size of the system controller registers,
+    one range of 0x100 bytes.
+
+  Required properties for the AP system controller:
+  - interrupts: the AP syscon node must include the logical module
+    interrupts, stated in order of module instance <module 0>,
+    <module 1>, <module 2> ... for the CP system controller this
+    is not required not of any use.
+
+/dts-v1/;
+/include/ "integrator.dtsi"
+
+/ {
+	model = "ARM Integrator/AP";
+	compatible = "arm,integrator-ap";
+
+	core-module@10000000 {
+		compatible = "arm,core-module-integrator";
+		reg = <0x10000000 0x200>;
+	};
+
+	syscon {
+		compatible = "arm,integrator-ap-syscon";
+		reg = <0x11000000 0x100>;
+		interrupt-parent = <&pic>;
+		/* These are the logic module IRQs */
+		interrupts = <9>, <10>, <11>, <12>;
+	};
+};
 
 
 ARM Versatile Application and Platform Baseboards

+ 1 - 0
arch/arm/Kconfig

@@ -317,6 +317,7 @@ config ARCH_INTEGRATOR
 	select NEED_MACH_MEMORY_H
 	select PLAT_VERSATILE
 	select SPARSE_IRQ
+	select USE_OF
 	select VERSATILE_FPGA_IRQ
 	help
 	  Support for ARM's Integrator platform.

+ 5 - 0
arch/arm/boot/dts/integrator.dtsi

@@ -5,6 +5,11 @@
 /include/ "skeleton.dtsi"
 
 / {
+	core-module@10000000 {
+		compatible = "arm,core-module-integrator";
+		reg = <0x10000000 0x200>;
+	};
+
 	timer@13000000 {
 		reg = <0x13000000 0x100>;
 		interrupt-parent = <&pic>;

+ 4 - 1
arch/arm/boot/dts/integratorap.dts

@@ -19,8 +19,11 @@
 	};
 
 	syscon {
-		/* AP system controller registers */
+		compatible = "arm,integrator-ap-syscon";
 		reg = <0x11000000 0x100>;
+		interrupt-parent = <&pic>;
+		/* These are the logical module IRQs */
+		interrupts = <9>, <10>, <11>, <12>;
 	};
 
 	timer0: timer@13000000 {

+ 2 - 2
arch/arm/boot/dts/integratorcp.dts

@@ -18,8 +18,8 @@
 		bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk";
 	};
 
-	cpcon {
-		/* CP controller registers */
+	syscon {
+		compatible = "arm,integrator-cp-syscon";
 		reg = <0xcb000000 0x100>;
 	};
 

+ 12 - 13
arch/arm/configs/integrator_defconfig

@@ -1,15 +1,17 @@
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
-CONFIG_TINY_RCU=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_INTEGRATOR=y
 CONFIG_ARCH_INTEGRATOR_AP=y
 CONFIG_ARCH_INTEGRATOR_CP=y
+CONFIG_INTEGRATOR_IMPD1=y
 CONFIG_CPU_ARM720T=y
 CONFIG_CPU_ARM920T=y
 CONFIG_CPU_ARM922T=y
@@ -18,12 +20,9 @@ CONFIG_CPU_ARM1020=y
 CONFIG_CPU_ARM1022=y
 CONFIG_CPU_ARM1026=y
 CONFIG_PCI=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
+# CONFIG_ATAGS is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="console=ttyAM0,38400n8 root=/dev/nfs ip=bootp"
@@ -44,24 +43,20 @@ CONFIG_IP_PNP_BOOTP=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_PHYSMAP=y
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NET_PCI=y
 CONFIG_E100=y
 CONFIG_SMC91X=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_AMBA_PL010=y
-CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
 CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_ARMCLCD=y
@@ -71,19 +66,23 @@ CONFIG_FB_MATROX_MYSTIQUE=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_MMC=y
 CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PL030=y
+CONFIG_COMMON_CLK_DEBUG=y
 CONFIG_EXT2_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
 CONFIG_CRAMFS=y
 CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_NFSD=y
 CONFIG_NFSD_V3=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_MAGIC_SYSRQ=y

+ 5 - 2
arch/arm/mach-integrator/include/mach/cm.h → arch/arm/mach-integrator/cm.h

@@ -1,9 +1,12 @@
 /*
- * update the core module control register.
+ * access the core module control register.
  */
+u32 cm_get(void);
 void cm_control(u32, u32);
 
-#define CM_CTRL	__io_address(INTEGRATOR_HDR_CTRL)
+struct device_node;
+void cm_init(void);
+void cm_clear_irqs(void);
 
 #define CM_CTRL_LED			(1 << 0)
 #define CM_CTRL_nMBDET			(1 << 1)

+ 83 - 99
arch/arm/mach-integrator/core.c

@@ -22,77 +22,30 @@
 #include <linux/amba/serial.h>
 #include <linux/io.h>
 #include <linux/stat.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <mach/cm.h>
-#include <mach/irqs.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/time.h>
 #include <asm/pgtable.h>
 
+#include "cm.h"
 #include "common.h"
 
-#ifdef CONFIG_ATAGS
-
-#define INTEGRATOR_RTC_IRQ	{ IRQ_RTCINT }
-#define INTEGRATOR_UART0_IRQ	{ IRQ_UARTINT0 }
-#define INTEGRATOR_UART1_IRQ	{ IRQ_UARTINT1 }
-#define KMI0_IRQ		{ IRQ_KMIINT0 }
-#define KMI1_IRQ		{ IRQ_KMIINT1 }
-
-static AMBA_APB_DEVICE(rtc, "rtc", 0,
-	INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
-
-static AMBA_APB_DEVICE(uart0, "uart0", 0,
-	INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, NULL);
-
-static AMBA_APB_DEVICE(uart1, "uart1", 0,
-	INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, NULL);
-
-static AMBA_APB_DEVICE(kmi0, "kmi0", 0, KMI0_BASE, KMI0_IRQ, NULL);
-static AMBA_APB_DEVICE(kmi1, "kmi1", 0, KMI1_BASE, KMI1_IRQ, NULL);
-
-static struct amba_device *amba_devs[] __initdata = {
-	&rtc_device,
-	&uart0_device,
-	&uart1_device,
-	&kmi0_device,
-	&kmi1_device,
-};
+static DEFINE_RAW_SPINLOCK(cm_lock);
+static void __iomem *cm_base;
 
-int __init integrator_init(bool is_cp)
+/**
+ * cm_get - get the value from the CM_CTRL register
+ */
+u32 cm_get(void)
 {
-	int i;
-
-	/*
-	 * The Integrator/AP lacks necessary AMBA PrimeCell IDs, so we need to
-	 * hard-code them. The Integator/CP and forward have proper cell IDs.
-	 * Else we leave them undefined to the bus driver can autoprobe them.
-	 */
-	if (!is_cp && IS_ENABLED(CONFIG_ARCH_INTEGRATOR_AP)) {
-		rtc_device.periphid	= 0x00041030;
-		uart0_device.periphid	= 0x00041010;
-		uart1_device.periphid	= 0x00041010;
-		kmi0_device.periphid	= 0x00041050;
-		kmi1_device.periphid	= 0x00041050;
-		uart0_device.dev.platform_data = &ap_uart_data;
-		uart1_device.dev.platform_data = &ap_uart_data;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-		struct amba_device *d = amba_devs[i];
-		amba_device_register(d, &iomem_resource);
-	}
-
-	return 0;
+	return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
 }
 
-#endif
-
-static DEFINE_RAW_SPINLOCK(cm_lock);
-
 /**
  * cm_control - update the CM_CTRL register.
  * @mask: bits to change
@@ -104,12 +57,80 @@ void cm_control(u32 mask, u32 set)
 	u32 val;
 
 	raw_spin_lock_irqsave(&cm_lock, flags);
-	val = readl(CM_CTRL) & ~mask;
-	writel(val | set, CM_CTRL);
+	val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask;
+	writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
 	raw_spin_unlock_irqrestore(&cm_lock, flags);
 }
 
-EXPORT_SYMBOL(cm_control);
+static const char *integrator_arch_str(u32 id)
+{
+	switch ((id >> 16) & 0xff) {
+	case 0x00:
+		return "ASB little-endian";
+	case 0x01:
+		return "AHB little-endian";
+	case 0x03:
+		return "AHB-Lite system bus, bi-endian";
+	case 0x04:
+		return "AHB";
+	case 0x08:
+		return "AHB system bus, ASB processor bus";
+	default:
+		return "Unknown";
+	}
+}
+
+static const char *integrator_fpga_str(u32 id)
+{
+	switch ((id >> 12) & 0xf) {
+	case 0x01:
+		return "XC4062";
+	case 0x02:
+		return "XC4085";
+	case 0x03:
+		return "XVC600";
+	case 0x04:
+		return "EPM7256AE (Altera PLD)";
+	default:
+		return "Unknown";
+	}
+}
+
+void cm_clear_irqs(void)
+{
+	/* disable core module IRQs */
+	writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET +
+		IRQ_ENABLE_CLEAR);
+}
+
+static const struct of_device_id cm_match[] = {
+	{ .compatible = "arm,core-module-integrator"},
+	{ },
+};
+
+void cm_init(void)
+{
+	struct device_node *cm = of_find_matching_node(NULL, cm_match);
+	u32 val;
+
+	if (!cm) {
+		pr_crit("no core module node found in device tree\n");
+		return;
+	}
+	cm_base = of_iomap(cm, 0);
+	if (!cm_base) {
+		pr_crit("could not remap core module\n");
+		return;
+	}
+	cm_clear_irqs();
+	val = readl(cm_base + INTEGRATOR_HDR_ID_OFFSET);
+	pr_info("Detected ARM core module:\n");
+	pr_info("    Manufacturer: %02x\n", (val >> 24));
+	pr_info("    Architecture: %s\n", integrator_arch_str(val));
+	pr_info("    FPGA: %s\n", integrator_fpga_str(val));
+	pr_info("    Build: %02x\n", (val >> 4) & 0xFF);
+	pr_info("    Rev: %c\n", ('A' + (val & 0x03)));
+}
 
 /*
  * We need to stop things allocating the low memory; ideally we need a
@@ -145,27 +166,7 @@ static ssize_t intcp_get_arch(struct device *dev,
 			      struct device_attribute *attr,
 			      char *buf)
 {
-	const char *arch;
-
-	switch ((integrator_id >> 16) & 0xff) {
-	case 0x00:
-		arch = "ASB little-endian";
-		break;
-	case 0x01:
-		arch = "AHB little-endian";
-		break;
-	case 0x03:
-		arch = "AHB-Lite system bus, bi-endian";
-		break;
-	case 0x04:
-		arch = "AHB";
-		break;
-	default:
-		arch = "Unknown";
-		break;
-	}
-
-	return sprintf(buf, "%s\n", arch);
+	return sprintf(buf, "%s\n", integrator_arch_str(integrator_id));
 }
 
 static struct device_attribute intcp_arch_attr =
@@ -175,24 +176,7 @@ static ssize_t intcp_get_fpga(struct device *dev,
 			      struct device_attribute *attr,
 			      char *buf)
 {
-	const char *fpga;
-
-	switch ((integrator_id >> 12) & 0xf) {
-	case 0x01:
-		fpga = "XC4062";
-		break;
-	case 0x02:
-		fpga = "XC4085";
-		break;
-	case 0x04:
-		fpga = "EPM7256AE (Altera PLD)";
-		break;
-	default:
-		fpga = "Unknown";
-		break;
-	}
-
-	return sprintf(buf, "%s\n", fpga);
+	return sprintf(buf, "%s\n", integrator_fpga_str(integrator_id));
 }
 
 static struct device_attribute intcp_fpga_attr =

+ 0 - 81
arch/arm/mach-integrator/include/mach/irqs.h

@@ -1,81 +0,0 @@
-/*
- *  arch/arm/mach-integrator/include/mach/irqs.h
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-/*
- * Interrupt numbers, all of the above are just static reservations
- * used so they can be encoded into device resources. They will finally
- * be done away with when switching to device tree.
- */
-#define IRQ_PIC_START			64
-#define IRQ_SOFTINT			(IRQ_PIC_START+0)
-#define IRQ_UARTINT0			(IRQ_PIC_START+1)
-#define IRQ_UARTINT1			(IRQ_PIC_START+2)
-#define IRQ_KMIINT0			(IRQ_PIC_START+3)
-#define IRQ_KMIINT1			(IRQ_PIC_START+4)
-#define IRQ_TIMERINT0			(IRQ_PIC_START+5)
-#define IRQ_TIMERINT1			(IRQ_PIC_START+6)
-#define IRQ_TIMERINT2			(IRQ_PIC_START+7)
-#define IRQ_RTCINT			(IRQ_PIC_START+8)
-#define IRQ_AP_EXPINT0			(IRQ_PIC_START+9)
-#define IRQ_AP_EXPINT1			(IRQ_PIC_START+10)
-#define IRQ_AP_EXPINT2			(IRQ_PIC_START+11)
-#define IRQ_AP_EXPINT3			(IRQ_PIC_START+12)
-#define IRQ_AP_PCIINT0			(IRQ_PIC_START+13)
-#define IRQ_AP_PCIINT1			(IRQ_PIC_START+14)
-#define IRQ_AP_PCIINT2			(IRQ_PIC_START+15)
-#define IRQ_AP_PCIINT3			(IRQ_PIC_START+16)
-#define IRQ_AP_V3INT			(IRQ_PIC_START+17)
-#define IRQ_AP_CPINT0			(IRQ_PIC_START+18)
-#define IRQ_AP_CPINT1			(IRQ_PIC_START+19)
-#define IRQ_AP_LBUSTIMEOUT 		(IRQ_PIC_START+20)
-#define IRQ_AP_APCINT			(IRQ_PIC_START+21)
-#define IRQ_CP_CLCDCINT			(IRQ_PIC_START+22)
-#define IRQ_CP_MMCIINT0			(IRQ_PIC_START+23)
-#define IRQ_CP_MMCIINT1			(IRQ_PIC_START+24)
-#define IRQ_CP_AACIINT			(IRQ_PIC_START+25)
-#define IRQ_CP_CPPLDINT			(IRQ_PIC_START+26)
-#define IRQ_CP_ETHINT			(IRQ_PIC_START+27)
-#define IRQ_CP_TSPENINT			(IRQ_PIC_START+28)
-#define IRQ_PIC_END			(IRQ_PIC_START+28)
-
-#define IRQ_CIC_START			(IRQ_PIC_END+1)
-#define IRQ_CM_SOFTINT			(IRQ_CIC_START+0)
-#define IRQ_CM_COMMRX			(IRQ_CIC_START+1)
-#define IRQ_CM_COMMTX			(IRQ_CIC_START+2)
-#define IRQ_CIC_END			(IRQ_CIC_START+2)
-
-/*
- * IntegratorCP only
- */
-#define IRQ_SIC_START			(IRQ_CIC_END+1)
-#define IRQ_SIC_CP_SOFTINT		(IRQ_SIC_START+0)
-#define IRQ_SIC_CP_RI0			(IRQ_SIC_START+1)
-#define IRQ_SIC_CP_RI1			(IRQ_SIC_START+2)
-#define IRQ_SIC_CP_CARDIN		(IRQ_SIC_START+3)
-#define IRQ_SIC_CP_LMINT0		(IRQ_SIC_START+4)
-#define IRQ_SIC_CP_LMINT1		(IRQ_SIC_START+5)
-#define IRQ_SIC_CP_LMINT2		(IRQ_SIC_START+6)
-#define IRQ_SIC_CP_LMINT3		(IRQ_SIC_START+7)
-#define IRQ_SIC_CP_LMINT4		(IRQ_SIC_START+8)
-#define IRQ_SIC_CP_LMINT5		(IRQ_SIC_START+9)
-#define IRQ_SIC_CP_LMINT6		(IRQ_SIC_START+10)
-#define IRQ_SIC_CP_LMINT7		(IRQ_SIC_START+11)
-#define IRQ_SIC_END			(IRQ_SIC_START+11)

+ 11 - 141
arch/arm/mach-integrator/integrator_ap.c

@@ -51,13 +51,13 @@
 #include <asm/mach-types.h>
 
 #include <mach/lm.h>
-#include <mach/irqs.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
+#include "cm.h"
 #include "common.h"
 #include "pci_v3.h"
 
@@ -146,7 +146,7 @@ static int irq_suspend(void)
 static void irq_resume(void)
 {
 	/* disable all irq sources */
-	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+	cm_clear_irqs();
 	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
 	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 
@@ -402,8 +402,6 @@ void __init ap_init_early(void)
 {
 }
 
-#ifdef CONFIG_OF
-
 static void __init ap_of_timer_init(void)
 {
 	struct device_node *node;
@@ -450,8 +448,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = {
 
 static void __init ap_init_irq_of(void)
 {
-	/* disable core module IRQs */
-	writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
+	cm_init();
 	of_irq_init(fpga_irq_of_match);
 	integrator_clk_init(false);
 }
@@ -473,6 +470,11 @@ static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
 	{ /* sentinel */ },
 };
 
+static const struct of_device_id ap_syscon_match[] = {
+	{ .compatible = "arm,integrator-ap-syscon"},
+	{ },
+};
+
 static void __init ap_init_of(void)
 {
 	unsigned long sc_dec;
@@ -489,7 +491,8 @@ static void __init ap_init_of(void)
 	root = of_find_node_by_path("/");
 	if (!root)
 		return;
-	syscon = of_find_node_by_path("/syscon");
+
+	syscon = of_find_matching_node(root, ap_syscon_match);
 	if (!syscon)
 		return;
 
@@ -541,7 +544,7 @@ static void __init ap_init_of(void)
 		lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
 		lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
 		lmdev->resource.flags = IORESOURCE_MEM;
-		lmdev->irq = IRQ_AP_EXPINT0 + i;
+		lmdev->irq = irq_of_parse_and_map(syscon, i);
 		lmdev->id = i;
 
 		lm_device_register(lmdev);
@@ -564,136 +567,3 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
 	.restart	= integrator_restart,
 	.dt_compat      = ap_dt_board_compat,
 MACHINE_END
-
-#endif
-
-#ifdef CONFIG_ATAGS
-
-/*
- * For the ATAG boot some static mappings are needed. This will
- * go away with the ATAG support down the road.
- */
-
-static struct map_desc ap_io_desc_atag[] __initdata = {
-	{
-		.virtual	= IO_ADDRESS(INTEGRATOR_SC_BASE),
-		.pfn		= __phys_to_pfn(INTEGRATOR_SC_BASE),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE
-	},
-};
-
-static void __init ap_map_io_atag(void)
-{
-	iotable_init(ap_io_desc_atag, ARRAY_SIZE(ap_io_desc_atag));
-	ap_map_io();
-}
-
-/*
- * This is where non-devicetree initialization code is collected and stashed
- * for eventual deletion.
- */
-
-static struct platform_device pci_v3_device = {
-	.name		= "pci-v3",
-	.id		= 0,
-};
-
-static struct resource cfi_flash_resource = {
-	.start		= INTEGRATOR_FLASH_BASE,
-	.end		= INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device cfi_flash_device = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &ap_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &cfi_flash_resource,
-};
-
-static void __init ap_timer_init(void)
-{
-	struct clk *clk;
-	unsigned long rate;
-
-	clk = clk_get_sys("ap_timer", NULL);
-	BUG_ON(IS_ERR(clk));
-	clk_prepare_enable(clk);
-	rate = clk_get_rate(clk);
-
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
-	integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
-	integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
-				IRQ_TIMERINT1);
-}
-
-#define INTEGRATOR_SC_VALID_INT	0x003fffff
-
-static void __init ap_init_irq(void)
-{
-	/* Disable all interrupts initially. */
-	/* Do the core module ones */
-	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
-
-	/* do the header card stuff next */
-	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
-	fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
-		-1, INTEGRATOR_SC_VALID_INT, NULL);
-	integrator_clk_init(false);
-}
-
-static void __init ap_init(void)
-{
-	unsigned long sc_dec;
-	int i;
-
-	platform_device_register(&pci_v3_device);
-	platform_device_register(&cfi_flash_device);
-
-	ap_syscon_base = __io_address(INTEGRATOR_SC_BASE);
-	sc_dec = readl(ap_syscon_base + INTEGRATOR_SC_DEC_OFFSET);
-	for (i = 0; i < 4; i++) {
-		struct lm_device *lmdev;
-
-		if ((sc_dec & (16 << i)) == 0)
-			continue;
-
-		lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL);
-		if (!lmdev)
-			continue;
-
-		lmdev->resource.start = 0xc0000000 + 0x10000000 * i;
-		lmdev->resource.end = lmdev->resource.start + 0x0fffffff;
-		lmdev->resource.flags = IORESOURCE_MEM;
-		lmdev->irq = IRQ_AP_EXPINT0 + i;
-		lmdev->id = i;
-
-		lm_device_register(lmdev);
-	}
-
-	integrator_init(false);
-}
-
-MACHINE_START(INTEGRATOR, "ARM-Integrator")
-	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-	.atag_offset	= 0x100,
-	.reserve	= integrator_reserve,
-	.map_io		= ap_map_io_atag,
-	.init_early	= ap_init_early,
-	.init_irq	= ap_init_irq,
-	.handle_irq	= fpga_handle_irq,
-	.init_time	= ap_timer_init,
-	.init_machine	= ap_init,
-	.restart	= integrator_restart,
-MACHINE_END
-
-#endif

+ 9 - 176
arch/arm/mach-integrator/integrator_cp.c

@@ -36,9 +36,7 @@
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
-#include <mach/cm.h>
 #include <mach/lm.h>
-#include <mach/irqs.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
@@ -50,6 +48,7 @@
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
 
+#include "cm.h"
 #include "common.h"
 
 /* Base address to the CP controller */
@@ -249,7 +248,6 @@ static void __init intcp_init_early(void)
 #endif
 }
 
-#ifdef CONFIG_OF
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
 	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
 	{ /* Sentinel */ }
@@ -257,6 +255,7 @@ static const struct of_device_id fpga_irq_of_match[] __initconst = {
 
 static void __init intcp_init_irq_of(void)
 {
+	cm_init();
 	of_irq_init(fpga_irq_of_match);
 	integrator_clk_init(true);
 }
@@ -287,6 +286,11 @@ static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
 	{ /* sentinel */ },
 };
 
+static const struct of_device_id intcp_syscon_match[] = {
+	{ .compatible = "arm,integrator-cp-syscon"},
+	{ },
+};
+
 static void __init intcp_init_of(void)
 {
 	struct device_node *root;
@@ -301,7 +305,8 @@ static void __init intcp_init_of(void)
 	root = of_find_node_by_path("/");
 	if (!root)
 		return;
-	cpcon = of_find_node_by_path("/cpcon");
+
+	cpcon = of_find_matching_node(root, intcp_syscon_match);
 	if (!cpcon)
 		return;
 
@@ -354,175 +359,3 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
 	.restart	= integrator_restart,
 	.dt_compat      = intcp_dt_board_compat,
 MACHINE_END
-
-#endif
-
-#ifdef CONFIG_ATAGS
-
-/*
- * For the ATAG boot some static mappings are needed. This will
- * go away with the ATAG support down the road.
- */
-
-static struct map_desc intcp_io_desc_atag[] __initdata = {
-	{
-		.virtual	= IO_ADDRESS(INTEGRATOR_CP_CTL_BASE),
-		.pfn		= __phys_to_pfn(INTEGRATOR_CP_CTL_BASE),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE
-	},
-};
-
-static void __init intcp_map_io_atag(void)
-{
-	iotable_init(intcp_io_desc_atag, ARRAY_SIZE(intcp_io_desc_atag));
-	intcp_con_base = __io_address(INTEGRATOR_CP_CTL_BASE);
-	intcp_map_io();
-}
-
-
-/*
- * This is where non-devicetree initialization code is collected and stashed
- * for eventual deletion.
- */
-
-#define INTCP_FLASH_SIZE		SZ_32M
-
-static struct resource intcp_flash_resource = {
-	.start		= INTCP_PA_FLASH_BASE,
-	.end		= INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1,
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device intcp_flash_device = {
-	.name		= "physmap-flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &intcp_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &intcp_flash_resource,
-};
-
-#define INTCP_ETH_SIZE			0x10
-
-static struct resource smc91x_resources[] = {
-	[0] = {
-		.start	= INTEGRATOR_CP_ETH_BASE,
-		.end	= INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_CP_ETHINT,
-		.end	= IRQ_CP_ETHINT,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device smc91x_device = {
-	.name		= "smc91x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(smc91x_resources),
-	.resource	= smc91x_resources,
-};
-
-static struct platform_device *intcp_devs[] __initdata = {
-	&intcp_flash_device,
-	&smc91x_device,
-};
-
-#define INTCP_VA_CIC_BASE		__io_address(INTEGRATOR_HDR_BASE + 0x40)
-#define INTCP_VA_PIC_BASE		__io_address(INTEGRATOR_IC_BASE)
-#define INTCP_VA_SIC_BASE		__io_address(INTEGRATOR_CP_SIC_BASE)
-
-static void __init intcp_init_irq(void)
-{
-	u32 pic_mask, cic_mask, sic_mask;
-
-	/* These masks are for the HW IRQ registers */
-	pic_mask = ~((~0u) << (11 - 0));
-	pic_mask |= (~((~0u) << (29 - 22))) << 22;
-	cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START));
-	sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START));
-
-	/*
-	 * Disable all interrupt sources
-	 */
-	writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR);
-	writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR);
-	writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR);
-	writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR);
-	writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR);
-	writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR);
-
-	fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START,
-		      -1, pic_mask, NULL);
-
-	fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START,
-		      -1, cic_mask, NULL);
-
-	fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START,
-		      IRQ_CP_CPPLDINT, sic_mask, NULL);
-
-	integrator_clk_init(true);
-}
-
-#define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE)
-#define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
-#define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
-
-static void __init cp_timer_init(void)
-{
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
-	sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
-	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
-}
-
-#define INTEGRATOR_CP_MMC_IRQS	{ IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
-#define INTEGRATOR_CP_AACI_IRQS	{ IRQ_CP_AACIINT }
-
-static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE,
-	INTEGRATOR_CP_MMC_IRQS, &mmc_data);
-
-static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE,
-	INTEGRATOR_CP_AACI_IRQS, NULL);
-
-static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE,
-	{ IRQ_CP_CLCDCINT }, &clcd_data);
-
-static struct amba_device *amba_devs[] __initdata = {
-	&mmc_device,
-	&aaci_device,
-	&clcd_device,
-};
-
-static void __init intcp_init(void)
-{
-	int i;
-
-	platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs));
-
-	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
-		struct amba_device *d = amba_devs[i];
-		amba_device_register(d, &iomem_resource);
-	}
-	integrator_init(true);
-}
-
-MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
-	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-	.atag_offset	= 0x100,
-	.reserve	= integrator_reserve,
-	.map_io		= intcp_map_io_atag,
-	.init_early	= intcp_init_early,
-	.init_irq	= intcp_init_irq,
-	.handle_irq	= fpga_handle_irq,
-	.init_time	= cp_timer_init,
-	.init_machine	= intcp_init,
-	.restart	= integrator_restart,
-MACHINE_END
-
-#endif

+ 3 - 2
arch/arm/mach-integrator/leds.c

@@ -11,10 +11,11 @@
 #include <linux/slab.h>
 #include <linux/leds.h>
 
-#include <mach/cm.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
 
+#include "cm.h"
+
 #if defined(CONFIG_NEW_LEDS) && defined(CONFIG_LEDS_CLASS)
 
 #define ALPHA_REG __io_address(INTEGRATOR_DBG_BASE)
@@ -78,7 +79,7 @@ static void cm_led_set(struct led_classdev *cdev,
 
 static enum led_brightness cm_led_get(struct led_classdev *cdev)
 {
-	u32 reg = readl(CM_CTRL);
+	u32 reg = cm_get();
 
 	return (reg & CM_CTRL_LED) ? LED_FULL : LED_OFF;
 }

+ 26 - 101
arch/arm/mach-integrator/pci_v3.c

@@ -36,7 +36,6 @@
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <mach/irqs.h>
 
 #include <asm/mach/map.h>
 #include <asm/signal.h>
@@ -605,7 +604,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	return 1;
 }
 
-static irqreturn_t v3_irq(int dummy, void *devid)
+static irqreturn_t v3_irq(int irq, void *devid)
 {
 #ifdef CONFIG_DEBUG_LL
 	struct pt_regs *regs = get_irq_regs();
@@ -615,7 +614,7 @@ static irqreturn_t v3_irq(int dummy, void *devid)
 	extern void printascii(const char *);
 
 	sprintf(buf, "V3 int %d: pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x "
-		"ISTAT=%02x\n", IRQ_AP_V3INT, pc, instr,
+		"ISTAT=%02x\n", irq, pc, instr,
 		__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFADDR_OFFSET),
 		__raw_readl(ap_syscon_base + INTEGRATOR_SC_LBFCODE_OFFSET) & 255,
 		v3_readb(V3_LB_ISTAT));
@@ -809,32 +808,6 @@ static u8 __init pci_v3_swizzle(struct pci_dev *dev, u8 *pinp)
 	return pci_common_swizzle(dev, pinp);
 }
 
-static int irq_tab[4] __initdata = {
-	IRQ_AP_PCIINT0,	IRQ_AP_PCIINT1,	IRQ_AP_PCIINT2,	IRQ_AP_PCIINT3
-};
-
-/*
- * map the specified device/slot/pin to an IRQ.  This works out such
- * that slot 9 pin 1 is INT0, pin 2 is INT1, and slot 10 pin 1 is INT1.
- */
-static int __init pci_v3_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	int intnr = ((slot - 9) + (pin - 1)) & 3;
-
-	return irq_tab[intnr];
-}
-
-static struct hw_pci pci_v3 __initdata = {
-	.swizzle		= pci_v3_swizzle,
-	.setup			= pci_v3_setup,
-	.nr_controllers		= 1,
-	.ops			= &pci_v3_ops,
-	.preinit		= pci_v3_preinit,
-	.postinit		= pci_v3_postinit,
-};
-
-#ifdef CONFIG_OF
-
 static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	struct of_irq oirq;
@@ -851,14 +824,36 @@ static int __init pci_v3_map_irq_dt(const struct pci_dev *dev, u8 slot, u8 pin)
 				     oirq.size);
 }
 
-static int __init pci_v3_dtprobe(struct platform_device *pdev,
-				struct device_node *np)
+static struct hw_pci pci_v3 __initdata = {
+	.swizzle		= pci_v3_swizzle,
+	.setup			= pci_v3_setup,
+	.nr_controllers		= 1,
+	.ops			= &pci_v3_ops,
+	.preinit		= pci_v3_preinit,
+	.postinit		= pci_v3_postinit,
+};
+
+static int __init pci_v3_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct of_pci_range_parser parser;
 	struct of_pci_range range;
 	struct resource *res;
 	int irq, ret;
 
+	/* Remap the Integrator system controller */
+	ap_syscon_base = devm_ioremap(&pdev->dev, INTEGRATOR_SC_BASE, 0x100);
+	if (!ap_syscon_base) {
+		dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
+		return -ENODEV;
+	}
+
+	/* Device tree probe path */
+	if (!np) {
+		dev_err(&pdev->dev, "no device tree node for PCIv3\n");
+		return -ENODEV;
+	}
+
 	if (of_pci_range_parser_init(&parser, np))
 		return -EINVAL;
 
@@ -925,76 +920,6 @@ static int __init pci_v3_dtprobe(struct platform_device *pdev,
 	return 0;
 }
 
-#else
-
-static inline int pci_v3_dtprobe(struct platform_device *pdev,
-				  struct device_node *np)
-{
-	return -EINVAL;
-}
-
-#endif
-
-static int __init pci_v3_probe(struct platform_device *pdev)
-{
-	struct device_node *np = pdev->dev.of_node;
-	int ret;
-
-	/* Remap the Integrator system controller */
-	ap_syscon_base = ioremap(INTEGRATOR_SC_BASE, 0x100);
-	if (!ap_syscon_base) {
-		dev_err(&pdev->dev, "unable to remap the AP syscon for PCIv3\n");
-		return -ENODEV;
-	}
-
-	/* Device tree probe path */
-	if (np)
-		return pci_v3_dtprobe(pdev, np);
-
-	pci_v3_base = devm_ioremap(&pdev->dev, PHYS_PCI_V3_BASE, SZ_64K);
-	if (!pci_v3_base) {
-		dev_err(&pdev->dev, "unable to remap PCIv3 base\n");
-		return -ENODEV;
-	}
-
-	ret = devm_request_irq(&pdev->dev, IRQ_AP_V3INT, v3_irq, 0, "V3", NULL);
-	if (ret) {
-		dev_err(&pdev->dev, "unable to grab PCI error interrupt: %d\n",
-			ret);
-		return -ENODEV;
-	}
-
-	conf_mem.name = "PCIv3 config";
-	conf_mem.start = PHYS_PCI_CONFIG_BASE;
-	conf_mem.end = PHYS_PCI_CONFIG_BASE + SZ_16M - 1;
-	conf_mem.flags = IORESOURCE_MEM;
-
-	io_mem.name = "PCIv3 I/O";
-	io_mem.start = PHYS_PCI_IO_BASE;
-	io_mem.end = PHYS_PCI_IO_BASE + SZ_16M - 1;
-	io_mem.flags = IORESOURCE_MEM;
-
-	non_mem_pci = 0x00000000;
-	non_mem_pci_sz = SZ_256M;
-	non_mem.name = "PCIv3 non-prefetched mem";
-	non_mem.start = PHYS_PCI_MEM_BASE;
-	non_mem.end = PHYS_PCI_MEM_BASE + SZ_256M - 1;
-	non_mem.flags = IORESOURCE_MEM;
-
-	pre_mem_pci = 0x10000000;
-	pre_mem_pci_sz = SZ_256M;
-	pre_mem.name = "PCIv3 prefetched mem";
-	pre_mem.start = PHYS_PCI_PRE_BASE + SZ_256M;
-	pre_mem.end = PHYS_PCI_PRE_BASE + SZ_256M - 1;
-	pre_mem.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
-
-	pci_v3.map_irq = pci_v3_map_irq;
-
-	pci_common_init_dev(&pdev->dev, &pci_v3);
-
-	return 0;
-}
-
 static const struct of_device_id pci_ids[] = {
 	{ .compatible = "v3,v360epc-pci", },
 	{},

+ 43 - 18
drivers/cpufreq/integrator-cpufreq.c

@@ -15,18 +15,19 @@
 #include <linux/smp.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/icst.h>
 
-static struct cpufreq_driver integrator_driver;
+static void __iomem *cm_base;
+/* The cpufreq driver only use the OSC register */
+#define INTEGRATOR_HDR_OSC_OFFSET       0x08
+#define INTEGRATOR_HDR_LOCK_OFFSET      0x14
 
-#define CM_ID  	__io_address(INTEGRATOR_HDR_ID)
-#define CM_OSC	__io_address(INTEGRATOR_HDR_OSC)
-#define CM_STAT __io_address(INTEGRATOR_HDR_STAT)
-#define CM_LOCK __io_address(INTEGRATOR_HDR_LOCK)
+static struct cpufreq_driver integrator_driver;
 
 static const struct icst_params lclk_params = {
 	.ref		= 24000000,
@@ -100,7 +101,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
 	BUG_ON(cpu != smp_processor_id());
 
 	/* get current setting */
-	cm_osc = __raw_readl(CM_OSC);
+	cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
 	if (machine_is_integrator()) {
 		vco.s = (cm_osc >> 8) & 7;
@@ -128,7 +129,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
 
 	cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
 
-	cm_osc = __raw_readl(CM_OSC);
+	cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
 	if (machine_is_integrator()) {
 		cm_osc &= 0xfffff800;
@@ -138,9 +139,9 @@ static int integrator_set_target(struct cpufreq_policy *policy,
 	}
 	cm_osc |= vco.v;
 
-	__raw_writel(0xa05f, CM_LOCK);
-	__raw_writel(cm_osc, CM_OSC);
-	__raw_writel(0, CM_LOCK);
+	__raw_writel(0xa05f, cm_base + INTEGRATOR_HDR_LOCK_OFFSET);
+	__raw_writel(cm_osc, cm_base + INTEGRATOR_HDR_OSC_OFFSET);
+	__raw_writel(0, cm_base + INTEGRATOR_HDR_LOCK_OFFSET);
 
 	/*
 	 * Restore the CPUs allowed mask.
@@ -165,7 +166,7 @@ static unsigned int integrator_get(unsigned int cpu)
 	BUG_ON(cpu != smp_processor_id());
 
 	/* detect memory etc. */
-	cm_osc = __raw_readl(CM_OSC);
+	cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
 
 	if (machine_is_integrator()) {
 		vco.s = (cm_osc >> 8) & 7;
@@ -202,19 +203,43 @@ static struct cpufreq_driver integrator_driver = {
 	.name		= "integrator",
 };
 
-static int __init integrator_cpu_init(void)
+static int __init integrator_cpufreq_probe(struct platform_device *pdev)
 {
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+        if (!res)
+		return -ENODEV;
+
+	cm_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!cm_base)
+		return -ENODEV;
+
 	return cpufreq_register_driver(&integrator_driver);
 }
 
-static void __exit integrator_cpu_exit(void)
+static void __exit integrator_cpufreq_remove(struct platform_device *pdev)
 {
 	cpufreq_unregister_driver(&integrator_driver);
 }
 
+static const struct of_device_id integrator_cpufreq_match[] = {
+	{ .compatible = "arm,core-module-integrator"},
+	{ },
+};
+
+static struct platform_driver integrator_cpufreq_driver = {
+	.driver = {
+		.name = "integrator-cpufreq",
+		.owner = THIS_MODULE,
+		.of_match_table = integrator_cpufreq_match,
+	},
+	.remove = __exit_p(integrator_cpufreq_remove),
+};
+
+module_platform_driver_probe(integrator_cpufreq_driver,
+			     integrator_cpufreq_probe);
+
 MODULE_AUTHOR ("Russell M. King");
 MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs");
 MODULE_LICENSE ("GPL");
-
-module_init(integrator_cpu_init);
-module_exit(integrator_cpu_exit);