]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 12 Oct 2008 19:00:23 +0000 (12:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 12 Oct 2008 19:00:23 +0000 (12:00 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6:
  avr32: Fix build failures in board code
  avr32: Allow selecting multiple pins at once
  avr32: Minor pm_power_off cleanup
  avr32: Implement {read,write}[bwl]_be
  avr32: Replace static clock list with dynamic linked list
  avr32: Use platform_driver_probe for pdc platform driver
  avr32: Use platform_driver_probe for pio platform driver
  avr32: Provide a way to deselect pins in the portmux
  ngw100: export J15 through sysfs
  avr32: Allow fine-grained control over LCDC pins
  avr32: added mem kernel command line option support
  Add kernel support for oprofile callgraphs on AVR32
  avr32: use the new byteorder headers

20 files changed:
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/boards/atstk1000/atstk1003.c
arch/avr32/boards/atstk1000/atstk1004.c
arch/avr32/include/asm/byteorder.h
arch/avr32/include/asm/io.h
arch/avr32/kernel/process.c
arch/avr32/kernel/setup.c
arch/avr32/mach-at32ap/at32ap700x.c
arch/avr32/mach-at32ap/clock.c
arch/avr32/mach-at32ap/clock.h
arch/avr32/mach-at32ap/include/mach/at32ap700x.h
arch/avr32/mach-at32ap/include/mach/board.h
arch/avr32/mach-at32ap/include/mach/io.h
arch/avr32/mach-at32ap/include/mach/portmux.h
arch/avr32/mach-at32ap/pdc.c
arch/avr32/mach-at32ap/pio.c
arch/avr32/oprofile/Makefile
arch/avr32/oprofile/backtrace.c [new file with mode: 0644]
arch/avr32/oprofile/op_model_avr32.c

index f3085208959f13e01162d138dd50fbf496869ab2..6c54580a66df77bdcba2d1e889c95ba9b6524291 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/clk.h>
 #include <linux/etherdevice.h>
+#include <linux/gpio.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
@@ -193,7 +194,7 @@ static int __init atngw100_init(void)
         * PB28/EXTINT3 doesn't; it should be SMBALERT# (for PMBus),
         * but it's not available off-board.
         */
-       at32_select_periph(GPIO_PIN_PB(28), 0, AT32_GPIOF_PULLUP);
+       at32_select_periph(GPIO_PIOB_BASE, 1 << 28, 0, AT32_GPIOF_PULLUP);
        at32_select_gpio(i2c_gpio_data.sda_pin,
                AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
        at32_select_gpio(i2c_gpio_data.scl_pin,
@@ -207,6 +208,15 @@ postcore_initcall(atngw100_init);
 
 static int __init atngw100_arch_init(void)
 {
+       /* PB30 is the otherwise unused jumper on the mainboard, with an
+        * external pullup; the jumper grounds it.  Use it however you
+        * like, including letting U-Boot or Linux tweak boot sequences.
+        */
+       at32_select_gpio(GPIO_PIN_PB(30), 0);
+       gpio_request(GPIO_PIN_PB(30), "j15");
+       gpio_direction_input(GPIO_PIN_PB(30));
+       gpio_export(GPIO_PIN_PB(30), false);
+
        /* set_irq_type() after the arch_initcall for EIC has run, and
         * before the I2C subsystem could try using this IRQ.
         */
index 4fedbc4488de645a88f9c62157067ceb872276df..29e5b51a7fd2b8801a23655e17edcff41ade6ab2 100644 (file)
@@ -232,7 +232,7 @@ static void __init atstk1002_setup_extdac(void)
                goto err_set_clk;
        }
 
-       at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
+       at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);
        at73c213_data.dac_clk = gclk;
 
 err_set_clk:
@@ -330,13 +330,14 @@ static int __init atstk1002_init(void)
        at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
 #endif
 #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
-       at32_add_device_mci(0, &mci0_pdata);
+       at32_add_device_mci(0, &mci0_data);
 #endif
 #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
        set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
 #else
        at32_add_device_lcdc(0, &atstk1000_lcdc_data,
-                            fbmem_start, fbmem_size, 0);
+                            fbmem_start, fbmem_size,
+                            ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL);
 #endif
        at32_add_device_usba(0, NULL);
 #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
index acc61235b89587d939f724122bbb1914db8c06cc..be089d7f37ebf1b0fe955475417fce4fb66e86f9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/spi/spi.h>
 
 #include <asm/setup.h>
+#include <asm/atmel-mci.h>
 
 #include <mach/at32ap700x.h>
 #include <mach/board.h>
@@ -94,7 +95,7 @@ static void __init atstk1003_setup_extdac(void)
                goto err_set_clk;
        }
 
-       at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
+       at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);
        at73c213_data.dac_clk = gclk;
 
 err_set_clk:
index d6a2d02f03291e51b98953b76a9bfc0efe969027..248ef237c167b95283c30dec20ca0080c97e6feb 100644 (file)
@@ -21,6 +21,7 @@
 #include <video/atmel_lcdc.h>
 
 #include <asm/setup.h>
+#include <asm/atmel-mci.h>
 
 #include <mach/at32ap700x.h>
 #include <mach/board.h>
@@ -99,7 +100,7 @@ static void __init atstk1004_setup_extdac(void)
                goto err_set_clk;
        }
 
-       at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0);
+       at32_select_periph(GPIO_PIOA_BASE, (1 << 30), GPIO_PERIPH_A, 0);
        at73c213_data.dac_clk = gclk;
 
 err_set_clk:
@@ -150,7 +151,8 @@ static int __init atstk1004_init(void)
        at32_add_device_mci(0, &mci0_data);
 #endif
        at32_add_device_lcdc(0, &atstk1000_lcdc_data,
-                            fbmem_start, fbmem_size, 0);
+                            fbmem_start, fbmem_size,
+                            ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL);
        at32_add_device_usba(0, NULL);
 #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM
        at32_add_device_ssc(0, ATMEL_SSC_TX);
index d77b48ba73387ba57ac932e5a6676d43b1c6a584..8e3af02076dd59d8eedcf2cec413392ee867f68d 100644 (file)
@@ -7,6 +7,9 @@
 #include <asm/types.h>
 #include <linux/compiler.h>
 
+#define __BIG_ENDIAN
+#define __SWAB_64_THRU_32__
+
 #ifdef __CHECKER__
 extern unsigned long __builtin_bswap_32(unsigned long x);
 extern unsigned short __builtin_bswap_16(unsigned short x);
@@ -17,15 +20,18 @@ extern unsigned short __builtin_bswap_16(unsigned short x);
  * the result.
  */
 #if !(__GNUC__ == 4 && __GNUC_MINOR__ < 2)
-#define __arch__swab32(x) __builtin_bswap_32(x)
-#define __arch__swab16(x) __builtin_bswap_16(x)
-#endif
+static inline __attribute_const__ __u16 __arch_swab16(__u16 val)
+{
+       return __builtin_bswap_16(val);
+}
+#define __arch_swab16 __arch_swab16
 
-#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
-# define __BYTEORDER_HAS_U64__
-# define __SWAB_64_THRU_32__
+static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
+{
+       return __builtin_bswap_32(val);
+}
+#define __arch_swab32 __arch_swab32
 #endif
 
-#include <linux/byteorder/big_endian.h>
-
+#include <linux/byteorder.h>
 #endif /* __ASM_AVR32_BYTEORDER_H */
index a520f77ead96e62d02ee2197d85c2a76fa46c9e2..22c97ef92201bff82b5a7bc7a6fe139147c014a4 100644 (file)
@@ -160,6 +160,14 @@ BUILDIO_IOPORT(l, u32)
 #define readw_relaxed                  readw
 #define readl_relaxed                  readl
 
+#define readb_be                       __raw_readb
+#define readw_be                       __raw_readw
+#define readl_be                       __raw_readl
+
+#define writeb_be                      __raw_writeb
+#define writew_be                      __raw_writew
+#define writel_be                      __raw_writel
+
 #define __BUILD_MEMORY_STRING(bwl, type)                               \
 static inline void writes##bwl(volatile void __iomem *addr,            \
                               const void *data, unsigned int count)    \
