Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7a5b80590772c29bba1d54d3685622177d6fe39f
Commit:     7a5b80590772c29bba1d54d3685622177d6fe39f
Parent:     c6083cd61b5a64a1c73d1634744382f54cb99595
Author:     Haavard Skinnemoen <[EMAIL PROTECTED]>
AuthorDate: Mon Jun 4 12:58:30 2007 +0200
Committer:  Haavard Skinnemoen <[EMAIL PROTECTED]>
CommitDate: Wed Jul 18 20:45:51 2007 +0200

    [AVR32] Split SM device into PM, RTC, WDT and EIC
    
    Split the SM platform device into separate platform devices for PM,
    RTC, WDT and EIC. This is more correct according to the documentation
    and allows us to simplify the code a little.
    
    Also turn the EIC driver into a real platform driver.
    
    Signed-off-by: Haavard Skinnemoen <[EMAIL PROTECTED]>
    Acked-by: Hans-Christian Egtvedt <[EMAIL PROTECTED]>
---
 arch/avr32/mach-at32ap/at32ap.c     |   31 -----
 arch/avr32/mach-at32ap/at32ap7000.c |  213 ++++++++++++++++++-------------
 arch/avr32/mach-at32ap/extint.c     |  200 ++++++++++++++++++++---------
 arch/avr32/mach-at32ap/pm.h         |  112 ++++++++++++++++
 arch/avr32/mach-at32ap/sm.h         |  242 -----------------------------------
 include/asm-avr32/arch-at32ap/sm.h  |   27 ----
 6 files changed, 372 insertions(+), 453 deletions(-)

diff --git a/arch/avr32/mach-at32ap/at32ap.c b/arch/avr32/mach-at32ap/at32ap.c
index 90f207e..7c4987f 100644
--- a/arch/avr32/mach-at32ap/at32ap.c
+++ b/arch/avr32/mach-at32ap/at32ap.c
@@ -11,41 +11,10 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 
-#include <asm/io.h>
-
 #include <asm/arch/init.h>
-#include <asm/arch/sm.h>
-
-struct at32_sm system_manager;
-
-static int __init at32_sm_init(void)
-{
-       struct resource *regs;
-       struct at32_sm *sm = &system_manager;
-       int ret = -ENXIO;
-
-       regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0);
-       if (!regs)
-               goto fail;
-
-       spin_lock_init(&sm->lock);
-       sm->pdev = &at32_sm_device;
-
-       ret = -ENOMEM;
-       sm->regs = ioremap(regs->start, regs->end - regs->start + 1);
-       if (!sm->regs)
-               goto fail;
-
-       return 0;
-
-fail:
-       printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret);
-       return ret;
-}
 
 void __init setup_platform(void)
 {
-       at32_sm_init();
        at32_clock_init();
        at32_portmux_init();
 }
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c 
b/arch/avr32/mach-at32ap/at32ap7000.c
index 4dda42d..5faa97e 100644
--- a/arch/avr32/mach-at32ap/at32ap7000.c
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -17,14 +17,20 @@
 #include <asm/arch/at32ap7000.h>
 #include <asm/arch/board.h>
 #include <asm/arch/portmux.h>
-#include <asm/arch/sm.h>
 
 #include <video/atmel_lcdc.h>
 
 #include "clock.h"
 #include "hmatrix.h"
 #include "pio.h"
-#include "sm.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)                                    \
        {                                               \
@@ -88,6 +94,8 @@ static struct clk devname##_##_name = {                       
        \
        .index          = _index,                               \
 }
 
