From e88db8b91f1f5de24ae6bb3241d92fecaae64abf Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 26 Nov 2008 18:25:52 +0800 Subject: Revert "[ARM] pxa: introduce cpu_is_pxa26x()" This reverts commit da1a3dc0ebb4f9209a1939eaa6b18901e0cd7bc0. The originally proposed way in the above commit is incorrect. And there is no easy way to distinguish between pxa25x and pxa26x at run-time. Signed-off-by: Eric Miao --- arch/arm/mach-pxa/pxa25x.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch/arm/mach-pxa/pxa25x.c') diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 25d17a1dab78..6543321a2df4 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -36,12 +36,6 @@ #include "devices.h" #include "clock.h" -int cpu_is_pxa26x(void) -{ - return cpu_is_pxa250() && ((BOOT_DEF & 0x8) == 0); -} -EXPORT_SYMBOL_GPL(cpu_is_pxa26x); - /* * Various clock factors driven by the CCCR register. */ @@ -356,7 +350,7 @@ static int __init pxa25x_init(void) } /* Only add HWUART for PXA255/26x; PXA210/250 do not have it. */ - if (cpu_is_pxa255() || cpu_is_pxa26x()) { + if (cpu_is_pxa255()) { clks_register(&pxa25x_hwuart_clk, 1); ret = platform_device_register(&pxa_device_hwuart); } -- cgit v1.2.3 From 067455aa53a55404ded85227e87436478c2acc63 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 26 Nov 2008 18:12:04 +0800 Subject: [ARM] pxa: add support for additional GPIOs on PXA26x Original patch from Marek Vasut, the problems with PXA26x are: 1. there are additional 4 GPIOs 86,87,88,89 have their direction bits inverted in GPDR2, as well as their alternate function bits being '1' for their GPIO functionality in GAFRx 2. there is no easy way to decide if the processor is a pxa26x or a pxa250/pxa255 at run-time, so the assumption here is the pxa26x will be treated as one of the pxa25x variants, and board code should have a better knowledge of the processor it is featured Introduce pxa26x_init_irq() for the second purpose, and treat the additional GPIOs > 85 on PXA25x specially. Kconfig option CONFIG_CPU_PXA26x is introduced to optimize the code a bit when PXA26x support isn't needed. Board config options have to select this to enable the support for PXA26x. __gpio_is_inverted() will be optimized way when CONFIG_CPU_PXA26x isn't selected. Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/Kconfig | 6 ++++ arch/arm/mach-pxa/gpio.c | 47 +++++++++++++++++++++++------ arch/arm/mach-pxa/include/mach/mfp-pxa25x.h | 31 +++++++++++++++++++ arch/arm/mach-pxa/mfp-pxa2xx.c | 19 ++++++++---- arch/arm/mach-pxa/pxa25x.c | 8 +++++ 5 files changed, 95 insertions(+), 16 deletions(-) (limited to 'arch/arm/mach-pxa/pxa25x.c') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index a062235e83a8..6c59f989a61a 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -394,6 +394,12 @@ config PXA27x help Select code specific to PXA27x variants +config CPU_PXA26x + bool + select PXA25x + help + Select code specific to PXA26x (codename Dalhart) + config PXA3xx bool help diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c index 14930cf8be7b..843144ff1f61 100644 --- a/arch/arm/mach-pxa/gpio.c +++ b/arch/arm/mach-pxa/gpio.c @@ -33,6 +33,18 @@ struct pxa_gpio_chip { int pxa_last_gpio; +#ifdef CONFIG_CPU_PXA26x +/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted, + * as well as their Alternate Function value being '1' for GPIO in GAFRx. + */ +static int __gpio_is_inverted(unsigned gpio) +{ + return cpu_is_pxa25x() && gpio > 85; +} +#else +#define __gpio_is_inverted(gpio) (0) +#endif + /* * Configure pins for GPIO or other functions */ @@ -75,7 +87,10 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) gpdr = pxa->regbase + GPDR_OFFSET; local_irq_save(flags); value = __raw_readl(gpdr); - value &= ~mask; + if (__gpio_is_inverted(chip->base + offset)) + value |= mask; + else + value &= ~mask; __raw_writel(value, gpdr); local_irq_restore(flags); @@ -97,7 +112,10 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, gpdr = pxa->regbase + GPDR_OFFSET; local_irq_save(flags); tmp = __raw_readl(gpdr); - tmp |= mask; + if (__gpio_is_inverted(chip->base + offset)) + tmp &= ~mask; + else + tmp |= mask; __raw_writel(tmp, gpdr); local_irq_restore(flags); @@ -173,10 +191,17 @@ static unsigned long GPIO_IRQ_mask[4]; */ static int __gpio_is_occupied(unsigned gpio) { - if (cpu_is_pxa25x() || cpu_is_pxa27x()) - return GAFR(gpio) & (0x3 << (((gpio) & 0xf) * 2)); - else - return 0; + if (cpu_is_pxa27x() || cpu_is_pxa25x()) { + int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3; + int dir = GPDR(gpio) & GPIO_bit(gpio); + + if (__gpio_is_inverted(gpio)) + return af != 1 || dir == 0; + else + return af != 0 || dir != 0; + } + + return 0; } static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) @@ -190,9 +215,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) /* Don't mess with enabled GPIOs using preconfigured edges or * GPIOs set to alternate function or to output during probe */ - if ((GPIO_IRQ_rising_edge[idx] | - GPIO_IRQ_falling_edge[idx] | - GPDR(gpio)) & GPIO_bit(gpio)) + if ((GPIO_IRQ_rising_edge[idx] & GPIO_bit(gpio)) || + (GPIO_IRQ_falling_edge[idx] & GPIO_bit(gpio))) return 0; if (__gpio_is_occupied(gpio)) @@ -201,7 +225,10 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; } - GPDR(gpio) &= ~GPIO_bit(gpio); + if (__gpio_is_inverted(gpio)) + GPDR(gpio) |= GPIO_bit(gpio); + else + GPDR(gpio) &= ~GPIO_bit(gpio); if (type & IRQ_TYPE_EDGE_RISING) __set_bit(gpio, GPIO_IRQ_rising_edge); diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h index 617cab2cc8d0..a72869b73ee3 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa25x.h @@ -158,4 +158,35 @@ #define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW) #define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW) +#ifdef CONFIG_CPU_PXA26x +/* GPIO */ +#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0) +#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF1) +#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF1) +#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF1) +#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF1) + +/* SDRAM */ +#define GPIO86_nSDCS2 MFP_CFG_OUT(GPIO86, AF0, DRIVE_HIGH) +#define GPIO87_nSDCS3 MFP_CFG_OUT(GPIO87, AF0, DRIVE_HIGH) +#define GPIO88_RDnWR MFP_CFG_OUT(GPIO88, AF0, DRIVE_HIGH) +#define GPIO89_nACRESET MFP_CFG_OUT(GPIO89, AF0, DRIVE_HIGH) + +/* USB */ +#define GPIO9_USB_RCV MFP_CFG_IN(GPIO9, AF1) +#define GPIO32_USB_VP MFP_CFG_IN(GPIO32, AF2) +#define GPIO34_USB_VM MFP_CFG_IN(GPIO34, AF2) +#define GPIO39_USB_VPO MFP_CFG_OUT(GPIO39, AF3, DRIVE_LOW) +#define GPIO56_USB_VMO MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW) +#define GPIO57_USB_nOE MFP_CFG_OUT(GPIO57, AF1, DRIVE_HIGH) + +/* ASSP */ +#define GPIO28_ASSP_BITCLK_IN MFP_CFG_IN(GPIO28, AF3) +#define GPIO28_ASSP_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF3, DRIVE_LOW) +#define GPIO29_ASSP_RXD MFP_CFG_IN(GPIO29, AF3) +#define GPIO30_ASSP_TXD MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW) +#define GPIO31_ASSP_SFRM_IN MFP_CFG_IN(GPIO31, AF1) +#define GPIO31_ASSP_SFRM_OUT MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW) +#endif + #endif /* __ASM_ARCH_MFP_PXA25X_H */ diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 1f2298759077..33626de8cbf6 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -38,6 +38,7 @@ struct gpio_desc { unsigned valid : 1; unsigned can_wakeup : 1; unsigned keypad_gpio : 1; + unsigned dir_inverted : 1; unsigned int mask; /* bit mask in PWER or PKWR */ unsigned int mux_mask; /* bit mask of muxed gpio bits, 0 if no mux */ unsigned long config; @@ -54,7 +55,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */ int shft = (gpio & 0xf) << 1; int fn = MFP_AF(c); - int dir = c & MFP_DIR_OUT; + int is_out = (c & MFP_DIR_OUT) ? 1 : 0; if (fn > 3) return -EINVAL; @@ -68,7 +69,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) else GAFR_U(bank) = gafr; - if (dir == MFP_DIR_OUT) + if (is_out ^ gpio_desc[gpio].dir_inverted) GPDR(gpio) |= mask; else GPDR(gpio) &= ~mask; @@ -77,11 +78,11 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) switch (c & MFP_LPM_STATE_MASK) { case MFP_LPM_DRIVE_HIGH: PGSR(bank) |= mask; - dir = MFP_DIR_OUT; + is_out = 1; break; case MFP_LPM_DRIVE_LOW: PGSR(bank) &= ~mask; - dir = MFP_DIR_OUT; + is_out = 1; break; case MFP_LPM_DEFAULT: break; @@ -92,7 +93,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) break; } - if (dir == MFP_DIR_OUT) + if (is_out ^ gpio_desc[gpio].dir_inverted) gpdr_lpm[bank] |= mask; else gpdr_lpm[bank] &= ~mask; @@ -106,7 +107,7 @@ static int __mfp_config_gpio(unsigned gpio, unsigned long c) return -EINVAL; } - if ((c & MFP_LPM_CAN_WAKEUP) && (dir == MFP_DIR_OUT)) { + if ((c & MFP_LPM_CAN_WAKEUP) && is_out) { pr_warning("%s: output GPIO%d unable to wakeup\n", __func__, gpio); return -EINVAL; @@ -221,6 +222,12 @@ static void __init pxa25x_mfp_init(void) gpio_desc[i].can_wakeup = 1; gpio_desc[i].mask = GPIO_bit(i); } + + /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the + * direction bit inverted in GPDR2. See PXA26x DM 4.1.1. + */ + for (i = 86; i <= pxa_last_gpio; i++) + gpio_desc[i].dir_inverted = 1; } #else static inline void pxa25x_mfp_init(void) {} diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 6543321a2df4..0f672998b2eb 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -298,6 +298,14 @@ void __init pxa25x_init_irq(void) pxa_init_gpio(85, pxa25x_set_wake); } +#ifdef CONFIG_CPU_PXA26x +void __init pxa26x_init_irq(void) +{ + pxa_init_irq(32, pxa25x_set_wake); + pxa_init_gpio(90, pxa25x_set_wake); +} +#endif + static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_udc, &pxa_device_ffuart, -- cgit v1.2.3 From 724931465c234f71551e229dcd8842d1fc531d77 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 13 Nov 2008 23:50:56 +0100 Subject: [ARM] pxa: add resources for incoming rtc-pxa driver Add IO memory and IRQ ressources for pxa based SoC to be able to use the new rtc-pxa driver. Signed-off-by: Robert Jarzmik Signed-off-by: Eric Miao --- arch/arm/mach-pxa/devices.c | 27 ++++++++++++++++++++++++++- arch/arm/mach-pxa/devices.h | 1 + arch/arm/mach-pxa/pxa25x.c | 2 +- arch/arm/mach-pxa/pxa27x.c | 1 + arch/arm/mach-pxa/pxa3xx.c | 1 + 5 files changed, 30 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-pxa/pxa25x.c') diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 88c362651445..e16f8e3d58d3 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -330,11 +330,36 @@ void __init pxa_set_ficp_info(struct pxaficp_platform_data *info) pxa_register_device(&pxa_device_ficp, info); } -struct platform_device pxa_device_rtc = { +static struct resource pxa_rtc_resources[] = { + [0] = { + .start = 0x40900000, + .end = 0x40900000 + 0x3b, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_RTC1Hz, + .end = IRQ_RTC1Hz, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IRQ_RTCAlrm, + .end = IRQ_RTCAlrm, + .flags = IORESOURCE_IRQ, + }, +}; + +struct platform_device sa1100_device_rtc = { .name = "sa1100-rtc", .id = -1, }; +struct platform_device pxa_device_rtc = { + .name = "pxa-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(pxa_rtc_resources), + .resource = pxa_rtc_resources, +}; + static struct resource pxa_ac97_resources[] = { [0] = { .start = 0x40500000, diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index bb04af4b0aa3..ecc24a4dca6d 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -11,6 +11,7 @@ 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 sa1100_device_rtc; extern struct platform_device pxa_device_rtc; extern struct platform_device pxa_device_ac97; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 0f672998b2eb..265b8a5657b7 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -312,7 +312,7 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa_device_btuart, &pxa_device_stuart, &pxa_device_i2s, - &pxa_device_rtc, + &sa1100_device_rtc, &pxa25x_device_ssp, &pxa25x_device_nssp, &pxa25x_device_assp, diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7769718a80b4..9fdef7641c2f 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -333,6 +333,7 @@ static struct platform_device *devices[] __initdata = { &pxa_device_btuart, &pxa_device_stuart, &pxa_device_i2s, + &sa1100_device_rtc, &pxa_device_rtc, &pxa27x_device_ssp1, &pxa27x_device_ssp2, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index a9b175684736..041b8abb9e1a 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -541,6 +541,7 @@ static struct platform_device *devices[] __initdata = { &pxa_device_btuart, &pxa_device_stuart, &pxa_device_i2s, + &sa1100_device_rtc, &pxa_device_rtc, &pxa27x_device_ssp1, &pxa27x_device_ssp2, -- cgit v1.2.3