index 2c08ac992ac3d8435c2284224cbbd5a0691ac085..134d5302b6dd21fda7f676a9bdfa3923b19e5998 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/kallsyms.h>
 #include <linux/fs.h>
+#include <linux/pm.h>
 #include <linux/ptrace.h>
 #include <linux/reboot.h>
 #include <linux/tick.h>
@@ -20,7 +21,7 @@
 
 #include <mach/pm.h>
 
-void (*pm_power_off)(void) = NULL;
+void (*pm_power_off)(void);
 EXPORT_SYMBOL(pm_power_off);
 
 /*
index d8e623c426c1f324c37369eca13cf358e3b85ab1..5c7083916c33c14792728da5a08295476daebc17 100644 (file)
@@ -283,6 +283,25 @@ static int __init early_parse_fbmem(char *p)
 }
 early_param("fbmem", early_parse_fbmem);
 
+/*
+ * Pick out the memory size.  We look for mem=size@start,
+ * where start and size are "size[KkMmGg]"
+ */
+static int __init early_mem(char *p)
+{
+       resource_size_t size, start;
+
+       start = system_ram->start;
+       size  = memparse(p, &p);
+       if (*p == '@')
+               start = memparse(p + 1, &p);
+
+       system_ram->start = start;
+       system_ram->end = system_ram->start + size - 1;
+       return 0;
+}
+early_param("mem", early_mem);
+
 static int __init parse_tag_core(struct tag *tag)
 {
        if (tag->hdr.size > 2) {
index f1b9a3ac27336fe92c9c15cbe114212b5f98d4f5..813b6844cdf67a1ec485ccc4f3839baa42c2682d 100644 (file)
@@ -82,8 +82,9 @@ static struct platform_device _name##_id##_device = {         \
        .num_resources  = ARRAY_SIZE(_name##_id##_resource),    \
 }
 
-#define select_peripheral(pin, periph, flags)                  \
-       at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags)
+#define select_peripheral(port, pin_mask, periph, flags)       \
+       at32_select_periph(GPIO_##port##_BASE, pin_mask,        \
+                          GPIO_##periph, flags)
 
 #define DEV_CLK(_name, devname, bus, _index)                   \
 static struct clk devname##_##_name = {                                \
@@ -871,6 +872,7 @@ static struct clk atmel_psif1_pclk = {
 struct platform_device *__init at32_add_device_psif(unsigned int id)
 {
        struct platform_device *pdev;
+       u32 pin_mask;
 
        if (!(id == 0 || id == 1))
                return NULL;
@@ -881,20 +883,22 @@ struct platform_device *__init at32_add_device_psif(unsigned int id)
 
        switch (id) {
        case 0:
+               pin_mask  = (1 << 8) | (1 << 9); /* CLOCK & DATA */
+
                if (platform_device_add_resources(pdev, atmel_psif0_resource,
                                        ARRAY_SIZE(atmel_psif0_resource)))
                        goto err_add_resources;
                atmel_psif0_pclk.dev = &pdev->dev;
-               select_peripheral(PA(8), PERIPH_A, 0); /* CLOCK */
-               select_peripheral(PA(9), PERIPH_A, 0); /* DATA  */
+               select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
                break;
        case 1:
+               pin_mask  = (1 << 11) | (1 << 12); /* CLOCK & DATA */
+
                if (platform_device_add_resources(pdev, atmel_psif1_resource,
                                        ARRAY_SIZE(atmel_psif1_resource)))
                        goto err_add_resources;
                atmel_psif1_pclk.dev = &pdev->dev;
-               select_peripheral(PB(11), PERIPH_A, 0); /* CLOCK */
-               select_peripheral(PB(12), PERIPH_A, 0); /* DATA  */
+               select_peripheral(PIOB, pin_mask, PERIPH_A, 0);
                break;
        default:
                return NULL;
@@ -958,26 +962,30 @@ DEV_CLK(usart, atmel_usart3, pba, 6);
 
 static inline void configure_usart0_pins(void)
 {
-       select_peripheral(PA(8),  PERIPH_B, 0); /* RXD  */
-       select_peripheral(PA(9),  PERIPH_B, 0); /* TXD  */
+       u32 pin_mask = (1 << 8) | (1 << 9); /* RXD & TXD */
+
+       select_peripheral(PIOA, pin_mask, PERIPH_B, 0);
 }
 
 static inline void configure_usart1_pins(void)
 {
-       select_peripheral(PA(17), PERIPH_A, 0); /* RXD  */
-       select_peripheral(PA(18), PERIPH_A, 0); /* TXD  */
+       u32 pin_mask = (1 << 17) | (1 << 18); /* RXD & TXD */
+
+       select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
 }
 
 static inline void configure_usart2_pins(void)
 {
-       select_peripheral(PB(26), PERIPH_B, 0); /* RXD  */
-       select_peripheral(PB(27), PERIPH_B, 0); /* TXD  */
+       u32 pin_mask = (1 << 26) | (1 << 27); /* RXD & TXD */
+
+       select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
 }
 
 static inline void configure_usart3_pins(void)
 {
-       select_peripheral(PB(18), PERIPH_B, 0); /* RXD  */
-       select_peripheral(PB(17), PERIPH_B, 0); /* TXD  */
+       u32 pin_mask = (1 << 18) | (1 << 17); /* RXD & TXD */
+
+       select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
 }
 
 static struct platform_device *__initdata at32_usarts[4];
@@ -1057,59 +1065,69 @@ struct platform_device *__init
 at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
 {
        struct platform_device *pdev;
+       u32 pin_mask;
 
        switch (id) {
        case 0:
                pdev = &macb0_device;
 
-               select_peripheral(PC(3),  PERIPH_A, 0); /* TXD0 */
-               select_peripheral(PC(4),  PERIPH_A, 0); /* TXD1 */
-               select_peripheral(PC(7),  PERIPH_A, 0); /* TXEN */
-               select_peripheral(PC(8),  PERIPH_A, 0); /* TXCK */
-               select_peripheral(PC(9),  PERIPH_A, 0); /* RXD0 */
-               select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */
-               select_peripheral(PC(13), PERIPH_A, 0); /* RXER */
-               select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */
-               select_peripheral(PC(16), PERIPH_A, 0); /* MDC  */
-               select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */
+               pin_mask  = (1 << 3);   /* TXD0 */
+               pin_mask |= (1 << 4);   /* TXD1 */
+               pin_mask |= (1 << 7);   /* TXEN */
+               pin_mask |= (1 << 8);   /* TXCK */
+               pin_mask |= (1 << 9);   /* RXD0 */
+               pin_mask |= (1 << 10);  /* RXD1 */
+               pin_mask |= (1 << 13);  /* RXER */
+               pin_mask |= (1 << 15);  /* RXDV */
+               pin_mask |= (1 << 16);  /* MDC  */
+               pin_mask |= (1 << 17);  /* MDIO */
 
                if (!data->is_rmii) {
-                       select_peripheral(PC(0),  PERIPH_A, 0); /* COL  */
-                       select_peripheral(PC(1),  PERIPH_A, 0); /* CRS  */
-                       select_peripheral(PC(2),  PERIPH_A, 0); /* TXER */
-                       select_peripheral(PC(5),  PERIPH_A, 0); /* TXD2 */
-                       select_peripheral(PC(6),  PERIPH_A, 0); /* TXD3 */
-                       select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */
-                       select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */
-                       select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */
-                       select_peripheral(PC(18), PERIPH_A, 0); /* SPD  */
+                       pin_mask |= (1 << 0);   /* COL  */
+                       pin_mask |= (1 << 1);   /* CRS  */
+                       pin_mask |= (1 << 2);   /* TXER */
+                       pin_mask |= (1 << 5);   /* TXD2 */
+                       pin_mask |= (1 << 6);   /* TXD3 */
+                       pin_mask |= (1 << 11);  /* RXD2 */
+                       pin_mask |= (1 << 12);  /* RXD3 */
+                       pin_mask |= (1 << 14);  /* RXCK */
+                       pin_mask |= (1 << 18);  /* SPD  */
                }
+
+               select_peripheral(PIOC, pin_mask, PERIPH_A, 0);
+
                break;
 
        case 1:
                pdev = &macb1_device;
 
-               select_peripheral(PD(13), PERIPH_B, 0);         /* TXD0 */
-               select_peripheral(PD(14), PERIPH_B, 0);         /* TXD1 */
-               select_peripheral(PD(11), PERIPH_B, 0);         /* TXEN */
-               select_peripheral(PD(12), PERIPH_B, 0);         /* TXCK */
-               select_peripheral(PD(10), PERIPH_B, 0);         /* RXD0 */
-               select_peripheral(PD(6),  PERIPH_B, 0);         /* RXD1 */
-               select_peripheral(PD(5),  PERIPH_B, 0);         /* RXER */
-               select_peripheral(PD(4),  PERIPH_B, 0);         /* RXDV */
-               select_peripheral(PD(3),  PERIPH_B, 0);         /* MDC  */
-               select_peripheral(PD(2),  PERIPH_B, 0);         /* MDIO */
+               pin_mask  = (1 << 13);  /* TXD0 */
+               pin_mask |= (1 << 14);  /* TXD1 */
+               pin_mask |= (1 << 11);  /* TXEN */
+               pin_mask |= (1 << 12);  /* TXCK */
+               pin_mask |= (1 << 10);  /* RXD0 */
+               pin_mask |= (1 << 6);   /* RXD1 */
+               pin_mask |= (1 << 5);   /* RXER */
+               pin_mask |= (1 << 4);   /* RXDV */
+               pin_mask |= (1 << 3);   /* MDC  */
+               pin_mask |= (1 << 2);   /* MDIO */
+
+               if (!data->is_rmii)
+                       pin_mask |= (1 << 15);  /* SPD  */
+
+               select_peripheral(PIOD, pin_mask, PERIPH_B, 0);
 
                if (!data->is_rmii) {
-                       select_peripheral(PC(19), PERIPH_B, 0); /* COL  */
-                       select_peripheral(PC(23), PERIPH_B, 0); /* CRS  */
-                       select_peripheral(PC(26), PERIPH_B, 0); /* TXER */
-                       select_peripheral(PC(27), PERIPH_B, 0); /* TXD2 */
-                       select_peripheral(PC(28), PERIPH_B, 0); /* TXD3 */
-                       select_peripheral(PC(29), PERIPH_B, 0); /* RXD2 */
-                       select_peripheral(PC(30), PERIPH_B, 0); /* RXD3 */
-                       select_peripheral(PC(24), PERIPH_B, 0); /* RXCK */
-                       select_peripheral(PD(15), PERIPH_B, 0); /* SPD  */
+                       pin_mask  = (1 << 19);  /* COL  */
+                       pin_mask |= (1 << 23);  /* CRS  */
+                       pin_mask |= (1 << 26);  /* TXER */
+                       pin_mask |= (1 << 27);  /* TXD2 */
+                       pin_mask |= (1 << 28);  /* TXD3 */
+                       pin_mask |= (1 << 29);  /* RXD2 */
+                       pin_mask |= (1 << 30);  /* RXD3 */
+                       pin_mask |= (1 << 24);  /* RXCK */
+
+                       select_peripheral(PIOC, pin_mask, PERIPH_B, 0);
                }
                break;
 
@@ -1177,23 +1195,28 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
                { GPIO_PIN_PB(2), GPIO_PIN_PB(3),
                  GPIO_PIN_PB(4), GPIO_PIN_PA(27), };
        struct platform_device *pdev;
+       u32 pin_mask;
 
        switch (id) {
        case 0:
                pdev = &atmel_spi0_device;
+               pin_mask  = (1 << 1) | (1 << 2);        /* MOSI & SCK */
+
                /* pullup MISO so a level is always defined */
-               select_peripheral(PA(0),  PERIPH_A, AT32_GPIOF_PULLUP);
-               select_peripheral(PA(1),  PERIPH_A, 0); /* MOSI  */
-               select_peripheral(PA(2),  PERIPH_A, 0); /* SCK   */
+               select_peripheral(PIOA, (1 << 0), PERIPH_A, AT32_GPIOF_PULLUP);
+               select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
+
                at32_spi_setup_slaves(0, b, n, spi0_pins);
                break;
 
        case 1:
                pdev = &atmel_spi1_device;
+               pin_mask  = (1 << 1) | (1 << 5);        /* MOSI */
+
                /* pullup MISO so a level is always defined */
-               select_peripheral(PB(0),  PERIPH_B, AT32_GPIOF_PULLUP);
-               select_peripheral(PB(1),  PERIPH_B, 0); /* MOSI  */
-               select_peripheral(PB(5),  PERIPH_B, 0); /* SCK   */
+               select_peripheral(PIOB, (1 << 0), PERIPH_B, AT32_GPIOF_PULLUP);
+               select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
+
                at32_spi_setup_slaves(1, b, n, spi1_pins);
                break;
 
@@ -1226,6 +1249,7 @@ struct platform_device *__init at32_add_device_twi(unsigned int id,
                                                    unsigned int n)
 {
        struct platform_device *pdev;
+       u32 pin_mask;
 
        if (id != 0)
                return NULL;
@@ -1238,8 +1262,9 @@ struct platform_device *__init at32_add_device_twi(unsigned int id,
                                ARRAY_SIZE(atmel_twi0_resource)))
                goto err_add_resources;
 
-       select_peripheral(PA(6),  PERIPH_A, 0); /* SDA  */
-       select_peripheral(PA(7),  PERIPH_A, 0); /* SDL  */
+       pin_mask  = (1 << 6) | (1 << 7);        /* SDA & SDL */
+
+       select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
 
        atmel_twi0_pclk.dev = &pdev->dev;
 
@@ -1274,6 +1299,8 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
 {
        struct platform_device          *pdev;
        struct dw_dma_slave             *dws;
+       u32                             pioa_mask;
+       u32                             piob_mask;
 
        if (id != 0 || !data)
                return NULL;
@@ -1311,17 +1338,17 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
                goto fail;
 
        /* CLK line is common to both slots */
-       select_peripheral(PA(10), PERIPH_A, 0);
+       pioa_mask = 1 << 10;
 
        switch (data->slot[0].bus_width) {
        case 4:
-               select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
-               select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
-               select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
+               pioa_mask |= 1 << 13;           /* DATA1 */
+               pioa_mask |= 1 << 14;           /* DATA2 */
+               pioa_mask |= 1 << 15;           /* DATA3 */
                /* fall through */
        case 1:
-               select_peripheral(PA(11), PERIPH_A, 0); /* CMD   */
-               select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
+               pioa_mask |= 1 << 11;           /* CMD   */
+               pioa_mask |= 1 << 12;           /* DATA0 */
 
                if (gpio_is_valid(data->slot[0].detect_pin))
                        at32_select_gpio(data->slot[0].detect_pin, 0);
@@ -1335,15 +1362,19 @@ at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
                goto fail;
        }
 
+       select_peripheral(PIOA, pioa_mask, PERIPH_A, 0);
+       piob_mask = 0;
+
        switch (data->slot[1].bus_width) {
        case 4:
-               select_peripheral(PB(8),  PERIPH_B, 0); /* DATA1 */
-               select_peripheral(PB(9),  PERIPH_B, 0); /* DATA2 */
-               select_peripheral(PB(10), PERIPH_B, 0); /* DATA3 */
+               piob_mask |= 1 <<  8;           /* DATA1 */
+               piob_mask |= 1 <<  9;           /* DATA2 */
+               piob_mask |= 1 << 10;           /* DATA3 */
                /* fall through */
        case 1:
-               select_peripheral(PB(6),  PERIPH_B, 0); /* CMD   */
-               select_peripheral(PB(7),  PERIPH_B, 0); /* DATA0 */
+               piob_mask |= 1 <<  6;           /* CMD   */
+               piob_mask |= 1 <<  7;           /* DATA0 */
+               select_peripheral(PIOB, piob_mask, PERIPH_B, 0);
 
                if (gpio_is_valid(data->slot[1].detect_pin))
                        at32_select_gpio(data->slot[1].detect_pin, 0);
@@ -1405,13 +1436,14 @@ static struct clk atmel_lcdfb0_pixclk = {
 struct platform_device *__init
 at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
                     unsigned long fbmem_start, unsigned long fbmem_len,
-                    unsigned int pin_config)
+                    u64 pin_mask)
 {
        struct platform_device *pdev;
        struct atmel_lcdfb_info *info;
        struct fb_monspecs *monspecs;
        struct fb_videomode *modedb;
        unsigned int modedb_size;
+       u32 portc_mask, portd_mask, porte_mask;
 
        /*
         * Do a deep copy of the fb data, monspecs and modedb. Make
@@ -1433,76 +1465,21 @@ at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
        case 0:
                pdev = &atmel_lcdfb0_device;
 
-               switch (pin_config) {
-               case 0:
-                       select_peripheral(PC(19), PERIPH_A, 0); /* CC     */
-                       select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC  */
-                       select_peripheral(PC(21), PERIPH_A, 0); /* PCLK   */
-                       select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC  */
-                       select_peripheral(PC(23), PERIPH_A, 0); /* DVAL   */
-                       select_peripheral(PC(24), PERIPH_A, 0); /* MODE   */
-                       select_peripheral(PC(25), PERIPH_A, 0); /* PWR    */
-                       select_peripheral(PC(26), PERIPH_A, 0); /* DATA0  */
-                       select_peripheral(PC(27), PERIPH_A, 0); /* DATA1  */
-                       select_peripheral(PC(28), PERIPH_A, 0); /* DATA2  */
-                       select_peripheral(PC(29), PERIPH_A, 0); /* DATA3  */
-                       select_peripheral(PC(30), PERIPH_A, 0); /* DATA4  */
-                       select_peripheral(PC(31), PERIPH_A, 0); /* DATA5  */
-                       select_peripheral(PD(0),  PERIPH_A, 0); /* DATA6  */
-                       select_peripheral(PD(1),  PERIPH_A, 0); /* DATA7  */
-                       select_peripheral(PD(2),  PERIPH_A, 0); /* DATA8  */
-                       select_peripheral(PD(3),  PERIPH_A, 0); /* DATA9  */
-                       select_peripheral(PD(4),  PERIPH_A, 0); /* DATA10 */
-                       select_peripheral(PD(5),  PERIPH_A, 0); /* DATA11 */
-                       select_peripheral(PD(6),  PERIPH_A, 0); /* DATA12 */
-                       select_peripheral(PD(7),  PERIPH_A, 0); /* DATA13 */
-                       select_peripheral(PD(8),  PERIPH_A, 0); /* DATA14 */
-                       select_peripheral(PD(9),  PERIPH_A, 0); /* DATA15 */
-                       select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */
-                       select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */
-                       select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */
-                       select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */
-                       select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */
-                       select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */
-                       select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
-                       select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
-                       break;
-               case 1:
-                       select_peripheral(PE(0),  PERIPH_B, 0); /* CC     */
-                       select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC  */
-                       select_peripheral(PC(21), PERIPH_A, 0); /* PCLK   */
-                       select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC  */
-                       select_peripheral(PE(1),  PERIPH_B, 0); /* DVAL   */
-                       select_peripheral(PE(2),  PERIPH_B, 0); /* MODE   */
-                       select_peripheral(PC(25), PERIPH_A, 0); /* PWR    */
-                       select_peripheral(PE(3),  PERIPH_B, 0); /* DATA0  */
-                       select_peripheral(PE(4),  PERIPH_B, 0); /* DATA1  */
-                       select_peripheral(PE(5),  PERIPH_B, 0); /* DATA2  */
-                       select_peripheral(PE(6),  PERIPH_B, 0); /* DATA3  */
-                       select_peripheral(PE(7),  PERIPH_B, 0); /* DATA4  */
-                       select_peripheral(PC(31), PERIPH_A, 0); /* DATA5  */
-                       select_peripheral(PD(0),  PERIPH_A, 0); /* DATA6  */
-                       select_peripheral(PD(1),  PERIPH_A, 0); /* DATA7  */
-                       select_peripheral(PE(8),  PERIPH_B, 0); /* DATA8  */
-                       select_peripheral(PE(9),  PERIPH_B, 0); /* DATA9  */
-                       select_peripheral(PE(10), PERIPH_B, 0); /* DATA10 */
-                       select_peripheral(PE(11), PERIPH_B, 0); /* DATA11 */
-                       select_peripheral(PE(12), PERIPH_B, 0); /* DATA12 */
-                       select_peripheral(PD(7),  PERIPH_A, 0); /* DATA13 */
-                       select_peripheral(PD(8),  PERIPH_A, 0); /* DATA14 */
-                       select_peripheral(PD(9),  PERIPH_A, 0); /* DATA15 */
-                       select_peripheral(PE(13), PERIPH_B, 0); /* DATA16 */
-                       select_peripheral(PE(14), PERIPH_B, 0); /* DATA17 */
-                       select_peripheral(PE(15), PERIPH_B, 0); /* DATA18 */
-                       select_peripheral(PE(16), PERIPH_B, 0); /* DATA19 */
-                       select_peripheral(PE(17), PERIPH_B, 0); /* DATA20 */
-                       select_peripheral(PE(18), PERIPH_B, 0); /* DATA21 */
-                       select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */
-                       select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */
-                       break;
-               default:
-                       goto err_invalid_id;
-               }
+               if (pin_mask == 0ULL)
+                       /* Default to "full" lcdc control signals and 24bit */
+                       pin_mask = ATMEL_LCDC_PRI_24BIT | ATMEL_LCDC_PRI_CONTROL;
+
+               /* LCDC on port C */
+               portc_mask = (pin_mask & 0xfff80000) >> 19;
+               select_peripheral(PIOC, portc_mask, PERIPH_A, 0);
+
+               /* LCDC on port D */
+               portd_mask = pin_mask & 0x0003ffff;
+               select_peripheral(PIOD, portd_mask, PERIPH_A, 0);
+
+               /* LCDC on port E */
+               porte_mask = (pin_mask >> 32) & 0x0007ffff;
+               select_peripheral(PIOE, porte_mask, PERIPH_B, 0);
 
                clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
                clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
@@ -1551,6 +1528,7 @@ static struct clk atmel_pwm0_mck = {
 struct platform_device *__init at32_add_device_pwm(u32 mask)
 {
        struct platform_device *pdev;
+       u32 pin_mask;
 
        if (!mask)
                return NULL;
@@ -1566,14 +1544,21 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
        if (platform_device_add_data(pdev, &mask, sizeof(mask)))
                goto out_free_pdev;
 
+       pin_mask = 0;
        if (mask & (1 << 0))
-               select_peripheral(PA(28), PERIPH_A, 0);
+               pin_mask |= (1 << 28);
        if (mask & (1 << 1))
-               select_peripheral(PA(29), PERIPH_A, 0);
+               pin_mask |= (1 << 29);
+       if (pin_mask > 0)
+               select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
+
+       pin_mask = 0;
        if (mask & (1 << 2))
-               select_peripheral(PA(21), PERIPH_B, 0);
+               pin_mask |= (1 << 21);
        if (mask & (1 << 3))
-               select_peripheral(PA(22), PERIPH_B, 0);
+               pin_mask |= (1 << 22);
+       if (pin_mask > 0)
+               select_peripheral(PIOA, pin_mask, PERIPH_B, 0);
 
        atmel_pwm0_mck.dev = &pdev->dev;
 
@@ -1614,52 +1599,65 @@ struct platform_device *__init
 at32_add_device_ssc(unsigned int id, unsigned int flags)
 {
        struct platform_device *pdev;
+       u32 pin_mask = 0;
 
        switch (id) {
        case 0:
                pdev = &ssc0_device;
                if (flags & ATMEL_SSC_RF)
-                       select_peripheral(PA(21), PERIPH_A, 0); /* RF */
+                       pin_mask |= (1 << 21);  /* RF */
                if (flags & ATMEL_SSC_RK)
-                       select_peripheral(PA(22), PERIPH_A, 0); /* RK */
+                       pin_mask |= (1 << 22);  /* RK */
                if (flags & ATMEL_SSC_TK)
-                       select_peripheral(PA(23), PERIPH_A, 0); /* TK */
+                       pin_mask |= (1 << 23);  /* TK */
                if (flags & ATMEL_SSC_TF)
-                       select_peripheral(PA(24), PERIPH_A, 0); /* TF */
+                       pin_mask |= (1 << 24);  /* TF */
                if (flags & ATMEL_SSC_TD)
-                       select_peripheral(PA(25), PERIPH_A, 0); /* TD */
+                       pin_mask |= (1 << 25);  /* TD */
                if (flags & ATMEL_SSC_RD)
-                       select_peripheral(PA(26), PERIPH_A, 0); /* RD */
+                       pin_mask |= (1 << 26);  /* RD */
+
+               if (pin_mask > 0)
+                       select_peripheral(PIOA, pin_mask, PERIPH_A, 0);
+
                break;
        case 1:
                pdev = &ssc1_device;
                if (flags & ATMEL_SSC_RF)
-                       select_peripheral(PA(0), PERIPH_B, 0);  /* RF */
+                       pin_mask |= (1 << 0);   /* RF */
                if (flags & ATMEL_SSC_RK)
-                       select_peripheral(PA(1), PERIPH_B, 0);  /* RK */
+                       pin_mask |= (1 << 1);   /* RK */
                if (flags & ATMEL_SSC_TK)
-                       select_peripheral(PA(2), PERIPH_B, 0);  /* TK */
+                       pin_mask |= (1 << 2);   /* TK */
                if (flags & ATMEL_SSC_TF)
-                       select_peripheral(PA(3), PERIPH_B, 0);  /* TF */
+                       pin_mask |= (1 << 3);   /* TF */
                if (flags & ATMEL_SSC_TD)
-                       select_peripheral(PA(4), PERIPH_B, 0);  /* TD */
+                       pin_mask |= (1 << 4);   /* TD */
                if (flags & ATMEL_SSC_RD)
-                       select_peripheral(PA(5), PERIPH_B, 0);  /* RD */
+                       pin_mask |= (1 << 5);   /* RD */
+
+               if (pin_mask > 0)
+                       select_peripheral(PIOA, pin_mask, PERIPH_B, 0);
+
                break;
        case 2:
                pdev = &ssc2_device;
                if (flags & ATMEL_SSC_TD)
-                       select_peripheral(PB(13), PERIPH_A, 0); /* TD */
+                       pin_mask |= (1 << 13);  /* TD */
                if (flags & ATMEL_SSC_RD)
-                       select_peripheral(PB(14), PERIPH_A, 0); /* RD */
+                       pin_mask |= (1 << 14);  /* RD */
                if (flags & ATMEL_SSC_TK)
-                       select_peripheral(PB(15), PERIPH_A, 0); /* TK */
+                       pin_mask |= (1 << 15);  /* TK */
                if (flags & ATMEL_SSC_TF)
-                       select_peripheral(PB(16), PERIPH_A, 0); /* TF */
+                       pin_mask |= (1 << 16);  /* TF */
                if (flags & ATMEL_SSC_RF)
-                       select_peripheral(PB(17), PERIPH_A, 0); /* RF */
+                       pin_mask |= (1 << 17);  /* RF */
                if (flags & ATMEL_SSC_RK)
-                       select_peripheral(PB(18), PERIPH_A, 0); /* RK */
+                       pin_mask |= (1 << 18);  /* RK */
+
+               if (pin_mask > 0)
+                       select_peripheral(PIOB, pin_mask, PERIPH_A, 0);
+
                break;
        default:
                return NULL;
@@ -1797,14 +1795,15 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
                unsigned int cs, unsigned int extint)
 {
        static unsigned int extint_pin_map[4] __initdata = {
-               GPIO_PIN_PB(25),
-               GPIO_PIN_PB(26),
-               GPIO_PIN_PB(27),
-               GPIO_PIN_PB(28),
+               (1 << 25),
+               (1 << 26),
+               (1 << 27),
+               (1 << 28),
        };
        static bool common_pins_initialized __initdata = false;
        unsigned int extint_pin;
        int ret;
+       u32 pin_mask;
 
        if (extint >= ARRAY_SIZE(extint_pin_map))
                return -EINVAL;
@@ -1818,7 +1817,8 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
                if (ret)
                        return ret;
 
-               select_peripheral(PE(21), PERIPH_A, 0); /* NCS4   -> OE_N  */
+               /* NCS4   -> OE_N  */
+               select_peripheral(PIOE, (1 << 21), PERIPH_A, 0);
                hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF0_ENABLE);
                break;
        case 5:
@@ -1828,7 +1828,8 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
                if (ret)
                        return ret;
 
-               select_peripheral(PE(22), PERIPH_A, 0); /* NCS5   -> OE_N  */
+               /* NCS5   -> OE_N  */
+               select_peripheral(PIOE, (1 << 22), PERIPH_A, 0);
                hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_CF1_ENABLE);
                break;
        default:
@@ -1836,14 +1837,17 @@ static int __init at32_init_ide_or_cf(struct platform_device *pdev,
        }
 
        if (!common_pins_initialized) {
-               select_peripheral(PE(19), PERIPH_A, 0); /* CFCE1  -> CS0_N */
-               select_peripheral(PE(20), PERIPH_A, 0); /* CFCE2  -> CS1_N */
-               select_peripheral(PE(23), PERIPH_A, 0); /* CFRNW  -> DIR   */
-               select_peripheral(PE(24), PERIPH_A, 0); /* NWAIT  <- IORDY */
+               pin_mask  = (1 << 19);  /* CFCE1  -> CS0_N */
+               pin_mask |= (1 << 20);  /* CFCE2  -> CS1_N */
+               pin_mask |= (1 << 23);  /* CFRNW  -> DIR   */
+               pin_mask |= (1 << 24);  /* NWAIT  <- IORDY */
+
+               select_peripheral(PIOE, pin_mask, PERIPH_A, 0);
+
                common_pins_initialized = true;
        }
 
-       at32_select_periph(extint_pin, GPIO_PERIPH_A, AT32_GPIOF_DEGLITCH);
+       select_peripheral(PIOB, extint_pin, PERIPH_A, AT32_GPIOF_DEGLITCH);
 
        pdev->resource[1].start = EIM_IRQ_BASE + extint;
        pdev->resource[1].end = pdev->resource[1].start;
@@ -1982,6 +1986,7 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
 {
        struct platform_device *pdev;
        struct ac97c_platform_data _data;
+       u32 pin_mask;
 
        if (id != 0)
                return NULL;
@@ -2008,10 +2013,10 @@ at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data)
                                sizeof(struct ac97c_platform_data)))
                goto fail;
 
-       select_peripheral(PB(20), PERIPH_B, 0); /* SDO  */
-       select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */
-       select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */
-       select_peripheral(PB(23), PERIPH_B, 0); /* SDI  */
+       pin_mask  = (1 << 20) | (1 << 21);      /* SDO & SYNC */
+       pin_mask |= (1 << 22) | (1 << 23);      /* SCLK & SDI */
+
+       select_peripheral(PIOB, pin_mask, PERIPH_B, 0);
 
        /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */
        if (data->reset_pin != GPIO_PIN_NONE)
@@ -2053,6 +2058,7 @@ static struct clk abdac0_sample_clk = {
 struct platform_device *__init at32_add_device_abdac(unsigned int id)
 {
        struct platform_device *pdev;
+       u32 pin_mask;
 
        if (id != 0)
                return NULL;
@@ -2065,10 +2071,10 @@ struct platform_device *__init at32_add_device_abdac(unsigned int id)
                                ARRAY_SIZE(abdac0_resource)))
                goto err_add_resources;
 
-       select_peripheral(PB(20), PERIPH_A, 0); /* DATA1        */
-       select_peripheral(PB(21), PERIPH_A, 0); /* DATA0        */
-       select_peripheral(PB(22), PERIPH_A, 0); /* DATAN1       */
-       select_peripheral(PB(23), PERIPH_A, 0); /* DATAN0       */
+       pin_mask  = (1 << 20) | (1 << 22);      /* DATA1 & DATAN1 */
+       pin_mask |= (1 << 21) | (1 << 23);      /* DATA0 & DATAN0 */
+
+       select_peripheral(PIOB, pin_mask, PERIPH_A, 0);
 
        abdac0_pclk.dev = &pdev->dev;
        abdac0_sample_clk.dev = &pdev->dev;
@@ -2125,7 +2131,7 @@ static struct clk gclk4 = {
        .index          = 4,
 };
 
-struct clk *at32_clock_list[] = {
+static __initdata struct clk *init_clocks[] = {
        &osc32k,
        &osc0,
        &osc1,
@@ -2189,7 +2195,6 @@ struct clk *at32_clock_list[] = {
        &gclk3,
        &gclk4,
 };
-unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);
 
 void __init setup_platform(void)
 {
@@ -2220,14 +2225,19 @@ void __init setup_platform(void)
        genclk_init_parent(&abdac0_sample_clk);
 
        /*
-        * Turn on all clocks that have at least one user already, and
-        * turn off everything else. We only do this for module
-        * clocks, and even though it isn't particularly pretty to
-        * check the address of the mode function, it should do the
-        * trick...
+        * Build initial dynamic clock list by registering all clocks
+        * from the array.
+        * At the same time, turn on all clocks that have at least one
+        * user already, and turn off everything else. We only do this
+        * for module clocks, and even though it isn't particularly
+        * pretty to  check the address of the mode function, it should
+        * do the trick...
         */
-       for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) {
-               struct clk *clk = at32_clock_list[i];
+       for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {
+               struct clk *clk = init_clocks[i];
+
+               /* first, register clock */
+               at32_clk_register(clk);
 
                if (clk->users == 0)
                        continue;
index 6c27ddac5adf10c6870c1c4679f8f6ab93411dc8..138a00a2a2d0c5c833723a0a6610e8baf6d42a5c 100644 (file)
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/list.h>
 
 #include <mach/chip.h>
 
 #include "clock.h"
 
+/* at32 clock list */
+static LIST_HEAD(at32_clock_list);
+
 static DEFINE_SPINLOCK(clk_lock);
+static DEFINE_SPINLOCK(clk_list_lock);
+
+void at32_clk_register(struct clk *clk)
+{
+       spin_lock(&clk_list_lock);
+       /* add the new item to the end of the list */
+       list_add_tail(&clk->list, &at32_clock_list);
+       spin_unlock(&clk_list_lock);
+}
 
 struct clk *clk_get(struct device *dev, const char *id)
 {
-       int i;
+       struct clk *clk;
 
-       for (i = 0; i < at32_nr_clocks; i++) {
-               struct clk *clk = at32_clock_list[i];
+       spin_lock(&clk_list_lock);
 
-               if (clk->dev == dev && strcmp(id, clk->name) == 0)
+       list_for_each_entry(clk, &at32_clock_list, list) {
+               if (clk->dev == dev && strcmp(id, clk->name) == 0) {
+                       spin_unlock(&clk_list_lock);
                        return clk;
+               }
        }
 
+       spin_unlock(&clk_list_lock);
        return ERR_PTR(-ENOENT);
 }
 EXPORT_SYMBOL(clk_get);
@@ -203,8 +219,8 @@ dump_clock(struct clk *parent, struct clkinf *r)
 
        /* cost of this scan is small, but not linear... */
        r->nest = nest + NEST_DELTA;
-       for (i = 3; i < at32_nr_clocks; i++) {
-               clk = at32_clock_list[i];
+
+       list_for_each_entry(clk, &at32_clock_list, list) {
                if (clk->parent == parent)
                        dump_clock(clk, r);
        }
@@ -215,6 +231,7 @@ static int clk_show(struct seq_file *s, void *unused)
 {
        struct clkinf   r;
        int             i;
+       struct clk      *clk;
 
        /* show all the power manager registers */
        seq_printf(s, "MCCTRL  = %8x\n", pm_readl(MCCTRL));
@@ -234,14 +251,25 @@ static int clk_show(struct seq_file *s, void *unused)
 
        seq_printf(s, "\n");
 
-       /* show clock tree as derived from the three oscillators
-        * we "know" are at the head of the list
-        */
        r.s = s;
        r.nest = 0;
-       dump_clock(at32_clock_list[0], &r);
-       dump_clock(at32_clock_list[1], &r);
-       dump_clock(at32_clock_list[2], &r);
+       /* protected from changes on the list while dumping */
+       spin_lock(&clk_list_lock);
+
+       /* show clock tree as derived from the three oscillators */
+       clk = clk_get(NULL, "osc32k");
+       dump_clock(clk, &r);
+       clk_put(clk);
+
+       clk = clk_get(NULL, "osc0");
+       dump_clock(clk, &r);
+       clk_put(clk);
+
+       clk = clk_get(NULL, "osc1");
+       dump_clock(clk, &r);
+       clk_put(clk);
+
+       spin_unlock(&clk_list_lock);
 
        return 0;
 }
index bb8e1f295835e95fa306c42071a6d5c55fe4fe3b..623bf0e9a1e7a843ff66c02ed0aa4961dc3b784d 100644 (file)
  * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
+#include <linux/list.h>
+
+
+void at32_clk_register(struct clk *clk);
 
 struct clk {
+       struct list_head list;          /* linking element */
        const char      *name;          /* Clock name/function */
        struct device   *dev;           /* Device the clock is used by */
        struct clk      *parent;        /* Parent clock, if any */
@@ -25,6 +30,3 @@ struct clk {
        u16             users;          /* Enabled if non-zero */
        u16             index;          /* Sibling index */
 };
-
-extern struct clk *at32_clock_list[];
-extern unsigned int at32_nr_clocks;
index 1e9852d65ccaf04256dc96df8968984c772e692a..a77d372f6f3ea8660ffeec96cc31b52381a04b77 100644 (file)
 #define HMATRIX_BASE   0xfff00800
 #define SDRAMC_BASE    0xfff03800
 
+/* LCDC on port C */
+#define ATMEL_LCDC_PC_CC       (1ULL << 19)
+#define ATMEL_LCDC_PC_HSYNC    (1ULL << 20)
+#define ATMEL_LCDC_PC_PCLK     (1ULL << 21)
+#define ATMEL_LCDC_PC_VSYNC    (1ULL << 22)
+#define ATMEL_LCDC_PC_DVAL     (1ULL << 23)
+#define ATMEL_LCDC_PC_MODE     (1ULL << 24)
+#define ATMEL_LCDC_PC_PWR      (1ULL << 25)
+#define ATMEL_LCDC_PC_DATA0    (1ULL << 26)
+#define ATMEL_LCDC_PC_DATA1    (1ULL << 27)
+#define ATMEL_LCDC_PC_DATA2    (1ULL << 28)
+#define ATMEL_LCDC_PC_DATA3    (1ULL << 29)
+#define ATMEL_LCDC_PC_DATA4    (1ULL << 30)
+#define ATMEL_LCDC_PC_DATA5    (1ULL << 31)
+
+/* LCDC on port D */
+#define ATMEL_LCDC_PD_DATA6    (1ULL << 0)
+#define ATMEL_LCDC_PD_DATA7    (1ULL << 1)
+#define ATMEL_LCDC_PD_DATA8    (1ULL << 2)
+#define ATMEL_LCDC_PD_DATA9    (1ULL << 3)
+#define ATMEL_LCDC_PD_DATA10   (1ULL << 4)
+#define ATMEL_LCDC_PD_DATA11   (1ULL << 5)
+#define ATMEL_LCDC_PD_DATA12   (1ULL << 6)
+#define ATMEL_LCDC_PD_DATA13   (1ULL << 7)
+#define ATMEL_LCDC_PD_DATA14   (1ULL << 8)
+#define ATMEL_LCDC_PD_DATA15   (1ULL << 9)
+#define ATMEL_LCDC_PD_DATA16   (1ULL << 10)
+#define ATMEL_LCDC_PD_DATA17   (1ULL << 11)
+#define ATMEL_LCDC_PD_DATA18   (1ULL << 12)
+#define ATMEL_LCDC_PD_DATA19   (1ULL << 13)
+#define ATMEL_LCDC_PD_DATA20   (1ULL << 14)
+#define ATMEL_LCDC_PD_DATA21   (1ULL << 15)
+#define ATMEL_LCDC_PD_DATA22   (1ULL << 16)
+#define ATMEL_LCDC_PD_DATA23   (1ULL << 17)
+
+/* LCDC on port E */
+#define ATMEL_LCDC_PE_CC       (1ULL << (32 + 0))
+#define ATMEL_LCDC_PE_DVAL     (1ULL << (32 + 1))
+#define ATMEL_LCDC_PE_MODE     (1ULL << (32 + 2))
+#define ATMEL_LCDC_PE_DATA0    (1ULL << (32 + 3))
+#define ATMEL_LCDC_PE_DATA1    (1ULL << (32 + 4))
+#define ATMEL_LCDC_PE_DATA2    (1ULL << (32 + 5))
+#define ATMEL_LCDC_PE_DATA3    (1ULL << (32 + 6))
+#define ATMEL_LCDC_PE_DATA4    (1ULL << (32 + 7))
+#define ATMEL_LCDC_PE_DATA8    (1ULL << (32 + 8))
+#define ATMEL_LCDC_PE_DATA9    (1ULL << (32 + 9))
+#define ATMEL_LCDC_PE_DATA10   (1ULL << (32 + 10))
+#define ATMEL_LCDC_PE_DATA11   (1ULL << (32 + 11))
+#define ATMEL_LCDC_PE_DATA12   (1ULL << (32 + 12))
+#define ATMEL_LCDC_PE_DATA16   (1ULL << (32 + 13))
+#define ATMEL_LCDC_PE_DATA17   (1ULL << (32 + 14))
+#define ATMEL_LCDC_PE_DATA18   (1ULL << (32 + 15))
+#define ATMEL_LCDC_PE_DATA19   (1ULL << (32 + 16))
+#define ATMEL_LCDC_PE_DATA20   (1ULL << (32 + 17))
+#define ATMEL_LCDC_PE_DATA21   (1ULL << (32 + 18))
+
+
+#define ATMEL_LCDC(PORT, PIN)  (ATMEL_LCDC_##PORT##_##PIN)
+
+
+#define ATMEL_LCDC_PRI_24B_DATA        (                                       \
+               ATMEL_LCDC(PC, DATA0)  | ATMEL_LCDC(PC, DATA1)  |       \
+               ATMEL_LCDC(PC, DATA2)  | ATMEL_LCDC(PC, DATA3)  |       \
+               ATMEL_LCDC(PC, DATA4)  | ATMEL_LCDC(PC, DATA5)  |       \
+               ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |       \
+               ATMEL_LCDC(PD, DATA8)  | ATMEL_LCDC(PD, DATA9)  |       \
+               ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) |       \
+               ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) |       \
+               ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |       \
+               ATMEL_LCDC(PD, DATA16) | ATMEL_LCDC(PD, DATA17) |       \
+               ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) |       \
+               ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) |       \
+               ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_ALT_24B_DATA (                                      \
+               ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |       \
+               ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)  |       \
+               ATMEL_LCDC(PE, DATA4)  | ATMEL_LCDC(PC, DATA5)  |       \
+               ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |       \
+               ATMEL_LCDC(PE, DATA8)  | ATMEL_LCDC(PE, DATA9)  |       \
+               ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) |       \
+               ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) |       \
+               ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |       \
+               ATMEL_LCDC(PE, DATA16) | ATMEL_LCDC(PE, DATA17) |       \
+               ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) |       \
+               ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) |       \
+               ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_PRI_15B_DATA (                                      \
+               ATMEL_LCDC(PC, DATA0)  | ATMEL_LCDC(PC, DATA1)  |       \
+               ATMEL_LCDC(PC, DATA2)  | ATMEL_LCDC(PC, DATA3)  |       \
+               ATMEL_LCDC(PC, DATA4)  | ATMEL_LCDC(PC, DATA5)  |       \
+               ATMEL_LCDC(PD, DATA8)  | ATMEL_LCDC(PD, DATA9)  |       \
+               ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) |       \
+               ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) |       \
+               ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) |       \
+               ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
+
+#define ATMEL_LCDC_ALT_15B_DATA        (                                       \
+               ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |       \
+               ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)  |       \
+               ATMEL_LCDC(PE, DATA4)  | ATMEL_LCDC(PC, DATA5)  |       \
+               ATMEL_LCDC(PE, DATA8)  | ATMEL_LCDC(PE, DATA9)  |       \
+               ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) |       \
+               ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) |       \
+               ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) |       \
+               ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
+
+#define ATMEL_LCDC_PRI_CONTROL (                                       \
+               ATMEL_LCDC(PC, CC)   | ATMEL_LCDC(PC, DVAL) |           \
+               ATMEL_LCDC(PC, MODE) | ATMEL_LCDC(PC, PWR))
+
+#define ATMEL_LCDC_ALT_CONTROL (                                       \
+               ATMEL_LCDC(PE, CC)   | ATMEL_LCDC(PE, DVAL) |           \
+               ATMEL_LCDC(PE, MODE) | ATMEL_LCDC(PC, PWR))
+
+#define ATMEL_LCDC_CONTROL (                                           \
+               ATMEL_LCDC(PC, HSYNC) | ATMEL_LCDC(PC, VSYNC) |         \
+               ATMEL_LCDC(PC, PCLK))
+
+#define ATMEL_LCDC_PRI_24BIT   (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_24B_DATA)
+
+#define ATMEL_LCDC_ALT_24BIT   (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
+
+#define ATMEL_LCDC_PRI_15BIT   (ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
+
+#define ATMEL_LCDC_ALT_15BIT   (ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
+
 #endif /* __ASM_ARCH_AT32AP700X_H__ */