+static DEFINE_SPINLOCK(pm_lock);
+
 unsigned long at32ap7000_osc_rates[3] = {
        [0] = 32768,
        /* FIXME: these are ATSTK1002-specific */
@@ -104,11 +112,11 @@ static unsigned long pll_get_rate(struct clk *clk, 
unsigned long control)
 {
        unsigned long div, mul, rate;
 
-       if (!(control & SM_BIT(PLLEN)))
+       if (!(control & PM_BIT(PLLEN)))
                return 0;
 
-       div = SM_BFEXT(PLLDIV, control) + 1;
-       mul = SM_BFEXT(PLLMUL, control) + 1;
+       div = PM_BFEXT(PLLDIV, control) + 1;
+       mul = PM_BFEXT(PLLMUL, control) + 1;
 
        rate = clk->parent->get_rate(clk->parent);
        rate = (rate + div / 2) / div;
@@ -121,7 +129,7 @@ static unsigned long pll0_get_rate(struct clk *clk)
 {
        u32 control;
 
-       control = sm_readl(&system_manager, PM_PLL0);
+       control = pm_readl(PLL0);
 
        return pll_get_rate(clk, control);
 }
@@ -130,7 +138,7 @@ static unsigned long pll1_get_rate(struct clk *clk)
 {
        u32 control;
 
-       control = sm_readl(&system_manager, PM_PLL1);
+       control = pm_readl(PLL1);
 
        return pll_get_rate(clk, control);
 }
@@ -187,108 +195,104 @@ static unsigned long bus_clk_get_rate(struct clk *clk, 
unsigned int shift)
 
 static void cpu_clk_mode(struct clk *clk, int enabled)
 {
-       struct at32_sm *sm = &system_manager;
        unsigned long flags;
        u32 mask;
 
-       spin_lock_irqsave(&sm->lock, flags);
-       mask = sm_readl(sm, PM_CPU_MASK);
+       spin_lock_irqsave(&pm_lock, flags);
+       mask = pm_readl(CPU_MASK);
        if (enabled)
                mask |= 1 << clk->index;
        else
                mask &= ~(1 << clk->index);
-       sm_writel(sm, PM_CPU_MASK, mask);
-       spin_unlock_irqrestore(&sm->lock, flags);
+       pm_writel(CPU_MASK, mask);
+       spin_unlock_irqrestore(&pm_lock, flags);
 }
 
 static unsigned long cpu_clk_get_rate(struct clk *clk)
 {
        unsigned long cksel, shift = 0;
 
-       cksel = sm_readl(&system_manager, PM_CKSEL);
-       if (cksel & SM_BIT(CPUDIV))
-               shift = SM_BFEXT(CPUSEL, cksel) + 1;
+       cksel = pm_readl(CKSEL);
+       if (cksel & PM_BIT(CPUDIV))
+               shift = PM_BFEXT(CPUSEL, cksel) + 1;
 
        return bus_clk_get_rate(clk, shift);
 }
 
 static void hsb_clk_mode(struct clk *clk, int enabled)
 {
-       struct at32_sm *sm = &system_manager;
        unsigned long flags;
        u32 mask;
 
-       spin_lock_irqsave(&sm->lock, flags);
-       mask = sm_readl(sm, PM_HSB_MASK);
+       spin_lock_irqsave(&pm_lock, flags);
+       mask = pm_readl(HSB_MASK);
        if (enabled)
                mask |= 1 << clk->index;
        else
                mask &= ~(1 << clk->index);
-       sm_writel(sm, PM_HSB_MASK, mask);
-       spin_unlock_irqrestore(&sm->lock, flags);
+       pm_writel(HSB_MASK, mask);
+       spin_unlock_irqrestore(&pm_lock, flags);
 }
 
 static unsigned long hsb_clk_get_rate(struct clk *clk)
 {
        unsigned long cksel, shift = 0;
 
-       cksel = sm_readl(&system_manager, PM_CKSEL);
-       if (cksel & SM_BIT(HSBDIV))
-               shift = SM_BFEXT(HSBSEL, cksel) + 1;
+       cksel = pm_readl(CKSEL);
+       if (cksel & PM_BIT(HSBDIV))
+               shift = PM_BFEXT(HSBSEL, cksel) + 1;
 
        return bus_clk_get_rate(clk, shift);
 }
 
 static void pba_clk_mode(struct clk *clk, int enabled)
 {
-       struct at32_sm *sm = &system_manager;
        unsigned long flags;
        u32 mask;
 
-       spin_lock_irqsave(&sm->lock, flags);
-       mask = sm_readl(sm, PM_PBA_MASK);
+       spin_lock_irqsave(&pm_lock, flags);
+       mask = pm_readl(PBA_MASK);
        if (enabled)
                mask |= 1 << clk->index;
        else
                mask &= ~(1 << clk->index);
-       sm_writel(sm, PM_PBA_MASK, mask);
-       spin_unlock_irqrestore(&sm->lock, flags);
+       pm_writel(PBA_MASK, mask);
+       spin_unlock_irqrestore(&pm_lock, flags);
 }
 
 static unsigned long pba_clk_get_rate(struct clk *clk)
 {
        unsigned long cksel, shift = 0;
 
-       cksel = sm_readl(&system_manager, PM_CKSEL);
-       if (cksel & SM_BIT(PBADIV))
-               shift = SM_BFEXT(PBASEL, cksel) + 1;
+       cksel = pm_readl(CKSEL);
+       if (cksel & PM_BIT(PBADIV))
+               shift = PM_BFEXT(PBASEL, cksel) + 1;
 
        return bus_clk_get_rate(clk, shift);
 }
 
 static void pbb_clk_mode(struct clk *clk, int enabled)
 {
-       struct at32_sm *sm = &system_manager;
        unsigned long flags;
        u32 mask;
 
-       spin_lock_irqsave(&sm->lock, flags);
-       mask = sm_readl(sm, PM_PBB_MASK);
+       spin_lock_irqsave(&pm_lock, flags);
+       mask = pm_readl(PBB_MASK);
        if (enabled)
                mask |= 1 << clk->index;
        else
                mask &= ~(1 << clk->index);
-       sm_writel(sm, PM_PBB_MASK, mask);
-       spin_unlock_irqrestore(&sm->lock, flags);
+       pm_writel(PBB_MASK, mask);
+       spin_unlock_irqrestore(&pm_lock, flags);
 }
 
 static unsigned long pbb_clk_get_rate(struct clk *clk)
 {
        unsigned long cksel, shift = 0;
 
-       cksel = sm_readl(&system_manager, PM_CKSEL);
-       if (cksel & SM_BIT(PBBDIV))
-               shift = SM_BFEXT(PBBSEL, cksel) + 1;
+       cksel = pm_readl(CKSEL);
+       if (cksel & PM_BIT(PBBDIV))
+               shift = PM_BFEXT(PBBSEL, cksel) + 1;
 
        return bus_clk_get_rate(clk, shift);
 }
@@ -327,12 +331,12 @@ static void genclk_mode(struct clk *clk, int enabled)
 {
        u32 control;
 
-       control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
+       control = pm_readl(GCCTRL(clk->index));
        if (enabled)
-               control |= SM_BIT(CEN);
+               control |= PM_BIT(CEN);
        else
-               control &= ~SM_BIT(CEN);
-       sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
+               control &= ~PM_BIT(CEN);
+       pm_writel(GCCTRL(clk->index), control);
 }
 
 static unsigned long genclk_get_rate(struct clk *clk)
@@ -340,9 +344,9 @@ static unsigned long genclk_get_rate(struct clk *clk)
        u32 control;
        unsigned long div = 1;
 
-       control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
-       if (control & SM_BIT(DIVEN))
-               div = 2 * (SM_BFEXT(DIV, control) + 1);
+       control = pm_readl(GCCTRL(clk->index));
+       if (control & PM_BIT(DIVEN))
+               div = 2 * (PM_BFEXT(DIV, control) + 1);
 
        return clk->parent->get_rate(clk->parent) / div;
 }
@@ -353,23 +357,22 @@ static long genclk_set_rate(struct clk *clk, unsigned 
long rate, int apply)
        unsigned long parent_rate, actual_rate, div;
 
        parent_rate = clk->parent->get_rate(clk->parent);
-       control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
+       control = pm_readl(GCCTRL(clk->index));
 
        if (rate > 3 * parent_rate / 4) {
                actual_rate = parent_rate;
-               control &= ~SM_BIT(DIVEN);
+               control &= ~PM_BIT(DIVEN);
        } else {
                div = (parent_rate + rate) / (2 * rate) - 1;
-               control = SM_BFINS(DIV, div, control) | SM_BIT(DIVEN);
+               control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN);
                actual_rate = parent_rate / (2 * (div + 1));
        }
 
