diff options
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r-- | arch/arm/mach-ep93xx/adssphere.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/clock.c | 131 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/core.c | 202 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/edb93xx.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/gesbc9312.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/gpio.c | 65 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 103 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/hardware.h | 17 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/io.h | 17 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/platform.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/system.h | 12 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/include/mach/ts72xx.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/micro9.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-ep93xx/ts72xx.c | 15 |
14 files changed, 454 insertions, 172 deletions
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c index 3fbd9b0fbe2..caf6d5154ae 100644 --- a/arch/arm/mach-ep93xx/adssphere.c +++ b/arch/arm/mach-ep93xx/adssphere.c @@ -12,18 +12,15 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/mtd/physmap.h> #include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/i2c.h> +#include <linux/mtd/physmap.h> + #include <mach/hardware.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> + static struct physmap_flash_data adssphere_flash_data = { .width = 4, }; diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c index 6c4c1633ed1..3dd0e2a2309 100644 --- a/arch/arm/mach-ep93xx/clock.c +++ b/arch/arm/mach-ep93xx/clock.c @@ -22,48 +22,39 @@ #include <mach/hardware.h> -/* - * The EP93xx has two external crystal oscillators. To generate the - * required high-frequency clocks, the processor uses two phase-locked- - * loops (PLLs) to multiply the incoming external clock signal to much - * higher frequencies that are then divided down by programmable dividers - * to produce the needed clocks. The PLLs operate independently of one - * another. - */ -#define EP93XX_EXT_CLK_RATE 14745600 -#define EP93XX_EXT_RTC_RATE 32768 - - struct clk { unsigned long rate; int users; int sw_locked; - u32 enable_reg; + void __iomem *enable_reg; u32 enable_mask; unsigned long (*get_rate)(struct clk *clk); + int (*set_rate)(struct clk *clk, unsigned long rate); }; static unsigned long get_uart_rate(struct clk *clk); +static int set_keytchclk_rate(struct clk *clk, unsigned long rate); + static struct clk clk_uart1 = { .sw_locked = 1, - .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, - .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U1EN, + .enable_reg = EP93XX_SYSCON_DEVCFG, + .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN, .get_rate = get_uart_rate, }; static struct clk clk_uart2 = { .sw_locked = 1, - .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, - .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U2EN, + .enable_reg = EP93XX_SYSCON_DEVCFG, + .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN, .get_rate = get_uart_rate, }; static struct clk clk_uart3 = { .sw_locked = 1, - .enable_reg = EP93XX_SYSCON_DEVICE_CONFIG, - .enable_mask = EP93XX_SYSCON_DEVICE_CONFIG_U3EN, + .enable_reg = EP93XX_SYSCON_DEVCFG, + .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN, .get_rate = get_uart_rate, }; static struct clk clk_pll1; @@ -75,6 +66,15 @@ static struct clk clk_usb_host = { .enable_reg = EP93XX_SYSCON_PWRCNT, .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, }; +static struct clk clk_keypad = { + .sw_locked = 1, + .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, + .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, + .set_rate = set_keytchclk_rate, +}; +static struct clk clk_pwm = { + .rate = EP93XX_EXT_CLK_RATE, +}; /* DMA Clocks */ static struct clk clk_m2p0 = { @@ -130,27 +130,29 @@ static struct clk clk_m2m1 = { { .dev_id = dev, .con_id = con, .clk = ck } static struct clk_lookup clocks[] = { - INIT_CK("apb:uart1", NULL, &clk_uart1), - INIT_CK("apb:uart2", NULL, &clk_uart2), - INIT_CK("apb:uart3", NULL, &clk_uart3), - INIT_CK(NULL, "pll1", &clk_pll1), - INIT_CK(NULL, "fclk", &clk_f), - INIT_CK(NULL, "hclk", &clk_h), - INIT_CK(NULL, "pclk", &clk_p), - INIT_CK(NULL, "pll2", &clk_pll2), - INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), - INIT_CK(NULL, "m2p0", &clk_m2p0), - INIT_CK(NULL, "m2p1", &clk_m2p1), - INIT_CK(NULL, "m2p2", &clk_m2p2), - INIT_CK(NULL, "m2p3", &clk_m2p3), - INIT_CK(NULL, "m2p4", &clk_m2p4), - INIT_CK(NULL, "m2p5", &clk_m2p5), - INIT_CK(NULL, "m2p6", &clk_m2p6), - INIT_CK(NULL, "m2p7", &clk_m2p7), - INIT_CK(NULL, "m2p8", &clk_m2p8), - INIT_CK(NULL, "m2p9", &clk_m2p9), - INIT_CK(NULL, "m2m0", &clk_m2m0), - INIT_CK(NULL, "m2m1", &clk_m2m1), + INIT_CK("apb:uart1", NULL, &clk_uart1), + INIT_CK("apb:uart2", NULL, &clk_uart2), + INIT_CK("apb:uart3", NULL, &clk_uart3), + INIT_CK(NULL, "pll1", &clk_pll1), + INIT_CK(NULL, "fclk", &clk_f), + INIT_CK(NULL, "hclk", &clk_h), + INIT_CK(NULL, "pclk", &clk_p), + INIT_CK(NULL, "pll2", &clk_pll2), + INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), + INIT_CK("ep93xx-keypad", NULL, &clk_keypad), + INIT_CK(NULL, "pwm_clk", &clk_pwm), + INIT_CK(NULL, "m2p0", &clk_m2p0), + INIT_CK(NULL, "m2p1", &clk_m2p1), + INIT_CK(NULL, "m2p2", &clk_m2p2), + INIT_CK(NULL, "m2p3", &clk_m2p3), + INIT_CK(NULL, "m2p4", &clk_m2p4), + INIT_CK(NULL, "m2p5", &clk_m2p5), + INIT_CK(NULL, "m2p6", &clk_m2p6), + INIT_CK(NULL, "m2p7", &clk_m2p7), + INIT_CK(NULL, "m2p8", &clk_m2p8), + INIT_CK(NULL, "m2p9", &clk_m2p9), + INIT_CK(NULL, "m2m0", &clk_m2m0), + INIT_CK(NULL, "m2m1", &clk_m2m1), }; @@ -160,9 +162,11 @@ int clk_enable(struct clk *clk) u32 value; value = __raw_readl(clk->enable_reg); + value |= clk->enable_mask; if (clk->sw_locked) - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(value | clk->enable_mask, clk->enable_reg); + ep93xx_syscon_swlocked_write(value, clk->enable_reg); + else + __raw_writel(value, clk->enable_reg); } return 0; @@ -175,9 +179,11 @@ void clk_disable(struct clk *clk) u32 value; value = __raw_readl(clk->enable_reg); + value &= ~clk->enable_mask; if (clk->sw_locked) - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(value & ~clk->enable_mask, clk->enable_reg); + ep93xx_syscon_swlocked_write(value, clk->enable_reg); + else + __raw_writel(value, clk->enable_reg); } } EXPORT_SYMBOL(clk_disable); @@ -202,6 +208,43 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); +static int set_keytchclk_rate(struct clk *clk, unsigned long rate) +{ + u32 val; + u32 div_bit; + + val = __raw_readl(clk->enable_reg); + + /* + * The Key Matrix and ADC clocks are configured using the same + * System Controller register. The clock used will be either + * 1/4 or 1/16 the external clock rate depending on the + * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV + * bit being set or cleared. + */ + div_bit = clk->enable_mask >> 15; + + if (rate == EP93XX_KEYTCHCLK_DIV4) + val |= div_bit; + else if (rate == EP93XX_KEYTCHCLK_DIV16) + val &= ~div_bit; + else + return -EINVAL; + + ep93xx_syscon_swlocked_write(val, clk->enable_reg); + clk->rate = rate; + return 0; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + if (clk->set_rate) + return clk->set_rate(clk, rate); + + return -EINVAL; +} +EXPORT_SYMBOL(clk_set_rate); + static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 }; static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 }; diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 204dc5cbd0b..16b92c37ec9 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -16,40 +16,24 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/spinlock.h> -#include <linux/sched.h> +#include <linux/platform_device.h> #include <linux/interrupt.h> -#include <linux/serial.h> -#include <linux/tty.h> -#include <linux/bitops.h> -#include <linux/serial_8250.h> -#include <linux/serial_core.h> -#include <linux/device.h> -#include <linux/mm.h> #include <linux/dma-mapping.h> -#include <linux/time.h> #include <linux/timex.h> -#include <linux/delay.h> +#include <linux/io.h> +#include <linux/gpio.h> +#include <linux/leds.h> #include <linux/termios.h> #include <linux/amba/bus.h> #include <linux/amba/serial.h> -#include <linux/io.h> #include <linux/i2c.h> #include <linux/i2c-gpio.h> -#include <asm/types.h> -#include <asm/setup.h> -#include <asm/memory.h> #include <mach/hardware.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/tlbflush.h> -#include <asm/pgtable.h> #include <asm/mach/map.h> #include <asm/mach/time.h> #include <asm/mach/irq.h> -#include <mach/gpio.h> #include <asm/hardware/vic.h> @@ -98,7 +82,7 @@ void __init ep93xx_map_io(void) */ static unsigned int last_jiffy_time; -#define TIMER4_TICKS_PER_JIFFY ((CLOCK_TICK_RATE + (HZ/2)) / HZ) +#define TIMER4_TICKS_PER_JIFFY DIV_ROUND_CLOSEST(CLOCK_TICK_RATE, HZ) static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id) { @@ -362,8 +346,8 @@ void __init ep93xx_init_irq(void) { int gpio_irq; - vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); - vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); + vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); + vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); for (gpio_irq = gpio_to_irq(0); gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) { @@ -385,6 +369,47 @@ void __init ep93xx_init_irq(void) /************************************************************************* + * EP93xx System Controller Software Locked register handling + *************************************************************************/ + +/* + * syscon_swlock prevents anything else from writing to the syscon + * block while a software locked register is being written. + */ +static DEFINE_SPINLOCK(syscon_swlock); + +void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg) +{ + unsigned long flags; + + spin_lock_irqsave(&syscon_swlock, flags); + + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); + __raw_writel(val, reg); + + spin_unlock_irqrestore(&syscon_swlock, flags); +} +EXPORT_SYMBOL(ep93xx_syscon_swlocked_write); + +void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits) +{ + unsigned long flags; + unsigned int val; + + spin_lock_irqsave(&syscon_swlock, flags); + + val = __raw_readl(EP93XX_SYSCON_DEVCFG); + val |= set_bits; + val &= ~clear_bits; + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); + __raw_writel(val, EP93XX_SYSCON_DEVCFG); + + spin_unlock_irqrestore(&syscon_swlock, flags); +} +EXPORT_SYMBOL(ep93xx_devcfg_set_clear); + + +/************************************************************************* * EP93xx peripheral handling *************************************************************************/ #define EP93XX_UART_MCR_OFFSET (0x0100) @@ -517,10 +542,8 @@ static struct platform_device ep93xx_eth_device = { void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr) { - if (copy_addr) { - memcpy(data->dev_addr, - (void *)(EP93XX_ETHERNET_BASE + 0x50), 6); - } + if (copy_addr) + memcpy_fromio(data->dev_addr, EP93XX_ETHERNET_BASE + 0x50, 6); ep93xx_eth_data = *data; platform_device_register(&ep93xx_eth_device); @@ -546,19 +569,125 @@ void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num) platform_device_register(&ep93xx_i2c_device); } + +/************************************************************************* + * EP93xx LEDs + *************************************************************************/ +static struct gpio_led ep93xx_led_pins[] = { + { + .name = "platform:grled", + .gpio = EP93XX_GPIO_LINE_GRLED, + }, { + .name = "platform:rdled", + .gpio = EP93XX_GPIO_LINE_RDLED, + }, +}; + +static struct gpio_led_platform_data ep93xx_led_data = { + .num_leds = ARRAY_SIZE(ep93xx_led_pins), + .leds = ep93xx_led_pins, +}; + +static struct platform_device ep93xx_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &ep93xx_led_data, + }, +}; + + +/************************************************************************* + * EP93xx pwm peripheral handling + *************************************************************************/ +static struct resource ep93xx_pwm0_resource[] = { + { + .start = EP93XX_PWM_PHYS_BASE, + .end = EP93XX_PWM_PHYS_BASE + 0x10 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ep93xx_pwm0_device = { + .name = "ep93xx-pwm", + .id = 0, + .num_resources = ARRAY_SIZE(ep93xx_pwm0_resource), + .resource = ep93xx_pwm0_resource, +}; + +static struct resource ep93xx_pwm1_resource[] = { + { + .start = EP93XX_PWM_PHYS_BASE + 0x20, + .end = EP93XX_PWM_PHYS_BASE + 0x30 - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device ep93xx_pwm1_device = { + .name = "ep93xx-pwm", + .id = 1, + .num_resources = ARRAY_SIZE(ep93xx_pwm1_resource), + .resource = ep93xx_pwm1_resource, +}; + +void __init ep93xx_register_pwm(int pwm0, int pwm1) +{ + if (pwm0) + platform_device_register(&ep93xx_pwm0_device); + + /* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */ + if (pwm1) + platform_device_register(&ep93xx_pwm1_device); +} + +int ep93xx_pwm_acquire_gpio(struct platform_device *pdev) +{ + int err; + + if (pdev->id == 0) { + err = 0; + } else if (pdev->id == 1) { + err = gpio_request(EP93XX_GPIO_LINE_EGPIO14, + dev_name(&pdev->dev)); + if (err) + return err; + err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0); + if (err) + goto fail; + + /* PWM 1 output on EGPIO[14] */ + ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG); + } else { + err = -ENODEV; + } + + return err; + +fail: + gpio_free(EP93XX_GPIO_LINE_EGPIO14); + return err; +} +EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio); + +void ep93xx_pwm_release_gpio(struct platform_device *pdev) +{ + if (pdev->id == 1) { + gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14); + gpio_free(EP93XX_GPIO_LINE_EGPIO14); + + /* EGPIO[14] used for GPIO */ + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG); + } +} +EXPORT_SYMBOL(ep93xx_pwm_release_gpio); + + extern void ep93xx_gpio_init(void); void __init ep93xx_init_devices(void) { - unsigned int v; - - /* - * Disallow access to MaverickCrunch initially. - */ - v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); - v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG); + /* Disallow access to MaverickCrunch initially */ + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); ep93xx_gpio_init(); @@ -568,4 +697,5 @@ void __init ep93xx_init_devices(void) platform_device_register(&ep93xx_rtc_device); platform_device_register(&ep93xx_ohci_device); + platform_device_register(&ep93xx_leds); } diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index e9e45b92457..73145ae5d3f 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c @@ -26,18 +26,16 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/mtd/physmap.h> #include <linux/platform_device.h> -#include <linux/io.h> #include <linux/i2c.h> +#include <linux/mtd/physmap.h> + #include <mach/hardware.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> + static struct physmap_flash_data edb93xx_flash_data; static struct resource edb93xx_flash_resource = { diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c index 3bad500b71b..3da7ca816d1 100644 --- a/arch/arm/mach-ep93xx/gesbc9312.c +++ b/arch/arm/mach-ep93xx/gesbc9312.c @@ -12,18 +12,15 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/mtd/physmap.h> #include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/i2c.h> +#include <linux/mtd/physmap.h> + #include <mach/hardware.h> + #include <asm/mach-types.h> #include <asm/mach/arch.h> + static struct physmap_flash_data gesbc9312_flash_data = { .width = 4, }; diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c index 482cf3d2fbc..1ea8871e03a 100644 --- a/arch/arm/mach-ep93xx/gpio.c +++ b/arch/arm/mach-ep93xx/gpio.c @@ -17,15 +17,16 @@ #include <linux/module.h> #include <linux/seq_file.h> #include <linux/io.h> +#include <linux/gpio.h> +#include <linux/irq.h> -#include <mach/ep93xx-regs.h> -#include <asm/gpio.h> +#include <mach/hardware.h> struct ep93xx_gpio_chip { struct gpio_chip chip; - unsigned int data_reg; - unsigned int data_dir_reg; + void __iomem *data_reg; + void __iomem *data_dir_reg; }; #define to_ep93xx_gpio_chip(c) container_of(c, struct ep93xx_gpio_chip, chip) @@ -111,15 +112,61 @@ static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip); u8 data_reg, data_dir_reg; - int i; + int gpio, i; data_reg = __raw_readb(ep93xx_chip->data_reg); data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg); - for (i = 0; i < chip->ngpio; i++) - seq_printf(s, "GPIO %s%d: %s %s\n", chip->label, i, - (data_reg & (1 << i)) ? "set" : "clear", - (data_dir_reg & (1 << i)) ? "out" : "in"); + gpio = ep93xx_chip->chip.base; + for (i = 0; i < chip->ngpio; i++, gpio++) { + int is_out = data_dir_reg & (1 << i); + + seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s", + chip->label, i, gpio, + gpiochip_is_requested(chip, i) ? : "", + is_out ? "out" : "in ", + (data_reg & (1 << i)) ? "hi" : "lo"); + + if (!is_out) { + int irq = gpio_to_irq(gpio); + struct irq_desc *desc = irq_desc + irq; + + if (irq >= 0 && desc->action) { + char *trigger; + + switch (desc->status & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_NONE: + trigger = "(default)"; + break; + case IRQ_TYPE_EDGE_FALLING: + trigger = "edge-falling"; + break; + case IRQ_TYPE_EDGE_RISING: + trigger = "edge-rising"; + break; + case IRQ_TYPE_EDGE_BOTH: + trigger = "edge-both"; + break; + case IRQ_TYPE_LEVEL_HIGH: + trigger = "level-high"; + break; + case IRQ_TYPE_LEVEL_LOW: + trigger = "level-low"; + break; + default: + trigger = "?trigger?"; + break; + } + + seq_printf(s, " irq-%d %s%s", + irq, trigger, + (desc->status & IRQ_WAKEUP) + ? " wakeup" : ""); + } + } + + seq_printf(s, "\n"); + } } #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio) \ diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index 967c079180d..ea78e908fc8 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h @@ -52,40 +52,43 @@ #define EP93XX_AHB_VIRT_BASE 0xfef00000 #define EP93XX_AHB_SIZE 0x00100000 +#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x)) + #define EP93XX_APB_PHYS_BASE 0x80800000 #define EP93XX_APB_VIRT_BASE 0xfed00000 #define EP93XX_APB_SIZE 0x00200000 +#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x)) + /* AHB peripherals */ -#define EP93XX_DMA_BASE ((void __iomem *) \ - (EP93XX_AHB_VIRT_BASE + 0x00000000)) +#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000) -#define EP93XX_ETHERNET_BASE (EP93XX_AHB_VIRT_BASE + 0x00010000) #define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000) +#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000) -#define EP93XX_USB_BASE (EP93XX_AHB_VIRT_BASE + 0x00020000) #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) +#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) -#define EP93XX_RASTER_BASE (EP93XX_AHB_VIRT_BASE + 0x00030000) +#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) -#define EP93XX_GRAPHICS_ACCEL_BASE (EP93XX_AHB_VIRT_BASE + 0x00040000) +#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) -#define EP93XX_SDRAM_CONTROLLER_BASE (EP93XX_AHB_VIRT_BASE + 0x00060000) +#define EP93XX_SDRAM_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00060000) -#define EP93XX_PCMCIA_CONTROLLER_BASE (EP93XX_AHB_VIRT_BASE + 0x00080000) +#define EP93XX_PCMCIA_CONTROLLER_BASE EP93XX_AHB_IOMEM(0x00080000) -#define EP93XX_BOOT_ROM_BASE (EP93XX_AHB_VIRT_BASE + 0x00090000) +#define EP93XX_BOOT_ROM_BASE EP93XX_AHB_IOMEM(0x00090000) -#define EP93XX_IDE_BASE (EP93XX_AHB_VIRT_BASE + 0x000a0000) +#define EP93XX_IDE_BASE EP93XX_AHB_IOMEM(0x000a0000) -#define EP93XX_VIC1_BASE (EP93XX_AHB_VIRT_BASE + 0x000b0000) +#define EP93XX_VIC1_BASE EP93XX_AHB_IOMEM(0x000b0000) -#define EP93XX_VIC2_BASE (EP93XX_AHB_VIRT_BASE + 0x000c0000) +#define EP93XX_VIC2_BASE EP93XX_AHB_IOMEM(0x000c0000) /* APB peripherals */ -#define EP93XX_TIMER_BASE (EP93XX_APB_VIRT_BASE + 0x00010000) +#define EP93XX_TIMER_BASE EP93XX_APB_IOMEM(0x00010000) #define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x)) #define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00) #define EP93XX_TIMER1_VALUE EP93XX_TIMER_REG(0x04) @@ -102,11 +105,11 @@ #define EP93XX_TIMER3_CONTROL EP93XX_TIMER_REG(0x88) #define EP93XX_TIMER3_CLEAR EP93XX_TIMER_REG(0x8c) -#define EP93XX_I2S_BASE (EP93XX_APB_VIRT_BASE + 0x00020000) +#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000) -#define EP93XX_SECURITY_BASE (EP93XX_APB_VIRT_BASE + 0x00030000) +#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000) -#define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000) +#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) #define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) #define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c) #define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50) @@ -124,32 +127,33 @@ #define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8) #define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) -#define EP93XX_AAC_BASE (EP93XX_APB_VIRT_BASE + 0x00080000) +#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) -#define EP93XX_SPI_BASE (EP93XX_APB_VIRT_BASE + 0x000a0000) +#define EP93XX_SPI_BASE EP93XX_APB_IOMEM(0x000a0000) -#define EP93XX_IRDA_BASE (EP93XX_APB_VIRT_BASE + 0x000b0000) +#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) -#define EP93XX_UART1_BASE (EP93XX_APB_VIRT_BASE + 0x000c0000) #define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000) +#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000) -#define EP93XX_UART2_BASE (EP93XX_APB_VIRT_BASE + 0x000d0000) #define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000) +#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000) -#define EP93XX_UART3_BASE (EP93XX_APB_VIRT_BASE + 0x000e0000) #define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000) +#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) -#define EP93XX_KEY_MATRIX_BASE (EP93XX_APB_VIRT_BASE + 0x000f0000) +#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) -#define EP93XX_ADC_BASE (EP93XX_APB_VIRT_BASE + 0x00100000) -#define EP93XX_TOUCHSCREEN_BASE (EP93XX_APB_VIRT_BASE + 0x00100000) +#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) +#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) -#define EP93XX_PWM_BASE (EP93XX_APB_VIRT_BASE + 0x00110000) +#define EP93XX_PWM_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00110000) +#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) -#define EP93XX_RTC_BASE (EP93XX_APB_VIRT_BASE + 0x00120000) #define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) +#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000) -#define EP93XX_SYSCON_BASE (EP93XX_APB_VIRT_BASE + 0x00130000) +#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000) #define EP93XX_SYSCON_REG(x) (EP93XX_SYSCON_BASE + (x)) #define EP93XX_SYSCON_POWER_STATE EP93XX_SYSCON_REG(0x00) #define EP93XX_SYSCON_PWRCNT EP93XX_SYSCON_REG(0x04) @@ -172,14 +176,45 @@ #define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) #define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20) #define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24) -#define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) -#define EP93XX_SYSCON_DEVICE_CONFIG_U3EN (1<<24) -#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE (1<<23) -#define EP93XX_SYSCON_DEVICE_CONFIG_U2EN (1<<20) -#define EP93XX_SYSCON_DEVICE_CONFIG_U1EN (1<<18) +#define EP93XX_SYSCON_DEVCFG EP93XX_SYSCON_REG(0x80) +#define EP93XX_SYSCON_DEVCFG_SWRST (1<<31) +#define EP93XX_SYSCON_DEVCFG_D1ONG (1<<30) +#define EP93XX_SYSCON_DEVCFG_D0ONG (1<<29) +#define EP93XX_SYSCON_DEVCFG_IONU2 (1<<28) +#define EP93XX_SYSCON_DEVCFG_GONK (1<<27) +#define EP93XX_SYSCON_DEVCFG_TONG (1<<26) +#define EP93XX_SYSCON_DEVCFG_MONG (1<<25) +#define EP93XX_SYSCON_DEVCFG_U3EN (1<<24) +#define EP93XX_SYSCON_DEVCFG_CPENA (1<<23) +#define EP93XX_SYSCON_DEVCFG_A2ONG (1<<22) +#define EP93XX_SYSCON_DEVCFG_A1ONG (1<<21) +#define EP93XX_SYSCON_DEVCFG_U2EN (1<<20) +#define EP93XX_SYSCON_DEVCFG_EXVC (1<<19) +#define EP93XX_SYSCON_DEVCFG_U1EN (1<<18) +#define EP93XX_SYSCON_DEVCFG_TIN (1<<17) +#define EP93XX_SYSCON_DEVCFG_HC3IN (1<<15) +#define EP93XX_SYSCON_DEVCFG_HC3EN (1<<14) +#define EP93XX_SYSCON_DEVCFG_HC1IN (1<<13) +#define EP93XX_SYSCON_DEVCFG_HC1EN (1<<12) +#define EP93XX_SYSCON_DEVCFG_HONIDE (1<<11) +#define EP93XX_SYSCON_DEVCFG_GONIDE (1<<10) +#define EP93XX_SYSCON_DEVCFG_PONG (1<<9) +#define EP93XX_SYSCON_DEVCFG_EONIDE (1<<8) +#define EP93XX_SYSCON_DEVCFG_I2SONSSP (1<<7) +#define EP93XX_SYSCON_DEVCFG_I2SONAC97 (1<<6) +#define EP93XX_SYSCON_DEVCFG_RASONP3 (1<<4) +#define EP93XX_SYSCON_DEVCFG_RAS (1<<3) +#define EP93XX_SYSCON_DEVCFG_ADCPD (1<<2) +#define EP93XX_SYSCON_DEVCFG_KEYS (1<<1) +#define EP93XX_SYSCON_DEVCFG_SHENA (1<<0) +#define EP93XX_SYSCON_KEYTCHCLKDIV EP93XX_SYSCON_REG(0x90) +#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN (1<<31) +#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) +#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15) +#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0) #define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) -#define EP93XX_WATCHDOG_BASE (EP93XX_APB_VIRT_BASE + 0x00140000) +#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) #endif diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index 2866297310b..349fa7cb72d 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h @@ -4,12 +4,23 @@ #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H -#include "ep93xx-regs.h" +#include <mach/ep93xx-regs.h> +#include <mach/platform.h> #define pcibios_assign_all_busses() 0 -#include "platform.h" +/* + * The EP93xx has two external crystal oscillators. To generate the + * required high-frequency clocks, the processor uses two phase-locked- + * loops (PLLs) to multiply the incoming external clock signal to much + * higher frequencies that are then divided down by programmable dividers + * to produce the needed clocks. The PLLs operate independently of one + * another. + */ +#define EP93XX_EXT_CLK_RATE 14745600 +#define EP93XX_EXT_RTC_RATE 32768 -#include "ts72xx.h" +#define EP93XX_KEYTCHCLK_DIV4 (EP93XX_EXT_CLK_RATE / 4) +#define EP93XX_KEYTCHCLK_DIV16 (EP93XX_EXT_CLK_RATE / 16) #endif diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h index fd5f081cc8b..cebcc1c53d6 100644 --- a/arch/arm/mach-ep93xx/include/mach/io.h +++ b/arch/arm/mach-ep93xx/include/mach/io.h @@ -1,8 +1,21 @@ /* * arch/arm/mach-ep93xx/include/mach/io.h */ +#ifndef __ASM_MACH_IO_H +#define __ASM_MACH_IO_H #define IO_SPACE_LIMIT 0xffffffff -#define __io(p) __typesafe_io(p) -#define __mem_pci(p) (p) +#define __io(p) __typesafe_io(p) +#define __mem_pci(p) (p) + +/* + * A typesafe __io() variation for variable initialisers + */ +#ifdef __ASSEMBLER__ +#define IOMEM(p) p +#else +#define IOMEM(p) ((void __iomem __force *)(p)) +#endif + +#endif /* __ASM_MACH_IO_H */ diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 05f0f4f2f3c..5f5fa6574d3 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h @@ -5,6 +5,7 @@ #ifndef __ASSEMBLY__ struct i2c_board_info; +struct platform_device; struct ep93xx_eth_data { @@ -15,8 +16,27 @@ struct ep93xx_eth_data void ep93xx_map_io(void); void ep93xx_init_irq(void); void ep93xx_init_time(unsigned long); + +/* EP93xx System Controller software locked register write */ +void ep93xx_syscon_swlocked_write(unsigned int val, void __iomem *reg); +void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits); + +static inline void ep93xx_devcfg_set_bits(unsigned int bits) +{ + ep93xx_devcfg_set_clear(bits, 0x00); +} + +static inline void ep93xx_devcfg_clear_bits(unsigned int bits) +{ + ep93xx_devcfg_set_clear(0x00, bits); +} + void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); void ep93xx_register_i2c(struct i2c_board_info *devices, int num); +void ep93xx_register_pwm(int pwm0, int pwm1); +int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); +void ep93xx_pwm_release_gpio(struct platform_device *pdev); + void ep93xx_init_devices(void); extern struct sys_timer ep93xx_timer; diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h index ed8f35e4f06..6d661fe9d66 100644 --- a/arch/arm/mach-ep93xx/include/mach/system.h +++ b/arch/arm/mach-ep93xx/include/mach/system.h @@ -11,15 +11,13 @@ static inline void arch_idle(void) static inline void arch_reset(char mode, const char *cmd) { - u32 devicecfg; - local_irq_disable(); - devicecfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(devicecfg | 0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(devicecfg & ~0x80000000, EP93XX_SYSCON_DEVICE_CONFIG); + /* + * Set then clear the SWRST bit to initiate a software reset + */ + ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_SWRST); + ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_SWRST); while (1) ; diff --git a/arch/arm/mach-ep93xx/include/mach/ts72xx.h b/arch/arm/mach-ep93xx/include/mach/ts72xx.h index 411734422c1..3bd934e9a7f 100644 --- a/arch/arm/mach-ep93xx/include/mach/ts72xx.h +++ b/arch/arm/mach-ep93xx/include/mach/ts72xx.h @@ -67,7 +67,6 @@ #ifndef __ASSEMBLY__ -#include <linux/io.h> static inline int board_is_ts7200(void) { diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c index 15d6815d78c..0a313e82fb7 100644 --- a/arch/arm/mach-ep93xx/micro9.c +++ b/arch/arm/mach-ep93xx/micro9.c @@ -9,21 +9,16 @@ * published by the Free Software Foundation. */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> #include <linux/kernel.h> -#include <linux/mm.h> +#include <linux/init.h> #include <linux/platform_device.h> -#include <linux/sched.h> -#include <linux/io.h> -#include <linux/i2c.h> #include <linux/mtd/physmap.h> #include <mach/hardware.h> -#include <asm/mach/arch.h> #include <asm/mach-types.h> +#include <asm/mach/arch.h> + static struct ep93xx_eth_data micro9_eth_data = { .phy_id = 0x1f, diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index aaf1371412a..259f7822ba5 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -12,19 +12,18 @@ #include <linux/kernel.h> #include <linux/init.h> -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/mtd/physmap.h> #include <linux/platform_device.h> -#include <linux/m48t86.h> #include <linux/io.h> -#include <linux/i2c.h> +#include <linux/m48t86.h> +#include <linux/mtd/physmap.h> + #include <mach/hardware.h> +#include <mach/ts72xx.h> + #include <asm/mach-types.h> -#include <asm/mach/arch.h> #include <asm/mach/map.h> +#include <asm/mach/arch.h> + static struct map_desc ts72xx_io_desc[] __initdata = { { |