index e60e9076544d08ace7891dbe1d1ffbf31df4f45f..c48386d66bc38f9fb0c1e287748b6de16a8ac903 100644 (file)
@@ -43,7 +43,7 @@ struct atmel_lcdfb_info;
 struct platform_device *
 at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
                     unsigned long fbmem_start, unsigned long fbmem_len,
-                    unsigned int pin_config);
+                    u64 pin_mask);
 
 struct usba_platform_data;
 struct platform_device *
index 4ec6abc68ea38084fae0a1d269f5fd53ebe34589..22ea79b740528b62dcd0bc9c4a211e2236bde564 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef __ASM_AVR32_ARCH_AT32AP_IO_H
 #define __ASM_AVR32_ARCH_AT32AP_IO_H
 
-/* For "bizarre" halfword swapping */
-#include <linux/byteorder/swabb.h>
+#include <linux/swab.h>
 
 #if defined(CONFIG_AP700X_32_BIT_SMC)
 # define __swizzle_addr_b(addr)        (addr ^ 3UL)
index b1abe6b4e4efef469f8098dd2d1ebb04873d937d..21c79373b53f04dae129e8a3907638f180577b7e 100644 (file)
 #define AT32_GPIOF_DEGLITCH    0x00000008      /* (IN) Filter glitches */
 #define AT32_GPIOF_MULTIDRV    0x00000010      /* Enable multidriver option */
 
