diff options
author | Paul Mackerras <paulus@samba.org> | 2005-10-30 21:37:12 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-10-30 21:37:12 -0500 |
commit | 23fd07750a789a66fe88cf173d52a18f1a387da4 (patch) | |
tree | 06fdd6df35fdb835abdaa9b754d62f6b84b97250 /arch/mips/au1000/common | |
parent | bd787d438a59266af3c9f6351644c85ef1dd21fe (diff) | |
parent | ed28f96ac1960f30f818374d65be71d2fdf811b0 (diff) |
Merge ../linux-2.6 by hand
Diffstat (limited to 'arch/mips/au1000/common')
-rw-r--r-- | arch/mips/au1000/common/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/au1000/common/au1xxx_irqmap.c | 32 | ||||
-rw-r--r-- | arch/mips/au1000/common/cputable.c | 3 | ||||
-rw-r--r-- | arch/mips/au1000/common/dbdma.c | 319 | ||||
-rw-r--r-- | arch/mips/au1000/common/dma.c | 1 | ||||
-rw-r--r-- | arch/mips/au1000/common/gpio.c | 119 | ||||
-rw-r--r-- | arch/mips/au1000/common/irq.c | 105 | ||||
-rw-r--r-- | arch/mips/au1000/common/platform.c | 248 | ||||
-rw-r--r-- | arch/mips/au1000/common/power.c | 19 | ||||
-rw-r--r-- | arch/mips/au1000/common/prom.c | 3 | ||||
-rw-r--r-- | arch/mips/au1000/common/puts.c | 77 | ||||
-rw-r--r-- | arch/mips/au1000/common/setup.c | 12 | ||||
-rw-r--r-- | arch/mips/au1000/common/time.c | 26 | ||||
-rw-r--r-- | arch/mips/au1000/common/usbdev.c | 12 |
14 files changed, 714 insertions, 264 deletions
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile index 594b75e5e080..a1edfd1f643c 100644 --- a/arch/mips/au1000/common/Makefile +++ b/arch/mips/au1000/common/Makefile | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \ | 9 | obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \ |
10 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ | 10 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ |
11 | sleeper.o cputable.o dma.o dbdma.o | 11 | sleeper.o cputable.o dma.o dbdma.o gpio.o |
12 | 12 | ||
13 | obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o | 13 | obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o |
14 | obj-$(CONFIG_KGDB) += dbg_io.o | 14 | obj-$(CONFIG_KGDB) += dbg_io.o |
diff --git a/arch/mips/au1000/common/au1xxx_irqmap.c b/arch/mips/au1000/common/au1xxx_irqmap.c index 8a0f39f67c59..0b2c03c52319 100644 --- a/arch/mips/au1000/common/au1xxx_irqmap.c +++ b/arch/mips/au1000/common/au1xxx_irqmap.c | |||
@@ -173,14 +173,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = { | |||
173 | { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, | 173 | { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, |
174 | { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0}, | 174 | { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0}, |
175 | { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0}, | 175 | { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0}, |
176 | { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | 176 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, |
177 | { AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | 177 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, |
178 | { AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | 178 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, |
179 | { AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | 179 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, |
180 | { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | 180 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, |
181 | { AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | 181 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, |
182 | { AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | 182 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, |
183 | { AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | 183 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, |
184 | { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0}, | 184 | { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0}, |
185 | { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, | 185 | { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, |
186 | { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, | 186 | { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, |
@@ -201,14 +201,14 @@ au1xxx_irq_map_t au1xxx_ic0_map[] = { | |||
201 | { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, | 201 | { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0}, |
202 | { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0}, | 202 | { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0}, |
203 | { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0}, | 203 | { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0}, |
204 | { AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | 204 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, |
205 | { AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | 205 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, |
206 | { AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | 206 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, |
207 | { AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | 207 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, |
208 | { AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | 208 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, |
209 | { AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | 209 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, |
210 | { AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | 210 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, |
211 | { AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | 211 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, |
212 | { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0}, | 212 | { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0}, |
213 | { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 }, | 213 | { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 }, |
214 | { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, | 214 | { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, |
diff --git a/arch/mips/au1000/common/cputable.c b/arch/mips/au1000/common/cputable.c index f5521dfccfd6..4dbde82c8215 100644 --- a/arch/mips/au1000/common/cputable.c +++ b/arch/mips/au1000/common/cputable.c | |||
@@ -37,7 +37,8 @@ struct cpu_spec cpu_specs[] = { | |||
37 | { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 }, | 37 | { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 }, |
38 | { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 }, | 38 | { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 }, |
39 | { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 }, | 39 | { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 }, |
40 | { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 }, | 40 | { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 }, |
41 | { 0xffffffff, 0x04030201, "Au1200 AC", 0, 1 }, | ||
41 | { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 }, | 42 | { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 }, |
42 | }; | 43 | }; |
43 | 44 | ||
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index adfc3172aace..d00e8247d6c2 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c | |||
@@ -29,6 +29,7 @@ | |||
29 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 29 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
30 | * | 30 | * |
31 | */ | 31 | */ |
32 | |||
32 | #include <linux/config.h> | 33 | #include <linux/config.h> |
33 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
34 | #include <linux/errno.h> | 35 | #include <linux/errno.h> |
@@ -38,10 +39,12 @@ | |||
38 | #include <linux/string.h> | 39 | #include <linux/string.h> |
39 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
40 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/module.h> | ||
41 | #include <asm/mach-au1x00/au1000.h> | 43 | #include <asm/mach-au1x00/au1000.h> |
42 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 44 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
43 | #include <asm/system.h> | 45 | #include <asm/system.h> |
44 | 46 | ||
47 | |||
45 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | 48 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) |
46 | 49 | ||
47 | /* | 50 | /* |
@@ -61,37 +64,10 @@ static DEFINE_SPINLOCK(au1xxx_dbdma_spin_lock); | |||
61 | */ | 64 | */ |
62 | #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) | 65 | #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1)) |
63 | 66 | ||
64 | static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; | 67 | static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE; |
65 | static int dbdma_initialized; | 68 | static int dbdma_initialized=0; |
66 | static void au1xxx_dbdma_init(void); | 69 | static void au1xxx_dbdma_init(void); |
67 | 70 | ||
68 | typedef struct dbdma_device_table { | ||
69 | u32 dev_id; | ||
70 | u32 dev_flags; | ||
71 | u32 dev_tsize; | ||
72 | u32 dev_devwidth; | ||
73 | u32 dev_physaddr; /* If FIFO */ | ||
74 | u32 dev_intlevel; | ||
75 | u32 dev_intpolarity; | ||
76 | } dbdev_tab_t; | ||
77 | |||
78 | typedef struct dbdma_chan_config { | ||
79 | u32 chan_flags; | ||
80 | u32 chan_index; | ||
81 | dbdev_tab_t *chan_src; | ||
82 | dbdev_tab_t *chan_dest; | ||
83 | au1x_dma_chan_t *chan_ptr; | ||
84 | au1x_ddma_desc_t *chan_desc_base; | ||
85 | au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr; | ||
86 | void *chan_callparam; | ||
87 | void (*chan_callback)(int, void *, struct pt_regs *); | ||
88 | } chan_tab_t; | ||
89 | |||
90 | #define DEV_FLAGS_INUSE (1 << 0) | ||
91 | #define DEV_FLAGS_ANYUSE (1 << 1) | ||
92 | #define DEV_FLAGS_OUT (1 << 2) | ||
93 | #define DEV_FLAGS_IN (1 << 3) | ||
94 | |||
95 | static dbdev_tab_t dbdev_tab[] = { | 71 | static dbdev_tab_t dbdev_tab[] = { |
96 | #ifdef CONFIG_SOC_AU1550 | 72 | #ifdef CONFIG_SOC_AU1550 |
97 | /* UARTS */ | 73 | /* UARTS */ |
@@ -157,25 +133,25 @@ static dbdev_tab_t dbdev_tab[] = { | |||
157 | { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 133 | { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
158 | { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 134 | { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
159 | 135 | ||
160 | { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | 136 | { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, |
161 | { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 137 | { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, |
162 | { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | 138 | { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, |
163 | { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 139 | { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, |
164 | 140 | ||
165 | { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | 141 | { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, |
166 | { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 142 | { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, |
167 | 143 | ||
168 | { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, | 144 | { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, |
169 | { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, | 145 | { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, |
170 | { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 146 | { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
171 | 147 | ||
172 | { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, | 148 | { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 }, |
173 | { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, | 149 | { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 }, |
174 | { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 150 | { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
175 | 151 | ||
176 | { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 152 | { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, |
177 | { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 153 | { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, |
178 | { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 154 | { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, |
179 | { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 155 | { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
180 | 156 | ||
181 | { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 157 | { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
@@ -184,6 +160,24 @@ static dbdev_tab_t dbdev_tab[] = { | |||
184 | 160 | ||
185 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 161 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
186 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 162 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
163 | |||
164 | /* Provide 16 user definable device types */ | ||
165 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
166 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
167 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
168 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
169 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
170 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
171 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
172 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
173 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
174 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
175 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
176 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
177 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
178 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
179 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
180 | { 0, 0, 0, 0, 0, 0, 0 }, | ||
187 | }; | 181 | }; |
188 | 182 | ||
189 | #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t)) | 183 | #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t)) |
@@ -203,6 +197,36 @@ find_dbdev_id (u32 id) | |||
203 | return NULL; | 197 | return NULL; |
204 | } | 198 | } |
205 | 199 | ||
200 | void * au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp) | ||
201 | { | ||
202 | return phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); | ||
203 | } | ||
204 | EXPORT_SYMBOL(au1xxx_ddma_get_nextptr_virt); | ||
205 | |||
206 | u32 | ||
207 | au1xxx_ddma_add_device(dbdev_tab_t *dev) | ||
208 | { | ||
209 | u32 ret = 0; | ||
210 | dbdev_tab_t *p=NULL; | ||
211 | static u16 new_id=0x1000; | ||
212 | |||
213 | p = find_dbdev_id(0); | ||
214 | if ( NULL != p ) | ||
215 | { | ||
216 | memcpy(p, dev, sizeof(dbdev_tab_t)); | ||
217 | p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id); | ||
218 | ret = p->dev_id; | ||
219 | new_id++; | ||
220 | #if 0 | ||
221 | printk("add_device: id:%x flags:%x padd:%x\n", | ||
222 | p->dev_id, p->dev_flags, p->dev_physaddr ); | ||
223 | #endif | ||
224 | } | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | EXPORT_SYMBOL(au1xxx_ddma_add_device); | ||
229 | |||
206 | /* Allocate a channel and return a non-zero descriptor if successful. | 230 | /* Allocate a channel and return a non-zero descriptor if successful. |
207 | */ | 231 | */ |
208 | u32 | 232 | u32 |
@@ -215,7 +239,7 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
215 | int i; | 239 | int i; |
216 | dbdev_tab_t *stp, *dtp; | 240 | dbdev_tab_t *stp, *dtp; |
217 | chan_tab_t *ctp; | 241 | chan_tab_t *ctp; |
218 | volatile au1x_dma_chan_t *cp; | 242 | au1x_dma_chan_t *cp; |
219 | 243 | ||
220 | /* We do the intialization on the first channel allocation. | 244 | /* We do the intialization on the first channel allocation. |
221 | * We have to wait because of the interrupt handler initialization | 245 | * We have to wait because of the interrupt handler initialization |
@@ -225,9 +249,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
225 | au1xxx_dbdma_init(); | 249 | au1xxx_dbdma_init(); |
226 | dbdma_initialized = 1; | 250 | dbdma_initialized = 1; |
227 | 251 | ||
228 | if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS)) | ||
229 | return 0; | ||
230 | |||
231 | if ((stp = find_dbdev_id(srcid)) == NULL) return 0; | 252 | if ((stp = find_dbdev_id(srcid)) == NULL) return 0; |
232 | if ((dtp = find_dbdev_id(destid)) == NULL) return 0; | 253 | if ((dtp = find_dbdev_id(destid)) == NULL) return 0; |
233 | 254 | ||
@@ -271,7 +292,6 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
271 | */ | 292 | */ |
272 | ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL); | 293 | ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL); |
273 | chan_tab_ptr[i] = ctp; | 294 | chan_tab_ptr[i] = ctp; |
274 | ctp->chan_index = chan = i; | ||
275 | break; | 295 | break; |
276 | } | 296 | } |
277 | } | 297 | } |
@@ -279,10 +299,11 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
279 | 299 | ||
280 | if (ctp != NULL) { | 300 | if (ctp != NULL) { |
281 | memset(ctp, 0, sizeof(chan_tab_t)); | 301 | memset(ctp, 0, sizeof(chan_tab_t)); |
302 | ctp->chan_index = chan = i; | ||
282 | dcp = DDMA_CHANNEL_BASE; | 303 | dcp = DDMA_CHANNEL_BASE; |
283 | dcp += (0x0100 * chan); | 304 | dcp += (0x0100 * chan); |
284 | ctp->chan_ptr = (au1x_dma_chan_t *)dcp; | 305 | ctp->chan_ptr = (au1x_dma_chan_t *)dcp; |
285 | cp = (volatile au1x_dma_chan_t *)dcp; | 306 | cp = (au1x_dma_chan_t *)dcp; |
286 | ctp->chan_src = stp; | 307 | ctp->chan_src = stp; |
287 | ctp->chan_dest = dtp; | 308 | ctp->chan_dest = dtp; |
288 | ctp->chan_callback = callback; | 309 | ctp->chan_callback = callback; |
@@ -299,6 +320,9 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
299 | i |= DDMA_CFG_DED; | 320 | i |= DDMA_CFG_DED; |
300 | if (dtp->dev_intpolarity) | 321 | if (dtp->dev_intpolarity) |
301 | i |= DDMA_CFG_DP; | 322 | i |= DDMA_CFG_DP; |
323 | if ((stp->dev_flags & DEV_FLAGS_SYNC) || | ||
324 | (dtp->dev_flags & DEV_FLAGS_SYNC)) | ||
325 | i |= DDMA_CFG_SYNC; | ||
302 | cp->ddma_cfg = i; | 326 | cp->ddma_cfg = i; |
303 | au_sync(); | 327 | au_sync(); |
304 | 328 | ||
@@ -309,14 +333,14 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
309 | rv = (u32)(&chan_tab_ptr[chan]); | 333 | rv = (u32)(&chan_tab_ptr[chan]); |
310 | } | 334 | } |
311 | else { | 335 | else { |
312 | /* Release devices. | 336 | /* Release devices */ |
313 | */ | ||
314 | stp->dev_flags &= ~DEV_FLAGS_INUSE; | 337 | stp->dev_flags &= ~DEV_FLAGS_INUSE; |
315 | dtp->dev_flags &= ~DEV_FLAGS_INUSE; | 338 | dtp->dev_flags &= ~DEV_FLAGS_INUSE; |
316 | } | 339 | } |
317 | } | 340 | } |
318 | return rv; | 341 | return rv; |
319 | } | 342 | } |
343 | EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc); | ||
320 | 344 | ||
321 | /* Set the device width if source or destination is a FIFO. | 345 | /* Set the device width if source or destination is a FIFO. |
322 | * Should be 8, 16, or 32 bits. | 346 | * Should be 8, 16, or 32 bits. |
@@ -344,6 +368,7 @@ au1xxx_dbdma_set_devwidth(u32 chanid, int bits) | |||
344 | 368 | ||
345 | return rv; | 369 | return rv; |
346 | } | 370 | } |
371 | EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth); | ||
347 | 372 | ||
348 | /* Allocate a descriptor ring, initializing as much as possible. | 373 | /* Allocate a descriptor ring, initializing as much as possible. |
349 | */ | 374 | */ |
@@ -370,7 +395,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
370 | * and if we try that first we are likely to not waste larger | 395 | * and if we try that first we are likely to not waste larger |
371 | * slabs of memory. | 396 | * slabs of memory. |
372 | */ | 397 | */ |
373 | desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL); | 398 | desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), |
399 | GFP_KERNEL|GFP_DMA); | ||
374 | if (desc_base == 0) | 400 | if (desc_base == 0) |
375 | return 0; | 401 | return 0; |
376 | 402 | ||
@@ -381,7 +407,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
381 | kfree((const void *)desc_base); | 407 | kfree((const void *)desc_base); |
382 | i = entries * sizeof(au1x_ddma_desc_t); | 408 | i = entries * sizeof(au1x_ddma_desc_t); |
383 | i += (sizeof(au1x_ddma_desc_t) - 1); | 409 | i += (sizeof(au1x_ddma_desc_t) - 1); |
384 | if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0) | 410 | if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0) |
385 | return 0; | 411 | return 0; |
386 | 412 | ||
387 | desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t)); | 413 | desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t)); |
@@ -403,7 +429,13 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
403 | cmd0 |= DSCR_CMD0_SID(srcid); | 429 | cmd0 |= DSCR_CMD0_SID(srcid); |
404 | cmd0 |= DSCR_CMD0_DID(destid); | 430 | cmd0 |= DSCR_CMD0_DID(destid); |
405 | cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV; | 431 | cmd0 |= DSCR_CMD0_IE | DSCR_CMD0_CV; |
406 | cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_CURRENT); | 432 | cmd0 |= DSCR_CMD0_ST(DSCR_CMD0_ST_NOCHANGE); |
433 | |||
434 | /* is it mem to mem transfer? */ | ||
435 | if(((DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(srcid) == DSCR_CMD0_ALWAYS)) && | ||
436 | ((DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_THROTTLE) || (DSCR_CUSTOM2DEV_ID(destid) == DSCR_CMD0_ALWAYS))) { | ||
437 | cmd0 |= DSCR_CMD0_MEM; | ||
438 | } | ||
407 | 439 | ||
408 | switch (stp->dev_devwidth) { | 440 | switch (stp->dev_devwidth) { |
409 | case 8: | 441 | case 8: |
@@ -461,9 +493,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
461 | /* If source input is fifo, set static address. | 493 | /* If source input is fifo, set static address. |
462 | */ | 494 | */ |
463 | if (stp->dev_flags & DEV_FLAGS_IN) { | 495 | if (stp->dev_flags & DEV_FLAGS_IN) { |
464 | src0 = stp->dev_physaddr; | 496 | if ( stp->dev_flags & DEV_FLAGS_BURSTABLE ) |
497 | src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST); | ||
498 | else | ||
465 | src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); | 499 | src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC); |
500 | |||
466 | } | 501 | } |
502 | if (stp->dev_physaddr) | ||
503 | src0 = stp->dev_physaddr; | ||
467 | 504 | ||
468 | /* Set up dest1. For now, assume no stride and increment. | 505 | /* Set up dest1. For now, assume no stride and increment. |
469 | * A channel attribute update can change this later. | 506 | * A channel attribute update can change this later. |
@@ -487,10 +524,18 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
487 | /* If destination output is fifo, set static address. | 524 | /* If destination output is fifo, set static address. |
488 | */ | 525 | */ |
489 | if (dtp->dev_flags & DEV_FLAGS_OUT) { | 526 | if (dtp->dev_flags & DEV_FLAGS_OUT) { |
490 | dest0 = dtp->dev_physaddr; | 527 | if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE ) |
528 | dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST); | ||
529 | else | ||
491 | dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC); | 530 | dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC); |
492 | } | 531 | } |
532 | if (dtp->dev_physaddr) | ||
533 | dest0 = dtp->dev_physaddr; | ||
493 | 534 | ||
535 | #if 0 | ||
536 | printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", | ||
537 | dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 ); | ||
538 | #endif | ||
494 | for (i=0; i<entries; i++) { | 539 | for (i=0; i<entries; i++) { |
495 | dp->dscr_cmd0 = cmd0; | 540 | dp->dscr_cmd0 = cmd0; |
496 | dp->dscr_cmd1 = cmd1; | 541 | dp->dscr_cmd1 = cmd1; |
@@ -499,6 +544,8 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
499 | dp->dscr_dest0 = dest0; | 544 | dp->dscr_dest0 = dest0; |
500 | dp->dscr_dest1 = dest1; | 545 | dp->dscr_dest1 = dest1; |
501 | dp->dscr_stat = 0; | 546 | dp->dscr_stat = 0; |
547 | dp->sw_context = 0; | ||
548 | dp->sw_status = 0; | ||
502 | dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1)); | 549 | dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1)); |
503 | dp++; | 550 | dp++; |
504 | } | 551 | } |
@@ -511,13 +558,14 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int entries) | |||
511 | 558 | ||
512 | return (u32)(ctp->chan_desc_base); | 559 | return (u32)(ctp->chan_desc_base); |
513 | } | 560 | } |
561 | EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc); | ||
514 | 562 | ||
515 | /* Put a source buffer into the DMA ring. | 563 | /* Put a source buffer into the DMA ring. |
516 | * This updates the source pointer and byte count. Normally used | 564 | * This updates the source pointer and byte count. Normally used |
517 | * for memory to fifo transfers. | 565 | * for memory to fifo transfers. |
518 | */ | 566 | */ |
519 | u32 | 567 | u32 |
520 | au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes) | 568 | _au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags) |
521 | { | 569 | { |
522 | chan_tab_t *ctp; | 570 | chan_tab_t *ctp; |
523 | au1x_ddma_desc_t *dp; | 571 | au1x_ddma_desc_t *dp; |
@@ -544,8 +592,24 @@ au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes) | |||
544 | */ | 592 | */ |
545 | dp->dscr_source0 = virt_to_phys(buf); | 593 | dp->dscr_source0 = virt_to_phys(buf); |
546 | dp->dscr_cmd1 = nbytes; | 594 | dp->dscr_cmd1 = nbytes; |
547 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ | 595 | /* Check flags */ |
548 | ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */ | 596 | if (flags & DDMA_FLAGS_IE) |
597 | dp->dscr_cmd0 |= DSCR_CMD0_IE; | ||
598 | if (flags & DDMA_FLAGS_NOIE) | ||
599 | dp->dscr_cmd0 &= ~DSCR_CMD0_IE; | ||
600 | |||
601 | /* | ||
602 | * There is an errata on the Au1200/Au1550 parts that could result | ||
603 | * in "stale" data being DMA'd. It has to do with the snoop logic on | ||
604 | * the dache eviction buffer. NONCOHERENT_IO is on by default for | ||
605 | * these parts. If it is fixedin the future, these dma_cache_inv will | ||
606 | * just be nothing more than empty macros. See io.h. | ||
607 | * */ | ||
608 | dma_cache_wback_inv((unsigned long)buf, nbytes); | ||
609 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ | ||
610 | au_sync(); | ||
611 | dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); | ||
612 | ctp->chan_ptr->ddma_dbell = 0; | ||
549 | 613 | ||
550 | /* Get next descriptor pointer. | 614 | /* Get next descriptor pointer. |
551 | */ | 615 | */ |
@@ -555,13 +619,14 @@ au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes) | |||
555 | */ | 619 | */ |
556 | return nbytes; | 620 | return nbytes; |
557 | } | 621 | } |
622 | EXPORT_SYMBOL(_au1xxx_dbdma_put_source); | ||
558 | 623 | ||
559 | /* Put a destination buffer into the DMA ring. | 624 | /* Put a destination buffer into the DMA ring. |
560 | * This updates the destination pointer and byte count. Normally used | 625 | * This updates the destination pointer and byte count. Normally used |
561 | * to place an empty buffer into the ring for fifo to memory transfers. | 626 | * to place an empty buffer into the ring for fifo to memory transfers. |
562 | */ | 627 | */ |
563 | u32 | 628 | u32 |
564 | au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes) | 629 | _au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags) |
565 | { | 630 | { |
566 | chan_tab_t *ctp; | 631 | chan_tab_t *ctp; |
567 | au1x_ddma_desc_t *dp; | 632 | au1x_ddma_desc_t *dp; |
@@ -583,11 +648,33 @@ au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes) | |||
583 | if (dp->dscr_cmd0 & DSCR_CMD0_V) | 648 | if (dp->dscr_cmd0 & DSCR_CMD0_V) |
584 | return 0; | 649 | return 0; |
585 | 650 | ||
586 | /* Load up buffer address and byte count. | 651 | /* Load up buffer address and byte count */ |
587 | */ | 652 | |
653 | /* Check flags */ | ||
654 | if (flags & DDMA_FLAGS_IE) | ||
655 | dp->dscr_cmd0 |= DSCR_CMD0_IE; | ||
656 | if (flags & DDMA_FLAGS_NOIE) | ||
657 | dp->dscr_cmd0 &= ~DSCR_CMD0_IE; | ||
658 | |||
588 | dp->dscr_dest0 = virt_to_phys(buf); | 659 | dp->dscr_dest0 = virt_to_phys(buf); |
589 | dp->dscr_cmd1 = nbytes; | 660 | dp->dscr_cmd1 = nbytes; |
661 | #if 0 | ||
662 | printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n", | ||
663 | dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0, | ||
664 | dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 ); | ||
665 | #endif | ||
666 | /* | ||
667 | * There is an errata on the Au1200/Au1550 parts that could result in | ||
668 | * "stale" data being DMA'd. It has to do with the snoop logic on the | ||
669 | * dache eviction buffer. NONCOHERENT_IO is on by default for these | ||
670 | * parts. If it is fixedin the future, these dma_cache_inv will just | ||
671 | * be nothing more than empty macros. See io.h. | ||
672 | * */ | ||
673 | dma_cache_inv((unsigned long)buf,nbytes); | ||
590 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ | 674 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ |
675 | au_sync(); | ||
676 | dma_cache_wback_inv((unsigned long)dp, sizeof(dp)); | ||
677 | ctp->chan_ptr->ddma_dbell = 0; | ||
591 | 678 | ||
592 | /* Get next descriptor pointer. | 679 | /* Get next descriptor pointer. |
593 | */ | 680 | */ |
@@ -597,6 +684,7 @@ au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes) | |||
597 | */ | 684 | */ |
598 | return nbytes; | 685 | return nbytes; |
599 | } | 686 | } |
687 | EXPORT_SYMBOL(_au1xxx_dbdma_put_dest); | ||
600 | 688 | ||
601 | /* Get a destination buffer into the DMA ring. | 689 | /* Get a destination buffer into the DMA ring. |
602 | * Normally used to get a full buffer from the ring during fifo | 690 | * Normally used to get a full buffer from the ring during fifo |
@@ -646,7 +734,7 @@ void | |||
646 | au1xxx_dbdma_stop(u32 chanid) | 734 | au1xxx_dbdma_stop(u32 chanid) |
647 | { | 735 | { |
648 | chan_tab_t *ctp; | 736 | chan_tab_t *ctp; |
649 | volatile au1x_dma_chan_t *cp; | 737 | au1x_dma_chan_t *cp; |
650 | int halt_timeout = 0; | 738 | int halt_timeout = 0; |
651 | 739 | ||
652 | ctp = *((chan_tab_t **)chanid); | 740 | ctp = *((chan_tab_t **)chanid); |
@@ -666,6 +754,7 @@ au1xxx_dbdma_stop(u32 chanid) | |||
666 | cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); | 754 | cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); |
667 | au_sync(); | 755 | au_sync(); |
668 | } | 756 | } |
757 | EXPORT_SYMBOL(au1xxx_dbdma_stop); | ||
669 | 758 | ||
670 | /* Start using the current descriptor pointer. If the dbdma encounters | 759 | /* Start using the current descriptor pointer. If the dbdma encounters |
671 | * a not valid descriptor, it will stop. In this case, we can just | 760 | * a not valid descriptor, it will stop. In this case, we can just |
@@ -675,17 +764,17 @@ void | |||
675 | au1xxx_dbdma_start(u32 chanid) | 764 | au1xxx_dbdma_start(u32 chanid) |
676 | { | 765 | { |
677 | chan_tab_t *ctp; | 766 | chan_tab_t *ctp; |
678 | volatile au1x_dma_chan_t *cp; | 767 | au1x_dma_chan_t *cp; |
679 | 768 | ||
680 | ctp = *((chan_tab_t **)chanid); | 769 | ctp = *((chan_tab_t **)chanid); |
681 | |||
682 | cp = ctp->chan_ptr; | 770 | cp = ctp->chan_ptr; |
683 | cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); | 771 | cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); |
684 | cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ | 772 | cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ |
685 | au_sync(); | 773 | au_sync(); |
686 | cp->ddma_dbell = 0xffffffff; /* Make it go */ | 774 | cp->ddma_dbell = 0; |
687 | au_sync(); | 775 | au_sync(); |
688 | } | 776 | } |
777 | EXPORT_SYMBOL(au1xxx_dbdma_start); | ||
689 | 778 | ||
690 | void | 779 | void |
691 | au1xxx_dbdma_reset(u32 chanid) | 780 | au1xxx_dbdma_reset(u32 chanid) |
@@ -704,15 +793,21 @@ au1xxx_dbdma_reset(u32 chanid) | |||
704 | 793 | ||
705 | do { | 794 | do { |
706 | dp->dscr_cmd0 &= ~DSCR_CMD0_V; | 795 | dp->dscr_cmd0 &= ~DSCR_CMD0_V; |
796 | /* reset our SW status -- this is used to determine | ||
797 | * if a descriptor is in use by upper level SW. Since | ||
798 | * posting can reset 'V' bit. | ||
799 | */ | ||
800 | dp->sw_status = 0; | ||
707 | dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); | 801 | dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); |
708 | } while (dp != ctp->chan_desc_base); | 802 | } while (dp != ctp->chan_desc_base); |
709 | } | 803 | } |
804 | EXPORT_SYMBOL(au1xxx_dbdma_reset); | ||
710 | 805 | ||
711 | u32 | 806 | u32 |
712 | au1xxx_get_dma_residue(u32 chanid) | 807 | au1xxx_get_dma_residue(u32 chanid) |
713 | { | 808 | { |
714 | chan_tab_t *ctp; | 809 | chan_tab_t *ctp; |
715 | volatile au1x_dma_chan_t *cp; | 810 | au1x_dma_chan_t *cp; |
716 | u32 rv; | 811 | u32 rv; |
717 | 812 | ||
718 | ctp = *((chan_tab_t **)chanid); | 813 | ctp = *((chan_tab_t **)chanid); |
@@ -738,8 +833,7 @@ au1xxx_dbdma_chan_free(u32 chanid) | |||
738 | 833 | ||
739 | au1xxx_dbdma_stop(chanid); | 834 | au1xxx_dbdma_stop(chanid); |
740 | 835 | ||
741 | if (ctp->chan_desc_base != NULL) | 836 | kfree((void *)ctp->chan_desc_base); |
742 | kfree(ctp->chan_desc_base); | ||
743 | 837 | ||
744 | stp->dev_flags &= ~DEV_FLAGS_INUSE; | 838 | stp->dev_flags &= ~DEV_FLAGS_INUSE; |
745 | dtp->dev_flags &= ~DEV_FLAGS_INUSE; | 839 | dtp->dev_flags &= ~DEV_FLAGS_INUSE; |
@@ -747,15 +841,16 @@ au1xxx_dbdma_chan_free(u32 chanid) | |||
747 | 841 | ||
748 | kfree(ctp); | 842 | kfree(ctp); |
749 | } | 843 | } |
844 | EXPORT_SYMBOL(au1xxx_dbdma_chan_free); | ||
750 | 845 | ||
751 | static irqreturn_t | 846 | static irqreturn_t |
752 | dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 847 | dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
753 | { | 848 | { |
754 | u32 intstat; | 849 | u32 intstat; |
755 | u32 chan_index; | 850 | u32 chan_index; |
756 | chan_tab_t *ctp; | 851 | chan_tab_t *ctp; |
757 | au1x_ddma_desc_t *dp; | 852 | au1x_ddma_desc_t *dp; |
758 | volatile au1x_dma_chan_t *cp; | 853 | au1x_dma_chan_t *cp; |
759 | 854 | ||
760 | intstat = dbdma_gptr->ddma_intstat; | 855 | intstat = dbdma_gptr->ddma_intstat; |
761 | au_sync(); | 856 | au_sync(); |
@@ -774,19 +869,27 @@ dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
774 | (ctp->chan_callback)(irq, ctp->chan_callparam, regs); | 869 | (ctp->chan_callback)(irq, ctp->chan_callparam, regs); |
775 | 870 | ||
776 | ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); | 871 | ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); |
777 | 872 | return IRQ_RETVAL(1); | |
778 | return IRQ_HANDLED; | ||
779 | } | 873 | } |
780 | 874 | ||
781 | static void | 875 | static void au1xxx_dbdma_init(void) |
782 | au1xxx_dbdma_init(void) | ||
783 | { | 876 | { |
877 | int irq_nr; | ||
878 | |||
784 | dbdma_gptr->ddma_config = 0; | 879 | dbdma_gptr->ddma_config = 0; |
785 | dbdma_gptr->ddma_throttle = 0; | 880 | dbdma_gptr->ddma_throttle = 0; |
786 | dbdma_gptr->ddma_inten = 0xffff; | 881 | dbdma_gptr->ddma_inten = 0xffff; |
787 | au_sync(); | 882 | au_sync(); |
788 | 883 | ||
789 | if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT, | 884 | #if defined(CONFIG_SOC_AU1550) |
885 | irq_nr = AU1550_DDMA_INT; | ||
886 | #elif defined(CONFIG_SOC_AU1200) | ||
887 | irq_nr = AU1200_DDMA_INT; | ||
888 | #else | ||
889 | #error Unknown Au1x00 SOC | ||
890 | #endif | ||
891 | |||
892 | if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT, | ||
790 | "Au1xxx dbdma", (void *)dbdma_gptr)) | 893 | "Au1xxx dbdma", (void *)dbdma_gptr)) |
791 | printk("Can't get 1550 dbdma irq"); | 894 | printk("Can't get 1550 dbdma irq"); |
792 | } | 895 | } |
@@ -797,7 +900,8 @@ au1xxx_dbdma_dump(u32 chanid) | |||
797 | chan_tab_t *ctp; | 900 | chan_tab_t *ctp; |
798 | au1x_ddma_desc_t *dp; | 901 | au1x_ddma_desc_t *dp; |
799 | dbdev_tab_t *stp, *dtp; | 902 | dbdev_tab_t *stp, *dtp; |
800 | volatile au1x_dma_chan_t *cp; | 903 | au1x_dma_chan_t *cp; |
904 | u32 i = 0; | ||
801 | 905 | ||
802 | ctp = *((chan_tab_t **)chanid); | 906 | ctp = *((chan_tab_t **)chanid); |
803 | stp = ctp->chan_src; | 907 | stp = ctp->chan_src; |
@@ -822,15 +926,64 @@ au1xxx_dbdma_dump(u32 chanid) | |||
822 | dp = ctp->chan_desc_base; | 926 | dp = ctp->chan_desc_base; |
823 | 927 | ||
824 | do { | 928 | do { |
825 | printk("dp %08x, cmd0 %08x, cmd1 %08x\n", | 929 | printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n", |
826 | (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); | 930 | i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1); |
827 | printk("src0 %08x, src1 %08x, dest0 %08x\n", | 931 | printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n", |
828 | dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0); | 932 | dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1); |
829 | printk("dest1 %08x, stat %08x, nxtptr %08x\n", | 933 | printk("stat %08x, nxtptr %08x\n", |
830 | dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr); | 934 | dp->dscr_stat, dp->dscr_nxtptr); |
831 | dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); | 935 | dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); |
832 | } while (dp != ctp->chan_desc_base); | 936 | } while (dp != ctp->chan_desc_base); |
833 | } | 937 | } |
834 | 938 | ||
939 | /* Put a descriptor into the DMA ring. | ||
940 | * This updates the source/destination pointers and byte count. | ||
941 | */ | ||
942 | u32 | ||
943 | au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr ) | ||
944 | { | ||
945 | chan_tab_t *ctp; | ||
946 | au1x_ddma_desc_t *dp; | ||
947 | u32 nbytes=0; | ||
948 | |||
949 | /* I guess we could check this to be within the | ||
950 | * range of the table...... | ||
951 | */ | ||
952 | ctp = *((chan_tab_t **)chanid); | ||
953 | |||
954 | /* We should have multiple callers for a particular channel, | ||
955 | * an interrupt doesn't affect this pointer nor the descriptor, | ||
956 | * so no locking should be needed. | ||
957 | */ | ||
958 | dp = ctp->put_ptr; | ||
959 | |||
960 | /* If the descriptor is valid, we are way ahead of the DMA | ||
961 | * engine, so just return an error condition. | ||
962 | */ | ||
963 | if (dp->dscr_cmd0 & DSCR_CMD0_V) | ||
964 | return 0; | ||
965 | |||
966 | /* Load up buffer addresses and byte count. | ||
967 | */ | ||
968 | dp->dscr_dest0 = dscr->dscr_dest0; | ||
969 | dp->dscr_source0 = dscr->dscr_source0; | ||
970 | dp->dscr_dest1 = dscr->dscr_dest1; | ||
971 | dp->dscr_source1 = dscr->dscr_source1; | ||
972 | dp->dscr_cmd1 = dscr->dscr_cmd1; | ||
973 | nbytes = dscr->dscr_cmd1; | ||
974 | /* Allow the caller to specifiy if an interrupt is generated */ | ||
975 | dp->dscr_cmd0 &= ~DSCR_CMD0_IE; | ||
976 | dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V; | ||
977 | ctp->chan_ptr->ddma_dbell = 0; | ||
978 | |||
979 | /* Get next descriptor pointer. | ||
980 | */ | ||
981 | ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); | ||
982 | |||
983 | /* return something not zero. | ||
984 | */ | ||
985 | return nbytes; | ||
986 | } | ||
987 | |||
835 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ | 988 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ |
836 | 989 | ||
diff --git a/arch/mips/au1000/common/dma.c b/arch/mips/au1000/common/dma.c index 372c33f1353d..1905c6b104f2 100644 --- a/arch/mips/au1000/common/dma.c +++ b/arch/mips/au1000/common/dma.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/module.h> | ||
43 | #include <asm/system.h> | 42 | #include <asm/system.h> |
44 | #include <asm/mach-au1x00/au1000.h> | 43 | #include <asm/mach-au1x00/au1000.h> |
45 | #include <asm/mach-au1x00/au1000_dma.h> | 44 | #include <asm/mach-au1x00/au1000_dma.h> |
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c new file mode 100644 index 000000000000..5f5915b83142 --- /dev/null +++ b/arch/mips/au1000/common/gpio.c | |||
@@ -0,0 +1,119 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License as published by the | ||
4 | * Free Software Foundation; either version 2 of the License, or (at your | ||
5 | * option) any later version. | ||
6 | * | ||
7 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
8 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
9 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
10 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
11 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
12 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
13 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
14 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
15 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
16 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | #include <linux/config.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <au1000.h> | ||
25 | #include <au1xxx_gpio.h> | ||
26 | |||
27 | #define gpio1 sys | ||
28 | #if !defined(CONFIG_SOC_AU1000) | ||
29 | static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE; | ||
30 | |||
31 | #define GPIO2_OUTPUT_ENABLE_MASK 0x00010000 | ||
32 | |||
33 | int au1xxx_gpio2_read(int signal) | ||
34 | { | ||
35 | signal -= 200; | ||
36 | /* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */ | ||
37 | return ((gpio2->pinstate >> signal) & 0x01); | ||
38 | } | ||
39 | |||
40 | void au1xxx_gpio2_write(int signal, int value) | ||
41 | { | ||
42 | signal -= 200; | ||
43 | |||
44 | gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) | | ||
45 | (value << signal); | ||
46 | } | ||
47 | |||
48 | void au1xxx_gpio2_tristate(int signal) | ||
49 | { | ||
50 | signal -= 200; | ||
51 | gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */ | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | int au1xxx_gpio1_read(int signal) | ||
56 | { | ||
57 | /* gpio1->trioutclr |= (0x01 << signal); */ | ||
58 | return ((gpio1->pinstaterd >> signal) & 0x01); | ||
59 | } | ||
60 | |||
61 | void au1xxx_gpio1_write(int signal, int value) | ||
62 | { | ||
63 | if(value) | ||
64 | gpio1->outputset = (0x01 << signal); | ||
65 | else | ||
66 | gpio1->outputclr = (0x01 << signal); /* Output a Zero */ | ||
67 | } | ||
68 | |||
69 | void au1xxx_gpio1_tristate(int signal) | ||
70 | { | ||
71 | gpio1->trioutclr = (0x01 << signal); /* Tristate signal */ | ||
72 | } | ||
73 | |||
74 | |||
75 | int au1xxx_gpio_read(int signal) | ||
76 | { | ||
77 | if(signal >= 200) | ||
78 | #if defined(CONFIG_SOC_AU1000) | ||
79 | return 0; | ||
80 | #else | ||
81 | return au1xxx_gpio2_read(signal); | ||
82 | #endif | ||
83 | else | ||
84 | return au1xxx_gpio1_read(signal); | ||
85 | } | ||
86 | |||
87 | void au1xxx_gpio_write(int signal, int value) | ||
88 | { | ||
89 | if(signal >= 200) | ||
90 | #if defined(CONFIG_SOC_AU1000) | ||
91 | ; | ||
92 | #else | ||
93 | au1xxx_gpio2_write(signal, value); | ||
94 | #endif | ||
95 | else | ||
96 | au1xxx_gpio1_write(signal, value); | ||
97 | } | ||
98 | |||
99 | void au1xxx_gpio_tristate(int signal) | ||
100 | { | ||
101 | if(signal >= 200) | ||
102 | #if defined(CONFIG_SOC_AU1000) | ||
103 | ; | ||
104 | #else | ||
105 | au1xxx_gpio2_tristate(signal); | ||
106 | #endif | ||
107 | else | ||
108 | au1xxx_gpio1_tristate(signal); | ||
109 | } | ||
110 | |||
111 | void au1xxx_gpio1_set_inputs(void) | ||
112 | { | ||
113 | gpio1->pininputen = 0; | ||
114 | } | ||
115 | |||
116 | EXPORT_SYMBOL(au1xxx_gpio1_set_inputs); | ||
117 | EXPORT_SYMBOL(au1xxx_gpio_tristate); | ||
118 | EXPORT_SYMBOL(au1xxx_gpio_write); | ||
119 | EXPORT_SYMBOL(au1xxx_gpio_read); | ||
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index d1eb5a4a9a19..1339a0979f66 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c | |||
@@ -83,7 +83,7 @@ inline void local_disable_irq(unsigned int irq_nr); | |||
83 | void (*board_init_irq)(void); | 83 | void (*board_init_irq)(void); |
84 | 84 | ||
85 | #ifdef CONFIG_PM | 85 | #ifdef CONFIG_PM |
86 | extern void counter0_irq(int irq, void *dev_id, struct pt_regs *regs); | 86 | extern irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs); |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | static DEFINE_SPINLOCK(irq_lock); | 89 | static DEFINE_SPINLOCK(irq_lock); |
@@ -253,52 +253,72 @@ void restore_local_and_enable(int controller, unsigned long mask) | |||
253 | 253 | ||
254 | 254 | ||
255 | static struct hw_interrupt_type rise_edge_irq_type = { | 255 | static struct hw_interrupt_type rise_edge_irq_type = { |
256 | "Au1000 Rise Edge", | 256 | .typename = "Au1000 Rise Edge", |
257 | startup_irq, | 257 | .startup = startup_irq, |
258 | shutdown_irq, | 258 | .shutdown = shutdown_irq, |
259 | local_enable_irq, | 259 | .enable = local_enable_irq, |
260 | local_disable_irq, | 260 | .disable = local_disable_irq, |
261 | mask_and_ack_rise_edge_irq, | 261 | .ack = mask_and_ack_rise_edge_irq, |
262 | end_irq, | 262 | .end = end_irq, |
263 | NULL | ||
264 | }; | 263 | }; |
265 | 264 | ||
266 | static struct hw_interrupt_type fall_edge_irq_type = { | 265 | static struct hw_interrupt_type fall_edge_irq_type = { |
267 | "Au1000 Fall Edge", | 266 | .typename = "Au1000 Fall Edge", |
268 | startup_irq, | 267 | .startup = startup_irq, |
269 | shutdown_irq, | 268 | .shutdown = shutdown_irq, |
270 | local_enable_irq, | 269 | .enable = local_enable_irq, |
271 | local_disable_irq, | 270 | .disable = local_disable_irq, |
272 | mask_and_ack_fall_edge_irq, | 271 | .ack = mask_and_ack_fall_edge_irq, |
273 | end_irq, | 272 | .end = end_irq, |
274 | NULL | ||
275 | }; | 273 | }; |
276 | 274 | ||
277 | static struct hw_interrupt_type either_edge_irq_type = { | 275 | static struct hw_interrupt_type either_edge_irq_type = { |
278 | "Au1000 Rise or Fall Edge", | 276 | .typename = "Au1000 Rise or Fall Edge", |
279 | startup_irq, | 277 | .startup = startup_irq, |
280 | shutdown_irq, | 278 | .shutdown = shutdown_irq, |
281 | local_enable_irq, | 279 | .enable = local_enable_irq, |
282 | local_disable_irq, | 280 | .disable = local_disable_irq, |
283 | mask_and_ack_either_edge_irq, | 281 | .ack = mask_and_ack_either_edge_irq, |
284 | end_irq, | 282 | .end = end_irq, |
285 | NULL | ||
286 | }; | 283 | }; |
287 | 284 | ||
288 | static struct hw_interrupt_type level_irq_type = { | 285 | static struct hw_interrupt_type level_irq_type = { |
289 | "Au1000 Level", | 286 | .typename = "Au1000 Level", |
290 | startup_irq, | 287 | .startup = startup_irq, |
291 | shutdown_irq, | 288 | .shutdown = shutdown_irq, |
292 | local_enable_irq, | 289 | .enable = local_enable_irq, |
293 | local_disable_irq, | 290 | .disable = local_disable_irq, |
294 | mask_and_ack_level_irq, | 291 | .ack = mask_and_ack_level_irq, |
295 | end_irq, | 292 | .end = end_irq, |
296 | NULL | ||
297 | }; | 293 | }; |
298 | 294 | ||
299 | #ifdef CONFIG_PM | 295 | #ifdef CONFIG_PM |
300 | void startup_match20_interrupt(void) | 296 | void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *)) |
301 | { | 297 | { |
298 | struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT]; | ||
299 | |||
300 | static struct irqaction action; | ||
301 | memset(&action, 0, sizeof(struct irqaction)); | ||
302 | |||
303 | /* This is a big problem.... since we didn't use request_irq | ||
304 | * when kernel/irq.c calls probe_irq_xxx this interrupt will | ||
305 | * be probed for usage. This will end up disabling the device :( | ||
306 | * Give it a bogus "action" pointer -- this will keep it from | ||
307 | * getting auto-probed! | ||
308 | * | ||
309 | * By setting the status to match that of request_irq() we | ||
310 | * can avoid it. --cgray | ||
311 | */ | ||
312 | action.dev_id = handler; | ||
313 | action.flags = SA_INTERRUPT; | ||
314 | cpus_clear(action.mask); | ||
315 | action.name = "Au1xxx TOY"; | ||
316 | action.handler = handler; | ||
317 | action.next = NULL; | ||
318 | |||
319 | desc->action = &action; | ||
320 | desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS); | ||
321 | |||
302 | local_enable_irq(AU1000_TOY_MATCH2_INT); | 322 | local_enable_irq(AU1000_TOY_MATCH2_INT); |
303 | } | 323 | } |
304 | #endif | 324 | #endif |
@@ -426,7 +446,6 @@ void __init arch_init_irq(void) | |||
426 | extern int au1xxx_ic0_nr_irqs; | 446 | extern int au1xxx_ic0_nr_irqs; |
427 | 447 | ||
428 | cp0_status = read_c0_status(); | 448 | cp0_status = read_c0_status(); |
429 | memset(irq_desc, 0, sizeof(irq_desc)); | ||
430 | set_except_vector(0, au1000_IRQ); | 449 | set_except_vector(0, au1000_IRQ); |
431 | 450 | ||
432 | /* Initialize interrupt controllers to a safe state. | 451 | /* Initialize interrupt controllers to a safe state. |
@@ -492,7 +511,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs) | |||
492 | intc0_req0 |= au_readl(IC0_REQ0INT); | 511 | intc0_req0 |= au_readl(IC0_REQ0INT); |
493 | 512 | ||
494 | if (!intc0_req0) return; | 513 | if (!intc0_req0) return; |
495 | 514 | #ifdef AU1000_USB_DEV_REQ_INT | |
496 | /* | 515 | /* |
497 | * Because of the tight timing of SETUP token to reply | 516 | * Because of the tight timing of SETUP token to reply |
498 | * transactions, the USB devices-side packet complete | 517 | * transactions, the USB devices-side packet complete |
@@ -503,7 +522,7 @@ void intc0_req0_irqdispatch(struct pt_regs *regs) | |||
503 | do_IRQ(AU1000_USB_DEV_REQ_INT, regs); | 522 | do_IRQ(AU1000_USB_DEV_REQ_INT, regs); |
504 | return; | 523 | return; |
505 | } | 524 | } |
506 | 525 | #endif | |
507 | irq = au_ffs(intc0_req0) - 1; | 526 | irq = au_ffs(intc0_req0) - 1; |
508 | intc0_req0 &= ~(1<<irq); | 527 | intc0_req0 &= ~(1<<irq); |
509 | do_IRQ(irq, regs); | 528 | do_IRQ(irq, regs); |
@@ -521,17 +540,7 @@ void intc0_req1_irqdispatch(struct pt_regs *regs) | |||
521 | 540 | ||
522 | irq = au_ffs(intc0_req1) - 1; | 541 | irq = au_ffs(intc0_req1) - 1; |
523 | intc0_req1 &= ~(1<<irq); | 542 | intc0_req1 &= ~(1<<irq); |
524 | #ifdef CONFIG_PM | 543 | do_IRQ(irq, regs); |
525 | if (irq == AU1000_TOY_MATCH2_INT) { | ||
526 | mask_and_ack_rise_edge_irq(irq); | ||
527 | counter0_irq(irq, NULL, regs); | ||
528 | local_enable_irq(irq); | ||
529 | } | ||
530 | else | ||
531 | #endif | ||
532 | { | ||
533 | do_IRQ(irq, regs); | ||
534 | } | ||
535 | } | 544 | } |
536 | 545 | ||
537 | 546 | ||
diff --git a/arch/mips/au1000/common/platform.c b/arch/mips/au1000/common/platform.c index 0776b2db5641..1f7b465c8038 100644 --- a/arch/mips/au1000/common/platform.c +++ b/arch/mips/au1000/common/platform.c | |||
@@ -7,13 +7,15 @@ | |||
7 | * License version 2. This program is licensed "as is" without any | 7 | * License version 2. This program is licensed "as is" without any |
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | #include <linux/config.h> | ||
10 | #include <linux/device.h> | 11 | #include <linux/device.h> |
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 13 | #include <linux/init.h> |
13 | #include <linux/resource.h> | 14 | #include <linux/resource.h> |
14 | 15 | ||
15 | #include <asm/mach-au1x00/au1000.h> | 16 | #include <asm/mach-au1x00/au1xxx.h> |
16 | 17 | ||
18 | /* OHCI (USB full speed host controller) */ | ||
17 | static struct resource au1xxx_usb_ohci_resources[] = { | 19 | static struct resource au1xxx_usb_ohci_resources[] = { |
18 | [0] = { | 20 | [0] = { |
19 | .start = USB_OHCI_BASE, | 21 | .start = USB_OHCI_BASE, |
@@ -41,8 +43,252 @@ static struct platform_device au1xxx_usb_ohci_device = { | |||
41 | .resource = au1xxx_usb_ohci_resources, | 43 | .resource = au1xxx_usb_ohci_resources, |
42 | }; | 44 | }; |
43 | 45 | ||
46 | /*** AU1100 LCD controller ***/ | ||
47 | |||
48 | #ifdef CONFIG_FB_AU1100 | ||
49 | static struct resource au1100_lcd_resources[] = { | ||
50 | [0] = { | ||
51 | .start = LCD_PHYS_ADDR, | ||
52 | .end = LCD_PHYS_ADDR + 0x800 - 1, | ||
53 | .flags = IORESOURCE_MEM, | ||
54 | }, | ||
55 | [1] = { | ||
56 | .start = AU1100_LCD_INT, | ||
57 | .end = AU1100_LCD_INT, | ||
58 | .flags = IORESOURCE_IRQ, | ||
59 | } | ||
60 | }; | ||
61 | |||
62 | static u64 au1100_lcd_dmamask = ~(u32)0; | ||
63 | |||
64 | static struct platform_device au1100_lcd_device = { | ||
65 | .name = "au1100-lcd", | ||
66 | .id = 0, | ||
67 | .dev = { | ||
68 | .dma_mask = &au1100_lcd_dmamask, | ||
69 | .coherent_dma_mask = 0xffffffff, | ||
70 | }, | ||
71 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
72 | .resource = au1100_lcd_resources, | ||
73 | }; | ||
74 | #endif | ||
75 | |||
76 | #ifdef CONFIG_SOC_AU1200 | ||
77 | /* EHCI (USB high speed host controller) */ | ||
78 | static struct resource au1xxx_usb_ehci_resources[] = { | ||
79 | [0] = { | ||
80 | .start = USB_EHCI_BASE, | ||
81 | .end = USB_EHCI_BASE + USB_EHCI_LEN - 1, | ||
82 | .flags = IORESOURCE_MEM, | ||
83 | }, | ||
84 | [1] = { | ||
85 | .start = AU1000_USB_HOST_INT, | ||
86 | .end = AU1000_USB_HOST_INT, | ||
87 | .flags = IORESOURCE_IRQ, | ||
88 | }, | ||
89 | }; | ||
90 | |||
91 | static u64 ehci_dmamask = ~(u32)0; | ||
92 | |||
93 | static struct platform_device au1xxx_usb_ehci_device = { | ||
94 | .name = "au1xxx-ehci", | ||
95 | .id = 0, | ||
96 | .dev = { | ||
97 | .dma_mask = &ehci_dmamask, | ||
98 | .coherent_dma_mask = 0xffffffff, | ||
99 | }, | ||
100 | .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), | ||
101 | .resource = au1xxx_usb_ehci_resources, | ||
102 | }; | ||
103 | |||
104 | /* Au1200 UDC (USB gadget controller) */ | ||
105 | static struct resource au1xxx_usb_gdt_resources[] = { | ||
106 | [0] = { | ||
107 | .start = USB_UDC_BASE, | ||
108 | .end = USB_UDC_BASE + USB_UDC_LEN - 1, | ||
109 | .flags = IORESOURCE_MEM, | ||
110 | }, | ||
111 | [1] = { | ||
112 | .start = AU1200_USB_INT, | ||
113 | .end = AU1200_USB_INT, | ||
114 | .flags = IORESOURCE_IRQ, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static struct resource au1xxx_mmc_resources[] = { | ||
119 | [0] = { | ||
120 | .start = SD0_PHYS_ADDR, | ||
121 | .end = SD0_PHYS_ADDR + 0x40, | ||
122 | .flags = IORESOURCE_MEM, | ||
123 | }, | ||
124 | [1] = { | ||
125 | .start = SD1_PHYS_ADDR, | ||
126 | .end = SD1_PHYS_ADDR + 0x40, | ||
127 | .flags = IORESOURCE_MEM, | ||
128 | }, | ||
129 | [2] = { | ||
130 | .start = AU1200_SD_INT, | ||
131 | .end = AU1200_SD_INT, | ||
132 | .flags = IORESOURCE_IRQ, | ||
133 | } | ||
134 | }; | ||
135 | |||
136 | static u64 udc_dmamask = ~(u32)0; | ||
137 | |||
138 | static struct platform_device au1xxx_usb_gdt_device = { | ||
139 | .name = "au1xxx-udc", | ||
140 | .id = 0, | ||
141 | .dev = { | ||
142 | .dma_mask = &udc_dmamask, | ||
143 | .coherent_dma_mask = 0xffffffff, | ||
144 | }, | ||
145 | .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources), | ||
146 | .resource = au1xxx_usb_gdt_resources, | ||
147 | }; | ||
148 | |||
149 | /* Au1200 UOC (USB OTG controller) */ | ||
150 | static struct resource au1xxx_usb_otg_resources[] = { | ||
151 | [0] = { | ||
152 | .start = USB_UOC_BASE, | ||
153 | .end = USB_UOC_BASE + USB_UOC_LEN - 1, | ||
154 | .flags = IORESOURCE_MEM, | ||
155 | }, | ||
156 | [1] = { | ||
157 | .start = AU1200_USB_INT, | ||
158 | .end = AU1200_USB_INT, | ||
159 | .flags = IORESOURCE_IRQ, | ||
160 | }, | ||
161 | }; | ||
162 | |||
163 | static u64 uoc_dmamask = ~(u32)0; | ||
164 | |||
165 | static struct platform_device au1xxx_usb_otg_device = { | ||
166 | .name = "au1xxx-uoc", | ||
167 | .id = 0, | ||
168 | .dev = { | ||
169 | .dma_mask = &uoc_dmamask, | ||
170 | .coherent_dma_mask = 0xffffffff, | ||
171 | }, | ||
172 | .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources), | ||
173 | .resource = au1xxx_usb_otg_resources, | ||
174 | }; | ||
175 | |||
176 | static struct resource au1200_lcd_resources[] = { | ||
177 | [0] = { | ||
178 | .start = LCD_PHYS_ADDR, | ||
179 | .end = LCD_PHYS_ADDR + 0x800 - 1, | ||
180 | .flags = IORESOURCE_MEM, | ||
181 | }, | ||
182 | [1] = { | ||
183 | .start = AU1200_LCD_INT, | ||
184 | .end = AU1200_LCD_INT, | ||
185 | .flags = IORESOURCE_IRQ, | ||
186 | } | ||
187 | }; | ||
188 | |||
189 | static struct resource au1200_ide0_resources[] = { | ||
190 | [0] = { | ||
191 | .start = AU1XXX_ATA_PHYS_ADDR, | ||
192 | .end = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN, | ||
193 | .flags = IORESOURCE_MEM, | ||
194 | }, | ||
195 | [1] = { | ||
196 | .start = AU1XXX_ATA_INT, | ||
197 | .end = AU1XXX_ATA_INT, | ||
198 | .flags = IORESOURCE_IRQ, | ||
199 | } | ||
200 | }; | ||
201 | |||
202 | static u64 au1200_lcd_dmamask = ~(u32)0; | ||
203 | |||
204 | static struct platform_device au1200_lcd_device = { | ||
205 | .name = "au1200-lcd", | ||
206 | .id = 0, | ||
207 | .dev = { | ||
208 | .dma_mask = &au1200_lcd_dmamask, | ||
209 | .coherent_dma_mask = 0xffffffff, | ||
210 | }, | ||
211 | .num_resources = ARRAY_SIZE(au1200_lcd_resources), | ||
212 | .resource = au1200_lcd_resources, | ||
213 | }; | ||
214 | |||
215 | |||
216 | static u64 ide0_dmamask = ~(u32)0; | ||
217 | |||
218 | static struct platform_device au1200_ide0_device = { | ||
219 | .name = "au1200-ide", | ||
220 | .id = 0, | ||
221 | .dev = { | ||
222 | .dma_mask = &ide0_dmamask, | ||
223 | .coherent_dma_mask = 0xffffffff, | ||
224 | }, | ||
225 | .num_resources = ARRAY_SIZE(au1200_ide0_resources), | ||
226 | .resource = au1200_ide0_resources, | ||
227 | }; | ||
228 | |||
229 | static u64 au1xxx_mmc_dmamask = ~(u32)0; | ||
230 | |||
231 | static struct platform_device au1xxx_mmc_device = { | ||
232 | .name = "au1xxx-mmc", | ||
233 | .id = 0, | ||
234 | .dev = { | ||
235 | .dma_mask = &au1xxx_mmc_dmamask, | ||
236 | .coherent_dma_mask = 0xffffffff, | ||
237 | }, | ||
238 | .num_resources = ARRAY_SIZE(au1xxx_mmc_resources), | ||
239 | .resource = au1xxx_mmc_resources, | ||
240 | }; | ||
241 | #endif /* #ifdef CONFIG_SOC_AU1200 */ | ||
242 | |||
243 | static struct platform_device au1x00_pcmcia_device = { | ||
244 | .name = "au1x00-pcmcia", | ||
245 | .id = 0, | ||
246 | }; | ||
247 | |||
248 | #ifdef CONFIG_MIPS_DB1200 | ||
249 | |||
250 | static struct resource smc91x_resources[] = { | ||
251 | [0] = { | ||
252 | .name = "smc91x-regs", | ||
253 | .start = AU1XXX_SMC91111_PHYS_ADDR, | ||
254 | .end = AU1XXX_SMC91111_PHYS_ADDR + 0xfffff, | ||
255 | .flags = IORESOURCE_MEM, | ||
256 | }, | ||
257 | [1] = { | ||
258 | .start = AU1XXX_SMC91111_IRQ, | ||
259 | .end = AU1XXX_SMC91111_IRQ, | ||
260 | .flags = IORESOURCE_IRQ, | ||
261 | }, | ||
262 | }; | ||
263 | |||
264 | static struct platform_device smc91x_device = { | ||
265 | .name = "smc91x", | ||
266 | .id = -1, | ||
267 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
268 | .resource = smc91x_resources, | ||
269 | }; | ||
270 | |||
271 | #endif | ||
272 | |||
44 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | 273 | static struct platform_device *au1xxx_platform_devices[] __initdata = { |
45 | &au1xxx_usb_ohci_device, | 274 | &au1xxx_usb_ohci_device, |
275 | &au1x00_pcmcia_device, | ||
276 | #ifdef CONFIG_FB_AU1100 | ||
277 | &au1100_lcd_device, | ||
278 | #endif | ||
279 | #ifdef CONFIG_SOC_AU1200 | ||
280 | #if 0 /* fixme */ | ||
281 | &au1xxx_usb_ehci_device, | ||
282 | #endif | ||
283 | &au1xxx_usb_gdt_device, | ||
284 | &au1xxx_usb_otg_device, | ||
285 | &au1200_lcd_device, | ||
286 | &au1200_ide0_device, | ||
287 | &au1xxx_mmc_device, | ||
288 | #endif | ||
289 | #ifdef CONFIG_MIPS_DB1200 | ||
290 | &smc91x_device, | ||
291 | #endif | ||
46 | }; | 292 | }; |
47 | 293 | ||
48 | int au1xxx_platform_init(void) | 294 | int au1xxx_platform_init(void) |
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c index c40daccbb5b1..f85093b8d54d 100644 --- a/arch/mips/au1000/common/power.c +++ b/arch/mips/au1000/common/power.c | |||
@@ -34,11 +34,13 @@ | |||
34 | #include <linux/pm.h> | 34 | #include <linux/pm.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/sysctl.h> | 36 | #include <linux/sysctl.h> |
37 | #include <linux/jiffies.h> | ||
37 | 38 | ||
38 | #include <asm/string.h> | 39 | #include <asm/string.h> |
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
40 | #include <asm/io.h> | 41 | #include <asm/io.h> |
41 | #include <asm/system.h> | 42 | #include <asm/system.h> |
43 | #include <asm/cacheflush.h> | ||
42 | #include <asm/mach-au1x00/au1000.h> | 44 | #include <asm/mach-au1x00/au1000.h> |
43 | 45 | ||
44 | #ifdef CONFIG_PM | 46 | #ifdef CONFIG_PM |
@@ -50,7 +52,7 @@ | |||
50 | # define DPRINTK(fmt, args...) | 52 | # define DPRINTK(fmt, args...) |
51 | #endif | 53 | #endif |
52 | 54 | ||
53 | static void calibrate_delay(void); | 55 | static void au1000_calibrate_delay(void); |
54 | 56 | ||
55 | extern void set_au1x00_speed(unsigned int new_freq); | 57 | extern void set_au1x00_speed(unsigned int new_freq); |
56 | extern unsigned int get_au1x00_speed(void); | 58 | extern unsigned int get_au1x00_speed(void); |
@@ -260,7 +262,7 @@ int au_sleep(void) | |||
260 | } | 262 | } |
261 | 263 | ||
262 | static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, | 264 | static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, |
263 | void *buffer, size_t * len) | 265 | void __user *buffer, size_t * len, loff_t *ppos) |
264 | { | 266 | { |
265 | int retval = 0; | 267 | int retval = 0; |
266 | #ifdef SLEEP_TEST_TIMEOUT | 268 | #ifdef SLEEP_TEST_TIMEOUT |
@@ -294,10 +296,9 @@ static int pm_do_sleep(ctl_table * ctl, int write, struct file *file, | |||
294 | } | 296 | } |
295 | 297 | ||
296 | static int pm_do_suspend(ctl_table * ctl, int write, struct file *file, | 298 | static int pm_do_suspend(ctl_table * ctl, int write, struct file *file, |
297 | void *buffer, size_t * len) | 299 | void __user *buffer, size_t * len, loff_t *ppos) |
298 | { | 300 | { |
299 | int retval = 0; | 301 | int retval = 0; |
300 | void au1k_wait(void); | ||
301 | 302 | ||
302 | if (!write) { | 303 | if (!write) { |
303 | *len = 0; | 304 | *len = 0; |
@@ -306,7 +307,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file, | |||
306 | if (retval) | 307 | if (retval) |
307 | return retval; | 308 | return retval; |
308 | suspend_mode = 1; | 309 | suspend_mode = 1; |
309 | au1k_wait(); | 310 | |
310 | retval = pm_send_all(PM_RESUME, (void *) 0); | 311 | retval = pm_send_all(PM_RESUME, (void *) 0); |
311 | } | 312 | } |
312 | return retval; | 313 | return retval; |
@@ -314,7 +315,7 @@ static int pm_do_suspend(ctl_table * ctl, int write, struct file *file, | |||
314 | 315 | ||
315 | 316 | ||
316 | static int pm_do_freq(ctl_table * ctl, int write, struct file *file, | 317 | static int pm_do_freq(ctl_table * ctl, int write, struct file *file, |
317 | void *buffer, size_t * len) | 318 | void __user *buffer, size_t * len, loff_t *ppos) |
318 | { | 319 | { |
319 | int retval = 0, i; | 320 | int retval = 0, i; |
320 | unsigned long val, pll; | 321 | unsigned long val, pll; |
@@ -409,14 +410,14 @@ static int pm_do_freq(ctl_table * ctl, int write, struct file *file, | |||
409 | 410 | ||
410 | 411 | ||
411 | /* We don't want _any_ interrupts other than | 412 | /* We don't want _any_ interrupts other than |
412 | * match20. Otherwise our calibrate_delay() | 413 | * match20. Otherwise our au1000_calibrate_delay() |
413 | * calculation will be off, potentially a lot. | 414 | * calculation will be off, potentially a lot. |
414 | */ | 415 | */ |
415 | intc0_mask = save_local_and_disable(0); | 416 | intc0_mask = save_local_and_disable(0); |
416 | intc1_mask = save_local_and_disable(1); | 417 | intc1_mask = save_local_and_disable(1); |
417 | local_enable_irq(AU1000_TOY_MATCH2_INT); | 418 | local_enable_irq(AU1000_TOY_MATCH2_INT); |
418 | spin_unlock_irqrestore(&pm_lock, flags); | 419 | spin_unlock_irqrestore(&pm_lock, flags); |
419 | calibrate_delay(); | 420 | au1000_calibrate_delay(); |
420 | restore_local_and_enable(0, intc0_mask); | 421 | restore_local_and_enable(0, intc0_mask); |
421 | restore_local_and_enable(1, intc1_mask); | 422 | restore_local_and_enable(1, intc1_mask); |
422 | return retval; | 423 | return retval; |
@@ -456,7 +457,7 @@ __initcall(pm_init); | |||
456 | better than 1% */ | 457 | better than 1% */ |
457 | #define LPS_PREC 8 | 458 | #define LPS_PREC 8 |
458 | 459 | ||
459 | static void calibrate_delay(void) | 460 | static void au1000_calibrate_delay(void) |
460 | { | 461 | { |
461 | unsigned long ticks, loopbit; | 462 | unsigned long ticks, loopbit; |
462 | int lps_precision = LPS_PREC; | 463 | int lps_precision = LPS_PREC; |
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index 22e5a85af4d5..9c171afd9a53 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c | |||
@@ -75,7 +75,8 @@ void prom_init_cmdline(void) | |||
75 | } | 75 | } |
76 | if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ | 76 | if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ |
77 | --cp; | 77 | --cp; |
78 | *cp = '\0'; | 78 | if (prom_argc > 1) |
79 | *cp = '\0'; | ||
79 | 80 | ||
80 | } | 81 | } |
81 | 82 | ||
diff --git a/arch/mips/au1000/common/puts.c b/arch/mips/au1000/common/puts.c index c2ae4624b77b..2705829cd466 100644 --- a/arch/mips/au1000/common/puts.c +++ b/arch/mips/au1000/common/puts.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #define TIMEOUT 0xffffff | 39 | #define TIMEOUT 0xffffff |
40 | #define SLOW_DOWN | 40 | #define SLOW_DOWN |
41 | 41 | ||
42 | static const char digits[16] = "0123456789abcdef"; | ||
43 | static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE; | 42 | static volatile unsigned long * const com1 = (unsigned long *)SERIAL_BASE; |
44 | 43 | ||
45 | 44 | ||
@@ -54,7 +53,7 @@ static inline void slow_down(void) | |||
54 | #endif | 53 | #endif |
55 | 54 | ||
56 | void | 55 | void |
57 | putch(const unsigned char c) | 56 | prom_putchar(const unsigned char c) |
58 | { | 57 | { |
59 | unsigned char ch; | 58 | unsigned char ch; |
60 | int i = 0; | 59 | int i = 0; |
@@ -69,77 +68,3 @@ putch(const unsigned char c) | |||
69 | } while (0 == (ch & TX_BUSY)); | 68 | } while (0 == (ch & TX_BUSY)); |
70 | com1[SER_DATA] = c; | 69 | com1[SER_DATA] = c; |
71 | } | 70 | } |
72 | |||
73 | void | ||
74 | puts(unsigned char *cp) | ||
75 | { | ||
76 | unsigned char ch; | ||
77 | int i = 0; | ||
78 | |||
79 | while (*cp) { | ||
80 | do { | ||
81 | ch = com1[SER_CMD]; | ||
82 | slow_down(); | ||
83 | i++; | ||
84 | if (i>TIMEOUT) { | ||
85 | break; | ||
86 | } | ||
87 | } while (0 == (ch & TX_BUSY)); | ||
88 | com1[SER_DATA] = *cp++; | ||
89 | } | ||
90 | putch('\r'); | ||
91 | putch('\n'); | ||
92 | } | ||
93 | |||
94 | void | ||
95 | fputs(const char *cp) | ||
96 | { | ||
97 | unsigned char ch; | ||
98 | int i = 0; | ||
99 | |||
100 | while (*cp) { | ||
101 | |||
102 | do { | ||
103 | ch = com1[SER_CMD]; | ||
104 | slow_down(); | ||
105 | i++; | ||
106 | if (i>TIMEOUT) { | ||
107 | break; | ||
108 | } | ||
109 | } while (0 == (ch & TX_BUSY)); | ||
110 | com1[SER_DATA] = *cp++; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | |||
115 | void | ||
116 | put64(uint64_t ul) | ||
117 | { | ||
118 | int cnt; | ||
119 | unsigned ch; | ||
120 | |||
121 | cnt = 16; /* 16 nibbles in a 64 bit long */ | ||
122 | putch('0'); | ||
123 | putch('x'); | ||
124 | do { | ||
125 | cnt--; | ||
126 | ch = (unsigned char)(ul >> cnt * 4) & 0x0F; | ||
127 | putch(digits[ch]); | ||
128 | } while (cnt > 0); | ||
129 | } | ||
130 | |||
131 | void | ||
132 | put32(unsigned u) | ||
133 | { | ||
134 | int cnt; | ||
135 | unsigned ch; | ||
136 | |||
137 | cnt = 8; /* 8 nibbles in a 32 bit long */ | ||
138 | putch('0'); | ||
139 | putch('x'); | ||
140 | do { | ||
141 | cnt--; | ||
142 | ch = (unsigned char)(u >> cnt * 4) & 0x0F; | ||
143 | putch(digits[ch]); | ||
144 | } while (cnt > 0); | ||
145 | } | ||
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index eff89e109ce6..1ef15d5ef943 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/module.h> | ||
35 | 36 | ||
36 | #include <asm/cpu.h> | 37 | #include <asm/cpu.h> |
37 | #include <asm/bootinfo.h> | 38 | #include <asm/bootinfo.h> |
@@ -57,7 +58,7 @@ extern void au1xxx_time_init(void); | |||
57 | extern void au1xxx_timer_setup(struct irqaction *irq); | 58 | extern void au1xxx_timer_setup(struct irqaction *irq); |
58 | extern void set_cpuspec(void); | 59 | extern void set_cpuspec(void); |
59 | 60 | ||
60 | static int __init au1x00_setup(void) | 61 | void __init plat_setup(void) |
61 | { | 62 | { |
62 | struct cpu_spec *sp; | 63 | struct cpu_spec *sp; |
63 | char *argptr; | 64 | char *argptr; |
@@ -106,8 +107,6 @@ static int __init au1x00_setup(void) | |||
106 | /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ | 107 | /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ |
107 | #ifdef CONFIG_MIPS_HYDROGEN3 | 108 | #ifdef CONFIG_MIPS_HYDROGEN3 |
108 | strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor"); | 109 | strcat(argptr, " video=au1100fb:panel:Hydrogen_3_NEC_panel_320x240,nohwcursor"); |
109 | #else | ||
110 | strcat(argptr, " video=au1100fb:panel:s10,nohwcursor"); | ||
111 | #endif | 110 | #endif |
112 | } | 111 | } |
113 | #endif | 112 | #endif |
@@ -153,15 +152,11 @@ static int __init au1x00_setup(void) | |||
153 | au_sync(); | 152 | au_sync(); |
154 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); | 153 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); |
155 | au_writel(0, SYS_TOYTRIM); | 154 | au_writel(0, SYS_TOYTRIM); |
156 | |||
157 | return 0; | ||
158 | } | 155 | } |
159 | 156 | ||
160 | early_initcall(au1x00_setup); | ||
161 | |||
162 | #if defined(CONFIG_64BIT_PHYS_ADDR) | 157 | #if defined(CONFIG_64BIT_PHYS_ADDR) |
163 | /* This routine should be valid for all Au1x based boards */ | 158 | /* This routine should be valid for all Au1x based boards */ |
164 | phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 159 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) |
165 | { | 160 | { |
166 | u32 start, end; | 161 | u32 start, end; |
167 | 162 | ||
@@ -192,4 +187,5 @@ phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
192 | /* default nop */ | 187 | /* default nop */ |
193 | return phys_addr; | 188 | return phys_addr; |
194 | } | 189 | } |
190 | EXPORT_SYMBOL(__fixup_bigphys_addr); | ||
195 | #endif | 191 | #endif |
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 57675b41480e..883d3f3d8c53 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/mc146818rtc.h> | 50 | #include <linux/mc146818rtc.h> |
51 | #include <linux/timex.h> | 51 | #include <linux/timex.h> |
52 | 52 | ||
53 | extern void startup_match20_interrupt(void); | ||
54 | extern void do_softirq(void); | 53 | extern void do_softirq(void); |
55 | extern volatile unsigned long wall_jiffies; | 54 | extern volatile unsigned long wall_jiffies; |
56 | unsigned long missed_heart_beats = 0; | 55 | unsigned long missed_heart_beats = 0; |
@@ -58,14 +57,17 @@ unsigned long missed_heart_beats = 0; | |||
58 | static unsigned long r4k_offset; /* Amount to increment compare reg each time */ | 57 | static unsigned long r4k_offset; /* Amount to increment compare reg each time */ |
59 | static unsigned long r4k_cur; /* What counter should be at next timer irq */ | 58 | static unsigned long r4k_cur; /* What counter should be at next timer irq */ |
60 | int no_au1xxx_32khz; | 59 | int no_au1xxx_32khz; |
61 | void (*au1k_wait_ptr)(void); | 60 | extern int allow_au1k_wait; /* default off for CP0 Counter */ |
62 | 61 | ||
63 | /* Cycle counter value at the previous timer interrupt.. */ | 62 | /* Cycle counter value at the previous timer interrupt.. */ |
64 | static unsigned int timerhi = 0, timerlo = 0; | 63 | static unsigned int timerhi = 0, timerlo = 0; |
65 | 64 | ||
66 | #ifdef CONFIG_PM | 65 | #ifdef CONFIG_PM |
67 | #define MATCH20_INC 328 | 66 | #if HZ < 100 || HZ > 1000 |
68 | extern void startup_match20_interrupt(void); | 67 | #error "unsupported HZ value! Must be in [100,1000]" |
68 | #endif | ||
69 | #define MATCH20_INC (328*100/HZ) /* magic number 328 is for HZ=100... */ | ||
70 | extern void startup_match20_interrupt(irqreturn_t (*handler)(int, void *, struct pt_regs *)); | ||
69 | static unsigned long last_pc0, last_match20; | 71 | static unsigned long last_pc0, last_match20; |
70 | #endif | 72 | #endif |
71 | 73 | ||
@@ -117,17 +119,16 @@ null: | |||
117 | } | 119 | } |
118 | 120 | ||
119 | #ifdef CONFIG_PM | 121 | #ifdef CONFIG_PM |
120 | void counter0_irq(int irq, void *dev_id, struct pt_regs *regs) | 122 | irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs) |
121 | { | 123 | { |
122 | unsigned long pc0; | 124 | unsigned long pc0; |
123 | int time_elapsed; | 125 | int time_elapsed; |
124 | static int jiffie_drift = 0; | 126 | static int jiffie_drift = 0; |
125 | 127 | ||
126 | kstat.irqs[0][irq]++; | ||
127 | if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) { | 128 | if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) { |
128 | /* should never happen! */ | 129 | /* should never happen! */ |
129 | printk(KERN_WARNING "counter 0 w status eror\n"); | 130 | printk(KERN_WARNING "counter 0 w status error\n"); |
130 | return; | 131 | return IRQ_NONE; |
131 | } | 132 | } |
132 | 133 | ||
133 | pc0 = au_readl(SYS_TOYREAD); | 134 | pc0 = au_readl(SYS_TOYREAD); |
@@ -164,6 +165,8 @@ void counter0_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
164 | update_process_times(user_mode(regs)); | 165 | update_process_times(user_mode(regs)); |
165 | #endif | 166 | #endif |
166 | } | 167 | } |
168 | |||
169 | return IRQ_HANDLED; | ||
167 | } | 170 | } |
168 | 171 | ||
169 | /* When we wakeup from sleep, we have to "catch up" on all of the | 172 | /* When we wakeup from sleep, we have to "catch up" on all of the |
@@ -388,7 +391,6 @@ void au1xxx_timer_setup(struct irqaction *irq) | |||
388 | { | 391 | { |
389 | unsigned int est_freq; | 392 | unsigned int est_freq; |
390 | extern unsigned long (*do_gettimeoffset)(void); | 393 | extern unsigned long (*do_gettimeoffset)(void); |
391 | extern void au1k_wait(void); | ||
392 | 394 | ||
393 | printk("calculating r4koff... "); | 395 | printk("calculating r4koff... "); |
394 | r4k_offset = cal_r4koff(); | 396 | r4k_offset = cal_r4koff(); |
@@ -441,18 +443,18 @@ void au1xxx_timer_setup(struct irqaction *irq) | |||
441 | au_sync(); | 443 | au_sync(); |
442 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | 444 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); |
443 | 445 | ||
444 | /* setup match20 to interrupt once every 10ms */ | 446 | /* setup match20 to interrupt once every HZ */ |
445 | last_pc0 = last_match20 = au_readl(SYS_TOYREAD); | 447 | last_pc0 = last_match20 = au_readl(SYS_TOYREAD); |
446 | au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); | 448 | au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); |
447 | au_sync(); | 449 | au_sync(); |
448 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | 450 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); |
449 | startup_match20_interrupt(); | 451 | startup_match20_interrupt(counter0_irq); |
450 | 452 | ||
451 | do_gettimeoffset = do_fast_pm_gettimeoffset; | 453 | do_gettimeoffset = do_fast_pm_gettimeoffset; |
452 | 454 | ||
453 | /* We can use the real 'wait' instruction. | 455 | /* We can use the real 'wait' instruction. |
454 | */ | 456 | */ |
455 | au1k_wait_ptr = au1k_wait; | 457 | allow_au1k_wait = 1; |
456 | } | 458 | } |
457 | 459 | ||
458 | #else | 460 | #else |
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c index 447a9a4612a8..0b21bed7ee55 100644 --- a/arch/mips/au1000/common/usbdev.c +++ b/arch/mips/au1000/common/usbdev.c | |||
@@ -1005,11 +1005,11 @@ process_ep0_receive (struct usb_dev* dev) | |||
1005 | #endif | 1005 | #endif |
1006 | dev->ep0_stage = SETUP_STAGE; | 1006 | dev->ep0_stage = SETUP_STAGE; |
1007 | break; | 1007 | break; |
1008 | } | 1008 | } |
1009 | 1009 | ||
1010 | spin_unlock(&ep0->lock); | 1010 | spin_unlock(&ep0->lock); |
1011 | // we're done processing the packet, free it | 1011 | // we're done processing the packet, free it |
1012 | kfree(pkt); | 1012 | kfree(pkt); |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | 1015 | ||
@@ -1072,8 +1072,7 @@ dma_done_ep0_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
1072 | clear_dma_done1(ep0->indma); | 1072 | clear_dma_done1(ep0->indma); |
1073 | 1073 | ||
1074 | pkt = send_packet_complete(ep0); | 1074 | pkt = send_packet_complete(ep0); |
1075 | if (pkt) | 1075 | kfree(pkt); |
1076 | kfree(pkt); | ||
1077 | } | 1076 | } |
1078 | 1077 | ||
1079 | /* | 1078 | /* |
@@ -1302,8 +1301,7 @@ usbdev_exit(void) | |||
1302 | endpoint_flush(ep); | 1301 | endpoint_flush(ep); |
1303 | } | 1302 | } |
1304 | 1303 | ||
1305 | if (usbdev.full_conf_desc) | 1304 | kfree(usbdev.full_conf_desc); |
1306 | kfree(usbdev.full_conf_desc); | ||
1307 | } | 1305 | } |
1308 | 1306 | ||
1309 | int | 1307 | int |