aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/Kconfig4
-rw-r--r--arch/arm/mach-pxa/Makefile1
-rw-r--r--arch/arm/mach-pxa/clock.c15
-rw-r--r--arch/arm/mach-pxa/corgi.c7
-rw-r--r--arch/arm/mach-pxa/devices.h11
-rw-r--r--arch/arm/mach-pxa/dma.c44
-rw-r--r--arch/arm/mach-pxa/em-x270.c354
-rw-r--r--arch/arm/mach-pxa/generic.c101
-rw-r--r--arch/arm/mach-pxa/generic.h6
-rw-r--r--arch/arm/mach-pxa/idp.c3
-rw-r--r--arch/arm/mach-pxa/irq.c106
-rw-r--r--arch/arm/mach-pxa/lpd270.c3
-rw-r--r--arch/arm/mach-pxa/lubbock.c3
-rw-r--r--arch/arm/mach-pxa/mainstone.c3
-rw-r--r--arch/arm/mach-pxa/pm.c184
-rw-r--r--arch/arm/mach-pxa/poodle.c3
-rw-r--r--arch/arm/mach-pxa/pxa25x.c137
-rw-r--r--arch/arm/mach-pxa/pxa27x.c183
-rw-r--r--arch/arm/mach-pxa/sleep.S112
-rw-r--r--arch/arm/mach-pxa/spitz.c7
-rw-r--r--arch/arm/mach-pxa/time.c263
-rw-r--r--arch/arm/mach-pxa/tosa.c4
-rw-r--r--arch/arm/mach-pxa/trizeps4.c3
23 files changed, 1025 insertions, 532 deletions
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 5c0a10041cd..5ebec6d88b5 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -37,6 +37,10 @@ config MACH_TRIZEPS4
bool "Keith und Koep Trizeps4 DIMM-Module"
select PXA27x
+config MACH_EM_X270
+ bool "CompuLab EM-x270 platform"
+ select PXA27x
+
endchoice
if PXA_SHARPSL
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index 9093eb1c94e..7d6ab5c59ab 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o sp
obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o
obj-$(CONFIG_MACH_TOSA) += tosa.o
+obj-$(CONFIG_MACH_EM_X270) += em-x270.o
# Support for blinky lights
led-y := leds.o
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index 8f7c90a0593..34a31caa6f9 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -12,7 +12,6 @@
#include <asm/arch/pxa-regs.h>
#include <asm/hardware.h>
-#include <asm/semaphore.h>
struct clk {
struct list_head node;
@@ -25,21 +24,21 @@ struct clk {
};
static LIST_HEAD(clocks);
-static DECLARE_MUTEX(clocks_sem);
+static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return clk;
}
@@ -101,18 +100,18 @@ static struct clk clk_gpio27 = {
int clk_register(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
- down(&clocks_sem);
+ mutex_lock(&clocks_mutex);
list_del(&clk->node);
- up(&clocks_sem);
+ mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index a1a900d1666..aab27297b3c 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -44,6 +44,7 @@
#include <asm/hardware/scoop.h>
#include "generic.h"
+#include "devices.h"
#include "sharpsl.h"
@@ -368,7 +369,7 @@ MACHINE_START(CORGI, "SHARP Corgi")
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
.map_io = pxa_map_io,
- .init_irq = pxa_init_irq,
+ .init_irq = pxa25x_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
@@ -380,7 +381,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
.map_io = pxa_map_io,
- .init_irq = pxa_init_irq,
+ .init_irq = pxa25x_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
@@ -392,7 +393,7 @@ MACHINE_START(HUSKY, "SHARP Husky")
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.fixup = fixup_corgi,
.map_io = pxa_map_io,
- .init_irq = pxa_init_irq,
+ .init_irq = pxa25x_init_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
new file mode 100644
index 00000000000..636fdb1c049
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.h
@@ -0,0 +1,11 @@
+extern struct platform_device pxa_device_mci;
+extern struct platform_device pxa_device_udc;
+extern struct platform_device pxa_device_fb;
+extern struct platform_device pxa_device_ffuart;
+extern struct platform_device pxa_device_btuart;
+extern struct platform_device pxa_device_stuart;
+extern struct platform_device pxa_device_hwuart;
+extern struct platform_device pxa_device_i2c;
+extern struct platform_device pxa_device_i2s;
+extern struct platform_device pxa_device_ficp;
+extern struct platform_device pxa_device_rtc;
diff --git a/arch/arm/mach-pxa/dma.c b/arch/arm/mach-pxa/dma.c
index 4440babe7b9..93c4f31f127 100644
--- a/arch/arm/mach-pxa/dma.c
+++ b/arch/arm/mach-pxa/dma.c
@@ -25,12 +25,15 @@
#include <asm/arch/pxa-regs.h>
-static struct dma_channel {
+struct dma_channel {
char *name;
+ pxa_dma_prio prio;
void (*irq_handler)(int, void *);
void *data;
-} dma_channels[PXA_DMA_CHANNELS];
+};
+static struct dma_channel *dma_channels;
+static int num_dma_channels;
int pxa_request_dma (char *name, pxa_dma_prio prio,
void (*irq_handler)(int, void *),
@@ -47,8 +50,9 @@ int pxa_request_dma (char *name, pxa_dma_prio prio,
do {
/* try grabbing a DMA channel with the requested priority */
- pxa_for_each_dma_prio (i, prio) {
- if (!dma_channels[i].name) {
+ for (i = 0; i < num_dma_channels; i++) {
+ if ((dma_channels[i].prio == prio) &&
+ !dma_channels[i].name) {
found = 1;
break;
}
@@ -91,7 +95,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
{
int i, dint = DINT;
- for (i = 0; i < PXA_DMA_CHANNELS; i++) {
+ for (i = 0; i < num_dma_channels; i++) {
if (dint & (1 << i)) {
struct dma_channel *channel = &dma_channels[i];
if (channel->name && channel->irq_handler) {
@@ -109,18 +113,32 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int __init pxa_dma_init (void)
+int __init pxa_init_dma(int num_ch)
{
- int ret;
+ int i, ret;
- ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
- if (ret)
+ dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL);
+ if (dma_channels == NULL)
+ return -ENOMEM;
+
+ ret = request_irq(IRQ_DMA, dma_irq_handler, IRQF_DISABLED, "DMA", NULL);
+ if (ret) {
printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
- return ret;
-}
+ kfree(dma_channels);
+ return ret;
+ }
-arch_initcall(pxa_dma_init);
+ /* dma channel priorities on pxa2xx processors:
+ * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH
+ * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM
+ * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW
+ */
+ for (i = 0; i < num_ch; i++)
+ dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW);
+
+ num_dma_channels = num_ch;
+ return 0;
+}
EXPORT_SYMBOL(pxa_request_dma);
EXPORT_SYMBOL(pxa_free_dma);
-
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
new file mode 100644
index 00000000000..3d0ad5065ee
--- /dev/null
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -0,0 +1,354 @@
+/*
+ * Support for CompuLab EM-x270 platform
+ *
+ * Copyright (C) 2007 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <linux/dm9000.h>
+#include <linux/rtc-v3020.h>
+
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/ohci.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/bitfield.h>
+
+#include "generic.h"
+
+/* GPIO IRQ usage */
+#define EM_X270_MMC_PD (105)
+#define EM_X270_ETHIRQ IRQ_GPIO(41)
+#define EM_X270_MMC_IRQ IRQ_GPIO(13)
+
+static struct resource em_x270_dm9k_resource[] = {
+ [0] = {
+ .start = PXA_CS2_PHYS,
+ .end = PXA_CS2_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = PXA_CS2_PHYS + 8,
+ .end = PXA_CS2_PHYS + 8 + 0x3f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = EM_X270_ETHIRQ,
+ .end = EM_X270_ETHIRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* for the moment we limit ourselves to 32bit IO until some
+ * better IO routines can be written and tested
+ */
+static struct dm9000_plat_data em_x270_dm9k_platdata = {
+ .flags = DM9000_PLATF_32BITONLY,
+};
+
+/* Ethernet device */
+static struct platform_device em_x270_dm9k = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(em_x270_dm9k_resource),
+ .resource = em_x270_dm9k_resource,
+ .dev = {
+ .platform_data = &em_x270_dm9k_platdata,
+ }
+};
+
+/* audio device */
+static struct platform_device em_x270_audio = {
+ .name = "pxa2xx-ac97",
+ .id = -1,
+};
+
+/* WM9712 touchscreen controller. Hopefully the driver will make it to
+ * the mainstream sometime */
+static struct platform_device em_x270_ts = {
+ .name = "wm97xx-ts",
+ .id = -1,
+};
+
+/* RTC */
+static struct resource em_x270_v3020_resource[] = {
+ [0] = {
+ .start = PXA_CS4_PHYS,
+ .end = PXA_CS4_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct v3020_platform_data em_x270_v3020_platdata = {
+ .leftshift = 0,
+};
+
+static struct platform_device em_x270_rtc = {
+ .name = "v3020",
+ .num_resources = ARRAY_SIZE(em_x270_v3020_resource),
+ .resource = em_x270_v3020_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &em_x270_v3020_platdata,
+ }
+};
+
+/* NAND flash */
+#define GPIO_NAND_CS (11)
+#define GPIO_NAND_RB (56)
+
+static inline void nand_cs_on(void)
+{
+ GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+static void nand_cs_off(void)
+{
+ dsb();
+
+ GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS);
+}
+
+/* hardware specific access to control-lines */
+static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
+
+ dsb();
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if (ctrl & NAND_ALE)
+ nandaddr |= (1 << 3);
+ else
+ nandaddr &= ~(1 << 3);
+ if (ctrl & NAND_CLE)
+ nandaddr |= (1 << 2);
+ else
+ nandaddr &= ~(1 << 2);
+ if (ctrl & NAND_NCE)
+ nand_cs_on();
+ else
+ nand_cs_off();
+ }
+
+ dsb();
+ this->IO_ADDR_W = (void __iomem *)nandaddr;
+ if (dat != NAND_CMD_NONE)
+ writel(dat, this->IO_ADDR_W);
+
+ dsb();
+}
+
+/* read device ready pin */
+static int em_x270_nand_device_ready(struct mtd_info *mtd)
+{
+ dsb();
+
+ return GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB);
+}
+
+static struct mtd_partition em_x270_partition_info[] = {
+ [0] = {
+ .name = "em_x270-0",
+ .offset = 0,
+ .size = SZ_4M,
+ },
+ [1] = {
+ .name = "em_x270-1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+static const char *em_x270_part_probes[] = { "cmdlinepart", NULL };
+
+struct platform_nand_data em_x270_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(em_x270_partition_info),
+ .partitions = em_x270_partition_info,
+ .chip_delay = 20,
+ .part_probe_types = em_x270_part_probes,
+ },
+ .ctrl = {
+ .hwcontrol = 0,
+ .dev_ready = em_x270_nand_device_ready,
+ .select_chip = 0,
+ .cmd_ctrl = em_x270_nand_cmd_ctl,
+ },
+};
+
+static struct resource em_x270_nand_resource[] = {
+ [0] = {
+ .start = PXA_CS1_PHYS,
+ .end = PXA_CS1_PHYS + 12,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device em_x270_nand = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(em_x270_nand_resource),
+ .resource = em_x270_nand_resource,
+ .id = -1,
+ .dev = {
+ .platform_data = &em_x270_nand_platdata,
+ }
+};
+
+/* platform devices */
+static struct platform_device *platform_devices[] __initdata = {
+ &em_x270_dm9k,
+ &em_x270_audio,
+ &em_x270_ts,
+ &em_x270_rtc,
+ &em_x270_nand,
+};
+
+
+/* PXA27x OHCI controller setup */
+static int em_x270_ohci_init(struct device *dev)
+{
+ /* Set the Power Control Polarity Low */
+ UHCHR = (UHCHR | UHCHR_PCPL) &
+ ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSE);
+
+ /* enable port 2 transiever */
+ UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
+
+ return 0;
+}
+
+static struct pxaohci_platform_data em_x270_ohci_platform_data = {
+ .port_mode = PMM_PERPORT_MODE,
+ .init = em_x270_ohci_init,
+};
+
+
+static int em_x270_mci_init(struct device *dev,
+ irq_handler_t em_x270_detect_int,
+ void *data)
+{
+ int err;
+
+ /* setup GPIO for PXA27x MMC controller */
+ pxa_gpio_mode(GPIO32_MMCCLK_MD);
+ pxa_gpio_mode(GPIO112_MMCCMD_MD);
+ pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+ pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+ pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+ pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+
+ /* EM-X270 uses GPIO13 as SD power enable */
+ pxa_gpio_mode(EM_X270_MMC_PD | GPIO_OUT);
+
+ err = request_irq(EM_X270_MMC_IRQ, em_x270_detect_int,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n",
+ __FUNCTION__, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
+{
+ /*
+ FIXME: current hardware implementation does not allow to
+ enable/disable MMC power. This will be fixed in next HW releases,
+ and we'll need to add implmentation here.
+ */
+ return;
+}
+
+static void em_x270_mci_exit(struct device *dev, void *data)
+{
+ free_irq(EM_X270_MMC_IRQ, data);
+}
+
+static struct pxamci_platform_data em_x270_mci_platform_data = {
+ .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31,
+ .init = em_x270_mci_init,
+ .setpower = em_x270_mci_setpower,
+ .exit = em_x270_mci_exit,
+};
+
+/* LCD 480x640 */
+static struct pxafb_mode_info em_x270_lcd_mode = {
+ .pixclock = 50000,
+ .bpp = 16,
+ .xres = 480,
+ .yres = 640,
+ .hsync_len = 8,
+ .vsync_len = 2,
+ .left_margin = 8,
+ .upper_margin = 0,
+ .right_margin = 24,
+ .lower_margin = 4,
+ .cmap_greyscale = 0,
+};
+
+static struct pxafb_mach_info em_x270_lcd = {
+ .modes = &em_x270_lcd_mode,
+ .num_modes = 1,
+ .cmap_inverse = 0,
+ .cmap_static = 0,
+ .lccr0 = LCCR0_PAS,
+ .lccr3 = LCCR3_PixClkDiv(0x01) | LCCR3_Acb(0xff),
+};
+
+static void __init em_x270_init(void)
+{
+ /* setup LCD */
+ set_pxa_fb_info(&em_x270_lcd);
+
+ /* register EM-X270 platform devices */
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ /* set MCI and OHCI platform parameters */
+ pxa_set_mci_info(&em_x270_mci_platform_data);
+ pxa_set_ohci_info(&em_x270_ohci_platform_data);
+
+ /* setup STUART GPIOs */
+ pxa_gpio_mode(GPIO46_STRXD_MD);
+ pxa_gpio_mode(GPIO47_STTXD_MD);
+
+ /* setup BTUART GPIOs */
+ pxa_gpio_mode(GPIO42_BTRXD_MD);
+ pxa_gpio_mode(GPIO43_BTTXD_MD);
+ pxa_gpio_mode(GPIO44_BTCTS_MD);
+ pxa_gpio_mode(GPIO45_BTRTS_MD);
+
+ /* Setup interrupt for dm9000 */
+ set_irq_type(EM_X270_ETHIRQ, IRQT_RISING);
+}
+
+MACHINE_START(EM_X270, "Compulab EM-x270")
+ .boot_params = 0xa0000100,
+ .phys_io = 0x40000000,
+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
+ .map_io = pxa_map_io,
+ .init_irq = pxa27x_init_irq,
+ .timer = &pxa_timer,
+ .init_machine = em_x270_init,
+MACHINE_END
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 64b08b744f9..5510f6fdce5 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -43,6 +43,7 @@
#include <asm/arch/irda.h>
#include <asm/arch/i2c.h>
+#include "devices.h"
#include "generic.h"
/*
@@ -242,7 +243,7 @@ static struct resource pxamci_resources[] = {
static u64 pxamci_dmamask = 0xffffffffUL;
-static struct platform_device pxamci_device = {
+struct platform_device pxa_device_mci = {
.name = "pxa2xx-mci",
.id = -1,
.dev = {
@@ -255,7 +256,7 @@ static struct platform_device pxamci_device = {
void __init pxa_set_mci_info(struct pxamci_platform_data *info)
{
- pxamci_device.dev.platform_data = info;
+ pxa_device_mci.dev.platform_data = info;
}
@@ -281,7 +282,7 @@ static struct resource pxa2xx_udc_resources[] = {
static u64 udc_dma_mask = ~(u32)0;
-static struct platform_device udc_device = {
+struct platform_device pxa_device_udc = {
.name = "pxa2xx-udc",
.id = -1,
.resource = pxa2xx_udc_resources,
@@ -307,7 +308,7 @@ static struct resource pxafb_resources[] = {
static u64 fb_dma_mask = ~(u64)0;
-static struct platform_device pxafb_device = {
+struct platform_device pxa_device_fb = {
.name = "pxa2xx-fb",
.id = -1,
.dev = {
@@ -320,32 +321,32 @@ static struct platform_device pxafb_device = {
void __init set_pxa_fb_info(struct pxafb_mach_info *info)
{
- pxafb_device.dev.platform_data = info;
+ pxa_device_fb.dev.platform_data = info;
}
void __init set_pxa_fb_parent(struct device *parent_dev)
{
- pxafb_device.dev.parent = parent_dev;
+ pxa_device_fb.dev.parent = parent_dev;
}
-static struct platform_device ffuart_device = {
+struct platform_device pxa_device_ffuart= {
.name = "pxa2xx-uart",
.id = 0,
};
-static struct platform_device btuart_device = {
+struct platform_device pxa_device_btuart = {
.name = "pxa2xx-uart",
.id = 1,
};
-static struct platform_device stuart_device = {
+struct platform_device pxa_device_stuart = {
.name = "pxa2xx-uart",
.id = 2,
};
-static struct platform_device hwuart_device = {
+struct platform_device pxa_device_hwuart = {
.name = "pxa2xx-uart",
.id = 3,
};
-static struct resource i2c_resources[] = {
+static struct resource pxai2c_resources[] = {
{
.start = 0x40301680,
.end = 0x403016a3,
@@ -357,40 +358,19 @@ static struct resource i2c_resources[] = {
},
};
-static struct platform_device i2c_device = {
+struct platform_device pxa_device_i2c = {
.name = "pxa2xx-i2c",
.id = 0,
- .resource = i2c_resources,
- .num_resources = ARRAY_SIZE(i2c_resources),
+ .resource = pxai2c_resources,
+ .num_resources = ARRAY_SIZE(pxai2c_resources),
};
-#ifdef CONFIG_PXA27x
-static struct resource i2c_power_resources[] = {
- {
- .start = 0x40f00180,
- .end = 0x40f001a3,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IRQ_PWRI2C,
- .end = IRQ_PWRI2C,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device i2c_power_device = {
- .name = "pxa2xx-i2c",
- .id = 1,
- .resource = i2c_power_resources,
- .num_resources = ARRAY_SIZE(i2c_resources),
-};
-#endif
-
void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
{
- i2c_device.dev.platform_data = info;
+ pxa_device_i2c.dev.platform_data = info;
}
-static struct resource i2s_resources[] = {
+static struct resource pxai2s_resources[] = {
{
.start = 0x40400000,
.end = 0x40400083,
@@ -402,16 +382,16 @@ static struct resource i2s_resources[] = {
},
};
-static struct platform_device i2s_device = {
+struct platform_device pxa_device_i2s = {
.name = "pxa2xx-i2s",
.id = -1,
- .resource = i2s_resources,
- .num_resources = ARRAY_SIZE(i2s_resources),
+ .resource = pxai2s_resources,
+ .num_resources = ARRAY_SIZE(pxai2s_resources),
};
static u64 pxaficp_dmamask = ~(u32)0;
-static struct platform_device pxaficp_device = {
+struct platform_device pxa_device_ficp = {
.name = "pxa2xx-ir",
.id = -1,
.dev = {
@@ -422,45 +402,10 @@ static struct platform_device pxaficp_device = {
void __init pxa_set_ficp_info(struct pxaficp_platform_data *info)
{
- pxaficp_device.dev.platform_data = info;
+ pxa_device_ficp.dev.platform_data = info;
}
-static struct platform_device pxartc_device = {
+struct platform_device pxa_device_rtc = {
.name = "sa1100-rtc",
.id = -1,
};
-
-static struct platform_device *devices[] __initdata = {
- &pxamci_device,
- &udc_device,
- &pxafb_device,
- &ffuart_device,
- &btuart_device,
- &stuart_device,
- &pxaficp_device,
- &i2c_device,
-#ifdef CONFIG_PXA27x
- &i2c_power_device,
-#endif
- &i2s_device,
- &pxartc_device,
-};
-
-static int __init pxa_init(void)
-{
- int cpuid, ret;
-
- ret = platform_add_devices(devices, ARRAY_SIZE(devices));
- if (ret)
- return ret;
-
- /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
- cpuid = read_cpuid(CPUID_ID);
- if (((cpuid >> 4) & 0xfff) == 0x2d0 ||
- ((cpuid >> 4) & 0xfff) == 0x290)
- ret = platform_device_register(&hwuart_device);
-
- return ret;
-}
-
-subsys_initcall(pxa_init);
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index e54a8dd63c1..91ab2ad8b34 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -12,8 +12,12 @@
struct sys_timer;
extern struct sys_timer pxa_timer;
+extern void __init pxa_init_irq_low(void);
+extern void __init pxa_init_irq_high(void);
+extern void __init pxa_init_irq_gpio(int gpio_nr);
+extern void __init pxa25x_init_irq(void);
+extern void __init pxa27x_init_irq(void);
extern void __init pxa_map_io(void);
-extern void __init pxa_init_irq(void);
extern unsigned int get_clk_frequency_khz(int info);
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index 64df44043a6..465108da285 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -38,6 +38,7 @@
#include <asm/arch/mmc.h>
#include "generic.h"
+#include "devices.h"
/* TODO:
* - add pxa2xx_audio_ops_t device structure
@@ -152,7 +153,7 @@ static void __init idp_init(void)
static void __init idp_init_irq(void)
{
- pxa_init_irq();
+ pxa25x_init_irq();
set_irq_type(TOUCH_PANEL_IRQ, TOUCH_PANEL_IRQ_EDGE);
}
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 4619d5fe606..4b867b0789d 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -30,12 +30,12 @@
static void pxa_mask_low_irq(unsigned int irq)
{
- ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
+ ICMR &= ~(1 << irq);
}
static void pxa_unmask_low_irq(unsigned int irq)
{
- ICMR |= (1 << (irq + PXA_IRQ_SKIP));
+ ICMR |= (1 << irq);
}
static int pxa_set_wake(unsigned int irq, unsigned int on)
@@ -67,7 +67,27 @@ static struct irq_chip pxa_internal_chip_low = {
.set_wake = pxa_set_wake,
};
-#if PXA_INTERNAL_IRQS > 32
+void __init pxa_init_irq_low(void)
+{
+ int irq;
+
+ /* disable all IRQs */
+ ICMR = 0;
+
+ /* all IRQs are IRQ, not FIQ */
+ ICLR = 0;
+
+ /* only unmasked interrupts kick us out of idle */
+ ICCR = 1;
+
+ for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
+ set_irq_chip(irq, &pxa_internal_chip_low);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+}
+
+#ifdef CONFIG_PXA27x
/*
* This is for the second set of internal IRQs as found on the PXA27x.
@@ -75,12 +95,12 @@ static struct irq_chip pxa_internal_chip_low = {
static void pxa_mask_high_irq(unsigned int irq)
{
- ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP));
+ ICMR2 &= ~(1 << (irq - 32));
}
static void pxa_unmask_high_irq(unsigned int irq)
{
- ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP));
+ ICMR2 |= (1 << (irq - 32));
}
static struct irq_chip pxa_internal_chip_high = {
@@ -90,6 +110,19 @@ static struct irq_chip pxa_internal_chip_high = {
.unmask = pxa_unmask_high_irq,
};
+void __init pxa_init_irq_high(void)
+{
+ int irq;
+
+ ICMR2 = 0;
+ ICLR2 = 0;
+
+ for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
+ set_irq_chip(irq, &pxa_internal_chip_high);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+}
#endif
/* Note that if an input/irq line ever gets changed to an output during
@@ -217,7 +250,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
do {
loop = 0;
- mask = GEDR0 & ~3;
+ mask = GEDR0 & GPIO_IRQ_mask[0] & ~3;
if (mask) {
GEDR0 = mask;
irq = IRQ_GPIO(2);
@@ -233,7 +266,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
loop = 1;
}
- mask = GEDR1;
+ mask = GEDR1 & GPIO_IRQ_mask[1];
if (mask) {
GEDR1 = mask;
irq = IRQ_GPIO(32);
@@ -248,7 +281,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
loop = 1;
}
- mask = GEDR2;
+ mask = GEDR2 & GPIO_IRQ_mask[2];
if (mask) {
GEDR2 = mask;
irq = IRQ_GPIO(64);
@@ -263,8 +296,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
loop = 1;
}
-#if PXA_LAST_GPIO >= 96
- mask = GEDR3;
+ mask = GEDR3 & GPIO_IRQ_mask[3];
if (mask) {
GEDR3 = mask;
irq = IRQ_GPIO(96);
@@ -278,7 +310,6 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
} while (mask);
loop = 1;
}
-#endif
} while (loop);
}
@@ -314,64 +345,27 @@ static struct irq_chip pxa_muxed_gpio_chip = {
.set_wake = pxa_set_gpio_wake,
};
-
-void __init pxa_init_irq(void)
+void __init pxa_init_irq_gpio(int gpio_nr)
{
- int irq;
-
- /* disable all IRQs */
- ICMR = 0;
-
- /* all IRQs are IRQ, not FIQ */
- ICLR = 0;
+ int irq, i;
/* clear all GPIO edge detects */
- GFER0 = 0;
- GFER1 = 0;
- GFER2 = 0;
- GRER0 = 0;
- GRER1 = 0;
- GRER2 = 0;
- GEDR0 = GEDR0;
- GEDR1 = GEDR1;
- GEDR2 = GEDR2;
-
-#ifdef CONFIG_PXA27x
- /* And similarly for the extra regs on the PXA27x */
- ICMR2 = 0;
- ICLR2 = 0;
- GFER3 = 0;
- GRER3 = 0;
- GEDR3 = GEDR3;
-#endif
-
- /* only unmasked interrupts kick us out of idle */
- ICCR = 1;
+ for (i = 0; i < gpio_nr; i += 32) {
+ GFER(i) = 0;
+ GRER(i) = 0;
+ GEDR(i) = GEDR(i);
+ }
/* GPIO 0 and 1 must have their mask bit always set */
GPIO_IRQ_mask[0] = 3;
- for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
- set_irq_chip(irq, &pxa_internal_chip_low);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-
-#if PXA_INTERNAL_IRQS > 32
- for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
- set_irq_chip(irq, &pxa_internal_chip_high);
- set_irq_handler(irq, handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
-#endif
-
for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
set_irq_chip(irq, &pxa_low_gpio_chip);
set_irq_handler(irq, handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {
+ for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(gpio_nr); irq++) {
set_irq_chip(irq, &pxa_muxed_gpio_chip);
set_irq_handler(irq, handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index e3097664ffe..26116440a7c 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/