-void at32_select_periph(unsigned int pin, unsigned int periph,
-                       unsigned long flags);
+void at32_select_periph(unsigned int port, unsigned int pin,
+                       unsigned int periph, unsigned long flags);
 void at32_select_gpio(unsigned int pin, unsigned long flags);
+void at32_deselect_pin(unsigned int pin);
 void at32_reserve_pin(unsigned int pin);
 
 #endif /* __ASM_ARCH_PORTMUX_H__ */
index 1040bda4fda7c843ea0d4955129f17cc94ab79bd..61ab15aae97008e798f5b89d6a225d195ca1b578 100644 (file)
@@ -35,7 +35,6 @@ static int __init pdc_probe(struct platform_device *pdev)
 }
 
 static struct platform_driver pdc_driver = {
-       .probe          = pdc_probe,
        .driver         = {
                .name   = "pdc",
        },
@@ -43,6 +42,6 @@ static struct platform_driver pdc_driver = {
 
 static int __init pdc_init(void)
 {
-       return platform_driver_register(&pdc_driver);
+       return platform_driver_probe(&pdc_driver, pdc_probe);
 }
 arch_initcall(pdc_init);
index 405ee6bad4ce59dd888448b100daba698cf12b0c..ed81a8bcb22d44ffa733beed2b43119caca29036 100644 (file)
@@ -50,35 +50,48 @@ static struct pio_device *gpio_to_pio(unsigned int gpio)
 }
 
 /* Pin multiplexing API */
+static DEFINE_SPINLOCK(pio_lock);
 
-void __init at32_select_periph(unsigned int pin, unsigned int periph,
-                              unsigned long flags)
+void __init at32_select_periph(unsigned int port, u32 pin_mask,
+                              unsigned int periph, unsigned long flags)
 {
        struct pio_device *pio;
-       unsigned int pin_index = pin & 0x1f;
-       u32 mask = 1 << pin_index;
 
-       pio = gpio_to_pio(pin);
+       /* assign and verify pio */
+       pio = gpio_to_pio(port);
        if (unlikely(!pio)) {
-               printk("pio: invalid pin %u\n", pin);
+               printk(KERN_WARNING "pio: invalid port %u\n", port);
                goto fail;
        }
 
-       if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask)
-                        || gpiochip_is_requested(&pio->chip, pin_index))) {
-               printk("%s: pin %u is busy\n", pio->name, pin_index);
+       /* Test if any of the requested pins is already muxed */
+       spin_lock(&pio_lock);
+       if (unlikely(pio->pinmux_mask & pin_mask)) {
+               printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n",
+                      pio->name, pin_mask, pio->pinmux_mask & pin_mask);
+               spin_unlock(&pio_lock);
                goto fail;
        }
 