-       printk("clk %s: new rate %lu (actual rate %lu)\n",
-              clk->name, rate, actual_rate);
+       dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n",
+               clk->name, rate, actual_rate);
 
        if (apply)
-               sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index,
-                         control);
+               pm_writel(GCCTRL(clk->index), control);
 
        return actual_rate;
 }
@@ -378,24 +381,24 @@ int genclk_set_parent(struct clk *clk, struct clk *parent)
 {
        u32 control;
 
-       printk("clk %s: new parent %s (was %s)\n",
-              clk->name, parent->name, clk->parent->name);
+       dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n",
+               clk->name, parent->name, clk->parent->name);
 
-       control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
+       control = pm_readl(GCCTRL(clk->index));
 
        if (parent == &osc1 || parent == &pll1)
-               control |= SM_BIT(OSCSEL);
+               control |= PM_BIT(OSCSEL);
        else if (parent == &osc0 || parent == &pll0)
-               control &= ~SM_BIT(OSCSEL);
+               control &= ~PM_BIT(OSCSEL);
        else
                return -EINVAL;
 
        if (parent == &pll0 || parent == &pll1)
-               control |= SM_BIT(PLLSEL);
+               control |= PM_BIT(PLLSEL);
        else
-               control &= ~SM_BIT(PLLSEL);
+               control &= ~PM_BIT(PLLSEL);
 
-       sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
+       pm_writel(GCCTRL(clk->index), control);
        clk->parent = parent;
 
        return 0;
@@ -408,11 +411,11 @@ static void __init genclk_init_parent(struct clk *clk)
 
        BUG_ON(clk->index > 7);
 
-       control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
-       if (control & SM_BIT(OSCSEL))
-               parent = (control & SM_BIT(PLLSEL)) ? &pll1 : &osc1;
+       control = pm_readl(GCCTRL(clk->index));
+       if (control & PM_BIT(OSCSEL))
+               parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1;
        else
-               parent = (control & SM_BIT(PLLSEL)) ? &pll0 : &osc0;
+               parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0;
 
        clk->parent = parent;
 }
@@ -420,21 +423,53 @@ static void __init genclk_init_parent(struct clk *clk)
 /* --------------------------------------------------------------------
  *  System peripherals
  * -------------------------------------------------------------------- */
