]> err.no Git - linux-2.6/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen...
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 12 Oct 2007 02:13:44 +0000 (19:13 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 12 Oct 2007 02:13:44 +0000 (19:13 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6:
  [AVR32] Fix random segfault with preemption
  [AVR32] Don't use __builtin_xchg()
  [AVR32] ngw100 i2c-gpio tweaks
  [AVR32] Ignore a few irrelevant syscalls
  [AVR32] SMC configuration in clock cycles
  [AVR32] Drop support for redundant "keepinitrd" boot-time parm.
  [AVR32] Make dma_sync_*_for_cpu no-ops
  [AVR32] Remove unneeded 8K alignment of .text section
  [AVR32] Kill a few hardcoded constants in vmlinux.lds
  [AVR32] rename vmlinux.lds
  [AVR32] fix command line parsing in early_parse_fbmem
  [AVR32] checkstack support
  [AVR32] Wire up USBA device
  [AVR32] add multidrive support for pio driver
  [AVR32] /sys/kernel/debug/at32ap_clk
  [AVR32] Move AT32_PM_BASE definition into pm.h

21 files changed:
arch/avr32/boards/atngw100/flash.c
arch/avr32/boards/atngw100/setup.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/boards/atstk1000/flash.c
arch/avr32/kernel/Makefile
arch/avr32/kernel/entry-avr32b.S
arch/avr32/kernel/setup.c
arch/avr32/kernel/vmlinux.lds.S [moved from arch/avr32/kernel/vmlinux.lds.c with 95% similarity]
arch/avr32/mach-at32ap/at32ap7000.c
arch/avr32/mach-at32ap/clock.c
arch/avr32/mach-at32ap/hsmc.c
arch/avr32/mach-at32ap/pio.c
arch/avr32/mach-at32ap/pm.h
arch/avr32/mm/init.c
include/asm-avr32/arch-at32ap/board.h
include/asm-avr32/arch-at32ap/portmux.h
include/asm-avr32/arch-at32ap/smc.h
include/asm-avr32/dma-mapping.h
include/asm-avr32/system.h
include/asm-avr32/unistd.h
scripts/checkstack.pl

index f9b32a8eab9b217bfca2db0e7f21c90b2cff5bf7..b07ae63aa54802eaa47b700c009da90c83f31a9a 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/arch/smc.h>
 
-static struct smc_config flash_config __initdata = {
+static struct smc_timing flash_timing __initdata = {
        .ncs_read_setup         = 0,
        .nrd_setup              = 40,
        .ncs_write_setup        = 0,
@@ -28,7 +28,9 @@ static struct smc_config flash_config __initdata = {
 
        .read_cycle             = 120,
        .write_cycle            = 120,
+};
 
+static struct smc_config flash_config __initdata = {
        .bus_width              = 2,
        .nrd_controlled         = 1,
        .nwe_controlled         = 1,
@@ -82,6 +84,7 @@ static int __init atngw100_flash_init(void)
 {
        int ret;
 
+       smc_set_timing(&flash_config, &flash_timing);
        ret = smc_set_configuration(0, &flash_config);
        if (ret < 0) {
                printk(KERN_ERR "atngw100: failed to set NOR flash timing\n");
index ef801563bbf58930cfb90762a345b0d480c99841..52987c81d668d1c5825f3f209058e99080ab462e 100644 (file)
@@ -125,8 +125,11 @@ static struct platform_device ngw_gpio_leds = {
 };
 
 static struct i2c_gpio_platform_data i2c_gpio_data = {
-       .sda_pin        = GPIO_PIN_PA(6),
-       .scl_pin        = GPIO_PIN_PA(7),
+       .sda_pin                = GPIO_PIN_PA(6),
+       .scl_pin                = GPIO_PIN_PA(7),
+       .sda_is_open_drain      = 1,
+       .scl_is_open_drain      = 1,
+       .udelay                 = 2,    /* close to 100 kHz */
 };
 
 static struct platform_device i2c_gpio_device = {
@@ -154,6 +157,7 @@ static int __init atngw100_init(void)
        set_hw_addr(at32_add_device_eth(1, &eth_data[1]));
 
        at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+       at32_add_device_usba(0, NULL);
 
        for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) {
                at32_select_gpio(ngw_leds[i].gpio,
@@ -161,8 +165,10 @@ static int __init atngw100_init(void)
        }
        platform_device_register(&ngw_gpio_leds);
 
-       at32_select_gpio(i2c_gpio_data.sda_pin, 0);
-       at32_select_gpio(i2c_gpio_data.scl_pin, 0);
+       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,
+               AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
        platform_device_register(&i2c_gpio_device);
 
        return 0;
index c9981b731efa58e1d20aecee60222081ed813b06..6b9e466104ad04d8c5be831774a937931eb298e3 100644 (file)
@@ -241,6 +241,7 @@ static int __init atstk1002_init(void)
        at32_add_device_lcdc(0, &atstk1000_lcdc_data,
                             fbmem_start, fbmem_size);
 #endif
+       at32_add_device_usba(0, NULL);
 #ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM
        at32_add_device_ssc(0, ATMEL_SSC_TX);
 #endif
index aac4300cca125afe112d97ce46a6fafec5acca72..3d0a102ad45ec1e8fd77ad4bd794b4d726a65888 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <asm/arch/smc.h>
 
-static struct smc_config flash_config __initdata = {
+static struct smc_timing flash_timing __initdata = {
        .ncs_read_setup         = 0,
        .nrd_setup              = 40,
        .ncs_write_setup        = 0,
@@ -28,7 +28,9 @@ static struct smc_config flash_config __initdata = {
 
        .read_cycle             = 120,
        .write_cycle            = 120,
+};
 
+static struct smc_config flash_config __initdata = {
        .bus_width              = 2,
        .nrd_controlled         = 1,
        .nwe_controlled         = 1,
@@ -82,6 +84,7 @@ static int __init atstk1000_flash_init(void)
 {
        int ret;
 
+       smc_set_timing(&flash_config, &flash_timing);
        ret = smc_set_configuration(0, &flash_config);
        if (ret < 0) {
                printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n");
index 90e5afff54a2d1d537e0bf202d1effb61244e803..989fcd1fef7ed4fd048096b88b18c98d366d1237 100644 (file)
@@ -11,8 +11,3 @@ obj-y                         += signal.o sys_avr32.o process.o time.o
 obj-y                          += init_task.o switch_to.o cpu.o
 obj-$(CONFIG_MODULES)          += module.o avr32_ksyms.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
-
-USE_STANDARD_AS_RULE           := true
-
-%.lds: %.lds.c FORCE
-       $(call if_changed_dep,cpp_lds_S)
index 42657f1703b2773dc3532eaf3a5bf99efcf7e26a..ccadfd9b438da8a86517b135da8c9a90d24b955d 100644 (file)
@@ -159,11 +159,18 @@ handle_vmalloc_miss:
 
        .section .scall.text,"ax",@progbits
 system_call:
+#ifdef CONFIG_PREEMPT
+       mask_interrupts
+#endif
        pushm   r12             /* r12_orig */
        stmts   --sp, r0-lr
-       zero_fp
+
        mfsr    r0, SYSREG_RAR_SUP
        mfsr    r1, SYSREG_RSR_SUP
+#ifdef CONFIG_PREEMPT
+       unmask_interrupts
+#endif
+       zero_fp
        stm     --sp, r0-r1
 
        /* check for syscall tracing */
@@ -638,6 +645,13 @@ irq_level\level:
        stmts   --sp,r0-lr
        mfsr    r8, rar_int\level
        mfsr    r9, rsr_int\level
+
+#ifdef CONFIG_PREEMPT
+       sub     r11, pc, (. - system_call)
+       cp.w    r11, r8
+       breq    4f
+#endif
+
        pushm   r8-r9
 
        mov     r11, sp
@@ -668,6 +682,16 @@ irq_level\level:
        sub     sp, -4          /* ignore r12_orig */
        rete
 
+#ifdef CONFIG_PREEMPT
+4:     mask_interrupts
+       mfsr    r8, rsr_int\level
+       sbr     r8, 16
+       mtsr    rsr_int\level, r8
+       ldmts   sp++, r0-lr
+       sub     sp, -4          /* ignore r12_orig */
+       rete
+#endif
+
 2:     get_thread_info r0
        ld.w    r1, r0[TI_flags]
        bld     r1, TIF_CPU_GOING_TO_SLEEP
index d08b0bc6b2bbc31338f9f0cbc2f0e2b1da282ee9..4b4c1884e1c5a4c7546eebf9ee39dcdf500e9781 100644 (file)
@@ -248,7 +248,7 @@ static int __init early_parse_fbmem(char *p)
 
        fbmem_size = memparse(p, &p);
        if (*p == '@') {
-               fbmem_start = memparse(p, &p);
+               fbmem_start = memparse(p + 1, &p);
                ret = add_reserved_region(fbmem_start,
                                          fbmem_start + fbmem_size - 1,
                                          "Framebuffer");
similarity index 95%
rename from arch/avr32/kernel/vmlinux.lds.c
rename to arch/avr32/kernel/vmlinux.lds.S
index db0438f35c0066b8776df3c326e8de8ec6402427..ce9ac9659883d0336cbbe0e796f660e1e97173a2 100644 (file)
@@ -9,6 +9,8 @@
  */
 #define LOAD_OFFSET 0x00000000
 #include <asm-generic/vmlinux.lds.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
 
 OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
 OUTPUT_ARCH(avr32)
@@ -58,11 +60,10 @@ SECTIONS
                        *(.init.ramfs)
                __initramfs_end = .;
 #endif
-               . = ALIGN(4096);
+               . = ALIGN(PAGE_SIZE);
                __init_end = .;
        }
 
-       . = ALIGN(8192);
        .text           : AT(ADDR(.text) - LOAD_OFFSET) {
                _evba = .;
                _text = .;
@@ -96,7 +97,7 @@ SECTIONS
 
        RODATA
 
-       . = ALIGN(8192);
+       . = ALIGN(THREAD_SIZE);
 
        .data           : AT(ADDR(.data) - LOAD_OFFSET) {
                _data = .;
@@ -107,7 +108,7 @@ SECTIONS
                *(.data.init_task)
 
                /* Then, the cacheline aligned data */
-               . = ALIGN(32);
+               . = ALIGN(L1_CACHE_BYTES);
                *(.data.cacheline_aligned)
 
                /* And the rest... */
index 64cc5583ddfb0a5feb89669d00ce853055421a68..f6d154ca4d24ebdd91c2fa1fef37d15a25184777 100644 (file)
 #include "pio.h"
 #include "pm.h"
 
-/*
- * We can reduce the code size a bit by using a constant here. Since
- * this file is completely chip-specific, it's safe to not use
- * ioremap. Generic drivers should of course never do this.
- */
-#define AT32_PM_BASE   0xfff00000
 
 #define PBMEM(base)                                    \
        {                                               \
@@ -1167,6 +1161,72 @@ at32_add_device_ssc(unsigned int id, unsigned int flags)
        return pdev;
 }
 
+/* --------------------------------------------------------------------
+ *  USB Device Controller
+ * -------------------------------------------------------------------- */
+static struct resource usba0_resource[] __initdata = {
+       {
+               .start          = 0xff300000,
+               .end            = 0xff3fffff,
+               .flags          = IORESOURCE_MEM,
+       }, {
+               .start          = 0xfff03000,
+               .end            = 0xfff033ff,
+               .flags          = IORESOURCE_MEM,
+       },
+       IRQ(31),
+};
+static struct clk usba0_pclk = {
+       .name           = "pclk",
+       .parent         = &pbb_clk,
+       .mode           = pbb_clk_mode,
+       .get_rate       = pbb_clk_get_rate,
+       .index          = 12,
+};
+static struct clk usba0_hclk = {
+       .name           = "hclk",
+       .parent         = &hsb_clk,
+       .mode           = hsb_clk_mode,
+       .get_rate       = hsb_clk_get_rate,
+       .index          = 6,
+};
+
+struct platform_device *__init
+at32_add_device_usba(unsigned int id, struct usba_platform_data *data)
+{
+       struct platform_device *pdev;
+
+       if (id != 0)
+               return NULL;
+
+       pdev = platform_device_alloc("atmel_usba_udc", 0);
+       if (!pdev)
+               return NULL;
+
+       if (platform_device_add_resources(pdev, usba0_resource,
+                                         ARRAY_SIZE(usba0_resource)))
+               goto out_free_pdev;
+
+       if (data) {
+               if (platform_device_add_data(pdev, data, sizeof(*data)))
+                       goto out_free_pdev;
+
+               if (data->vbus_pin != GPIO_PIN_NONE)
+                       at32_select_gpio(data->vbus_pin, 0);
+       }
+
+       usba0_pclk.dev = &pdev->dev;
+       usba0_hclk.dev = &pdev->dev;
+
+       platform_device_add(pdev);
+
+       return pdev;
+
+out_free_pdev:
+       platform_device_put(pdev);
+       return NULL;
+}
+
 /* --------------------------------------------------------------------
  *  GCLK
  * -------------------------------------------------------------------- */
@@ -1252,6 +1312,8 @@ struct clk *at32_clock_list[] = {
        &ssc0_pclk,
        &ssc1_pclk,
        &ssc2_pclk,
+       &usba0_hclk,
+       &usba0_pclk,
        &gclk0,
        &gclk1,
        &gclk2,
index 0f8c89c9f83243532c57dded20c5fc1be0893b91..4642117cc9ab8e362f0a07cc8205ab4e81c0c905 100644 (file)
@@ -150,3 +150,119 @@ struct clk *clk_get_parent(struct clk *clk)
        return clk->parent;
 }
 EXPORT_SYMBOL(clk_get_parent);
+
+
+
+#ifdef CONFIG_DEBUG_FS
+
+/* /sys/kernel/debug/at32ap_clk */
+
+#include <linux/io.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include "pm.h"
+
+
+#define        NEST_DELTA      2
+#define        NEST_MAX        6
+
+struct clkinf {
+       struct seq_file *s;
+       unsigned        nest;
+};
+
+static void
+dump_clock(struct clk *parent, struct clkinf *r)
+{
+       unsigned        nest = r->nest;
+       char            buf[16 + NEST_MAX];
+       struct clk      *clk;
+       unsigned        i;
+
+       /* skip clocks coupled to devices that aren't registered */
+       if (parent->dev && !parent->dev->bus_id[0] && !parent->users)
+               return;
+
+       /* <nest spaces> name <pad to end> */
+       memset(buf, ' ', sizeof(buf) - 1);
+       buf[sizeof(buf) - 1] = 0;
+       i = strlen(parent->name);
+       memcpy(buf + nest, parent->name,
+                       min(i, (unsigned)(sizeof(buf) - 1 - nest)));
+
+       seq_printf(r->s, "%s%c users=%2d %-3s %9ld Hz",
+               buf, parent->set_parent ? '*' : ' ',
+               parent->users,
+               parent->users ? "on" : "off",   /* NOTE: not-paranoid!! */
+               clk_get_rate(parent));
+       if (parent->dev)
+               seq_printf(r->s, ", for %s", parent->dev->bus_id);
+       seq_printf(r->s, "\n");
+
+       /* 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];
+               if (clk->parent == parent)
+                       dump_clock(clk, r);
+       }
+       r->nest = nest;
+}
+
+static int clk_show(struct seq_file *s, void *unused)
+{
+       struct clkinf   r;
+       int             i;
+
+       /* show all the power manager registers */
+       seq_printf(s, "MCCTRL  = %8x\n", pm_readl(MCCTRL));
+       seq_printf(s, "CKSEL   = %8x\n", pm_readl(CKSEL));
+       seq_printf(s, "CPUMASK = %8x\n", pm_readl(CPU_MASK));
+       seq_printf(s, "HSBMASK = %8x\n", pm_readl(HSB_MASK));
+       seq_printf(s, "PBAMASK = %8x\n", pm_readl(PBA_MASK));
+       seq_printf(s, "PBBMASK = %8x\n", pm_readl(PBB_MASK));
+       seq_printf(s, "PLL0    = %8x\n", pm_readl(PLL0));
+       seq_printf(s, "PLL1    = %8x\n", pm_readl(PLL1));
+       seq_printf(s, "IMR     = %8x\n", pm_readl(IMR));
+       for (i = 0; i < 8; i++) {
+               if (i == 5)
+                       continue;
+               seq_printf(s, "GCCTRL%d = %8x\n", i, pm_readl(GCCTRL(i)));
+       }
+
+       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);
+
+       return 0;
+}
+
+static int clk_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, clk_show, NULL);
+}
+
+static const struct file_operations clk_operations = {
+       .open           = clk_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init clk_debugfs_init(void)
+{
+       (void) debugfs_create_file("at32ap_clk", S_IFREG | S_IRUGO,
+                       NULL, NULL, &clk_operations);
+
+       return 0;
+}
+postcore_initcall(clk_debugfs_init);
+
+#endif
index 5e22a750632b78755c24d84d05718c24822b587c..704607fbcc696d2223241ff26103176daa254b46 100644 (file)
@@ -29,16 +29,25 @@ struct hsmc {
 
 static struct hsmc *hsmc;
 
-int smc_set_configuration(int cs, const struct smc_config *config)
+void smc_set_timing(struct smc_config *config,
+                   const struct smc_timing *timing)
 {
+       int recover;
+       int cycle;
+
        unsigned long mul;
-       unsigned long offset;
-       u32 setup, pulse, cycle, mode;
 
-       if (!hsmc)
-               return -ENODEV;
-       if (cs >= NR_CHIP_SELECTS)
-               return -EINVAL;
+       /* Reset all SMC timings */
+       config->ncs_read_setup  = 0;
+       config->nrd_setup       = 0;
+       config->ncs_write_setup = 0;
+       config->nwe_setup       = 0;
+       config->ncs_read_pulse  = 0;
+       config->nrd_pulse       = 0;
+       config->ncs_write_pulse = 0;
+       config->nwe_pulse       = 0;
+       config->read_cycle      = 0;
+       config->write_cycle     = 0;
 
        /*
         * cycles = x / T = x * f
@@ -50,16 +59,102 @@ int smc_set_configuration(int cs, const struct smc_config *config)
 
 #define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
 
-       setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
-                | HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
-                | HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
-                | HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
-       pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
-                | HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
-                | HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
-                | HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
-       cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
-                | HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
+       if (timing->ncs_read_setup > 0)
+               config->ncs_read_setup = ns2cyc(timing->ncs_read_setup);
+
+       if (timing->nrd_setup > 0)
+               config->nrd_setup = ns2cyc(timing->nrd_setup);
+
+       if (timing->ncs_write_setup > 0)
+               config->ncs_write_setup = ns2cyc(timing->ncs_write_setup);
+
+       if (timing->nwe_setup > 0)
+               config->nwe_setup = ns2cyc(timing->nwe_setup);
+
+       if (timing->ncs_read_pulse > 0)
+               config->ncs_read_pulse = ns2cyc(timing->ncs_read_pulse);
+
+       if (timing->nrd_pulse > 0)
+               config->nrd_pulse = ns2cyc(timing->nrd_pulse);
+
+       if (timing->ncs_write_pulse > 0)
+               config->ncs_write_pulse = ns2cyc(timing->ncs_write_pulse);
+
+       if (timing->nwe_pulse > 0)
+               config->nwe_pulse = ns2cyc(timing->nwe_pulse);
+
+       if (timing->read_cycle > 0)
+               config->read_cycle = ns2cyc(timing->read_cycle);
+
+       if (timing->write_cycle > 0)
+               config->write_cycle = ns2cyc(timing->write_cycle);
+
+       /* Extend read cycle in needed */
+       if (timing->ncs_read_recover > 0)
+               recover = ns2cyc(timing->ncs_read_recover);
+       else
+               recover = 1;
+
+       cycle = config->ncs_read_setup + config->ncs_read_pulse + recover;
+
+       if (config->read_cycle < cycle)
+               config->read_cycle = cycle;
+
+       /* Extend read cycle in needed */
+       if (timing->nrd_recover > 0)
+               recover = ns2cyc(timing->nrd_recover);
+       else
+               recover = 1;
+
+       cycle = config->nrd_setup + config->nrd_pulse + recover;
+
+       if (config->read_cycle < cycle)
+               config->read_cycle = cycle;
+
+       /* Extend write cycle in needed */
+       if (timing->ncs_write_recover > 0)
+               recover = ns2cyc(timing->ncs_write_recover);
+       else
+               recover = 1;
+
+       cycle = config->ncs_write_setup + config->ncs_write_pulse + recover;
+
+       if (config->write_cycle < cycle)
+               config->write_cycle = cycle;
+
+       /* Extend write cycle in needed */
+       if (timing->nwe_recover > 0)
+               recover = ns2cyc(timing->nwe_recover);
+       else
+               recover = 1;
+
+       cycle = config->nwe_setup + config->nwe_pulse + recover;
+
+       if (config->write_cycle < cycle)
+               config->write_cycle = cycle;
+}
+EXPORT_SYMBOL(smc_set_timing);
+
+int smc_set_configuration(int cs, const struct smc_config *config)
+{
+       unsigned long offset;
+       u32 setup, pulse, cycle, mode;
+
+       if (!hsmc)
+               return -ENODEV;
+       if (cs >= NR_CHIP_SELECTS)
+               return -EINVAL;
+
+       setup = (HSMC_BF(NWE_SETUP, config->nwe_setup)
+                | HSMC_BF(NCS_WR_SETUP, config->ncs_write_setup)
+                | HSMC_BF(NRD_SETUP, config->nrd_setup)
+                | HSMC_BF(NCS_RD_SETUP, config->ncs_read_setup));
+       pulse = (HSMC_BF(NWE_PULSE, config->nwe_pulse)
+                | HSMC_BF(NCS_WR_PULSE, config->ncs_write_pulse)
+                | HSMC_BF(NRD_PULSE, config->nrd_pulse)
+                | HSMC_BF(NCS_RD_PULSE, config->ncs_read_pulse));
+       cycle = (HSMC_BF(NWE_CYCLE, config->write_cycle)
+                | HSMC_BF(NRD_CYCLE, config->read_cycle));
 
        switch (config->bus_width) {
        case 1:
index 1eb99b814f5bcaf021f06ef46ea26c3cc96fa67f..d61a02da898cd68bd08316474ee2c2762dfd8036 100644 (file)
@@ -110,6 +110,10 @@ void __init at32_select_gpio(unsigned int pin, unsigned long flags)
                        pio_writel(pio, SODR, mask);
                else
                        pio_writel(pio, CODR, mask);
+               if (flags & AT32_GPIOF_MULTIDRV)
+                       pio_writel(pio, MDER, mask);
+               else
+                       pio_writel(pio, MDDR, mask);
                pio_writel(pio, PUDR, mask);
                pio_writel(pio, OER, mask);
        } else {
index a1f8aced0a8c8dd2ff862c4e240ddfd6a351e658..47efd0d1951f41d86c21ddaae1c4c318a75efa08 100644 (file)
@@ -4,6 +4,14 @@
 #ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
 #define __ARCH_AVR32_MACH_AT32AP_PM_H__
 
+/*
+ * We can reduce the code size a bit by using a constant here. Since
+ * this file is only used on AVR32 AP CPUs with segmentation enabled,
+ * it's safe to not use ioremap. Generic drivers should of course
+ * never do this.
+ */
+#define AT32_PM_BASE   0xfff00000
+
 /* PM register offsets */
 #define PM_MCCTRL                              0x0000
 #define PM_CKSEL                               0x0004
index 82cf70854b90d3999e0672b6f8a2fa1c2601129c..480760bde63f9d2f342c5d32364ffa078800349a 100644 (file)
@@ -224,19 +224,9 @@ void free_initmem(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-static int keep_initrd;
-
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-       if (!keep_initrd)
-               free_area(start, end, "initrd");
-}
-
-static int __init keepinitrd_setup(char *__unused)
-{
-       keep_initrd = 1;
-       return 1;
+       free_area(start, end, "initrd");
 }
 
-__setup("keepinitrd", keepinitrd_setup);
 #endif
index 0215965dc586d4db7037299ef56e735e9cb5a0b4..7dbd603c38cc3cf6e5a2244e547c90b45df46e7e 100644 (file)
@@ -6,6 +6,8 @@
 
 #include <linux/types.h>
 
+#define GPIO_PIN_NONE  (-1)
+
 /* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
 void at32_add_system_devices(void);
 
@@ -36,6 +38,12 @@ struct platform_device *
 at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
                     unsigned long fbmem_start, unsigned long fbmem_len);
 
+struct usba_platform_data {
+       int vbus_pin;
+};
+struct platform_device *
+at32_add_device_usba(unsigned int id, struct usba_platform_data *data);
+
 /* depending on what's hooked up, not all SSC pins will be used */
 #define        ATMEL_SSC_TK            0x01
 #define        ATMEL_SSC_TF            0x02
index 9930871decde1e61bbb522b9d9243759263f773c..b1abe6b4e4efef469f8098dd2d1ebb04873d937d 100644 (file)
@@ -19,6 +19,7 @@
 #define AT32_GPIOF_OUTPUT      0x00000002      /* (OUT) Enable output driver */
 #define AT32_GPIOF_HIGH                0x00000004      /* (OUT) Set output high */
 #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);
index 07152b7fd9c94da03f2c3d2fa1af3c9d00464b8c..c98eea44a70a08eba09b2d24b7f522dd6ea5b255 100644 (file)
 /*
  * All timing parameters are in nanoseconds.
  */
+struct smc_timing {
+       /* Delay from address valid to assertion of given strobe */
+       int ncs_read_setup;
+       int nrd_setup;
+       int ncs_write_setup;
+       int nwe_setup;
+
+       /* Pulse length of given strobe */
+       int ncs_read_pulse;
+       int nrd_pulse;
+       int ncs_write_pulse;
+       int nwe_pulse;
+
+       /* Total cycle length of given operation */
+       int read_cycle;
+       int write_cycle;
+
+       /* Minimal recovery times, will extend cycle if needed */
+       int ncs_read_recover;
+       int nrd_recover;
+       int ncs_write_recover;
+       int nwe_recover;
+};
+
+/*
+ * All timing parameters are in clock cycles.
+ */
 struct smc_config {
+
        /* Delay from address valid to assertion of given strobe */
-       u16             ncs_read_setup;
-       u16             nrd_setup;
-       u16             ncs_write_setup;
-       u16             nwe_setup;
+       u             ncs_read_setup;
+       u             nrd_setup;
+       u             ncs_write_setup;
+       u             nwe_setup;
 
        /* Pulse length of given strobe */
-       u16             ncs_read_pulse;
-       u16             nrd_pulse;
-       u16             ncs_write_pulse;
-       u16             nwe_pulse;
+       u             ncs_read_pulse;
+       u             nrd_pulse;
+       u             ncs_write_pulse;
+       u             nwe_pulse;
 
        /* Total cycle length of given operation */
-       u16             read_cycle;
-       u16             write_cycle;
+       u             read_cycle;
+       u             write_cycle;
 
        /* Bus width in bytes */
        u8              bus_width;
@@ -76,6 +104,9 @@ struct smc_config {
        unsigned int    tdf_mode:1;
 };
 
+extern void smc_set_timing(struct smc_config *config,
+                          const struct smc_timing *timing);
+
 extern int smc_set_configuration(int cs, const struct smc_config *config);
 extern struct smc_config *smc_get_configuration(int cs);
 
index 21bb60bbb9a1889e3eb058f5b4045238b45bf33a..81e342636ac4cb3d93fc612b9018f5895f57e2c7 100644 (file)
@@ -264,7 +264,11 @@ static inline void
 dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
                        size_t size, enum dma_data_direction direction)
 {
-       dma_cache_sync(dev, bus_to_virt(dma_handle), size, direction);
+       /*
+        * No need to do anything since the CPU isn't supposed to
+        * touch this memory after we flushed it at mapping- or
+        * sync-for-device time.
+        */
 }
 
 static inline void
@@ -309,12 +313,11 @@ static inline void
 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
                    int nents, enum dma_data_direction direction)
 {
-       int i;
-
-       for (i = 0; i < nents; i++) {
-               dma_cache_sync(dev, page_address(sg[i].page) + sg[i].offset,
-                              sg[i].length, direction);
-       }
+       /*
+        * No need to do anything since the CPU isn't supposed to
+        * touch this memory after we flushed it at mapping- or
+        * sync-for-device time.
+        */
 }
 
 static inline void
index a8236bacc8789133c573885d3065ba97005eebc3..dc2d527cef4132532db6bda322f66167618f1d7f 100644 (file)
@@ -73,11 +73,16 @@ extern struct task_struct *__switch_to(struct task_struct *,
 
 extern void __xchg_called_with_bad_pointer(void);
 
-#ifdef __CHECKER__
-extern unsigned long __builtin_xchg(void *ptr, unsigned long x);
-#endif
+static inline unsigned long xchg_u32(u32 val, volatile u32 *m)
+{
+       u32 ret;
 
-#define xchg_u32(val, m) __builtin_xchg((void *)m, val)
+       asm volatile("xchg %[ret], %[m], %[val]"
+                       : [ret] "=&r"(ret), "=m"(*m)
+                       : "m"(*m), [m] "r"(m), [val] "r"(val)
+                       : "memory");
+       return ret;
+}
 
 static inline unsigned long __xchg(unsigned long x,
                                       volatile void *ptr,
index 3b4e35b55c822299072a04496ef11c70ea82fa13..de09009593f84eb12d3e8fa38c0450df96777b7d 100644 (file)
 #ifdef __KERNEL__
 #define NR_syscalls            282
 
+/* Old stuff */
+#define __IGNORE_uselib
+#define __IGNORE_mmap
+
+/* NUMA stuff */
+#define __IGNORE_mbind
+#define __IGNORE_get_mempolicy
+#define __IGNORE_set_mempolicy
+#define __IGNORE_migrate_pages
+#define __IGNORE_move_pages
+
+/* SMP stuff */
+#define __IGNORE_getcpu
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_STAT64
index f7844f6aa487a8c77fc08ff0edf11a8e0ab20d16..663158627155151d60315059a81f1b02d68af697 100755 (executable)
@@ -12,6 +12,7 @@
 #      sh64 port by Paul Mundt
 #      Random bits by Matt Mackall <mpm@selenic.com>
 #      M68k port by Geert Uytterhoeven and Andreas Schwab
+#      AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
 #
 #      Usage:
 #      objdump -d vmlinux | stackcheck.pl [arch]
@@ -37,6 +38,10 @@ my (@stack, $re, $x, $xs);
        if ($arch eq 'arm') {
                #c0008ffc:      e24dd064        sub     sp, sp, #100    ; 0x64
                $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+       } elsif ($arch eq 'avr32') {
+               #8000008a:       20 1d           sub sp,4
+               #80000ca8:       fa cd 05 b0     sub sp,sp,1456
+               $re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
        } elsif ($arch =~ /^i[3456]86$/) {
                #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
                $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%esp$/o;