-       pio_writel(pio, PUER, mask);
+       pio->pinmux_mask |= pin_mask;
+
+       /* enable pull ups */
+       pio_writel(pio, PUER, pin_mask);
+
+       /* select either peripheral A or B */
        if (periph)
-               pio_writel(pio, BSR, mask);
+               pio_writel(pio, BSR, pin_mask);
        else
-               pio_writel(pio, ASR, mask);
+               pio_writel(pio, ASR, pin_mask);
+
+       /* enable peripheral control */
+       pio_writel(pio, PDR, pin_mask);
 
-       pio_writel(pio, PDR, mask);
+       /* Disable pull ups if not requested. */
        if (!(flags & AT32_GPIOF_PULLUP))
-               pio_writel(pio, PUDR, mask);
+               pio_writel(pio, PUDR, pin_mask);
+
+       spin_unlock(&pio_lock);
 
        return;
 
@@ -134,6 +147,25 @@ fail:
        dump_stack();
 }
 
+/*
+ * Undo a previous pin reservation. Will not affect the hardware
+ * configuration.
+ */
+void at32_deselect_pin(unsigned int pin)
+{
+       struct pio_device *pio;
+       unsigned int pin_index = pin & 0x1f;
+
+       pio = gpio_to_pio(pin);
+       if (unlikely(!pio)) {
+               printk("pio: invalid pin %u\n", pin);
+               dump_stack();
+               return;
+       }
+
+       clear_bit(pin_index, &pio->pinmux_mask);
+}
+
 /* Reserve a pin, preventing anyone else from changing its configuration. */
 void __init at32_reserve_pin(unsigned int pin)
 {
@@ -382,7 +414,6 @@ static int __init pio_probe(struct platform_device *pdev)
 }
 
 static struct platform_driver pio_driver = {
-       .probe          = pio_probe,
        .driver         = {
                .name           = "pio",
        },
@@ -390,7 +421,7 @@ static struct platform_driver pio_driver = {
 
 static int __init pio_init(void)
 {
-       return platform_driver_register(&pio_driver);
+       return platform_driver_probe(&pio_driver, pio_probe);
 }
 postcore_initcall(pio_init);
 
index 1fe81c3c1e86921cedd64597ce3f3fb515007f0b..e0eb520e02872e01cec8fdb69c61439c27cc13fc 100644 (file)
@@ -5,4 +5,4 @@ oprofile-y              := $(addprefix ../../../drivers/oprofile/,      \
                                event_buffer.o oprofile_files.o         \
                                oprofilefs.o oprofile_stats.o           \
                                timer_int.o)
-oprofile-y             += op_model_avr32.o
+oprofile-y             += op_model_avr32.o backtrace.o
diff --git a/arch/avr32/oprofile/backtrace.c b/arch/avr32/oprofile/backtrace.c
new file mode 100644 (file)
index 0000000..75d9ad6
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * AVR32 specific backtracing code for oprofile
+ *
+ * Copyright 2008 Weinmann GmbH
+ *
+ * Author: Nikolaus Voss <n.voss@weinmann.de>
+ *
+ * Based on i386 oprofile backtrace code by John Levon and David Smith
+ *
+ * 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/oprofile.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+/* The first two words of each frame on the stack look like this if we have
+ * frame pointers */
+struct frame_head {
+       unsigned long lr;
+       struct frame_head *fp;
+};
+
+/* copied from arch/avr32/kernel/process.c */
+static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p)
+{
+       return (p > (unsigned long)tinfo)
+               && (p < (unsigned long)tinfo + THREAD_SIZE - 3);
+}
+
+/* copied from arch/x86/oprofile/backtrace.c */
+static struct frame_head *dump_user_backtrace(struct frame_head *head)
+{
+       struct frame_head bufhead[2];
+
+       /* Also check accessibility of one struct frame_head beyond */
+       if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
+               return NULL;
+       if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
+               return NULL;
+
+       oprofile_add_trace(bufhead[0].lr);
+
+       /* frame pointers should strictly progress back up the stack
+        * (towards higher addresses) */
+       if (bufhead[0].fp <= head)
+               return NULL;
+
+       return bufhead[0].fp;
+}
+
+void avr32_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+       /* Get first frame pointer */
+       struct frame_head *head = (struct frame_head *)(regs->r7);
+
+       if (!user_mode(regs)) {
+#ifdef CONFIG_FRAME_POINTER
+               /*
+                * Traverse the kernel stack from frame to frame up to
+                * "depth" steps.
+                */
+               while (depth-- && valid_stack_ptr(task_thread_info(current),
+                                                 (unsigned long)head)) {
+                       oprofile_add_trace(head->lr);
+                       if (head->fp <= head)
+                               break;
+                       head = head->fp;
+               }
+#endif
+       } else {
+               /* Assume we have frame pointers in user mode process */
+               while (depth-- && head)
+                       head = dump_user_backtrace(head);
+       }
+}
+
+
index df42325c7f81da49e882c23c535a8eafd7a2356c..a3e9b3c4845a50f0fc53bf164923a084650f5c17 100644 (file)
@@ -22,6 +22,8 @@
 #define AVR32_PERFCTR_IRQ_GROUP        0
 #define AVR32_PERFCTR_IRQ_LINE 1
 
+void avr32_backtrace(struct pt_regs * const regs, unsigned int depth);
+
 enum { PCCNT, PCNT0, PCNT1, NR_counter };
 
 struct avr32_perf_counter {
@@ -223,6 +225,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        memcpy(ops, &avr32_perf_counter_ops,
                        sizeof(struct oprofile_operations));
 
+       ops->backtrace = avr32_backtrace;
+
        printk(KERN_INFO "oprofile: using AVR32 performance monitoring.\n");
 
        return 0;