-static struct resource sm_resource[] = {
-       PBMEM(0xfff00000),
-       NAMED_IRQ(19, "eim"),
-       NAMED_IRQ(20, "pm"),
-       NAMED_IRQ(21, "rtc"),
+static struct resource at32_pm0_resource[] = {
+       {
+               .start  = 0xfff00000,
+               .end    = 0xfff0007f,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(20),
 };
-struct platform_device at32_sm_device = {
-       .name           = "sm",
-       .id             = 0,
-       .resource       = sm_resource,
-       .num_resources  = ARRAY_SIZE(sm_resource),
+
+static struct resource at32ap700x_rtc0_resource[] = {
+       {
+               .start  = 0xfff00080,
+               .end    = 0xfff000af,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(21),
 };
-static struct clk at32_sm_pclk = {
+
+static struct resource at32_wdt0_resource[] = {
+       {
+               .start  = 0xfff000b0,
+               .end    = 0xfff000bf,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct resource at32_eic0_resource[] = {
+       {
+               .start  = 0xfff00100,
+               .end    = 0xfff0013f,
+               .flags  = IORESOURCE_MEM,
+       },
+       IRQ(19),
+};
+
+DEFINE_DEV(at32_pm, 0);
+DEFINE_DEV(at32ap700x_rtc, 0);
+DEFINE_DEV(at32_wdt, 0);
+DEFINE_DEV(at32_eic, 0);
+
+/*
+ * Peripheral clock for PM, RTC, WDT and EIC. PM will ensure that this
+ * is always running.
+ */
+static struct clk at32_pm_pclk = {
        .name           = "pclk",
-       .dev            = &at32_sm_device.dev,
+       .dev            = &at32_pm0_device.dev,
        .parent         = &pbb_clk,
        .mode           = pbb_clk_mode,
        .get_rate       = pbb_clk_get_rate,
@@ -583,10 +618,11 @@ DEV_CLK(mck, pio4, pba, 14);
 
 void __init at32_add_system_devices(void)
 {
-       system_manager.eim_first_irq = EIM_IRQ_BASE;
-
-       platform_device_register(&at32_sm_device);
+       platform_device_register(&at32_pm0_device);
        platform_device_register(&at32_intc0_device);
+       platform_device_register(&at32ap700x_rtc0_device);
+       platform_device_register(&at32_wdt0_device);
+       platform_device_register(&at32_eic0_device);
        platform_device_register(&smc0_device);
        platform_device_register(&pdc_device);
 
@@ -1066,7 +1102,7 @@ struct clk *at32_clock_list[] = {
        &hsb_clk,
        &pba_clk,
        &pbb_clk,
-       &at32_sm_pclk,
+       &at32_pm_pclk,
        &at32_intc0_pclk,
        &hmatrix_clk,
        &ebi_clk,
@@ -1113,18 +1149,17 @@ void __init at32_portmux_init(void)
 
 void __init at32_clock_init(void)
 {
-       struct at32_sm *sm = &system_manager;
        u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;
        int i;
 
-       if (sm_readl(sm, PM_MCCTRL) & SM_BIT(PLLSEL))
+       if (pm_readl(MCCTRL) & PM_BIT(PLLSEL))
                main_clock = &pll0;
        else
                main_clock = &osc0;
 
-       if (sm_readl(sm, PM_PLL0) & SM_BIT(PLLOSC))
+       if (pm_readl(PLL0) & PM_BIT(PLLOSC))
                pll0.parent = &osc1;
-       if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
+       if (pm_readl(PLL1) & PM_BIT(PLLOSC))
                pll1.parent = &osc1;
 
        genclk_init_parent(&gclk0);
@@ -1157,8 +1192,8 @@ void __init at32_clock_init(void)
                        pbb_mask |= 1 << clk->index;
        }
 
-       sm_writel(sm, PM_CPU_MASK, cpu_mask);
-       sm_writel(sm, PM_HSB_MASK, hsb_mask);
-       sm_writel(sm, PM_PBA_MASK, pba_mask);
-       sm_writel(sm, PM_PBB_MASK, pbb_mask);
+       pm_writel(CPU_MASK, cpu_mask);
+       pm_writel(HSB_MASK, hsb_mask);
+       pm_writel(PBA_MASK, pba_mask);
+       pm_writel(PBB_MASK, pbb_mask);
 }
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 4a60ecc..8acd010 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -17,42 +17,83 @@
 
 #include <asm/io.h>
 
-#include <asm/arch/sm.h>
-
-#include "sm.h"
+/* EIC register offsets */
+#define EIC_IER                                        0x0000
+#define EIC_IDR                                        0x0004
+#define EIC_IMR                                        0x0008
+#define EIC_ISR                                        0x000c
+#define EIC_ICR                                        0x0010
+#define EIC_MODE                               0x0014
+#define EIC_EDGE                               0x0018
+#define EIC_LEVEL                              0x001c
+#define EIC_TEST                               0x0020
+#define EIC_NMIC                               0x0024
+
+/* Bitfields in TEST */
+#define EIC_TESTEN_OFFSET                      31
+#define EIC_TESTEN_SIZE                                1
+
+/* Bitfields in NMIC */
+#define EIC_EN_OFFSET                          0
+#define EIC_EN_SIZE                            1
+
+/* Bit manipulation macros */
+#define EIC_BIT(name)                                  \
+       (1 << EIC_##name##_OFFSET)
+#define EIC_BF(name,value)                             \
+       (((value) & ((1 << EIC_##name##_SIZE) - 1))     \
+        << EIC_##name##_OFFSET)
+#define EIC_BFEXT(name,value)                          \
+       (((value) >> EIC_##name##_OFFSET)               \
+        & ((1 << EIC_##name##_SIZE) - 1))
+#define EIC_BFINS(name,value,old)                      \
+       (((old) & ~(((1 << EIC_##name##_SIZE) - 1)      \
+                   << EIC_##name##_OFFSET))            \
+        | EIC_BF(name,value))
+
+/* Register access macros */
+#define eic_readl(port,reg)                            \
+       __raw_readl((port)->regs + EIC_##reg)
+#define eic_writel(port,reg,value)                     \
+       __raw_writel((value), (port)->regs + EIC_##reg)
+
+struct eic {
+       void __iomem *regs;
+       struct irq_chip *chip;
+       unsigned int first_irq;
+};
 
-static void eim_ack_irq(unsigned int irq)
+static void eic_ack_irq(unsigned int irq)
 {
-       struct at32_sm *sm = get_irq_chip_data(irq);
-       sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
+       struct eic *eic = get_irq_chip_data(irq);
+       eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
 }
 
-static void eim_mask_irq(unsigned int irq)
+static void eic_mask_irq(unsigned int irq)
 {
-       struct at32_sm *sm = get_irq_chip_data(irq);
-       sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
+       struct eic *eic = get_irq_chip_data(irq);
+       eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
 }
 
-static void eim_mask_ack_irq(unsigned int irq)
+static void eic_mask_ack_irq(unsigned int irq)
 {
-       struct at32_sm *sm = get_irq_chip_data(irq);
-       sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
-       sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
+       struct eic *eic = get_irq_chip_data(irq);
+       eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
+       eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
 }
 
-static void eim_unmask_irq(unsigned int irq)
+static void eic_unmask_irq(unsigned int irq)
 {
-       struct at32_sm *sm = get_irq_chip_data(irq);
-       sm_writel(sm, EIM_IER, 1 << (irq - sm->eim_first_irq));
+       struct eic *eic = get_irq_chip_data(irq);
+       eic_writel(eic, IER, 1 << (irq - eic->first_irq));
 }
 
-static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
+static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
 {
-       struct at32_sm *sm = get_irq_chip_data(irq);
+       struct eic *eic = get_irq_chip_data(irq);
        struct irq_desc *desc;
-       unsigned int i = irq - sm->eim_first_irq;
+       unsigned int i = irq - eic->first_irq;
        u32 mode, edge, level;
-       unsigned long flags;
        int ret = 0;
 
        flow_type &= IRQ_TYPE_SENSE_MASK;
@@ -60,11 +101,10 @@ static int eim_set_irq_type(unsigned int irq, unsigned int 
flow_type)
                flow_type = IRQ_TYPE_LEVEL_LOW;
 
        desc = &irq_desc[irq];
-       spin_lock_irqsave(&sm->lock, flags);
 
-       mode = sm_readl(sm, EIM_MODE);
-       edge = sm_readl(sm, EIM_EDGE);
-       level = sm_readl(sm, EIM_LEVEL);
+       mode = eic_readl(eic, MODE);
+       edge = eic_readl(eic, EDGE);
+       level = eic_readl(eic, LEVEL);
 
        switch (flow_type) {
        case IRQ_TYPE_LEVEL_LOW:
@@ -89,9 +129,9 @@ static int eim_set_irq_type(unsigned int irq, unsigned int 
flow_type)
        }
 
        if (ret == 0) {
-               sm_writel(sm, EIM_MODE, mode);
-               sm_writel(sm, EIM_EDGE, edge);
-               sm_writel(sm, EIM_LEVEL, level);
+               eic_writel(eic, MODE, mode);
+               eic_writel(eic, EDGE, edge);
+               eic_writel(eic, LEVEL, level);
 
                if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
                        flow_type |= IRQ_LEVEL;
@@ -99,35 +139,33 @@ static int eim_set_irq_type(unsigned int irq, unsigned int 
flow_type)
                desc->status |= flow_type;
        }
 
-       spin_unlock_irqrestore(&sm->lock, flags);
-
        return ret;
 }
 
-struct irq_chip eim_chip = {
-       .name           = "eim",
-       .ack            = eim_ack_irq,
-       .mask           = eim_mask_irq,
-       .mask_ack       = eim_mask_ack_irq,
-       .unmask         = eim_unmask_irq,
-       .set_type       = eim_set_irq_type,
+struct irq_chip eic_chip = {
+       .name           = "eic",
+       .ack            = eic_ack_irq,
+       .mask           = eic_mask_irq,
+       .mask_ack       = eic_mask_ack_irq,
+       .unmask         = eic_unmask_irq,
+       .set_type       = eic_set_irq_type,
 };
 
-static void demux_eim_irq(unsigned int irq, struct irq_desc *desc)
+static void demux_eic_irq(unsigned int irq, struct irq_desc *desc)
 {
-       struct at32_sm *sm = desc->handler_data;
+       struct eic *eic = desc->handler_data;
        struct irq_desc *ext_desc;
        unsigned long status, pending;
        unsigned int i, ext_irq;
 
-       status = sm_readl(sm, EIM_ISR);
-       pending = status & sm_readl(sm, EIM_IMR);
+       status = eic_readl(eic, ISR);
+       pending = status & eic_readl(eic, IMR);
 
        while (pending) {
                i = fls(pending) - 1;
                pending &= ~(1 << i);
 
-               ext_irq = i + sm->eim_first_irq;
+               ext_irq = i + eic->first_irq;
                ext_desc = irq_desc + ext_irq;
                if (ext_desc->status & IRQ_LEVEL)
                        handle_level_irq(ext_irq, ext_desc);
@@ -136,51 +174,85 @@ static void demux_eim_irq(unsigned int irq, struct 
irq_desc *desc)
        }
 }
 
-static int __init eim_init(void)
+static int __init eic_probe(struct platform_device *pdev)
 {
-       struct at32_sm *sm = &system_manager;
+       struct eic *eic;
+       struct resource *regs;
        unsigned int i;
        unsigned int nr_irqs;
        unsigned int int_irq;
+       int ret;
        u32 pattern;
 
-       /*
-        * The EIM is really the same module as SM, so register
-        * mapping, etc. has been taken care of already.
-        */
+       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       int_irq = platform_get_irq(pdev, 0);
+       if (!regs || !int_irq) {
+               dev_dbg(&pdev->dev, "missing regs and/or irq resource\n");
+               return -ENXIO;
+       }
+
+       ret = -ENOMEM;
+       eic = kzalloc(sizeof(struct eic), GFP_KERNEL);
+       if (!eic) {
+               dev_dbg(&pdev->dev, "no memory for eic structure\n");
+               goto err_kzalloc;
+       }
+
+       eic->first_irq = EIM_IRQ_BASE + 32 * pdev->id;
+       eic->regs = ioremap(regs->start, regs->end - regs->start + 1);
+       if (!eic->regs) {
+               dev_dbg(&pdev->dev, "failed to map regs\n");
+               goto err_ioremap;
+       }
 
        /*
         * Find out how many interrupt lines that are actually
         * implemented in hardware.
         */
-       sm_writel(sm, EIM_IDR, ~0UL);
-       sm_writel(sm, EIM_MODE, ~0UL);
-       pattern = sm_readl(sm, EIM_MODE);
+       eic_writel(eic, IDR, ~0UL);
+       eic_writel(eic, MODE, ~0UL);
+       pattern = eic_readl(eic, MODE);
        nr_irqs = fls(pattern);
 
        /* Trigger on falling edge unless overridden by driver */
-       sm_writel(sm, EIM_MODE, 0UL);
-       sm_writel(sm, EIM_EDGE, 0UL);
+       eic_writel(eic, MODE, 0UL);
+       eic_writel(eic, EDGE, 0UL);
 
-       sm->eim_chip = &eim_chip;
+       eic->chip = &eic_chip;
 
        for (i = 0; i < nr_irqs; i++) {
                /* NOTE the handler we set here is ignored by the demux */
-               set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip,
+               set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
                                         handle_level_irq);
-               set_irq_chip_data(sm->eim_first_irq + i, sm);
+               set_irq_chip_data(eic->first_irq + i, eic);
        }
 
-       int_irq = platform_get_irq_byname(sm->pdev, "eim");
-
-       set_irq_chained_handler(int_irq, demux_eim_irq);
-       set_irq_data(int_irq, sm);
+       set_irq_chained_handler(int_irq, demux_eic_irq);
+       set_irq_data(int_irq, eic);
 
-       printk("EIM: External Interrupt Module at 0x%p, IRQ %u\n",
-              sm->regs, int_irq);
-       printk("EIM: Handling %u external IRQs, starting with IRQ %u\n",
-              nr_irqs, sm->eim_first_irq);
+       dev_info(&pdev->dev,
+                "External Interrupt Controller at 0x%p, IRQ %u\n",
+                eic->regs, int_irq);
+       dev_info(&pdev->dev,
+                "Handling %u external IRQs, starting with IRQ %u\n",
+                nr_irqs, eic->first_irq);
 
        return 0;
+
+err_ioremap:
+       kfree(eic);
+err_kzalloc:
+       return ret;
+}
+
+static struct platform_driver eic_driver = {
+       .driver = {
+               .name = "at32_eic",
+       },
+};
+
+static int __init eic_init(void)
+{
+       return platform_driver_probe(&eic_driver, eic_probe);
 }
-arch_initcall(eim_init);
+arch_initcall(eic_init);
diff --git a/arch/avr32/mach-at32ap/pm.h b/arch/avr32/mach-at32ap/pm.h
new file mode 100644
index 0000000..a1f8ace
--- /dev/null
+++ b/arch/avr32/mach-at32ap/pm.h
@@ -0,0 +1,112 @@
+/*
+ * Register definitions for the Power Manager (PM)
+ */
+#ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
+#define __ARCH_AVR32_MACH_AT32AP_PM_H__
+
+/* PM register offsets */
+#define PM_MCCTRL                              0x0000
+#define PM_CKSEL                               0x0004
+#define PM_CPU_MASK                            0x0008
+#define PM_HSB_MASK                            0x000c
+#define PM_PBA_MASK                            0x0010
+#define PM_PBB_MASK                            0x0014
+#define PM_PLL0                                        0x0020
+#define PM_PLL1                                        0x0024
+#define PM_IER                                 0x0040
+#define PM_IDR                                 0x0044
+#define PM_IMR                                 0x0048
+#define PM_ISR                                 0x004c
+#define PM_ICR                                 0x0050
+#define PM_GCCTRL(x)                           (0x0060 + 4 * (x))
+#define PM_RCAUSE                              0x00c0
+
+/* Bitfields in CKSEL */
+#define PM_CPUSEL_OFFSET                       0
+#define PM_CPUSEL_SIZE                         3
+#define PM_CPUDIV_OFFSET                       7
+#define PM_CPUDIV_SIZE                         1
+#define PM_HSBSEL_OFFSET                       8
+#define PM_HSBSEL_SIZE                         3
+#define PM_HSBDIV_OFFSET                       15
+#define PM_HSBDIV_SIZE                         1
+#define PM_PBASEL_OFFSET                       16
+#define PM_PBASEL_SIZE                         3
+#define PM_PBADIV_OFFSET                       23
+#define PM_PBADIV_SIZE                         1
+#define PM_PBBSEL_OFFSET                       24
+#define PM_PBBSEL_SIZE                         3
+#define PM_PBBDIV_OFFSET                       31
+#define PM_PBBDIV_SIZE                         1
+
+/* Bitfields in PLL0 */
+#define PM_PLLEN_OFFSET                                0
+#define PM_PLLEN_SIZE                          1
+#define PM_PLLOSC_OFFSET                       1
+#define PM_PLLOSC_SIZE                         1
+#define PM_PLLOPT_OFFSET                       2
+#define PM_PLLOPT_SIZE                         3
+#define PM_PLLDIV_OFFSET                       8
+#define PM_PLLDIV_SIZE                         8
+#define PM_PLLMUL_OFFSET                       16
+#define PM_PLLMUL_SIZE                         8
+#define PM_PLLCOUNT_OFFSET                     24
+#define PM_PLLCOUNT_SIZE                       6
+#define PM_PLLTEST_OFFSET                      31
+#define PM_PLLTEST_SIZE                                1
+
+/* Bitfields in ICR */
+#define PM_LOCK0_OFFSET                                0
+#define PM_LOCK0_SIZE                          1
+#define PM_LOCK1_OFFSET                                1
+#define PM_LOCK1_SIZE                          1
+#define PM_WAKE_OFFSET                         2
+#define PM_WAKE_SIZE                           1
+#define PM_CKRDY_OFFSET                                5
+#define PM_CKRDY_SIZE                          1
+#define PM_MSKRDY_OFFSET                       6
+#define PM_MSKRDY_SIZE                         1
+
+/* Bitfields in GCCTRL0 */
+#define PM_OSCSEL_OFFSET                       0
+#define PM_OSCSEL_SIZE                         1
+#define PM_PLLSEL_OFFSET                       1
+#define PM_PLLSEL_SIZE                         1
+#define PM_CEN_OFFSET                          2
+#define PM_CEN_SIZE                            1
+#define PM_DIVEN_OFFSET                                4
+#define PM_DIVEN_SIZE                          1
+#define PM_DIV_OFFSET                          8
+#define PM_DIV_SIZE                            8
+
+/* Bitfields in RCAUSE */
+#define PM_POR_OFFSET                          0
+#define PM_POR_SIZE                            1
+#define PM_EXT_OFFSET                          2
+#define PM_EXT_SIZE                            1
+#define PM_WDT_OFFSET                          3
+#define PM_WDT_SIZE                            1
+#define PM_NTAE_OFFSET                         4
+#define PM_NTAE_SIZE                           1
+
+/* Bit manipulation macros */
+#define PM_BIT(name)                                   \
+       (1 << PM_##name##_OFFSET)
+#define PM_BF(name,value)                              \
+       (((value) & ((1 << PM_##name##_SIZE) - 1))      \
+        << PM_##name##_OFFSET)
+#define PM_BFEXT(name,value)                           \
+       (((value) >> PM_##name##_OFFSET)                \
+        & ((1 << PM_##name##_SIZE) - 1))
+#define PM_BFINS(name,value,old)\
+       (((old) & ~(((1 << PM_##name##_SIZE) - 1)       \
+                   << PM_##name##_OFFSET))             \
+        | PM_BF(name,value))
+
+/* Register access macros */
+#define pm_readl(reg)                                                  \
+       __raw_readl((void __iomem *)AT32_PM_BASE + PM_##reg)
+#define pm_writel(reg,value)                                           \
+       __raw_writel((value), (void __iomem *)AT32_PM_BASE + PM_##reg)
+
+#endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */
diff --git a/arch/avr32/mach-at32ap/sm.h b/arch/avr32/mach-at32ap/sm.h
deleted file mode 100644
index cad02b5..0000000
--- a/arch/avr32/mach-at32ap/sm.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Register definitions for SM
- *
- * System Manager
- */
-#ifndef __ASM_AVR32_SM_H__
-#define __ASM_AVR32_SM_H__
-
-/* SM register offsets */
-#define SM_PM_MCCTRL                            0x0000
-#define SM_PM_CKSEL                             0x0004
-#define SM_PM_CPU_MASK                          0x0008
-#define SM_PM_HSB_MASK                          0x000c
-#define SM_PM_PBA_MASK                         0x0010
-#define SM_PM_PBB_MASK                         0x0014
-#define SM_PM_PLL0                              0x0020
-#define SM_PM_PLL1                              0x0024
-#define SM_PM_VCTRL                             0x0030
-#define SM_PM_VMREF                             0x0034
-#define SM_PM_VMV                               0x0038
-#define SM_PM_IER                               0x0040
-#define SM_PM_IDR                               0x0044
-#define SM_PM_IMR                               0x0048
-#define SM_PM_ISR                               0x004c
-#define SM_PM_ICR                               0x0050
-#define SM_PM_GCCTRL                            0x0060
-#define SM_RTC_CTRL                             0x0080
-#define SM_RTC_VAL                              0x0084
-#define SM_RTC_TOP                              0x0088
-#define SM_RTC_IER                              0x0090
-#define SM_RTC_IDR                              0x0094
-#define SM_RTC_IMR                              0x0098
-#define SM_RTC_ISR                              0x009c
-#define SM_RTC_ICR                              0x00a0
-#define SM_WDT_CTRL                             0x00b0
-#define SM_WDT_CLR                              0x00b4
-#define SM_WDT_EXT                              0x00b8
-#define SM_RC_RCAUSE                            0x00c0
-#define SM_EIM_IER                              0x0100
-#define SM_EIM_IDR                              0x0104
-#define SM_EIM_IMR                              0x0108
-#define SM_EIM_ISR                              0x010c
-#define SM_EIM_ICR                              0x0110
-#define SM_EIM_MODE                             0x0114
-#define SM_EIM_EDGE                             0x0118
-#define SM_EIM_LEVEL                            0x011c
-#define SM_EIM_TEST                             0x0120
-#define SM_EIM_NMIC                             0x0124
-
-/* Bitfields in PM_MCCTRL */
-
-/* Bitfields in PM_CKSEL */
-#define SM_CPUSEL_OFFSET                        0
-#define SM_CPUSEL_SIZE                          3
-#define SM_CPUDIV_OFFSET                        7
-#define SM_CPUDIV_SIZE                          1
-#define SM_HSBSEL_OFFSET                        8
-#define SM_HSBSEL_SIZE                          3
-#define SM_HSBDIV_OFFSET                        15
-#define SM_HSBDIV_SIZE                          1
-#define SM_PBASEL_OFFSET                       16
-#define SM_PBASEL_SIZE                         3
-#define SM_PBADIV_OFFSET                       23
-#define SM_PBADIV_SIZE                         1
-#define SM_PBBSEL_OFFSET                       24
-#define SM_PBBSEL_SIZE                         3
-#define SM_PBBDIV_OFFSET                       31
-#define SM_PBBDIV_SIZE                         1
-
-/* Bitfields in PM_CPU_MASK */
-
-/* Bitfields in PM_HSB_MASK */
-
-/* Bitfields in PM_PBA_MASK */
-
-/* Bitfields in PM_PBB_MASK */
-
-/* Bitfields in PM_PLL0 */
-#define SM_PLLEN_OFFSET                         0
-#define SM_PLLEN_SIZE                           1
-#define SM_PLLOSC_OFFSET                        1
-#define SM_PLLOSC_SIZE                          1
-#define SM_PLLOPT_OFFSET                        2
-#define SM_PLLOPT_SIZE                          3
-#define SM_PLLDIV_OFFSET                        8
-#define SM_PLLDIV_SIZE                          8
-#define SM_PLLMUL_OFFSET                        16
-#define SM_PLLMUL_SIZE                          8
-#define SM_PLLCOUNT_OFFSET                      24
-#define SM_PLLCOUNT_SIZE                        6
-#define SM_PLLTEST_OFFSET                       31
-#define SM_PLLTEST_SIZE                         1
-
-/* Bitfields in PM_PLL1 */
-
-/* Bitfields in PM_VCTRL */
-#define SM_VAUTO_OFFSET                         0
-#define SM_VAUTO_SIZE                           1
-#define SM_PM_VCTRL_VAL_OFFSET                  8
-#define SM_PM_VCTRL_VAL_SIZE                    7
-
-/* Bitfields in PM_VMREF */
-#define SM_REFSEL_OFFSET                        0
-#define SM_REFSEL_SIZE                          4
-
-/* Bitfields in PM_VMV */
-#define SM_PM_VMV_VAL_OFFSET                    0
-#define SM_PM_VMV_VAL_SIZE                      8
-
-/* Bitfields in PM_IER */
-
-/* Bitfields in PM_IDR */
-
-/* Bitfields in PM_IMR */
-
-/* Bitfields in PM_ISR */
-
-/* Bitfields in PM_ICR */
-#define SM_LOCK0_OFFSET                         0
-#define SM_LOCK0_SIZE                           1
-#define SM_LOCK1_OFFSET                         1
-#define SM_LOCK1_SIZE                           1
-#define SM_WAKE_OFFSET                          2
-#define SM_WAKE_SIZE                            1
-#define SM_VOK_OFFSET                           3
-#define SM_VOK_SIZE                             1
-#define SM_VMRDY_OFFSET                         4
-#define SM_VMRDY_SIZE                           1
-#define SM_CKRDY_OFFSET                         5
-#define SM_CKRDY_SIZE                           1
-
-/* Bitfields in PM_GCCTRL */
-#define SM_OSCSEL_OFFSET                        0
-#define SM_OSCSEL_SIZE                          1
-#define SM_PLLSEL_OFFSET                        1
-#define SM_PLLSEL_SIZE                          1
-#define SM_CEN_OFFSET                           2
-#define SM_CEN_SIZE                             1
-#define SM_CPC_OFFSET                           3
-#define SM_CPC_SIZE                             1
-#define SM_DIVEN_OFFSET                         4
-#define SM_DIVEN_SIZE                           1
-#define SM_DIV_OFFSET                           8
-#define SM_DIV_SIZE                             8
-
-/* Bitfields in RTC_CTRL */
-#define SM_PCLR_OFFSET                          1
-#define SM_PCLR_SIZE                            1
-#define SM_TOPEN_OFFSET                         2
-#define SM_TOPEN_SIZE                           1
-#define SM_CLKEN_OFFSET                         3
-#define SM_CLKEN_SIZE                           1
-#define SM_PSEL_OFFSET                          8
-#define SM_PSEL_SIZE                            16
-
-/* Bitfields in RTC_VAL */
-#define SM_RTC_VAL_VAL_OFFSET                   0
-#define SM_RTC_VAL_VAL_SIZE                     31
-
-/* Bitfields in RTC_TOP */
-#define SM_RTC_TOP_VAL_OFFSET                   0
-#define SM_RTC_TOP_VAL_SIZE                     32
-
-/* Bitfields in RTC_IER */
-
-/* Bitfields in RTC_IDR */
-
-/* Bitfields in RTC_IMR */
-
-/* Bitfields in RTC_ISR */
-
-/* Bitfields in RTC_ICR */
-#define SM_TOPI_OFFSET                          0
-#define SM_TOPI_SIZE                            1
-
-/* Bitfields in WDT_CTRL */
-#define SM_KEY_OFFSET                           24
-#define SM_KEY_SIZE                             8
-
-/* Bitfields in WDT_CLR */
-
-/* Bitfields in WDT_EXT */
-
-/* Bitfields in RC_RCAUSE */
-#define SM_POR_OFFSET                           0
-#define SM_POR_SIZE                             1
-#define SM_BOD_OFFSET                           1
-#define SM_BOD_SIZE                             1
-#define SM_EXT_OFFSET                           2
-#define SM_EXT_SIZE                             1
-#define SM_WDT_OFFSET                           3
-#define SM_WDT_SIZE                             1
-#define SM_NTAE_OFFSET                          4
-#define SM_NTAE_SIZE                            1
-#define SM_SERP_OFFSET                          5
-#define SM_SERP_SIZE                            1
-
-/* Bitfields in EIM_IER */
-
-/* Bitfields in EIM_IDR */
-
-/* Bitfields in EIM_IMR */
-
-/* Bitfields in EIM_ISR */
-
-/* Bitfields in EIM_ICR */
-
-/* Bitfields in EIM_MODE */
-
-/* Bitfields in EIM_EDGE */
-#define SM_INT0_OFFSET                          0
-#define SM_INT0_SIZE                            1
-#define SM_INT1_OFFSET                          1
-#define SM_INT1_SIZE                            1
-#define SM_INT2_OFFSET                          2
-#define SM_INT2_SIZE                            1
-#define SM_INT3_OFFSET                          3
-#define SM_INT3_SIZE                            1
-
-/* Bitfields in EIM_LEVEL */
-
-/* Bitfields in EIM_TEST */
-#define SM_TESTEN_OFFSET                        31
-#define SM_TESTEN_SIZE                          1
-
-/* Bitfields in EIM_NMIC */
-#define SM_EN_OFFSET                            0
-#define SM_EN_SIZE                              1
-
-/* Bit manipulation macros */
-#define SM_BIT(name)                            (1 << SM_##name##_OFFSET)
-#define SM_BF(name,value)                       (((value) & ((1 << 
SM_##name##_SIZE) - 1)) << SM_##name##_OFFSET)
-#define SM_BFEXT(name,value)                    (((value) >> 
SM_##name##_OFFSET) & ((1 << SM_##name##_SIZE) - 1))
-#define SM_BFINS(name,value,old)                (((old) & ~(((1 << 
SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value))
-
-/* Register access macros */
-#define sm_readl(port,reg)                                     \
-       __raw_readl((port)->regs + SM_##reg)
-#define sm_writel(port,reg,value)                              \
-       __raw_writel((value), (port)->regs + SM_##reg)
-
-#endif /* __ASM_AVR32_SM_H__ */
diff --git a/include/asm-avr32/arch-at32ap/sm.h 
b/include/asm-avr32/arch-at32ap/sm.h
deleted file mode 100644
index 265a9ea..0000000
--- a/include/asm-avr32/arch-at32ap/sm.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * AT32 System Manager interface.
- *
- * Copyright (C) 2006 Atmel Corporation
- *
- * 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.
- */
-#ifndef __ASM_AVR32_AT32_SM_H__
-#define __ASM_AVR32_AT32_SM_H__
-
-struct irq_chip;
-struct platform_device;
-
-struct at32_sm {
-       spinlock_t lock;
-       void __iomem *regs;
-       struct irq_chip *eim_chip;
-       unsigned int eim_first_irq;
-       struct platform_device *pdev;
-};
-
-extern struct platform_device at32_sm_device;
-extern struct at32_sm system_manager;
-
-#endif /* __ASM_AVR32_AT32_SM_H__ */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to