GIT a06c536a927c4b40a7daf4629f4e8d856e4a0677 git://www.atmel.no/~hskinnemoen/linux/kernel/avr32.git#avr32-arch commit c167d302a0f9d1bad5f85d3fc245565055c19e9e Author: Haavard Skinnemoen Date: Fri Dec 8 12:55:03 2006 +0100 [AVR32] Add missing #include to delay.c __const_udelay() needs HZ, which is defined in . Signed-off-by: Haavard Skinnemoen commit 555b7e75007c3e3b36abebb942cff0aa9538260e Author: Haavard Skinnemoen Date: Fri Dec 8 12:53:26 2006 +0100 [AVR32] Pass dev parameter to dma_cache_sync() Fix build breakage resulting from the extra dev parameter added to dma_cache_sync(). Signed-off-by: Haavard Skinnemoen commit 14e7348dbe12c48bc582428d6205fbe242012d76 Author: Haavard Skinnemoen Date: Fri Dec 8 11:04:19 2006 +0100 [AVR32] Implement intc_get_pending() intc_get_pending() returns a bitmask with pending interrupts in a interrupt controller group (irq). This is used by the upcoming oprofile implementation for avr32 and may also be useful for chained interrupt controller drivers. Signed-off-by: Haavard Skinnemoen commit 58d5a1d546106d94ad00832c5d1b1f1aa1ccc11a Author: Haavard Skinnemoen Date: Mon Dec 4 14:17:39 2006 +0100 [AVR32] Don't include Include instead of from a few places. Signed-off-by: Haavard Skinnemoen commit 758321ab07d809fd70d3abea47bf7e466fce764b Author: Haavard Skinnemoen Date: Mon Dec 4 12:01:36 2006 +0100 [AVR32] Put the chip in "stop" mode when halting the system Make machine_halt() execute a sleep instruction to put the chip in "stop" mode when the system is halted. This switches off all clocks except the 32 kHz oscillator, which is needed for the RTC to keep ticking. Signed-off-by: Haavard Skinnemoen commit 3849b8bd24ac530980ca22d67c2fce2e6f1d61d7 Author: Haavard Skinnemoen Date: Mon Dec 4 12:00:03 2006 +0100 [AVR32] Set flow handler for external interrupts Make sure that the flow handler for external interrupts is updated whenever they type is changed. Also make sure that the defaults correspond with how the interrupt controller is configured. Signed-off-by: Haavard Skinnemoen commit 655aeb931c1966ca623a84fc898e6dc2cfc54e5d Author: Haavard Skinnemoen Date: Mon Dec 4 11:52:04 2006 +0100 [AVR32] Remove unused file Remove arch/avr32/mach-at32ap/sm.c, which is not referenced by any Makefile. Signed-off-by: Haavard Skinnemoen commit 072621c1db33656b7c4a7d6049aafe4b4bc0710f Author: Haavard Skinnemoen Date: Fri Dec 1 12:34:22 2006 +0100 [AVR32] GPIO: Use flags parameter in implementation as well A previous commit added "flags" to the prototype of at32_select_periph() and at32_select_gpio(), but didn't add them to the implementation. Also fix the header guard on so that it actually gets included through Signed-off-by: Haavard Skinnemoen commit bbd3291330beb091fd5dab465a3a617390de8501 Author: Paul Mundt Date: Fri Dec 1 16:50:50 2006 +0900 avr32: Fixup kprobes preemption handling. While working on SH kprobes, I noticed that avr32 got the preemption handling wrong in the no probe case. The idea is that upon entry of kprobe_handler() preemption is disabled outright across the life of the kprobe, only to be re-enabled in post_kprobe_handler(). However, in the event that the probe is never activated, there's never any chance of hitting the post probe handler, which allows for the current avr32 implementation to disable preemption indefinitely, as it's currently missing a re-enable when no probe is activated. Signed-off-by: Paul Mundt Signed-off-by: Haavard Skinnemoen commit 30329006e31bfd45771f9c20f5e66a7c7b6a339c Author: Haavard Skinnemoen Date: Wed Nov 8 18:03:45 2006 +0100 [AVR32] Remove mii_phy_addr and eth_addr from eth_platform_data The macb driver will probe for the PHY chip and read the mac address from the MACB registers, so we don't need them in eth_platform_data anymore. Since u-boot doesn't currently initialize the MACB registers with the mac addresses, the tag parsing code is kept but instead of sticking the information into eth_platform_data, it uses it to initialize the MACB registers (in case the boot loader didn't do it.) This code should be unnecessary at some point in the future. Signed-off-by: Haavard Skinnemoen commit 23badeb9c97d427bf5d97d4e8b99b6dd235ae143 Author: Haavard Skinnemoen Date: Tue Oct 24 09:34:48 2006 +0200 [AVR32] Move ethernet tag parsing to board-specific code By moving the ethernet tag parsing to the board-specific code we avoid the issue of figuring out which device we're supposed to attach the information to. The board specific code knows this because it's where the actual devices are instantiated. Signed-off-by: Haavard Skinnemoen commit 7f7f94058905b078458bff91d983cb8f47120cf4 Author: Haavard Skinnemoen Date: Tue Oct 31 16:31:42 2006 +0100 [AVR32] Move spi device definitions into main board setup file There's no point in having a separate file just to set up the board- specific data for spi. By moving it into the rest of the board- specific setup code, we can also make sure that the data is registered before we register the spi master controller. Signed-off-by: Haavard Skinnemoen commit 73c9ad7f8421881bff02da84192cd36fdea5844c Author: Haavard Skinnemoen Date: Tue Nov 28 11:22:42 2006 +0100 [AVR32] Update spi platform_device definition Use new GPIO framework to set up the portmux, rename spi0 -> atmel_spi0, rename mck -> pclk and add platform_device definition for the second SPI controller, spi1. Signed-off-by: Haavard Skinnemoen commit 084f174242c379d90afa4f67c8bb4d86dbbb0d37 Author: Haavard Skinnemoen Date: Mon Oct 30 09:23:12 2006 +0100 [AVR32] Add macb1 platform_device Add platform_device definition and pio init code for the second ethernet controller in AT32AP7000. Signed-off-by: Haavard Skinnemoen commit 01166724887021d49a06335674f0b331bd3d5835 Author: Haavard Skinnemoen Date: Mon Nov 13 10:23:15 2006 +0100 [AVR32] Implement arch-neutral GPIO API AVR32 implementation of the arch-neutral GPIO API described by Documentation/gpio.txt. This also contains a few related changes to the irq handling and pin configuration code, to make this actually usable. Signed-off-by: Haavard Skinnemoen arch/avr32/boards/atstk1000/Makefile | 2 - arch/avr32/boards/atstk1000/atstk1002.c | 14 ++++ arch/avr32/boards/atstk1000/spi.c | 27 ------- arch/avr32/mach-at32ap/at32ap7000.c | 44 ++++++++++-- arch/avr32/mach-at32ap/pio.c | 102 ++++++++++++++++++++++++++++ include/asm-avr32/arch-at32ap/at32ap7000.h | 2 + include/asm-avr32/arch-at32ap/gpio.h | 26 +++++++ include/asm-avr32/arch-at32ap/irq.h | 11 +++ include/asm-avr32/gpio.h | 6 ++ include/asm-avr32/irq.h | 8 ++ 10 files changed, 204 insertions(+), 38 deletions(-) diff --git a/arch/avr32/boards/atstk1000/Makefile b/arch/avr32/boards/atstk1000/Makefile index df94994..8e09922 100644 --- a/arch/avr32/boards/atstk1000/Makefile +++ b/arch/avr32/boards/atstk1000/Makefile @@ -1,2 +1,2 @@ -obj-y += setup.o spi.o flash.o +obj-y += setup.o flash.o obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index 32b361f..232eb65 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -8,15 +8,18 @@ * published by the Free Software Foundation. */ #include +#include #include #include #include #include #include #include +#include #include #include +#include #include #include @@ -29,6 +32,16 @@ static struct eth_addr __initdata hw_add static struct eth_platform_data __initdata eth_data[2]; extern struct lcdc_platform_data atstk1000_fb0_data; +static struct spi_board_info spi_board_info[] __initdata = { + { + .modalias = "ltv350qv", + .controller_data = (void *)GPIO_PIN_PA(4), + .max_speed_hz = 16000000, + .bus_num = 0, + .chip_select = 1, + }, +}; + /* * The next two functions should go away as the boot loader is * supposed to initialize the macb address registers with a valid @@ -103,6 +116,7 @@ static int __init atstk1002_init(void) set_hw_addr(at32_add_device_eth(0, ð_data[0])); + spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); at32_add_device_spi(0); at32_add_device_lcdc(0, &atstk1000_fb0_data); diff --git a/arch/avr32/boards/atstk1000/spi.c b/arch/avr32/boards/atstk1000/spi.c deleted file mode 100644 index 567726c..0000000 --- a/arch/avr32/boards/atstk1000/spi.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * ATSTK1000 SPI devices - * - * Copyright (C) 2005 Atmel Norway - * - * 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 -#include - -static struct spi_board_info spi_board_info[] __initdata = { - { - .modalias = "ltv350qv", - .max_speed_hz = 16000000, - .bus_num = 0, - .chip_select = 1, - }, -}; - -static int board_init_spi(void) -{ - spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); - return 0; -} -arch_initcall(board_init_spi); diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 48f4ef3..ccea2e4 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -728,12 +728,19 @@ at32_add_device_eth(unsigned int id, str /* -------------------------------------------------------------------- * SPI * -------------------------------------------------------------------- */ -static struct resource spi0_resource[] = { +static struct resource atmel_spi0_resource[] = { PBMEM(0xffe00000), IRQ(3), }; -DEFINE_DEV(spi, 0); -DEV_CLK(mck, spi0, pba, 0); +DEFINE_DEV(atmel_spi, 0); +DEV_CLK(pclk, atmel_spi0, pba, 0); + +static struct resource atmel_spi1_resource[] = { + PBMEM(0xffe00400), + IRQ(4), +}; +DEFINE_DEV(atmel_spi, 1); +DEV_CLK(pclk, atmel_spi1, pba, 1); struct platform_device *__init at32_add_device_spi(unsigned int id) { @@ -741,13 +748,33 @@ struct platform_device *__init at32_add_ switch (id) { case 0: - pdev = &spi0_device; + pdev = &atmel_spi0_device; select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ - select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ - select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ - select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ + + /* NPCS[2:0] */ + at32_select_gpio(GPIO_PIN_PA(3), + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + at32_select_gpio(GPIO_PIN_PA(4), + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + at32_select_gpio(GPIO_PIN_PA(5), + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + break; + + case 1: + pdev = &atmel_spi1_device; + select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ + select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ + select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ + + /* NPCS[2:0] */ + at32_select_gpio(GPIO_PIN_PB(2), + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + at32_select_gpio(GPIO_PIN_PB(3), + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + at32_select_gpio(GPIO_PIN_PB(4), + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); break; default: @@ -868,7 +895,8 @@ struct clk *at32_clock_list[] = { &macb0_pclk, &macb1_hclk, &macb1_pclk, - &spi0_mck, + &atmel_spi0_mck, + &atmel_spi1_pclk, &lcdc0_hclk, &lcdc0_pixclk, }; diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index f1280ed..b19a49f 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,7 @@ struct pio_device { const struct platform_device *pdev; struct clk *clk; u32 pinmux_mask; + u32 gpio_mask; char name[32]; }; @@ -113,12 +115,106 @@ void __init at32_select_gpio(unsigned in if (!(flags & AT32_GPIOF_PULLUP)) pio_writel(pio, PUDR, mask); + /* It's now allowed to use request_gpio on this pin */ + clear_bit(pin_index, &pio->gpio_mask); + return; fail: dump_stack(); } +/* GPIO API */ + +int gpio_request(unsigned int gpio, const char *label) +{ + struct pio_device *pio; + unsigned int pin; + + pio = gpio_to_pio(gpio); + if (!pio) + return -ENODEV; + + pin = gpio & 0x1f; + if (test_and_set_bit(pin, &pio->gpio_mask)) + return -EBUSY; + + return 0; +} +EXPORT_SYMBOL(gpio_request); + +void gpio_free(unsigned int gpio) +{ + struct pio_device *pio; + unsigned int pin; + + pio = gpio_to_pio(gpio); + if (!pio) { + printk(KERN_ERR + "gpio: attempted to free invalid pin %u\n", gpio); + return; + } + + pin = gpio & 0x1f; + if (!test_and_clear_bit(pin, &pio->gpio_mask)) + printk(KERN_ERR "gpio: freeing already-free pin %s[%u]\n", + pio->name, pin); +} +EXPORT_SYMBOL(gpio_free); + +int gpio_direction_input(unsigned int gpio) +{ + struct pio_device *pio; + unsigned int pin; + + pio = gpio_to_pio(gpio); + if (!pio) + return -ENODEV; + + pin = gpio & 0x1f; + pio_writel(pio, ODR, 1 << pin); + + return 0; +} +EXPORT_SYMBOL(gpio_direction_input); + +int gpio_direction_output(unsigned int gpio) +{ + struct pio_device *pio; + unsigned int pin; + + pio = gpio_to_pio(gpio); + if (!pio) + return -ENODEV; + + pin = gpio & 0x1f; + pio_writel(pio, OER, 1 << pin); + + return 0; +} +EXPORT_SYMBOL(gpio_direction_output); + +int gpio_get_value(unsigned int gpio) +{ + struct pio_device *pio = &pio_dev[gpio >> 5]; + + return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1; +} +EXPORT_SYMBOL(gpio_get_value); + +void gpio_set_value(unsigned int gpio, int value) +{ + struct pio_device *pio = &pio_dev[gpio >> 5]; + u32 mask; + + mask = 1 << (gpio & 0x1f); + if (value) + pio_writel(pio, SODR, mask); + else + pio_writel(pio, CODR, mask); +} +EXPORT_SYMBOL(gpio_set_value); + static int __init pio_probe(struct platform_device *pdev) { struct pio_device *pio = NULL; @@ -184,6 +280,12 @@ void __init at32_init_pio(struct platfor pio->pdev = pdev; pio->regs = ioremap(regs->start, regs->end - regs->start + 1); + /* + * request_gpio() is only valid for pins that have been + * configured as GPIO. + */ + pio->gpio_mask = ~0UL; + pio_writel(pio, ODR, ~0UL); pio_writel(pio, PER, ~0UL); } diff --git a/include/asm-avr32/arch-at32ap/at32ap7000.h b/include/asm-avr32/arch-at32ap/at32ap7000.h index ba85e04..3914d7b 100644 --- a/include/asm-avr32/arch-at32ap/at32ap7000.h +++ b/include/asm-avr32/arch-at32ap/at32ap7000.h @@ -24,10 +24,12 @@ #define GPIO_PIOA_BASE (0) #define GPIO_PIOB_BASE (GPIO_PIOA_BASE + 32) #define GPIO_PIOC_BASE (GPIO_PIOB_BASE + 32) #define GPIO_PIOD_BASE (GPIO_PIOC_BASE + 32) +#define GPIO_PIOE_BASE (GPIO_PIOD_BASE + 32) #define GPIO_PIN_PA(N) (GPIO_PIOA_BASE + (N)) #define GPIO_PIN_PB(N) (GPIO_PIOB_BASE + (N)) #define GPIO_PIN_PC(N) (GPIO_PIOC_BASE + (N)) #define GPIO_PIN_PD(N) (GPIO_PIOD_BASE + (N)) +#define GPIO_PIN_PE(N) (GPIO_PIOE_BASE + (N)) #endif /* __ASM_ARCH_AT32AP7000_H__ */ diff --git a/include/asm-avr32/arch-at32ap/gpio.h b/include/asm-avr32/arch-at32ap/gpio.h new file mode 100644 index 0000000..d082cb6 --- /dev/null +++ b/include/asm-avr32/arch-at32ap/gpio.h @@ -0,0 +1,26 @@ +#ifndef __ASM_AVR32_ARCH_GPIO_H +#define __ASM_AVR32_ARCH_GPIO_H + +#include +#include + +/* Arch-neutral GPIO API */ +int __must_check gpio_request(unsigned int gpio, const char *label); +void gpio_free(unsigned int gpio); + +int gpio_direction_input(unsigned int gpio); +int gpio_direction_output(unsigned int gpio); +int gpio_get_value(unsigned int gpio); +void gpio_set_value(unsigned int gpio, int value); + +static inline int gpio_to_irq(unsigned int gpio) +{ + return gpio + GPIO_IRQ_BASE; +} + +static inline int irq_to_gpio(unsigned int irq) +{ + return irq - GPIO_IRQ_BASE; +} + +#endif /* __ASM_AVR32_ARCH_GPIO_H */ diff --git a/include/asm-avr32/arch-at32ap/irq.h b/include/asm-avr32/arch-at32ap/irq.h new file mode 100644 index 0000000..1e2513e --- /dev/null +++ b/include/asm-avr32/arch-at32ap/irq.h @@ -0,0 +1,11 @@ +#ifndef __ASM_AVR32_ARCH_IRQ_H +#define __ASM_AVR32_ARCH_IRQ_H + +#define EIM_IRQ_BASE NR_INTERNAL_IRQS +#define NR_EIM_IRQS 32 +#define GPIO_IRQ_BASE (EIM_IRQ_BASE + NR_EIM_IRQS) +#define NR_GPIO_IRQS (4 * 32) + +#define NR_IRQS (GPIO_IRQ_BASE + NR_GPIO_IRQS) + +#endif /* __ASM_AVR32_ARCH_IRQ_H */ diff --git a/include/asm-avr32/gpio.h b/include/asm-avr32/gpio.h new file mode 100644 index 0000000..19e8ccc --- /dev/null +++ b/include/asm-avr32/gpio.h @@ -0,0 +1,6 @@ +#ifndef __ASM_AVR32_GPIO_H +#define __ASM_AVR32_GPIO_H + +#include + +#endif /* __ASM_AVR32_GPIO_H */ diff --git a/include/asm-avr32/irq.h b/include/asm-avr32/irq.h index f7e7257..83e6549 100644 --- a/include/asm-avr32/irq.h +++ b/include/asm-avr32/irq.h @@ -2,8 +2,12 @@ #ifndef __ASM_AVR32_IRQ_H #define __ASM_AVR32_IRQ_H #define NR_INTERNAL_IRQS 64 -#define NR_EXTERNAL_IRQS 64 -#define NR_IRQS (NR_INTERNAL_IRQS + NR_EXTERNAL_IRQS) + +#include + +#ifndef NR_IRQS +#define NR_IRQS (NR_INTERNAL_IRQS) +#endif #define irq_canonicalize(i) (i)