diff options
Diffstat (limited to 'arch/mips/alchemy/common')
-rw-r--r-- | arch/mips/alchemy/common/Makefile | 7 | ||||
-rw-r--r-- | arch/mips/alchemy/common/clocks.c | 7 | ||||
-rw-r--r-- | arch/mips/alchemy/common/dbdma.c | 187 | ||||
-rw-r--r-- | arch/mips/alchemy/common/dma.c | 36 | ||||
-rw-r--r-- | arch/mips/alchemy/common/gpiolib-au1000.c | 10 | ||||
-rw-r--r-- | arch/mips/alchemy/common/irq.c | 436 | ||||
-rw-r--r-- | arch/mips/alchemy/common/platform.c | 153 | ||||
-rw-r--r-- | arch/mips/alchemy/common/prom.c | 28 | ||||
-rw-r--r-- | arch/mips/alchemy/common/puts.c | 68 | ||||
-rw-r--r-- | arch/mips/alchemy/common/reset.c | 188 | ||||
-rw-r--r-- | arch/mips/alchemy/common/setup.c | 40 | ||||
-rw-r--r-- | arch/mips/alchemy/common/time.c | 35 |
12 files changed, 521 insertions, 674 deletions
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index b67fb512529d..06c0e65a54b5 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -5,14 +5,15 @@ | |||
5 | # Makefile for the Alchemy Au1xx0 CPUs, generic files. | 5 | # Makefile for the Alchemy Au1xx0 CPUs, generic files. |
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y += prom.o irq.o puts.o time.o reset.o \ | 8 | obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ |
9 | clocks.o platform.o power.o setup.o \ | ||
10 | sleeper.o dma.o dbdma.o | 9 | sleeper.o dma.o dbdma.o |
11 | 10 | ||
11 | obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o | ||
12 | |||
12 | # optional gpiolib support | 13 | # optional gpiolib support |
13 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) | 14 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) |
14 | ifeq ($(CONFIG_GPIOLIB),y) | 15 | ifeq ($(CONFIG_GPIOLIB),y) |
15 | obj-$(CONFIG_ALCHEMY_GPIO_AU1000) += gpiolib-au1000.o | 16 | obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o |
16 | endif | 17 | endif |
17 | endif | 18 | endif |
18 | 19 | ||
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c index d8991854530e..460c6285c1bb 100644 --- a/arch/mips/alchemy/common/clocks.c +++ b/arch/mips/alchemy/common/clocks.c | |||
@@ -40,8 +40,6 @@ | |||
40 | static unsigned int au1x00_clock; /* Hz */ | 40 | static unsigned int au1x00_clock; /* Hz */ |
41 | static unsigned long uart_baud_base; | 41 | static unsigned long uart_baud_base; |
42 | 42 | ||
43 | static DEFINE_SPINLOCK(time_lock); | ||
44 | |||
45 | /* | 43 | /* |
46 | * Set the au1000_clock | 44 | * Set the au1000_clock |
47 | */ | 45 | */ |
@@ -84,9 +82,6 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base) | |||
84 | unsigned long au1xxx_calc_clock(void) | 82 | unsigned long au1xxx_calc_clock(void) |
85 | { | 83 | { |
86 | unsigned long cpu_speed; | 84 | unsigned long cpu_speed; |
87 | unsigned long flags; | ||
88 | |||
89 | spin_lock_irqsave(&time_lock, flags); | ||
90 | 85 | ||
91 | /* | 86 | /* |
92 | * On early Au1000, sys_cpupll was write-only. Since these | 87 | * On early Au1000, sys_cpupll was write-only. Since these |
@@ -108,8 +103,6 @@ unsigned long au1xxx_calc_clock(void) | |||
108 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) | 103 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) |
109 | & 0x03) + 2) * 16)); | 104 | & 0x03) + 2) * 16)); |
110 | 105 | ||
111 | spin_unlock_irqrestore(&time_lock, flags); | ||
112 | |||
113 | set_au1x00_speed(cpu_speed); | 106 | set_au1x00_speed(cpu_speed); |
114 | 107 | ||
115 | return cpu_speed; | 108 | return cpu_speed; |
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index f9201ca2295b..99ae84ce5af3 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/init.h> | ||
33 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
@@ -58,7 +59,6 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock); | |||
58 | 59 | ||
59 | static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; | 60 | static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; |
60 | static int dbdma_initialized; | 61 | static int dbdma_initialized; |
61 | static void au1xxx_dbdma_init(void); | ||
62 | 62 | ||
63 | static dbdev_tab_t dbdev_tab[] = { | 63 | static dbdev_tab_t dbdev_tab[] = { |
64 | #ifdef CONFIG_SOC_AU1550 | 64 | #ifdef CONFIG_SOC_AU1550 |
@@ -237,7 +237,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
237 | void (*callback)(int, void *), void *callparam) | 237 | void (*callback)(int, void *), void *callparam) |
238 | { | 238 | { |
239 | unsigned long flags; | 239 | unsigned long flags; |
240 | u32 used, chan, rv; | 240 | u32 used, chan; |
241 | u32 dcp; | 241 | u32 dcp; |
242 | int i; | 242 | int i; |
243 | dbdev_tab_t *stp, *dtp; | 243 | dbdev_tab_t *stp, *dtp; |
@@ -250,8 +250,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
250 | * which can't be done successfully during board set up. | 250 | * which can't be done successfully during board set up. |
251 | */ | 251 | */ |
252 | if (!dbdma_initialized) | 252 | if (!dbdma_initialized) |
253 | au1xxx_dbdma_init(); | 253 | return 0; |
254 | dbdma_initialized = 1; | ||
255 | 254 | ||
256 | stp = find_dbdev_id(srcid); | 255 | stp = find_dbdev_id(srcid); |
257 | if (stp == NULL) | 256 | if (stp == NULL) |
@@ -261,7 +260,6 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
261 | return 0; | 260 | return 0; |
262 | 261 | ||
263 | used = 0; | 262 | used = 0; |
264 | rv = 0; | ||
265 | 263 | ||
266 | /* Check to see if we can get both channels. */ | 264 | /* Check to see if we can get both channels. */ |
267 | spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); | 265 | spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); |
@@ -282,63 +280,65 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
282 | used++; | 280 | used++; |
283 | spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags); | 281 | spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags); |
284 | 282 | ||
285 | if (!used) { | 283 | if (used) |
286 | /* Let's see if we can allocate a channel for it. */ | 284 | return 0; |
287 | ctp = NULL; | ||
288 | chan = 0; | ||
289 | spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); | ||
290 | for (i = 0; i < NUM_DBDMA_CHANS; i++) | ||
291 | if (chan_tab_ptr[i] == NULL) { | ||
292 | /* | ||
293 | * If kmalloc fails, it is caught below same | ||
294 | * as a channel not available. | ||
295 | */ | ||
296 | ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC); | ||
297 | chan_tab_ptr[i] = ctp; | ||
298 | break; | ||
299 | } | ||
300 | spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags); | ||
301 | |||
302 | if (ctp != NULL) { | ||
303 | memset(ctp, 0, sizeof(chan_tab_t)); | ||
304 | ctp->chan_index = chan = i; | ||
305 | dcp = DDMA_CHANNEL_BASE; | ||
306 | dcp += (0x0100 * chan); | ||
307 | ctp->chan_ptr = (au1x_dma_chan_t *)dcp; | ||
308 | cp = (au1x_dma_chan_t *)dcp; | ||
309 | ctp->chan_src = stp; | ||
310 | ctp->chan_dest = dtp; | ||
311 | ctp->chan_callback = callback; | ||
312 | ctp->chan_callparam = callparam; | ||
313 | |||
314 | /* Initialize channel configuration. */ | ||
315 | i = 0; | ||
316 | if (stp->dev_intlevel) | ||
317 | i |= DDMA_CFG_SED; | ||
318 | if (stp->dev_intpolarity) | ||
319 | i |= DDMA_CFG_SP; | ||
320 | if (dtp->dev_intlevel) | ||
321 | i |= DDMA_CFG_DED; | ||
322 | if (dtp->dev_intpolarity) | ||
323 | i |= DDMA_CFG_DP; | ||
324 | if ((stp->dev_flags & DEV_FLAGS_SYNC) || | ||
325 | (dtp->dev_flags & DEV_FLAGS_SYNC)) | ||
326 | i |= DDMA_CFG_SYNC; | ||
327 | cp->ddma_cfg = i; | ||
328 | au_sync(); | ||
329 | 285 | ||
330 | /* Return a non-zero value that can be used to | 286 | /* Let's see if we can allocate a channel for it. */ |
331 | * find the channel information in subsequent | 287 | ctp = NULL; |
332 | * operations. | 288 | chan = 0; |
289 | spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags); | ||
290 | for (i = 0; i < NUM_DBDMA_CHANS; i++) | ||
291 | if (chan_tab_ptr[i] == NULL) { | ||
292 | /* | ||
293 | * If kmalloc fails, it is caught below same | ||
294 | * as a channel not available. | ||
333 | */ | 295 | */ |
334 | rv = (u32)(&chan_tab_ptr[chan]); | 296 | ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC); |
335 | } else { | 297 | chan_tab_ptr[i] = ctp; |
336 | /* Release devices */ | 298 | break; |
337 | stp->dev_flags &= ~DEV_FLAGS_INUSE; | ||
338 | dtp->dev_flags &= ~DEV_FLAGS_INUSE; | ||
339 | } | 299 | } |
300 | spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags); | ||
301 | |||
302 | if (ctp != NULL) { | ||
303 | memset(ctp, 0, sizeof(chan_tab_t)); | ||
304 | ctp->chan_index = chan = i; | ||
305 | dcp = DDMA_CHANNEL_BASE; | ||
306 | dcp += (0x0100 * chan); | ||
307 | ctp->chan_ptr = (au1x_dma_chan_t *)dcp; | ||
308 | cp = (au1x_dma_chan_t *)dcp; | ||
309 | ctp->chan_src = stp; | ||
310 | ctp->chan_dest = dtp; | ||
311 | ctp->chan_callback = callback; | ||
312 | ctp->chan_callparam = callparam; | ||
313 | |||
314 | /* Initialize channel configuration. */ | ||
315 | i = 0; | ||
316 | if (stp->dev_intlevel) | ||
317 | i |= DDMA_CFG_SED; | ||
318 | if (stp->dev_intpolarity) | ||
319 | i |= DDMA_CFG_SP; | ||
320 | if (dtp->dev_intlevel) | ||
321 | i |= DDMA_CFG_DED; | ||
322 | if (dtp->dev_intpolarity) | ||
323 | i |= DDMA_CFG_DP; | ||
324 | if ((stp->dev_flags & DEV_FLAGS_SYNC) || | ||
325 | (dtp->dev_flags & DEV_FLAGS_SYNC)) | ||
326 | i |= DDMA_CFG_SYNC; | ||
327 | cp->ddma_cfg = i; | ||
328 | au_sync(); | ||
329 | |||
330 | /* | ||
331 | * Return a non-zero value that can be used to find the channel | ||
332 | * information in subsequent operations. | ||
333 | */ | ||
334 | return (u32)(&chan_tab_ptr[chan]); | ||
340 | } | 335 | } |
341 | return rv; | 336 | |
337 | /* Release devices */ | ||
338 | stp->dev_flags &= ~DEV_FLAGS_INUSE; | ||
339 | dtp->dev_flags &= ~DEV_FLAGS_INUSE; | ||
340 | |||
341 | return 0; | ||
342 | } | 342 | } |
343 | EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); | 343 | EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); |
344 | 344 | ||
@@ -572,7 +572,7 @@ EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); | |||
572 | * This updates the source pointer and byte count. Normally used | 572 | * This updates the source pointer and byte count. Normally used |
573 | * for memory to fifo transfers. | 573 | * for memory to fifo transfers. |
574 | */ | 574 | */ |
575 | u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) | 575 | u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) |
576 | { | 576 | { |
577 | chan_tab_t *ctp; | 577 | chan_tab_t *ctp; |
578 | au1x_ddma_desc_t *dp; | 578 | au1x_ddma_desc_t *dp; |
@@ -598,7 +598,7 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) | |||
598 | return 0; | 598 | return 0; |
599 | 599 | ||
600 | /* Load up buffer address and byte count. */ | 600 | /* Load up buffer address and byte count. */ |
601 | dp->dscr_source0 = virt_to_phys(buf); | 601 | dp->dscr_source0 = buf & ~0UL; |
602 | dp->dscr_cmd1 = nbytes; | 602 | dp->dscr_cmd1 = nbytes; |
603 | /* Check flags */ | 603 | /* Check flags */ |
604 | if (flags & DDMA_FLAGS_IE) | 604 | if (flags & DDMA_FLAGS_IE) |
@@ -625,14 +625,13 @@ u32 _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) | |||
625 | /* Return something non-zero. */ | 625 | /* Return something non-zero. */ |
626 | return nbytes; | 626 | return nbytes; |
627 | } | 627 | } |
628 | EXPORT_SYMBOL(_au1xxx_dbdma_put_source); | 628 | EXPORT_SYMBOL(au1xxx_dbdma_put_source); |
629 | 629 | ||
630 | /* Put a destination buffer into the DMA ring. | 630 | /* Put a destination buffer into the DMA ring. |
631 | * This updates the destination pointer and byte count. Normally used | 631 | * This updates the destination pointer and byte count. Normally used |
632 | * to place an empty buffer into the ring for fifo to memory transfers. | 632 | * to place an empty buffer into the ring for fifo to memory transfers. |
633 | */ | 633 | */ |
634 | u32 | 634 | u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) |
635 | _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) | ||
636 | { | 635 | { |
637 | chan_tab_t *ctp; | 636 | chan_tab_t *ctp; |
638 | au1x_ddma_desc_t *dp; | 637 | au1x_ddma_desc_t *dp; |
@@ -662,7 +661,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) | |||
662 | if (flags & DDMA_FLAGS_NOIE) | 661 | if (flags & DDMA_FLAGS_NOIE) |
663 | dp->dscr_cmd0 &= ~DSCR_CMD0_IE; | 662 | dp->dscr_cmd0 &= ~DSCR_CMD0_IE; |
664 | 663 | ||
665 | dp->dscr_dest0 = virt_to_phys(buf); | 664 | dp->dscr_dest0 = buf & ~0UL; |
666 | dp->dscr_cmd1 = nbytes; | 665 | dp->dscr_cmd1 = nbytes; |
667 | #if 0 | 666 | #if 0 |
668 | printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", | 667 | printk(KERN_DEBUG "cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", |
@@ -688,7 +687,7 @@ _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) | |||
688 | /* Return something non-zero. */ | 687 | /* Return something non-zero. */ |
689 | return nbytes; | 688 | return nbytes; |
690 | } | 689 | } |
691 | EXPORT_SYMBOL(_au1xxx_dbdma_put_dest); | 690 | EXPORT_SYMBOL(au1xxx_dbdma_put_dest); |
692 | 691 | ||
693 | /* | 692 | /* |
694 | * Get a destination buffer into the DMA ring. | 693 | * Get a destination buffer into the DMA ring. |
@@ -871,28 +870,6 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) | |||
871 | return IRQ_RETVAL(1); | 870 | return IRQ_RETVAL(1); |
872 | } | 871 | } |
873 | 872 | ||
874 | static void au1xxx_dbdma_init(void) | ||
875 | { | ||
876 | int irq_nr; | ||
877 | |||
878 | dbdma_gptr->ddma_config = 0; | ||
879 | dbdma_gptr->ddma_throttle = 0; | ||
880 | dbdma_gptr->ddma_inten = 0xffff; | ||
881 | au_sync(); | ||
882 | |||
883 | #if defined(CONFIG_SOC_AU1550) | ||
884 | irq_nr = AU1550_DDMA_INT; | ||
885 | #elif defined(CONFIG_SOC_AU1200) | ||
886 | irq_nr = AU1200_DDMA_INT; | ||
887 | #else | ||
888 | #error Unknown Au1x00 SOC | ||
889 | #endif | ||
890 | |||
891 | if (request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED, | ||
892 | "Au1xxx dbdma", (void *)dbdma_gptr)) | ||
893 | printk(KERN_ERR "Can't get 1550 dbdma irq"); | ||
894 | } | ||
895 | |||
896 | void au1xxx_dbdma_dump(u32 chanid) | 873 | void au1xxx_dbdma_dump(u32 chanid) |
897 | { | 874 | { |
898 | chan_tab_t *ctp; | 875 | chan_tab_t *ctp; |
@@ -906,7 +883,7 @@ void au1xxx_dbdma_dump(u32 chanid) | |||
906 | dtp = ctp->chan_dest; | 883 | dtp = ctp->chan_dest; |
907 | cp = ctp->chan_ptr; | 884 | cp = ctp->chan_ptr; |
908 | 885 | ||
909 | printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d) \n", | 886 | printk(KERN_DEBUG "Chan %x, stp %x (dev %d) dtp %x (dev %d)\n", |
910 | (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, | 887 | (u32)ctp, (u32)stp, stp - dbdev_tab, (u32)dtp, |
911 | dtp - dbdev_tab); | 888 | dtp - dbdev_tab); |
912 | printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n", | 889 | printk(KERN_DEBUG "desc base %x, get %x, put %x, cur %x\n", |
@@ -1041,4 +1018,38 @@ void au1xxx_dbdma_resume(void) | |||
1041 | } | 1018 | } |
1042 | } | 1019 | } |
1043 | #endif /* CONFIG_PM */ | 1020 | #endif /* CONFIG_PM */ |
1021 | |||
1022 | static int __init au1xxx_dbdma_init(void) | ||
1023 | { | ||
1024 | int irq_nr, ret; | ||
1025 | |||
1026 | dbdma_gptr->ddma_config = 0; | ||
1027 | dbdma_gptr->ddma_throttle = 0; | ||
1028 | dbdma_gptr->ddma_inten = 0xffff; | ||
1029 | au_sync(); | ||
1030 | |||
1031 | switch (alchemy_get_cputype()) { | ||
1032 | case ALCHEMY_CPU_AU1550: | ||
1033 | irq_nr = AU1550_DDMA_INT; | ||
1034 | break; | ||
1035 | case ALCHEMY_CPU_AU1200: | ||
1036 | irq_nr = AU1200_DDMA_INT; | ||
1037 | break; | ||
1038 | default: | ||
1039 | return -ENODEV; | ||
1040 | } | ||
1041 | |||
1042 | ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED, | ||
1043 | "Au1xxx dbdma", (void *)dbdma_gptr); | ||
1044 | if (ret) | ||
1045 | printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); | ||
1046 | else { | ||
1047 | dbdma_initialized = 1; | ||
1048 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); | ||
1049 | } | ||
1050 | |||
1051 | return ret; | ||
1052 | } | ||
1053 | subsys_initcall(au1xxx_dbdma_init); | ||
1054 | |||
1044 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ | 1055 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ |
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index d6fbda232e6a..d5278877891d 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c | |||
@@ -29,6 +29,8 @@ | |||
29 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 29 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | |||
33 | #include <linux/init.h> | ||
32 | #include <linux/module.h> | 34 | #include <linux/module.h> |
33 | #include <linux/kernel.h> | 35 | #include <linux/kernel.h> |
34 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
@@ -188,17 +190,14 @@ int request_au1000_dma(int dev_id, const char *dev_str, | |||
188 | dev = &dma_dev_table[dev_id]; | 190 | dev = &dma_dev_table[dev_id]; |
189 | 191 | ||
190 | if (irqhandler) { | 192 | if (irqhandler) { |
191 | chan->irq = AU1000_DMA_INT_BASE + i; | ||
192 | chan->irq_dev = irq_dev_id; | 193 | chan->irq_dev = irq_dev_id; |
193 | ret = request_irq(chan->irq, irqhandler, irqflags, dev_str, | 194 | ret = request_irq(chan->irq, irqhandler, irqflags, dev_str, |
194 | chan->irq_dev); | 195 | chan->irq_dev); |
195 | if (ret) { | 196 | if (ret) { |
196 | chan->irq = 0; | ||
197 | chan->irq_dev = NULL; | 197 | chan->irq_dev = NULL; |
198 | return ret; | 198 | return ret; |
199 | } | 199 | } |
200 | } else { | 200 | } else { |
201 | chan->irq = 0; | ||
202 | chan->irq_dev = NULL; | 201 | chan->irq_dev = NULL; |
203 | } | 202 | } |
204 | 203 | ||
@@ -226,13 +225,40 @@ void free_au1000_dma(unsigned int dmanr) | |||
226 | } | 225 | } |
227 | 226 | ||
228 | disable_dma(dmanr); | 227 | disable_dma(dmanr); |
229 | if (chan->irq) | 228 | if (chan->irq_dev) |
230 | free_irq(chan->irq, chan->irq_dev); | 229 | free_irq(chan->irq, chan->irq_dev); |
231 | 230 | ||
232 | chan->irq = 0; | ||
233 | chan->irq_dev = NULL; | 231 | chan->irq_dev = NULL; |
234 | chan->dev_id = -1; | 232 | chan->dev_id = -1; |
235 | } | 233 | } |
236 | EXPORT_SYMBOL(free_au1000_dma); | 234 | EXPORT_SYMBOL(free_au1000_dma); |
237 | 235 | ||
236 | static int __init au1000_dma_init(void) | ||
237 | { | ||
238 | int base, i; | ||
239 | |||
240 | switch (alchemy_get_cputype()) { | ||
241 | case ALCHEMY_CPU_AU1000: | ||
242 | base = AU1000_DMA_INT_BASE; | ||
243 | break; | ||
244 | case ALCHEMY_CPU_AU1500: | ||
245 | base = AU1500_DMA_INT_BASE; | ||
246 | break; | ||
247 | case ALCHEMY_CPU_AU1100: | ||
248 | base = AU1100_DMA_INT_BASE; | ||
249 | break; | ||
250 | default: | ||
251 | goto out; | ||
252 | } | ||
253 | |||
254 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) | ||
255 | au1000_dma_table[i].irq = base + i; | ||
256 | |||
257 | printk(KERN_INFO "Alchemy DMA initialized\n"); | ||
258 | |||
259 | out: | ||
260 | return 0; | ||
261 | } | ||
262 | arch_initcall(au1000_dma_init); | ||
263 | |||
238 | #endif /* AU1000 AU1500 AU1100 */ | 264 | #endif /* AU1000 AU1500 AU1100 */ |
diff --git a/arch/mips/alchemy/common/gpiolib-au1000.c b/arch/mips/alchemy/common/gpiolib-au1000.c index 1bfa91f939f4..c8e1a94d4a95 100644 --- a/arch/mips/alchemy/common/gpiolib-au1000.c +++ b/arch/mips/alchemy/common/gpiolib-au1000.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <asm/mach-au1x00/au1000.h> | 36 | #include <asm/mach-au1x00/au1000.h> |
37 | #include <asm/mach-au1x00/gpio.h> | 37 | #include <asm/mach-au1x00/gpio.h> |
38 | 38 | ||
39 | #if !defined(CONFIG_SOC_AU1000) | ||
40 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) | 39 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) |
41 | { | 40 | { |
42 | return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); | 41 | return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); |
@@ -63,7 +62,7 @@ static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset) | |||
63 | { | 62 | { |
64 | return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE); | 63 | return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE); |
65 | } | 64 | } |
66 | #endif /* !defined(CONFIG_SOC_AU1000) */ | 65 | |
67 | 66 | ||
68 | static int gpio1_get(struct gpio_chip *chip, unsigned offset) | 67 | static int gpio1_get(struct gpio_chip *chip, unsigned offset) |
69 | { | 68 | { |
@@ -104,7 +103,6 @@ struct gpio_chip alchemy_gpio_chip[] = { | |||
104 | .base = ALCHEMY_GPIO1_BASE, | 103 | .base = ALCHEMY_GPIO1_BASE, |
105 | .ngpio = ALCHEMY_GPIO1_NUM, | 104 | .ngpio = ALCHEMY_GPIO1_NUM, |
106 | }, | 105 | }, |
107 | #if !defined(CONFIG_SOC_AU1000) | ||
108 | [1] = { | 106 | [1] = { |
109 | .label = "alchemy-gpio2", | 107 | .label = "alchemy-gpio2", |
110 | .direction_input = gpio2_direction_input, | 108 | .direction_input = gpio2_direction_input, |
@@ -115,15 +113,13 @@ struct gpio_chip alchemy_gpio_chip[] = { | |||
115 | .base = ALCHEMY_GPIO2_BASE, | 113 | .base = ALCHEMY_GPIO2_BASE, |
116 | .ngpio = ALCHEMY_GPIO2_NUM, | 114 | .ngpio = ALCHEMY_GPIO2_NUM, |
117 | }, | 115 | }, |
118 | #endif | ||
119 | }; | 116 | }; |
120 | 117 | ||
121 | static int __init alchemy_gpiolib_init(void) | 118 | static int __init alchemy_gpiolib_init(void) |
122 | { | 119 | { |
123 | gpiochip_add(&alchemy_gpio_chip[0]); | 120 | gpiochip_add(&alchemy_gpio_chip[0]); |
124 | #if !defined(CONFIG_SOC_AU1000) | 121 | if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000) |
125 | gpiochip_add(&alchemy_gpio_chip[1]); | 122 | gpiochip_add(&alchemy_gpio_chip[1]); |
126 | #endif | ||
127 | 123 | ||
128 | return 0; | 124 | return 0; |
129 | } | 125 | } |
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index d670928afcfd..b2821ace4d00 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -39,168 +39,180 @@ | |||
39 | 39 | ||
40 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); | 40 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); |
41 | 41 | ||
42 | /* NOTE on interrupt priorities: The original writers of this code said: | ||
43 | * | ||
44 | * Because of the tight timing of SETUP token to reply transactions, | ||
45 | * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT) | ||
46 | * needs the highest priority. | ||
47 | */ | ||
48 | |||
42 | /* per-processor fixed function irqs */ | 49 | /* per-processor fixed function irqs */ |
43 | struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = { | 50 | struct au1xxx_irqmap { |
44 | 51 | int im_irq; | |
45 | #if defined(CONFIG_SOC_AU1000) | 52 | int im_type; |
46 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 53 | int im_request; /* set 1 to get higher priority */ |
47 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 54 | }; |
48 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 55 | |
49 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 56 | struct au1xxx_irqmap au1000_irqmap[] __initdata = { |
50 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 57 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
51 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 58 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
52 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | 59 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
53 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | 60 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
54 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | 61 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
55 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | 62 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
56 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | 63 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, |
57 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | 64 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, |
58 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | 65 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, |
59 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | 66 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, |
60 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 67 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, |
61 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 68 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, |
62 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 69 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, |
63 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 70 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, |
64 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 71 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
65 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 72 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
66 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 73 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
67 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 74 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
68 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 75 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
69 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 76 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
70 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 77 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
71 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 78 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
72 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 79 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
73 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 80 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
74 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 81 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
75 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
76 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
77 | |||
78 | #elif defined(CONFIG_SOC_AU1500) | ||
79 | |||
80 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
81 | { AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
82 | { AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
83 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
84 | { AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
85 | { AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
86 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
87 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
88 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
89 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
90 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
91 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
92 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
93 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
94 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
95 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
96 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
97 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
98 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
99 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
100 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
101 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
102 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
103 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
104 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
105 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
106 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
107 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
108 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
109 | |||
110 | #elif defined(CONFIG_SOC_AU1100) | ||
111 | |||
112 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
113 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
114 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
115 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
116 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
117 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
118 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
119 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
120 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
121 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
122 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
123 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
124 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
125 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
126 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
127 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
128 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
129 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
130 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
131 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
132 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
133 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
134 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
135 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
136 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
137 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 82 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
138 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 83 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
139 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 84 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
140 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 85 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
141 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 86 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
142 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 87 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
143 | 88 | { -1, }, | |
144 | #elif defined(CONFIG_SOC_AU1550) | 89 | }; |
145 | 90 | ||
146 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 91 | struct au1xxx_irqmap au1500_irqmap[] __initdata = { |
147 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | 92 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
148 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | 93 | { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, |
149 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 94 | { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, |
150 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 95 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
151 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | 96 | { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, |
152 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | 97 | { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, |
153 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 98 | { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, |
154 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 99 | { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, |
155 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 100 | { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, |
156 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 101 | { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, |
157 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 102 | { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, |
158 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 103 | { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, |
159 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 104 | { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, |
160 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 105 | { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, |
161 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 106 | { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
162 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 107 | { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
163 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 108 | { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
164 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 109 | { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
165 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 110 | { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
166 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 111 | { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
167 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 112 | { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
168 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 113 | { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
169 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 114 | { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
115 | { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
116 | { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
117 | { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
118 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
119 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
120 | { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
121 | { -1, }, | ||
122 | }; | ||
123 | |||
124 | struct au1xxx_irqmap au1100_irqmap[] __initdata = { | ||
125 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
126 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
127 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
128 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
129 | { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
130 | { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
131 | { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
132 | { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
133 | { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
134 | { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
135 | { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
136 | { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
137 | { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
138 | { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
139 | { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
140 | { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
141 | { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
142 | { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
143 | { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
144 | { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
145 | { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
146 | { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
147 | { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
148 | { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
149 | { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, | ||
150 | { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
151 | { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
152 | { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
153 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
154 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
155 | { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
156 | { -1, }, | ||
157 | }; | ||
158 | |||
159 | struct au1xxx_irqmap au1550_irqmap[] __initdata = { | ||
160 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
161 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
162 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
163 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
164 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
165 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
166 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
167 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
168 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
169 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
170 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
171 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
172 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
173 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
174 | { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
175 | { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
176 | { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
177 | { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
178 | { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
179 | { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
180 | { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
181 | { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
182 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
183 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, | ||
170 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 184 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
171 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 185 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
172 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 186 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
173 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 187 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
174 | 188 | { -1, }, | |
175 | #elif defined(CONFIG_SOC_AU1200) | 189 | }; |
176 | 190 | ||
177 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 191 | struct au1xxx_irqmap au1200_irqmap[] __initdata = { |
178 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 192 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
179 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 193 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
180 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 194 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
181 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 195 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
182 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 196 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
183 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 197 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
184 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 198 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
185 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 199 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
186 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 200 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
187 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 201 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
188 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 202 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
189 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 203 | { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
190 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 204 | { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
191 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 205 | { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
192 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 206 | { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
193 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 207 | { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
194 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 208 | { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
195 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 209 | { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
196 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 210 | { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
197 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 211 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
198 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 212 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
199 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 213 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
200 | 214 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | |
201 | #else | 215 | { -1, }, |
202 | #error "Error: Unknown Alchemy SOC" | ||
203 | #endif | ||
204 | }; | 216 | }; |
205 | 217 | ||
206 | 218 | ||
@@ -306,7 +318,7 @@ static void au1x_ic1_unmask(unsigned int irq_nr) | |||
306 | * nowhere in the current kernel sources is it disabled. --mlau | 318 | * nowhere in the current kernel sources is it disabled. --mlau |
307 | */ | 319 | */ |
308 | #if defined(CONFIG_MIPS_PB1000) | 320 | #if defined(CONFIG_MIPS_PB1000) |
309 | if (irq_nr == AU1000_GPIO_15) | 321 | if (irq_nr == AU1000_GPIO15_INT) |
310 | au_writel(0x4000, PB1000_MDR); /* enable int */ | 322 | au_writel(0x4000, PB1000_MDR); /* enable int */ |
311 | #endif | 323 | #endif |
312 | au_sync(); | 324 | au_sync(); |
@@ -378,11 +390,13 @@ static void au1x_ic1_maskack(unsigned int irq_nr) | |||
378 | 390 | ||
379 | static int au1x_ic1_setwake(unsigned int irq, unsigned int on) | 391 | static int au1x_ic1_setwake(unsigned int irq, unsigned int on) |
380 | { | 392 | { |
381 | unsigned int bit = irq - AU1000_INTC1_INT_BASE; | 393 | int bit = irq - AU1000_INTC1_INT_BASE; |
382 | unsigned long wakemsk, flags; | 394 | unsigned long wakemsk, flags; |
383 | 395 | ||
384 | /* only GPIO 0-7 can act as wakeup source: */ | 396 | /* only GPIO 0-7 can act as wakeup source. Fortunately these |
385 | if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7)) | 397 | * are wired up identically on all supported variants. |
398 | */ | ||
399 | if ((bit < 0) || (bit > 7)) | ||
386 | return -EINVAL; | 400 | return -EINVAL; |
387 | 401 | ||
388 | local_irq_save(flags); | 402 | local_irq_save(flags); |
@@ -504,11 +518,11 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) | |||
504 | asmlinkage void plat_irq_dispatch(void) | 518 | asmlinkage void plat_irq_dispatch(void) |
505 | { | 519 | { |
506 | unsigned int pending = read_c0_status() & read_c0_cause(); | 520 | unsigned int pending = read_c0_status() & read_c0_cause(); |
507 | unsigned long s, off, bit; | 521 | unsigned long s, off; |
508 | 522 | ||
509 | if (pending & CAUSEF_IP7) { | 523 | if (pending & CAUSEF_IP7) { |
510 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); | 524 | off = MIPS_CPU_IRQ_BASE + 7; |
511 | return; | 525 | goto handle; |
512 | } else if (pending & CAUSEF_IP2) { | 526 | } else if (pending & CAUSEF_IP2) { |
513 | s = IC0_REQ0INT; | 527 | s = IC0_REQ0INT; |
514 | off = AU1000_INTC0_INT_BASE; | 528 | off = AU1000_INTC0_INT_BASE; |
@@ -524,58 +538,20 @@ asmlinkage void plat_irq_dispatch(void) | |||
524 | } else | 538 | } else |
525 | goto spurious; | 539 | goto spurious; |
526 | 540 | ||
527 | bit = 0; | ||
528 | s = au_readl(s); | 541 | s = au_readl(s); |
529 | if (unlikely(!s)) { | 542 | if (unlikely(!s)) { |
530 | spurious: | 543 | spurious: |
531 | spurious_interrupt(); | 544 | spurious_interrupt(); |
532 | return; | 545 | return; |
533 | } | 546 | } |
534 | #ifdef AU1000_USB_DEV_REQ_INT | 547 | off += __ffs(s); |
535 | /* | 548 | handle: |
536 | * Because of the tight timing of SETUP token to reply | 549 | do_IRQ(off); |
537 | * transactions, the USB devices-side packet complete | ||
538 | * interrupt needs the highest priority. | ||
539 | */ | ||
540 | bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE); | ||
541 | if ((pending & CAUSEF_IP2) && (s & bit)) { | ||
542 | do_IRQ(AU1000_USB_DEV_REQ_INT); | ||
543 | return; | ||
544 | } | ||
545 | #endif | ||
546 | do_IRQ(__ffs(s) + off); | ||
547 | } | 550 | } |
548 | 551 | ||
549 | /* setup edge/level and assign request 0/1 */ | 552 | static void __init au1000_init_irq(struct au1xxx_irqmap *map) |
550 | void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count) | ||
551 | { | 553 | { |
552 | unsigned int bit, irq_nr; | 554 | unsigned int bit, irq_nr; |
553 | |||
554 | while (count--) { | ||
555 | irq_nr = map[count].im_irq; | ||
556 | |||
557 | if (((irq_nr < AU1000_INTC0_INT_BASE) || | ||
558 | (irq_nr >= AU1000_INTC0_INT_BASE + 32)) && | ||
559 | ((irq_nr < AU1000_INTC1_INT_BASE) || | ||
560 | (irq_nr >= AU1000_INTC1_INT_BASE + 32))) | ||
561 | continue; | ||
562 | |||
563 | if (irq_nr >= AU1000_INTC1_INT_BASE) { | ||
564 | bit = irq_nr - AU1000_INTC1_INT_BASE; | ||
565 | if (map[count].im_request) | ||
566 | au_writel(1 << bit, IC1_ASSIGNCLR); | ||
567 | } else { | ||
568 | bit = irq_nr - AU1000_INTC0_INT_BASE; | ||
569 | if (map[count].im_request) | ||
570 | au_writel(1 << bit, IC0_ASSIGNCLR); | ||
571 | } | ||
572 | |||
573 | au1x_ic_settype(irq_nr, map[count].im_type); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | void __init arch_init_irq(void) | ||
578 | { | ||
579 | int i; | 555 | int i; |
580 | 556 | ||
581 | /* | 557 | /* |
@@ -585,7 +561,7 @@ void __init arch_init_irq(void) | |||
585 | au_writel(0xffffffff, IC0_CFG1CLR); | 561 | au_writel(0xffffffff, IC0_CFG1CLR); |
586 | au_writel(0xffffffff, IC0_CFG2CLR); | 562 | au_writel(0xffffffff, IC0_CFG2CLR); |
587 | au_writel(0xffffffff, IC0_MASKCLR); | 563 | au_writel(0xffffffff, IC0_MASKCLR); |
588 | au_writel(0xffffffff, IC0_ASSIGNSET); | 564 | au_writel(0xffffffff, IC0_ASSIGNCLR); |
589 | au_writel(0xffffffff, IC0_WAKECLR); | 565 | au_writel(0xffffffff, IC0_WAKECLR); |
590 | au_writel(0xffffffff, IC0_SRCSET); | 566 | au_writel(0xffffffff, IC0_SRCSET); |
591 | au_writel(0xffffffff, IC0_FALLINGCLR); | 567 | au_writel(0xffffffff, IC0_FALLINGCLR); |
@@ -596,7 +572,7 @@ void __init arch_init_irq(void) | |||
596 | au_writel(0xffffffff, IC1_CFG1CLR); | 572 | au_writel(0xffffffff, IC1_CFG1CLR); |
597 | au_writel(0xffffffff, IC1_CFG2CLR); | 573 | au_writel(0xffffffff, IC1_CFG2CLR); |
598 | au_writel(0xffffffff, IC1_MASKCLR); | 574 | au_writel(0xffffffff, IC1_MASKCLR); |
599 | au_writel(0xffffffff, IC1_ASSIGNSET); | 575 | au_writel(0xffffffff, IC1_ASSIGNCLR); |
600 | au_writel(0xffffffff, IC1_WAKECLR); | 576 | au_writel(0xffffffff, IC1_WAKECLR); |
601 | au_writel(0xffffffff, IC1_SRCSET); | 577 | au_writel(0xffffffff, IC1_SRCSET); |
602 | au_writel(0xffffffff, IC1_FALLINGCLR); | 578 | au_writel(0xffffffff, IC1_FALLINGCLR); |
@@ -619,11 +595,43 @@ void __init arch_init_irq(void) | |||
619 | /* | 595 | /* |
620 | * Initialize IC0, which is fixed per processor. | 596 | * Initialize IC0, which is fixed per processor. |
621 | */ | 597 | */ |
622 | au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map)); | 598 | while (map->im_irq != -1) { |
599 | irq_nr = map->im_irq; | ||
623 | 600 | ||
624 | /* Boards can register additional (GPIO-based) IRQs. | 601 | if (irq_nr >= AU1000_INTC1_INT_BASE) { |
625 | */ | 602 | bit = irq_nr - AU1000_INTC1_INT_BASE; |
626 | board_init_irq(); | 603 | if (map->im_request) |
604 | au_writel(1 << bit, IC1_ASSIGNSET); | ||
605 | } else { | ||
606 | bit = irq_nr - AU1000_INTC0_INT_BASE; | ||
607 | if (map->im_request) | ||
608 | au_writel(1 << bit, IC0_ASSIGNSET); | ||
609 | } | ||
610 | |||
611 | au1x_ic_settype(irq_nr, map->im_type); | ||
612 | ++map; | ||
613 | } | ||
627 | 614 | ||
628 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); | 615 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); |
629 | } | 616 | } |
617 | |||
618 | void __init arch_init_irq(void) | ||
619 | { | ||
620 | switch (alchemy_get_cputype()) { | ||
621 | case ALCHEMY_CPU_AU1000: | ||
622 | au1000_init_irq(au1000_irqmap); | ||
623 | break; | ||
624 | case ALCHEMY_CPU_AU1500: | ||
625 | au1000_init_irq(au1500_irqmap); | ||
626 | break; | ||
627 | case ALCHEMY_CPU_AU1100: | ||
628 | au1000_init_irq(au1100_irqmap); | ||
629 | break; | ||
630 | case ALCHEMY_CPU_AU1550: | ||
631 | au1000_init_irq(au1550_irqmap); | ||
632 | break; | ||
633 | case ALCHEMY_CPU_AU1200: | ||
634 | au1000_init_irq(au1200_irqmap); | ||
635 | break; | ||
636 | } | ||
637 | } | ||
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 117f99f70649..2580e77624d2 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -19,39 +19,40 @@ | |||
19 | #include <asm/mach-au1x00/au1xxx.h> | 19 | #include <asm/mach-au1x00/au1xxx.h> |
20 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 20 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
21 | #include <asm/mach-au1x00/au1100_mmc.h> | 21 | #include <asm/mach-au1x00/au1100_mmc.h> |
22 | 22 | #include <asm/mach-au1x00/au1xxx_eth.h> | |
23 | #define PORT(_base, _irq) \ | 23 | |
24 | { \ | 24 | #define PORT(_base, _irq) \ |
25 | .iobase = _base, \ | 25 | { \ |
26 | .membase = (void __iomem *)_base,\ | 26 | .mapbase = _base, \ |
27 | .mapbase = CPHYSADDR(_base), \ | 27 | .irq = _irq, \ |
28 | .irq = _irq, \ | 28 | .regshift = 2, \ |
29 | .regshift = 2, \ | 29 | .iotype = UPIO_AU, \ |
30 | .iotype = UPIO_AU, \ | 30 | .flags = UPF_SKIP_TEST | UPF_IOREMAP | \ |
31 | .flags = UPF_SKIP_TEST \ | 31 | UPF_FIXED_TYPE, \ |
32 | .type = PORT_16550A, \ | ||
32 | } | 33 | } |
33 | 34 | ||
34 | static struct plat_serial8250_port au1x00_uart_data[] = { | 35 | static struct plat_serial8250_port au1x00_uart_data[] = { |
35 | #if defined(CONFIG_SERIAL_8250_AU1X00) | 36 | #if defined(CONFIG_SERIAL_8250_AU1X00) |
36 | #if defined(CONFIG_SOC_AU1000) | 37 | #if defined(CONFIG_SOC_AU1000) |
37 | PORT(UART0_ADDR, AU1000_UART0_INT), | 38 | PORT(UART0_PHYS_ADDR, AU1000_UART0_INT), |
38 | PORT(UART1_ADDR, AU1000_UART1_INT), | 39 | PORT(UART1_PHYS_ADDR, AU1000_UART1_INT), |
39 | PORT(UART2_ADDR, AU1000_UART2_INT), | 40 | PORT(UART2_PHYS_ADDR, AU1000_UART2_INT), |
40 | PORT(UART3_ADDR, AU1000_UART3_INT), | 41 | PORT(UART3_PHYS_ADDR, AU1000_UART3_INT), |
41 | #elif defined(CONFIG_SOC_AU1500) | 42 | #elif defined(CONFIG_SOC_AU1500) |
42 | PORT(UART0_ADDR, AU1500_UART0_INT), | 43 | PORT(UART0_PHYS_ADDR, AU1500_UART0_INT), |
43 | PORT(UART3_ADDR, AU1500_UART3_INT), | 44 | PORT(UART3_PHYS_ADDR, AU1500_UART3_INT), |
44 | #elif defined(CONFIG_SOC_AU1100) | 45 | #elif defined(CONFIG_SOC_AU1100) |
45 | PORT(UART0_ADDR, AU1100_UART0_INT), | 46 | PORT(UART0_PHYS_ADDR, AU1100_UART0_INT), |
46 | PORT(UART1_ADDR, AU1100_UART1_INT), | 47 | PORT(UART1_PHYS_ADDR, AU1100_UART1_INT), |
47 | PORT(UART3_ADDR, AU1100_UART3_INT), | 48 | PORT(UART3_PHYS_ADDR, AU1100_UART3_INT), |
48 | #elif defined(CONFIG_SOC_AU1550) | 49 | #elif defined(CONFIG_SOC_AU1550) |
49 | PORT(UART0_ADDR, AU1550_UART0_INT), | 50 | PORT(UART0_PHYS_ADDR, AU1550_UART0_INT), |
50 | PORT(UART1_ADDR, AU1550_UART1_INT), | 51 | PORT(UART1_PHYS_ADDR, AU1550_UART1_INT), |
51 | PORT(UART3_ADDR, AU1550_UART3_INT), | 52 | PORT(UART3_PHYS_ADDR, AU1550_UART3_INT), |
52 | #elif defined(CONFIG_SOC_AU1200) | 53 | #elif defined(CONFIG_SOC_AU1200) |
53 | PORT(UART0_ADDR, AU1200_UART0_INT), | 54 | PORT(UART0_PHYS_ADDR, AU1200_UART0_INT), |
54 | PORT(UART1_ADDR, AU1200_UART1_INT), | 55 | PORT(UART1_PHYS_ADDR, AU1200_UART1_INT), |
55 | #endif | 56 | #endif |
56 | #endif /* CONFIG_SERIAL_8250_AU1X00 */ | 57 | #endif /* CONFIG_SERIAL_8250_AU1X00 */ |
57 | { }, | 58 | { }, |
@@ -73,8 +74,8 @@ static struct resource au1xxx_usb_ohci_resources[] = { | |||
73 | .flags = IORESOURCE_MEM, | 74 | .flags = IORESOURCE_MEM, |
74 | }, | 75 | }, |
75 | [1] = { | 76 | [1] = { |
76 | .start = AU1000_USB_HOST_INT, | 77 | .start = FOR_PLATFORM_C_USB_HOST_INT, |
77 | .end = AU1000_USB_HOST_INT, | 78 | .end = FOR_PLATFORM_C_USB_HOST_INT, |
78 | .flags = IORESOURCE_IRQ, | 79 | .flags = IORESOURCE_IRQ, |
79 | }, | 80 | }, |
80 | }; | 81 | }; |
@@ -132,8 +133,8 @@ static struct resource au1xxx_usb_ehci_resources[] = { | |||
132 | .flags = IORESOURCE_MEM, | 133 | .flags = IORESOURCE_MEM, |
133 | }, | 134 | }, |
134 | [1] = { | 135 | [1] = { |
135 | .start = AU1000_USB_HOST_INT, | 136 | .start = AU1200_USB_INT, |
136 | .end = AU1000_USB_HOST_INT, | 137 | .end = AU1200_USB_INT, |
137 | .flags = IORESOURCE_IRQ, | 138 | .flags = IORESOURCE_IRQ, |
138 | }, | 139 | }, |
139 | }; | 140 | }; |
@@ -308,11 +309,6 @@ static struct platform_device au1200_mmc1_device = { | |||
308 | #endif /* #ifndef CONFIG_MIPS_DB1200 */ | 309 | #endif /* #ifndef CONFIG_MIPS_DB1200 */ |
309 | #endif /* #ifdef CONFIG_SOC_AU1200 */ | 310 | #endif /* #ifdef CONFIG_SOC_AU1200 */ |
310 | 311 | ||
311 | static struct platform_device au1x00_pcmcia_device = { | ||
312 | .name = "au1x00-pcmcia", | ||
313 | .id = 0, | ||
314 | }; | ||
315 | |||
316 | /* All Alchemy demoboards with I2C have this #define in their headers */ | 312 | /* All Alchemy demoboards with I2C have this #define in their headers */ |
317 | #ifdef SMBUS_PSC_BASE | 313 | #ifdef SMBUS_PSC_BASE |
318 | static struct resource pbdb_smbus_resources[] = { | 314 | static struct resource pbdb_smbus_resources[] = { |
@@ -331,10 +327,92 @@ static struct platform_device pbdb_smbus_device = { | |||
331 | }; | 327 | }; |
332 | #endif | 328 | #endif |
333 | 329 | ||
330 | /* Macro to help defining the Ethernet MAC resources */ | ||
331 | #define MAC_RES(_base, _enable, _irq) \ | ||
332 | { \ | ||
333 | .start = CPHYSADDR(_base), \ | ||
334 | .end = CPHYSADDR(_base + 0xffff), \ | ||
335 | .flags = IORESOURCE_MEM, \ | ||
336 | }, \ | ||
337 | { \ | ||
338 | .start = CPHYSADDR(_enable), \ | ||
339 | .end = CPHYSADDR(_enable + 0x3), \ | ||
340 | .flags = IORESOURCE_MEM, \ | ||
341 | }, \ | ||
342 | { \ | ||
343 | .start = _irq, \ | ||
344 | .end = _irq, \ | ||
345 | .flags = IORESOURCE_IRQ \ | ||
346 | } | ||
347 | |||
348 | static struct resource au1xxx_eth0_resources[] = { | ||
349 | #if defined(CONFIG_SOC_AU1000) | ||
350 | MAC_RES(AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT), | ||
351 | #elif defined(CONFIG_SOC_AU1100) | ||
352 | MAC_RES(AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT), | ||
353 | #elif defined(CONFIG_SOC_AU1550) | ||
354 | MAC_RES(AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT), | ||
355 | #elif defined(CONFIG_SOC_AU1500) | ||
356 | MAC_RES(AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT), | ||
357 | #endif | ||
358 | }; | ||
359 | |||
360 | |||
361 | static struct au1000_eth_platform_data au1xxx_eth0_platform_data = { | ||
362 | .phy1_search_mac0 = 1, | ||
363 | }; | ||
364 | |||
365 | static struct platform_device au1xxx_eth0_device = { | ||
366 | .name = "au1000-eth", | ||
367 | .id = 0, | ||
368 | .num_resources = ARRAY_SIZE(au1xxx_eth0_resources), | ||
369 | .resource = au1xxx_eth0_resources, | ||
370 | .dev.platform_data = &au1xxx_eth0_platform_data, | ||
371 | }; | ||
372 | |||
373 | #ifndef CONFIG_SOC_AU1100 | ||
374 | static struct resource au1xxx_eth1_resources[] = { | ||
375 | #if defined(CONFIG_SOC_AU1000) | ||
376 | MAC_RES(AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT), | ||
377 | #elif defined(CONFIG_SOC_AU1550) | ||
378 | MAC_RES(AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT), | ||
379 | #elif defined(CONFIG_SOC_AU1500) | ||
380 | MAC_RES(AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT), | ||
381 | #endif | ||
382 | }; | ||
383 | |||
384 | static struct au1000_eth_platform_data au1xxx_eth1_platform_data = { | ||
385 | .phy1_search_mac0 = 1, | ||
386 | }; | ||
387 | |||
388 | static struct platform_device au1xxx_eth1_device = { | ||
389 | .name = "au1000-eth", | ||
390 | .id = 1, | ||
391 | .num_resources = ARRAY_SIZE(au1xxx_eth1_resources), | ||
392 | .resource = au1xxx_eth1_resources, | ||
393 | .dev.platform_data = &au1xxx_eth1_platform_data, | ||
394 | }; | ||
395 | #endif | ||
396 | |||
397 | void __init au1xxx_override_eth_cfg(unsigned int port, | ||
398 | struct au1000_eth_platform_data *eth_data) | ||
399 | { | ||
400 | if (!eth_data || port > 1) | ||
401 | return; | ||
402 | |||
403 | if (port == 0) | ||
404 | memcpy(&au1xxx_eth0_platform_data, eth_data, | ||
405 | sizeof(struct au1000_eth_platform_data)); | ||
406 | #ifndef CONFIG_SOC_AU1100 | ||
407 | else | ||
408 | memcpy(&au1xxx_eth1_platform_data, eth_data, | ||
409 | sizeof(struct au1000_eth_platform_data)); | ||
410 | #endif | ||
411 | } | ||
412 | |||
334 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | 413 | static struct platform_device *au1xxx_platform_devices[] __initdata = { |
335 | &au1xx0_uart_device, | 414 | &au1xx0_uart_device, |
336 | &au1xxx_usb_ohci_device, | 415 | &au1xxx_usb_ohci_device, |
337 | &au1x00_pcmcia_device, | ||
338 | #ifdef CONFIG_FB_AU1100 | 416 | #ifdef CONFIG_FB_AU1100 |
339 | &au1100_lcd_device, | 417 | &au1100_lcd_device, |
340 | #endif | 418 | #endif |
@@ -351,6 +429,7 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { | |||
351 | #ifdef SMBUS_PSC_BASE | 429 | #ifdef SMBUS_PSC_BASE |
352 | &pbdb_smbus_device, | 430 | &pbdb_smbus_device, |
353 | #endif | 431 | #endif |
432 | &au1xxx_eth0_device, | ||
354 | }; | 433 | }; |
355 | 434 | ||
356 | static int __init au1xxx_platform_init(void) | 435 | static int __init au1xxx_platform_init(void) |
@@ -362,6 +441,12 @@ static int __init au1xxx_platform_init(void) | |||
362 | for (i = 0; au1x00_uart_data[i].flags; i++) | 441 | for (i = 0; au1x00_uart_data[i].flags; i++) |
363 | au1x00_uart_data[i].uartclk = uartclk; | 442 | au1x00_uart_data[i].uartclk = uartclk; |
364 | 443 | ||
444 | #ifndef CONFIG_SOC_AU1100 | ||
445 | /* Register second MAC if enabled in pinfunc */ | ||
446 | if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) | ||
447 | platform_device_register(&au1xxx_eth1_device); | ||
448 | #endif | ||
449 | |||
365 | return platform_add_devices(au1xxx_platform_devices, | 450 | return platform_add_devices(au1xxx_platform_devices, |
366 | ARRAY_SIZE(au1xxx_platform_devices)); | 451 | ARRAY_SIZE(au1xxx_platform_devices)); |
367 | } | 452 | } |
diff --git a/arch/mips/alchemy/common/prom.c b/arch/mips/alchemy/common/prom.c index 18b310b475ca..c29511b11d44 100644 --- a/arch/mips/alchemy/common/prom.c +++ b/arch/mips/alchemy/common/prom.c | |||
@@ -43,29 +43,15 @@ int prom_argc; | |||
43 | char **prom_argv; | 43 | char **prom_argv; |
44 | char **prom_envp; | 44 | char **prom_envp; |
45 | 45 | ||
46 | char * __init_or_module prom_getcmdline(void) | ||
47 | { | ||
48 | return &(arcs_cmdline[0]); | ||
49 | } | ||
50 | |||
51 | void prom_init_cmdline(void) | 46 | void prom_init_cmdline(void) |
52 | { | 47 | { |
53 | char *cp; | 48 | int i; |
54 | int actr; | ||
55 | |||
56 | actr = 1; /* Always ignore argv[0] */ | ||
57 | 49 | ||
58 | cp = &(arcs_cmdline[0]); | 50 | for (i = 1; i < prom_argc; i++) { |
59 | while (actr < prom_argc) { | 51 | strlcat(arcs_cmdline, prom_argv[i], COMMAND_LINE_SIZE); |
60 | strcpy(cp, prom_argv[actr]); | 52 | if (i < (prom_argc - 1)) |
61 | cp += strlen(prom_argv[actr]); | 53 | strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE); |
62 | *cp++ = ' '; | ||
63 | actr++; | ||
64 | } | 54 | } |
65 | if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ | ||
66 | --cp; | ||
67 | if (prom_argc > 1) | ||
68 | *cp = '\0'; | ||
69 | } | 55 | } |
70 | 56 | ||
71 | char *prom_getenv(char *envname) | 57 | char *prom_getenv(char *envname) |
@@ -121,14 +107,12 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) | |||
121 | int prom_get_ethernet_addr(char *ethernet_addr) | 107 | int prom_get_ethernet_addr(char *ethernet_addr) |
122 | { | 108 | { |
123 | char *ethaddr_str; | 109 | char *ethaddr_str; |
124 | char *argptr; | ||
125 | 110 | ||
126 | /* Check the environment variables first */ | 111 | /* Check the environment variables first */ |
127 | ethaddr_str = prom_getenv("ethaddr"); | 112 | ethaddr_str = prom_getenv("ethaddr"); |
128 | if (!ethaddr_str) { | 113 | if (!ethaddr_str) { |
129 | /* Check command line */ | 114 | /* Check command line */ |
130 | argptr = prom_getcmdline(); | 115 | ethaddr_str = strstr(arcs_cmdline, "ethaddr="); |
131 | ethaddr_str = strstr(argptr, "ethaddr="); | ||
132 | if (!ethaddr_str) | 116 | if (!ethaddr_str) |
133 | return -1; | 117 | return -1; |
134 | 118 | ||
diff --git a/arch/mips/alchemy/common/puts.c b/arch/mips/alchemy/common/puts.c deleted file mode 100644 index 55bbe24d45b6..000000000000 --- a/arch/mips/alchemy/common/puts.c +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * Low level UART routines to directly access Alchemy UART. | ||
5 | * | ||
6 | * Copyright 2001, 2008 MontaVista Software Inc. | ||
7 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <asm/mach-au1x00/au1000.h> | ||
31 | |||
32 | #define SERIAL_BASE UART_BASE | ||
33 | #define SER_CMD 0x7 | ||
34 | #define SER_DATA 0x1 | ||
35 | #define TX_BUSY 0x20 | ||
36 | |||
37 | #define TIMEOUT 0xffffff | ||
38 | #define SLOW_DOWN | ||
39 | |||
40 | static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE; | ||
41 | |||
42 | #ifdef SLOW_DOWN | ||
43 | static inline void slow_down(void) | ||
44 | { | ||
45 | int k; | ||
46 | |||
47 | for (k = 0; k < 10000; k++); | ||
48 | } | ||
49 | #else | ||
50 | #define slow_down() | ||
51 | #endif | ||
52 | |||
53 | void | ||
54 | prom_putchar(const unsigned char c) | ||
55 | { | ||
56 | unsigned char ch; | ||
57 | int i = 0; | ||
58 | |||
59 | do { | ||
60 | ch = com1[SER_CMD]; | ||
61 | slow_down(); | ||
62 | i++; | ||
63 | if (i > TIMEOUT) | ||
64 | break; | ||
65 | } while (0 == (ch & TX_BUSY)); | ||
66 | |||
67 | com1[SER_DATA] = c; | ||
68 | } | ||
diff --git a/arch/mips/alchemy/common/reset.c b/arch/mips/alchemy/common/reset.c deleted file mode 100644 index 4791011e8f92..000000000000 --- a/arch/mips/alchemy/common/reset.c +++ /dev/null | |||
@@ -1,188 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * Au1xx0 reset routines. | ||
5 | * | ||
6 | * Copyright 2001, 2006, 2008 MontaVista Software Inc. | ||
7 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <linux/gpio.h> | ||
31 | |||
32 | #include <asm/cacheflush.h> | ||
33 | #include <asm/mach-au1x00/au1000.h> | ||
34 | |||
35 | void au1000_restart(char *command) | ||
36 | { | ||
37 | /* Set all integrated peripherals to disabled states */ | ||
38 | extern void board_reset(void); | ||
39 | u32 prid = read_c0_prid(); | ||
40 | |||
41 | printk(KERN_NOTICE "\n** Resetting Integrated Peripherals\n"); | ||
42 | |||
43 | switch (prid & 0xFF000000) { | ||
44 | case 0x00000000: /* Au1000 */ | ||
45 | au_writel(0x02, 0xb0000010); /* ac97_enable */ | ||
46 | au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ | ||
47 | asm("sync"); | ||
48 | au_writel(0x00, 0xb017fffc); /* usbh_enable */ | ||
49 | au_writel(0x00, 0xb0200058); /* usbd_enable */ | ||
50 | au_writel(0x00, 0xb0300040); /* ir_enable */ | ||
51 | au_writel(0x00, 0xb4004104); /* mac dma */ | ||
52 | au_writel(0x00, 0xb4004114); /* mac dma */ | ||
53 | au_writel(0x00, 0xb4004124); /* mac dma */ | ||
54 | au_writel(0x00, 0xb4004134); /* mac dma */ | ||
55 | au_writel(0x00, 0xb0520000); /* macen0 */ | ||
56 | au_writel(0x00, 0xb0520004); /* macen1 */ | ||
57 | au_writel(0x00, 0xb1000008); /* i2s_enable */ | ||
58 | au_writel(0x00, 0xb1100100); /* uart0_enable */ | ||
59 | au_writel(0x00, 0xb1200100); /* uart1_enable */ | ||
60 | au_writel(0x00, 0xb1300100); /* uart2_enable */ | ||
61 | au_writel(0x00, 0xb1400100); /* uart3_enable */ | ||
62 | au_writel(0x02, 0xb1600100); /* ssi0_enable */ | ||
63 | au_writel(0x02, 0xb1680100); /* ssi1_enable */ | ||
64 | au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ | ||
65 | au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ | ||
66 | au_writel(0x00, 0xb1900028); /* sys_clksrc */ | ||
67 | au_writel(0x10, 0xb1900060); /* sys_cpupll */ | ||
68 | au_writel(0x00, 0xb1900064); /* sys_auxpll */ | ||
69 | au_writel(0x00, 0xb1900100); /* sys_pininputen */ | ||
70 | break; | ||
71 | case 0x01000000: /* Au1500 */ | ||
72 | au_writel(0x02, 0xb0000010); /* ac97_enable */ | ||
73 | au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ | ||
74 | asm("sync"); | ||
75 | au_writel(0x00, 0xb017fffc); /* usbh_enable */ | ||
76 | au_writel(0x00, 0xb0200058); /* usbd_enable */ | ||
77 | au_writel(0x00, 0xb4004104); /* mac dma */ | ||
78 | au_writel(0x00, 0xb4004114); /* mac dma */ | ||
79 | au_writel(0x00, 0xb4004124); /* mac dma */ | ||
80 | au_writel(0x00, 0xb4004134); /* mac dma */ | ||
81 | au_writel(0x00, 0xb1520000); /* macen0 */ | ||
82 | au_writel(0x00, 0xb1520004); /* macen1 */ | ||
83 | au_writel(0x00, 0xb1100100); /* uart0_enable */ | ||
84 | au_writel(0x00, 0xb1400100); /* uart3_enable */ | ||
85 | au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ | ||
86 | au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ | ||
87 | au_writel(0x00, 0xb1900028); /* sys_clksrc */ | ||
88 | au_writel(0x10, 0xb1900060); /* sys_cpupll */ | ||
89 | au_writel(0x00, 0xb1900064); /* sys_auxpll */ | ||
90 | au_writel(0x00, 0xb1900100); /* sys_pininputen */ | ||
91 | break; | ||
92 | case 0x02000000: /* Au1100 */ | ||
93 | au_writel(0x02, 0xb0000010); /* ac97_enable */ | ||
94 | au_writel(0x08, 0xb017fffc); /* usbh_enable - early errata */ | ||
95 | asm("sync"); | ||
96 | au_writel(0x00, 0xb017fffc); /* usbh_enable */ | ||
97 | au_writel(0x00, 0xb0200058); /* usbd_enable */ | ||
98 | au_writel(0x00, 0xb0300040); /* ir_enable */ | ||
99 | au_writel(0x00, 0xb4004104); /* mac dma */ | ||
100 | au_writel(0x00, 0xb4004114); /* mac dma */ | ||
101 | au_writel(0x00, 0xb4004124); /* mac dma */ | ||
102 | au_writel(0x00, 0xb4004134); /* mac dma */ | ||
103 | au_writel(0x00, 0xb0520000); /* macen0 */ | ||
104 | au_writel(0x00, 0xb1000008); /* i2s_enable */ | ||
105 | au_writel(0x00, 0xb1100100); /* uart0_enable */ | ||
106 | au_writel(0x00, 0xb1200100); /* uart1_enable */ | ||
107 | au_writel(0x00, 0xb1400100); /* uart3_enable */ | ||
108 | au_writel(0x02, 0xb1600100); /* ssi0_enable */ | ||
109 | au_writel(0x02, 0xb1680100); /* ssi1_enable */ | ||
110 | au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ | ||
111 | au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ | ||
112 | au_writel(0x00, 0xb1900028); /* sys_clksrc */ | ||
113 | au_writel(0x10, 0xb1900060); /* sys_cpupll */ | ||
114 | au_writel(0x00, 0xb1900064); /* sys_auxpll */ | ||
115 | au_writel(0x00, 0xb1900100); /* sys_pininputen */ | ||
116 | break; | ||
117 | case 0x03000000: /* Au1550 */ | ||
118 | au_writel(0x00, 0xb1a00004); /* psc 0 */ | ||
119 | au_writel(0x00, 0xb1b00004); /* psc 1 */ | ||
120 | au_writel(0x00, 0xb0a00004); /* psc 2 */ | ||
121 | au_writel(0x00, 0xb0b00004); /* psc 3 */ | ||
122 | au_writel(0x00, 0xb017fffc); /* usbh_enable */ | ||
123 | au_writel(0x00, 0xb0200058); /* usbd_enable */ | ||
124 | au_writel(0x00, 0xb4004104); /* mac dma */ | ||
125 | au_writel(0x00, 0xb4004114); /* mac dma */ | ||
126 | au_writel(0x00, 0xb4004124); /* mac dma */ | ||
127 | au_writel(0x00, 0xb4004134); /* mac dma */ | ||
128 | au_writel(0x00, 0xb1520000); /* macen0 */ | ||
129 | au_writel(0x00, 0xb1520004); /* macen1 */ | ||
130 | au_writel(0x00, 0xb1100100); /* uart0_enable */ | ||
131 | au_writel(0x00, 0xb1200100); /* uart1_enable */ | ||
132 | au_writel(0x00, 0xb1400100); /* uart3_enable */ | ||
133 | au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */ | ||
134 | au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */ | ||
135 | au_writel(0x00, 0xb1900028); /* sys_clksrc */ | ||
136 | au_writel(0x10, 0xb1900060); /* sys_cpupll */ | ||
137 | au_writel(0x00, 0xb1900064); /* sys_auxpll */ | ||
138 | au_writel(0x00, 0xb1900100); /* sys_pininputen */ | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | set_c0_status(ST0_BEV | ST0_ERL); | ||
143 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); | ||
144 | flush_cache_all(); | ||
145 | write_c0_wired(0); | ||
146 | |||
147 | /* Give board a chance to do a hardware reset */ | ||
148 | board_reset(); | ||
149 | |||
150 | /* Jump to the beggining in case board_reset() is empty */ | ||
151 | __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); | ||
152 | } | ||
153 | |||
154 | void au1000_halt(void) | ||
155 | { | ||
156 | #if defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550) | ||
157 | /* Power off system */ | ||
158 | printk(KERN_NOTICE "\n** Powering off...\n"); | ||
159 | au_writew(au_readw(0xAF00001C) | (3 << 14), 0xAF00001C); | ||
160 | au_sync(); | ||
161 | while (1); /* should not get here */ | ||
162 | #else | ||
163 | printk(KERN_NOTICE "\n** You can safely turn off the power\n"); | ||
164 | #ifdef CONFIG_MIPS_MIRAGE | ||
165 | gpio_direction_output(210, 1); | ||
166 | #endif | ||
167 | #ifdef CONFIG_MIPS_DB1200 | ||
168 | au_writew(au_readw(0xB980001C) | (1 << 14), 0xB980001C); | ||
169 | #endif | ||
170 | #ifdef CONFIG_PM | ||
171 | au_sleep(); | ||
172 | |||
173 | /* Should not get here */ | ||
174 | printk(KERN_ERR "Unable to put CPU in sleep mode\n"); | ||
175 | while (1); | ||
176 | #else | ||
177 | while (1) | ||
178 | __asm__(".set\tmips3\n\t" | ||
179 | "wait\n\t" | ||
180 | ".set\tmips0"); | ||
181 | #endif | ||
182 | #endif /* defined(CONFIG_MIPS_PB1550) || defined(CONFIG_MIPS_DB1550) */ | ||
183 | } | ||
184 | |||
185 | void au1000_power_off(void) | ||
186 | { | ||
187 | au1000_halt(); | ||
188 | } | ||
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 6184baa56786..561e5da2658b 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -29,18 +29,13 @@ | |||
29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
30 | #include <linux/jiffies.h> | 30 | #include <linux/jiffies.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/pm.h> | ||
33 | 32 | ||
34 | #include <asm/mipsregs.h> | 33 | #include <asm/mipsregs.h> |
35 | #include <asm/reboot.h> | ||
36 | #include <asm/time.h> | 34 | #include <asm/time.h> |
37 | 35 | ||
38 | #include <au1000.h> | 36 | #include <au1000.h> |
39 | 37 | ||
40 | extern void __init board_setup(void); | 38 | extern void __init board_setup(void); |
41 | extern void au1000_restart(char *); | ||
42 | extern void au1000_halt(void); | ||
43 | extern void au1000_power_off(void); | ||
44 | extern void set_cpuspec(void); | 39 | extern void set_cpuspec(void); |
45 | 40 | ||
46 | void __init plat_mem_setup(void) | 41 | void __init plat_mem_setup(void) |
@@ -57,10 +52,6 @@ void __init plat_mem_setup(void) | |||
57 | /* this is faster than wasting cycles trying to approximate it */ | 52 | /* this is faster than wasting cycles trying to approximate it */ |
58 | preset_lpj = (est_freq >> 1) / HZ; | 53 | preset_lpj = (est_freq >> 1) / HZ; |
59 | 54 | ||
60 | _machine_restart = au1000_restart; | ||
61 | _machine_halt = au1000_halt; | ||
62 | pm_power_off = au1000_power_off; | ||
63 | |||
64 | board_setup(); /* board specific setup */ | 55 | board_setup(); /* board specific setup */ |
65 | 56 | ||
66 | if (au1xxx_cpu_needs_config_od()) | 57 | if (au1xxx_cpu_needs_config_od()) |
@@ -78,37 +69,20 @@ void __init plat_mem_setup(void) | |||
78 | iomem_resource.end = IOMEM_RESOURCE_END; | 69 | iomem_resource.end = IOMEM_RESOURCE_END; |
79 | } | 70 | } |
80 | 71 | ||
81 | #if defined(CONFIG_64BIT_PHYS_ADDR) | 72 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) |
82 | /* This routine should be valid for all Au1x based boards */ | 73 | /* This routine should be valid for all Au1x based boards */ |
83 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 74 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) |
84 | { | 75 | { |
76 | u32 start = (u32)Au1500_PCI_MEM_START; | ||
77 | u32 end = (u32)Au1500_PCI_MEM_END; | ||
78 | |||
85 | /* Don't fixup 36-bit addresses */ | 79 | /* Don't fixup 36-bit addresses */ |
86 | if ((phys_addr >> 32) != 0) | 80 | if ((phys_addr >> 32) != 0) |
87 | return phys_addr; | 81 | return phys_addr; |
88 | 82 | ||
89 | #ifdef CONFIG_PCI | 83 | /* Check for PCI memory window */ |
90 | { | 84 | if (phys_addr >= start && (phys_addr + size - 1) <= end) |
91 | u32 start = (u32)Au1500_PCI_MEM_START; | 85 | return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START); |
92 | u32 end = (u32)Au1500_PCI_MEM_END; | ||
93 | |||
94 | /* Check for PCI memory window */ | ||
95 | if (phys_addr >= start && (phys_addr + size - 1) <= end) | ||
96 | return (phys_t) | ||
97 | ((phys_addr - start) + Au1500_PCI_MEM_START); | ||
98 | } | ||
99 | #endif | ||
100 | |||
101 | /* | ||
102 | * All Au1xx0 SOCs have a PCMCIA controller. | ||
103 | * We setup our 32-bit pseudo addresses to be equal to the | ||
104 | * 36-bit addr >> 4, to make it easier to check the address | ||
105 | * and fix it. | ||
106 | * The PCMCIA socket 0 physical attribute address is 0xF 4000 0000. | ||
107 | * The pseudo address we use is 0xF400 0000. Any address over | ||
108 | * 0xF400 0000 is a PCMCIA pseudo address. | ||
109 | */ | ||
110 | if ((phys_addr >= 0xF4000000) && (phys_addr < 0xFFFFFFFF)) | ||
111 | return (phys_t)(phys_addr << 4); | ||
112 | 86 | ||
113 | /* default nop */ | 87 | /* default nop */ |
114 | return phys_addr; | 88 | return phys_addr; |
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index 379a664809b0..2aecb2fdf982 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net> | 2 | * Copyright (C) 2008-2009 Manuel Lauss <manuel.lauss@gmail.com> |
3 | * | 3 | * |
4 | * Previous incarnations were: | 4 | * Previous incarnations were: |
5 | * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com> | 5 | * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com> |
@@ -85,7 +85,6 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = { | |||
85 | .name = "rtcmatch2", | 85 | .name = "rtcmatch2", |
86 | .features = CLOCK_EVT_FEAT_ONESHOT, | 86 | .features = CLOCK_EVT_FEAT_ONESHOT, |
87 | .rating = 100, | 87 | .rating = 100, |
88 | .irq = AU1000_RTC_MATCH2_INT, | ||
89 | .set_next_event = au1x_rtcmatch2_set_next_event, | 88 | .set_next_event = au1x_rtcmatch2_set_next_event, |
90 | .set_mode = au1x_rtcmatch2_set_mode, | 89 | .set_mode = au1x_rtcmatch2_set_mode, |
91 | .cpumask = cpu_all_mask, | 90 | .cpumask = cpu_all_mask, |
@@ -98,11 +97,13 @@ static struct irqaction au1x_rtcmatch2_irqaction = { | |||
98 | .dev_id = &au1x_rtcmatch2_clockdev, | 97 | .dev_id = &au1x_rtcmatch2_clockdev, |
99 | }; | 98 | }; |
100 | 99 | ||
101 | void __init plat_time_init(void) | 100 | static int __init alchemy_time_init(unsigned int m2int) |
102 | { | 101 | { |
103 | struct clock_event_device *cd = &au1x_rtcmatch2_clockdev; | 102 | struct clock_event_device *cd = &au1x_rtcmatch2_clockdev; |
104 | unsigned long t; | 103 | unsigned long t; |
105 | 104 | ||
105 | au1x_rtcmatch2_clockdev.irq = m2int; | ||
106 | |||
106 | /* Check if firmware (YAMON, ...) has enabled 32kHz and clock | 107 | /* Check if firmware (YAMON, ...) has enabled 32kHz and clock |
107 | * has been detected. If so install the rtcmatch2 clocksource, | 108 | * has been detected. If so install the rtcmatch2 clocksource, |
108 | * otherwise don't bother. Note that both bits being set is by | 109 | * otherwise don't bother. Note that both bits being set is by |
@@ -148,13 +149,18 @@ void __init plat_time_init(void) | |||
148 | cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); | 149 | cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); |
149 | cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */ | 150 | cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */ |
150 | clockevents_register_device(cd); | 151 | clockevents_register_device(cd); |
151 | setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction); | 152 | setup_irq(m2int, &au1x_rtcmatch2_irqaction); |
152 | 153 | ||
153 | printk(KERN_INFO "Alchemy clocksource installed\n"); | 154 | printk(KERN_INFO "Alchemy clocksource installed\n"); |
154 | 155 | ||
155 | return; | 156 | return 0; |
156 | 157 | ||
157 | cntr_err: | 158 | cntr_err: |
159 | return -1; | ||
160 | } | ||
161 | |||
162 | static void __init alchemy_setup_c0timer(void) | ||
163 | { | ||
158 | /* | 164 | /* |
159 | * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this | 165 | * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this |
160 | * function is called. Because the Alchemy counters are unusable | 166 | * function is called. Because the Alchemy counters are unusable |
@@ -166,3 +172,22 @@ cntr_err: | |||
166 | r4k_clockevent_init(); | 172 | r4k_clockevent_init(); |
167 | init_r4k_clocksource(); | 173 | init_r4k_clocksource(); |
168 | } | 174 | } |
175 | |||
176 | static int alchemy_m2inttab[] __initdata = { | ||
177 | AU1000_RTC_MATCH2_INT, | ||
178 | AU1500_RTC_MATCH2_INT, | ||
179 | AU1100_RTC_MATCH2_INT, | ||
180 | AU1550_RTC_MATCH2_INT, | ||
181 | AU1200_RTC_MATCH2_INT, | ||
182 | }; | ||
183 | |||
184 | void __init plat_time_init(void) | ||
185 | { | ||
186 | int t; | ||
187 | |||
188 | t = alchemy_get_cputype(); | ||
189 | if (t == ALCHEMY_CPU_UNKNOWN) | ||
190 | alchemy_setup_c0timer(); | ||
191 | else if (alchemy_time_init(alchemy_m2inttab[t])) | ||
192 | alchemy_setup_c0timer(); | ||
193 | } | ||