update the 2.4 kernel to 2.4.32. it seems pl2303 has the fixes from 2.6, so we now...
[openwrt/staging/mkresin.git] / openwrt / target / linux / linux-2.4 / patches / generic / 000-linux_mips.patch
1 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/au1xxx_irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/au1xxx_irqmap.c
2 --- linux-2.4.32-rc1/arch/mips/au1000/common/au1xxx_irqmap.c 2005-01-19 15:09:26.000000000 +0100
3 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/au1xxx_irqmap.c 2005-01-30 09:01:27.000000000 +0100
4 @@ -172,14 +172,14 @@
5 { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
6 { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0},
7 { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0},
8 - { AU1550_TOY_INT, INTC_INT_RISE_EDGE, 0 },
9 - { AU1550_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
10 - { AU1550_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
11 - { AU1550_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
12 - { AU1550_RTC_INT, INTC_INT_RISE_EDGE, 0 },
13 - { AU1550_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
14 - { AU1550_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
15 - { AU1550_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
16 + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
17 + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
18 + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
19 + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
20 + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
21 + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
22 + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
23 + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
24 { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0},
25 { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
26 { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
27 @@ -200,14 +200,14 @@
28 { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0},
29 { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0},
30 { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0},
31 - { AU1200_TOY_INT, INTC_INT_RISE_EDGE, 0 },
32 - { AU1200_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
33 - { AU1200_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
34 - { AU1200_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
35 - { AU1200_RTC_INT, INTC_INT_RISE_EDGE, 0 },
36 - { AU1200_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
37 - { AU1200_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
38 - { AU1200_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
39 + { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
40 + { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
41 + { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
42 + { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
43 + { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
44 + { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
45 + { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
46 + { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
47 { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0},
48 { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
49 { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0},
50 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/cputable.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/cputable.c
51 --- linux-2.4.32-rc1/arch/mips/au1000/common/cputable.c 2005-01-19 15:09:26.000000000 +0100
52 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/cputable.c 2005-01-30 09:01:27.000000000 +0100
53 @@ -39,7 +39,8 @@
54 { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1 },
55 { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
56 { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
57 - { 0xffffffff, 0x04030200, "Au1200 AA", 0, 1 },
58 + { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
59 + { 0xffffffff, 0x04030201, "Au1200 AC", 0, 0 },
60 { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
61 };
62
63 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/dbdma.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/dbdma.c
64 --- linux-2.4.32-rc1/arch/mips/au1000/common/dbdma.c 2005-01-19 15:09:26.000000000 +0100
65 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/dbdma.c 2005-02-08 07:28:37.000000000 +0100
66 @@ -41,6 +41,8 @@
67 #include <asm/au1xxx_dbdma.h>
68 #include <asm/system.h>
69
70 +#include <linux/module.h>
71 +
72 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
73
74 /*
75 @@ -60,37 +62,10 @@
76 */
77 #define ALIGN_ADDR(x, a) ((((u32)(x)) + (a-1)) & ~(a-1))
78
79 -static volatile dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
80 -static int dbdma_initialized;
81 +static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
82 +static int dbdma_initialized=0;
83 static void au1xxx_dbdma_init(void);
84
85 -typedef struct dbdma_device_table {
86 - u32 dev_id;
87 - u32 dev_flags;
88 - u32 dev_tsize;
89 - u32 dev_devwidth;
90 - u32 dev_physaddr; /* If FIFO */
91 - u32 dev_intlevel;
92 - u32 dev_intpolarity;
93 -} dbdev_tab_t;
94 -
95 -typedef struct dbdma_chan_config {
96 - u32 chan_flags;
97 - u32 chan_index;
98 - dbdev_tab_t *chan_src;
99 - dbdev_tab_t *chan_dest;
100 - au1x_dma_chan_t *chan_ptr;
101 - au1x_ddma_desc_t *chan_desc_base;
102 - au1x_ddma_desc_t *get_ptr, *put_ptr, *cur_ptr;
103 - void *chan_callparam;
104 - void (*chan_callback)(int, void *, struct pt_regs *);
105 -} chan_tab_t;
106 -
107 -#define DEV_FLAGS_INUSE (1 << 0)
108 -#define DEV_FLAGS_ANYUSE (1 << 1)
109 -#define DEV_FLAGS_OUT (1 << 2)
110 -#define DEV_FLAGS_IN (1 << 3)
111 -
112 static dbdev_tab_t dbdev_tab[] = {
113 #ifdef CONFIG_SOC_AU1550
114 /* UARTS */
115 @@ -156,13 +131,13 @@
116 { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
117 { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
118
119 - { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
120 - { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
121 - { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
122 - { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
123 + { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
124 + { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
125 + { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
126 + { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
127
128 - { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
129 - { DSCR_CMD0_AES_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
130 + { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
131 + { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
132
133 { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
134 { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
135 @@ -172,9 +147,9 @@
136 { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
137 { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
138
139 - { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
140 - { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
141 - { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
142 + { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
143 + { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
144 + { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
145 { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
146
147 { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
148 @@ -183,6 +158,24 @@
149
150 { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
151 { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
152 +
153 + /* Provide 16 user definable device types */
154 + { 0, 0, 0, 0, 0, 0, 0 },
155 + { 0, 0, 0, 0, 0, 0, 0 },
156 + { 0, 0, 0, 0, 0, 0, 0 },
157 + { 0, 0, 0, 0, 0, 0, 0 },
158 + { 0, 0, 0, 0, 0, 0, 0 },
159 + { 0, 0, 0, 0, 0, 0, 0 },
160 + { 0, 0, 0, 0, 0, 0, 0 },
161 + { 0, 0, 0, 0, 0, 0, 0 },
162 + { 0, 0, 0, 0, 0, 0, 0 },
163 + { 0, 0, 0, 0, 0, 0, 0 },
164 + { 0, 0, 0, 0, 0, 0, 0 },
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 };
171
172 #define DBDEV_TAB_SIZE (sizeof(dbdev_tab) / sizeof(dbdev_tab_t))
173 @@ -202,6 +195,30 @@
174 return NULL;
175 }
176
177 +u32
178 +au1xxx_ddma_add_device(dbdev_tab_t *dev)
179 +{
180 + u32 ret = 0;
181 + dbdev_tab_t *p=NULL;
182 + static u16 new_id=0x1000;
183 +
184 + p = find_dbdev_id(0);
185 + if ( NULL != p )
186 + {
187 + memcpy(p, dev, sizeof(dbdev_tab_t));
188 + p->dev_id = DSCR_DEV2CUSTOM_ID(new_id,dev->dev_id);
189 + ret = p->dev_id;
190 + new_id++;
191 +#if 0
192 + printk("add_device: id:%x flags:%x padd:%x\n",
193 + p->dev_id, p->dev_flags, p->dev_physaddr );
194 +#endif
195 + }
196 +
197 + return ret;
198 +}
199 +EXPORT_SYMBOL(au1xxx_ddma_add_device);
200 +
201 /* Allocate a channel and return a non-zero descriptor if successful.
202 */
203 u32
204 @@ -214,7 +231,7 @@
205 int i;
206 dbdev_tab_t *stp, *dtp;
207 chan_tab_t *ctp;
208 - volatile au1x_dma_chan_t *cp;
209 + au1x_dma_chan_t *cp;
210
211 /* We do the intialization on the first channel allocation.
212 * We have to wait because of the interrupt handler initialization
213 @@ -224,9 +241,6 @@
214 au1xxx_dbdma_init();
215 dbdma_initialized = 1;
216
217 - if ((srcid > DSCR_NDEV_IDS) || (destid > DSCR_NDEV_IDS))
218 - return 0;
219 -
220 if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
221 if ((dtp = find_dbdev_id(destid)) == NULL) return 0;
222
223 @@ -268,9 +282,9 @@
224 /* If kmalloc fails, it is caught below same
225 * as a channel not available.
226 */
227 - ctp = (chan_tab_t *)kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
228 + ctp = (chan_tab_t *)
229 + kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
230 chan_tab_ptr[i] = ctp;
231 - ctp->chan_index = chan = i;
232 break;
233 }
234 }
235 @@ -278,10 +292,11 @@
236
237 if (ctp != NULL) {
238 memset(ctp, 0, sizeof(chan_tab_t));
239 + ctp->chan_index = chan = i;
240 dcp = DDMA_CHANNEL_BASE;
241 dcp += (0x0100 * chan);
242 ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
243 - cp = (volatile au1x_dma_chan_t *)dcp;
244 + cp = (au1x_dma_chan_t *)dcp;
245 ctp->chan_src = stp;
246 ctp->chan_dest = dtp;
247 ctp->chan_callback = callback;
248 @@ -298,6 +313,9 @@
249 i |= DDMA_CFG_DED;
250 if (dtp->dev_intpolarity)
251 i |= DDMA_CFG_DP;
252 + if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
253 + (dtp->dev_flags & DEV_FLAGS_SYNC))
254 + i |= DDMA_CFG_SYNC;
255 cp->ddma_cfg = i;
256 au_sync();
257
258 @@ -308,14 +326,14 @@
259 rv = (u32)(&chan_tab_ptr[chan]);
260 }
261 else {
262 - /* Release devices.
263 - */
264 + /* Release devices */
265 stp->dev_flags &= ~DEV_FLAGS_INUSE;
266 dtp->dev_flags &= ~DEV_FLAGS_INUSE;
267 }
268 }
269 return rv;
270 }
271 +EXPORT_SYMBOL(au1xxx_dbdma_chan_alloc);
272
273 /* Set the device width if source or destination is a FIFO.
274 * Should be 8, 16, or 32 bits.
275 @@ -343,6 +361,7 @@
276
277 return rv;
278 }
279 +EXPORT_SYMBOL(au1xxx_dbdma_set_devwidth);
280
281 /* Allocate a descriptor ring, initializing as much as possible.
282 */
283 @@ -369,7 +388,8 @@
284 * and if we try that first we are likely to not waste larger
285 * slabs of memory.
286 */
287 - desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
288 + desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t),
289 + GFP_KERNEL|GFP_DMA);
290 if (desc_base == 0)
291 return 0;
292
293 @@ -380,7 +400,7 @@
294 kfree((const void *)desc_base);
295 i = entries * sizeof(au1x_ddma_desc_t);
296 i += (sizeof(au1x_ddma_desc_t) - 1);
297 - if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
298 + if ((desc_base = (u32)kmalloc(i, GFP_KERNEL|GFP_DMA)) == 0)
299 return 0;
300
301 desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
302 @@ -460,9 +480,14 @@
303 /* If source input is fifo, set static address.
304 */
305 if (stp->dev_flags & DEV_FLAGS_IN) {
306 - src0 = stp->dev_physaddr;
307 - src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
308 + if ( stp->dev_flags & DEV_FLAGS_BURSTABLE )
309 + src1 |= DSCR_SRC1_SAM(DSCR_xAM_BURST);
310 + else
311 + src1 |= DSCR_SRC1_SAM(DSCR_xAM_STATIC);
312 +
313 }
314 + if (stp->dev_physaddr)
315 + src0 = stp->dev_physaddr;
316
317 /* Set up dest1. For now, assume no stride and increment.
318 * A channel attribute update can change this later.
319 @@ -486,10 +511,18 @@
320 /* If destination output is fifo, set static address.
321 */
322 if (dtp->dev_flags & DEV_FLAGS_OUT) {
323 - dest0 = dtp->dev_physaddr;
324 + if ( dtp->dev_flags & DEV_FLAGS_BURSTABLE )
325 + dest1 |= DSCR_DEST1_DAM(DSCR_xAM_BURST);
326 + else
327 dest1 |= DSCR_DEST1_DAM(DSCR_xAM_STATIC);
328 }
329 + if (dtp->dev_physaddr)
330 + dest0 = dtp->dev_physaddr;
331
332 +#if 0
333 + printk("did:%x sid:%x cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
334 + dtp->dev_id, stp->dev_id, cmd0, cmd1, src0, src1, dest0, dest1 );
335 +#endif
336 for (i=0; i<entries; i++) {
337 dp->dscr_cmd0 = cmd0;
338 dp->dscr_cmd1 = cmd1;
339 @@ -498,6 +531,7 @@
340 dp->dscr_dest0 = dest0;
341 dp->dscr_dest1 = dest1;
342 dp->dscr_stat = 0;
343 + dp->sw_context = dp->sw_status = 0;
344 dp->dscr_nxtptr = DSCR_NXTPTR(virt_to_phys(dp + 1));
345 dp++;
346 }
347 @@ -510,13 +544,14 @@
348
349 return (u32)(ctp->chan_desc_base);
350 }
351 +EXPORT_SYMBOL(au1xxx_dbdma_ring_alloc);
352
353 /* Put a source buffer into the DMA ring.
354 * This updates the source pointer and byte count. Normally used
355 * for memory to fifo transfers.
356 */
357 u32
358 -au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes)
359 +_au1xxx_dbdma_put_source(u32 chanid, void *buf, int nbytes, u32 flags)
360 {
361 chan_tab_t *ctp;
362 au1x_ddma_desc_t *dp;
363 @@ -543,24 +578,40 @@
364 */
365 dp->dscr_source0 = virt_to_phys(buf);
366 dp->dscr_cmd1 = nbytes;
367 - dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
368 - ctp->chan_ptr->ddma_dbell = 0xffffffff; /* Make it go */
369 -
370 + /* Check flags */
371 + if (flags & DDMA_FLAGS_IE)
372 + dp->dscr_cmd0 |= DSCR_CMD0_IE;
373 + if (flags & DDMA_FLAGS_NOIE)
374 + dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
375 /* Get next descriptor pointer.
376 */
377 ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
378
379 + /*
380 + * There is an errata on the Au1200/Au1550 parts that could result
381 + * in "stale" data being DMA'd. It has to do with the snoop logic on
382 + * the dache eviction buffer. NONCOHERENT_IO is on by default for
383 + * these parts. If it is fixedin the future, these dma_cache_inv will
384 + * just be nothing more than empty macros. See io.h.
385 + * */
386 + dma_cache_wback_inv(buf,nbytes);
387 + dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
388 + au_sync();
389 + dma_cache_wback_inv(dp, sizeof(dp));
390 + ctp->chan_ptr->ddma_dbell = 0;
391 +
392 /* return something not zero.
393 */
394 return nbytes;
395 }
396 +EXPORT_SYMBOL(_au1xxx_dbdma_put_source);
397
398 /* Put a destination buffer into the DMA ring.
399 * This updates the destination pointer and byte count. Normally used
400 * to place an empty buffer into the ring for fifo to memory transfers.
401 */
402 u32
403 -au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes)
404 +_au1xxx_dbdma_put_dest(u32 chanid, void *buf, int nbytes, u32 flags)
405 {
406 chan_tab_t *ctp;
407 au1x_ddma_desc_t *dp;
408 @@ -582,11 +633,33 @@
409 if (dp->dscr_cmd0 & DSCR_CMD0_V)
410 return 0;
411
412 - /* Load up buffer address and byte count.
413 - */
414 + /* Load up buffer address and byte count */
415 +
416 + /* Check flags */
417 + if (flags & DDMA_FLAGS_IE)
418 + dp->dscr_cmd0 |= DSCR_CMD0_IE;
419 + if (flags & DDMA_FLAGS_NOIE)
420 + dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
421 +
422 dp->dscr_dest0 = virt_to_phys(buf);
423 dp->dscr_cmd1 = nbytes;
424 +#if 0
425 + printk("cmd0:%x cmd1:%x source0:%x source1:%x dest0:%x dest1:%x\n",
426 + dp->dscr_cmd0, dp->dscr_cmd1, dp->dscr_source0,
427 + dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1 );
428 +#endif
429 + /*
430 + * There is an errata on the Au1200/Au1550 parts that could result in
431 + * "stale" data being DMA'd. It has to do with the snoop logic on the
432 + * dache eviction buffer. NONCOHERENT_IO is on by default for these
433 + * parts. If it is fixedin the future, these dma_cache_inv will just
434 + * be nothing more than empty macros. See io.h.
435 + * */
436 + dma_cache_inv(buf,nbytes);
437 dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */
438 + au_sync();
439 + dma_cache_wback_inv(dp, sizeof(dp));
440 + ctp->chan_ptr->ddma_dbell = 0;
441
442 /* Get next descriptor pointer.
443 */
444 @@ -596,6 +669,7 @@
445 */
446 return nbytes;
447 }
448 +EXPORT_SYMBOL(_au1xxx_dbdma_put_dest);
449
450 /* Get a destination buffer into the DMA ring.
451 * Normally used to get a full buffer from the ring during fifo
452 @@ -645,7 +719,7 @@
453 au1xxx_dbdma_stop(u32 chanid)
454 {
455 chan_tab_t *ctp;
456 - volatile au1x_dma_chan_t *cp;
457 + au1x_dma_chan_t *cp;
458 int halt_timeout = 0;
459
460 ctp = *((chan_tab_t **)chanid);
461 @@ -665,6 +739,7 @@
462 cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V);
463 au_sync();
464 }
465 +EXPORT_SYMBOL(au1xxx_dbdma_stop);
466
467 /* Start using the current descriptor pointer. If the dbdma encounters
468 * a not valid descriptor, it will stop. In this case, we can just
469 @@ -674,17 +749,17 @@
470 au1xxx_dbdma_start(u32 chanid)
471 {
472 chan_tab_t *ctp;
473 - volatile au1x_dma_chan_t *cp;
474 + au1x_dma_chan_t *cp;
475
476 ctp = *((chan_tab_t **)chanid);
477 -
478 cp = ctp->chan_ptr;
479 cp->ddma_desptr = virt_to_phys(ctp->cur_ptr);
480 cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */
481 au_sync();
482 - cp->ddma_dbell = 0xffffffff; /* Make it go */
483 + cp->ddma_dbell = 0;
484 au_sync();
485 }
486 +EXPORT_SYMBOL(au1xxx_dbdma_start);
487
488 void
489 au1xxx_dbdma_reset(u32 chanid)
490 @@ -703,15 +778,21 @@
491
492 do {
493 dp->dscr_cmd0 &= ~DSCR_CMD0_V;
494 + /* reset our SW status -- this is used to determine
495 + * if a descriptor is in use by upper level SW. Since
496 + * posting can reset 'V' bit.
497 + */
498 + dp->sw_status = 0;
499 dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
500 } while (dp != ctp->chan_desc_base);
501 }
502 +EXPORT_SYMBOL(au1xxx_dbdma_reset);
503
504 u32
505 au1xxx_get_dma_residue(u32 chanid)
506 {
507 chan_tab_t *ctp;
508 - volatile au1x_dma_chan_t *cp;
509 + au1x_dma_chan_t *cp;
510 u32 rv;
511
512 ctp = *((chan_tab_t **)chanid);
513 @@ -746,15 +827,16 @@
514
515 kfree(ctp);
516 }
517 +EXPORT_SYMBOL(au1xxx_dbdma_chan_free);
518
519 static void
520 dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
521 {
522 - u32 intstat;
523 + u32 intstat, flags;
524 u32 chan_index;
525 chan_tab_t *ctp;
526 au1x_ddma_desc_t *dp;
527 - volatile au1x_dma_chan_t *cp;
528 + au1x_dma_chan_t *cp;
529
530 intstat = dbdma_gptr->ddma_intstat;
531 au_sync();
532 @@ -773,18 +855,26 @@
533 (ctp->chan_callback)(irq, ctp->chan_callparam, regs);
534
535 ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
536 -
537 }
538
539 -static void
540 -au1xxx_dbdma_init(void)
541 +static void au1xxx_dbdma_init(void)
542 {
543 + int irq_nr;
544 +
545 dbdma_gptr->ddma_config = 0;
546 dbdma_gptr->ddma_throttle = 0;
547 dbdma_gptr->ddma_inten = 0xffff;
548 au_sync();
549
550 - if (request_irq(AU1550_DDMA_INT, dbdma_interrupt, SA_INTERRUPT,
551 +#if defined(CONFIG_SOC_AU1550)
552 + irq_nr = AU1550_DDMA_INT;
553 +#elif defined(CONFIG_SOC_AU1200)
554 + irq_nr = AU1200_DDMA_INT;
555 +#else
556 + #error Unknown Au1x00 SOC
557 +#endif
558 +
559 + if (request_irq(irq_nr, dbdma_interrupt, SA_INTERRUPT,
560 "Au1xxx dbdma", (void *)dbdma_gptr))
561 printk("Can't get 1550 dbdma irq");
562 }
563 @@ -795,7 +885,8 @@
564 chan_tab_t *ctp;
565 au1x_ddma_desc_t *dp;
566 dbdev_tab_t *stp, *dtp;
567 - volatile au1x_dma_chan_t *cp;
568 + au1x_dma_chan_t *cp;
569 + u32 i = 0;
570
571 ctp = *((chan_tab_t **)chanid);
572 stp = ctp->chan_src;
573 @@ -820,15 +911,64 @@
574 dp = ctp->chan_desc_base;
575
576 do {
577 - printk("dp %08x, cmd0 %08x, cmd1 %08x\n",
578 - (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
579 - printk("src0 %08x, src1 %08x, dest0 %08x\n",
580 - dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0);
581 - printk("dest1 %08x, stat %08x, nxtptr %08x\n",
582 - dp->dscr_dest1, dp->dscr_stat, dp->dscr_nxtptr);
583 + printk("Dp[%d]= %08x, cmd0 %08x, cmd1 %08x\n",
584 + i++, (u32)dp, dp->dscr_cmd0, dp->dscr_cmd1);
585 + printk("src0 %08x, src1 %08x, dest0 %08x, dest1 %08x\n",
586 + dp->dscr_source0, dp->dscr_source1, dp->dscr_dest0, dp->dscr_dest1);
587 + printk("stat %08x, nxtptr %08x\n",
588 + dp->dscr_stat, dp->dscr_nxtptr);
589 dp = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
590 } while (dp != ctp->chan_desc_base);
591 }
592
593 +/* Put a descriptor into the DMA ring.
594 + * This updates the source/destination pointers and byte count.
595 + */
596 +u32
597 +au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr )
598 +{
599 + chan_tab_t *ctp;
600 + au1x_ddma_desc_t *dp;
601 + u32 nbytes=0;
602 +
603 + /* I guess we could check this to be within the
604 + * range of the table......
605 + */
606 + ctp = *((chan_tab_t **)chanid);
607 +
608 + /* We should have multiple callers for a particular channel,
609 + * an interrupt doesn't affect this pointer nor the descriptor,
610 + * so no locking should be needed.
611 + */
612 + dp = ctp->put_ptr;
613 +
614 + /* If the descriptor is valid, we are way ahead of the DMA
615 + * engine, so just return an error condition.
616 + */
617 + if (dp->dscr_cmd0 & DSCR_CMD0_V)
618 + return 0;
619 +
620 + /* Load up buffer addresses and byte count.
621 + */
622 + dp->dscr_dest0 = dscr->dscr_dest0;
623 + dp->dscr_source0 = dscr->dscr_source0;
624 + dp->dscr_dest1 = dscr->dscr_dest1;
625 + dp->dscr_source1 = dscr->dscr_source1;
626 + dp->dscr_cmd1 = dscr->dscr_cmd1;
627 + nbytes = dscr->dscr_cmd1;
628 + /* Allow the caller to specifiy if an interrupt is generated */
629 + dp->dscr_cmd0 &= ~DSCR_CMD0_IE;
630 + dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V;
631 + ctp->chan_ptr->ddma_dbell = 0;
632 +
633 + /* Get next descriptor pointer.
634 + */
635 + ctp->put_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
636 +
637 + /* return something not zero.
638 + */
639 + return nbytes;
640 +}
641 +
642 #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
643
644 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/gpio.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/gpio.c
645 --- linux-2.4.32-rc1/arch/mips/au1000/common/gpio.c 1970-01-01 01:00:00.000000000 +0100
646 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/gpio.c 2005-01-30 09:01:27.000000000 +0100
647 @@ -0,0 +1,118 @@
648 +/*
649 + * This program is free software; you can redistribute it and/or modify it
650 + * under the terms of the GNU General Public License as published by the
651 + * Free Software Foundation; either version 2 of the License, or (at your
652 + * option) any later version.
653 + *
654 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
655 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
656 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
657 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
658 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
659 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
660 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
661 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
662 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
663 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
664 + *
665 + * You should have received a copy of the GNU General Public License along
666 + * with this program; if not, write to the Free Software Foundation, Inc.,
667 + * 675 Mass Ave, Cambridge, MA 02139, USA.
668 + */
669 +
670 +#include <asm/au1000.h>
671 +#include <asm/au1xxx_gpio.h>
672 +
673 +#define gpio1 sys
674 +#if !defined(CONFIG_SOC_AU1000)
675 +static AU1X00_GPIO2 * const gpio2 = (AU1X00_GPIO2 *)GPIO2_BASE;
676 +
677 +#define GPIO2_OUTPUT_ENABLE_MASK 0x00010000
678 +
679 +int au1xxx_gpio2_read(int signal)
680 +{
681 + signal -= 200;
682 +/* gpio2->dir &= ~(0x01 << signal); //Set GPIO to input */
683 + return ((gpio2->pinstate >> signal) & 0x01);
684 +}
685 +
686 +void au1xxx_gpio2_write(int signal, int value)
687 +{
688 + signal -= 200;
689 +
690 + gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << signal) |
691 + (value << signal);
692 +}
693 +
694 +void au1xxx_gpio2_tristate(int signal)
695 +{
696 + signal -= 200;
697 + gpio2->dir &= ~(0x01 << signal); /* Set GPIO to input */
698 +}
699 +#endif
700 +
701 +int au1xxx_gpio1_read(int signal)
702 +{
703 +/* gpio1->trioutclr |= (0x01 << signal); */
704 + return ((gpio1->pinstaterd >> signal) & 0x01);
705 +}
706 +
707 +void au1xxx_gpio1_write(int signal, int value)
708 +{
709 + if(value)
710 + gpio1->outputset = (0x01 << signal);
711 + else
712 + gpio1->outputclr = (0x01 << signal); /* Output a Zero */
713 +}
714 +
715 +void au1xxx_gpio1_tristate(int signal)
716 +{
717 + gpio1->trioutclr = (0x01 << signal); /* Tristate signal */
718 +}
719 +
720 +
721 +int au1xxx_gpio_read(int signal)
722 +{
723 + if(signal >= 200)
724 +#if defined(CONFIG_SOC_AU1000)
725 + return 0;
726 +#else
727 + return au1xxx_gpio2_read(signal);
728 +#endif
729 + else
730 + return au1xxx_gpio1_read(signal);
731 +}
732 +
733 +void au1xxx_gpio_write(int signal, int value)
734 +{
735 + if(signal >= 200)
736 +#if defined(CONFIG_SOC_AU1000)
737 + ;
738 +#else
739 + au1xxx_gpio2_write(signal, value);
740 +#endif
741 + else
742 + au1xxx_gpio1_write(signal, value);
743 +}
744 +
745 +void au1xxx_gpio_tristate(int signal)
746 +{
747 + if(signal >= 200)
748 +#if defined(CONFIG_SOC_AU1000)
749 + ;
750 +#else
751 + au1xxx_gpio2_tristate(signal);
752 +#endif
753 + else
754 + au1xxx_gpio1_tristate(signal);
755 +}
756 +
757 +void au1xxx_gpio1_set_inputs(void)
758 +{
759 + gpio1->pininputen = 0;
760 +}
761 +
762 +EXPORT_SYMBOL(au1xxx_gpio1_set_inputs);
763 +EXPORT_SYMBOL(au1xxx_gpio_tristate);
764 +EXPORT_SYMBOL(au1xxx_gpio_write);
765 +EXPORT_SYMBOL(au1xxx_gpio_read);
766 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/irq.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/irq.c
767 --- linux-2.4.32-rc1/arch/mips/au1000/common/irq.c 2005-01-19 15:09:26.000000000 +0100
768 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/irq.c 2005-03-13 08:56:57.000000000 +0100
769 @@ -303,8 +303,30 @@
770 };
771
772 #ifdef CONFIG_PM
773 -void startup_match20_interrupt(void)
774 +void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *))
775 {
776 + static struct irqaction action;
777 + /* This is a big problem.... since we didn't use request_irq
778 + when kernel/irq.c calls probe_irq_xxx this interrupt will
779 + be probed for usage. This will end up disabling the device :(
780 +
781 + Give it a bogus "action" pointer -- this will keep it from
782 + getting auto-probed!
783 +
784 + By setting the status to match that of request_irq() we
785 + can avoid it. --cgray
786 + */
787 + action.dev_id = handler;
788 + action.flags = 0;
789 + action.mask = 0;
790 + action.name = "Au1xxx TOY";
791 + action.handler = handler;
792 + action.next = NULL;
793 +
794 + irq_desc[AU1000_TOY_MATCH2_INT].action = &action;
795 + irq_desc[AU1000_TOY_MATCH2_INT].status
796 + &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
797 +
798 local_enable_irq(AU1000_TOY_MATCH2_INT);
799 }
800 #endif
801 @@ -508,6 +530,7 @@
802
803 if (!intc0_req0) return;
804
805 +#ifdef AU1000_USB_DEV_REQ_INT
806 /*
807 * Because of the tight timing of SETUP token to reply
808 * transactions, the USB devices-side packet complete
809 @@ -518,6 +541,7 @@
810 do_IRQ(AU1000_USB_DEV_REQ_INT, regs);
811 return;
812 }
813 +#endif
814
815 irq = au_ffs(intc0_req0) - 1;
816 intc0_req0 &= ~(1<<irq);
817 @@ -536,17 +560,7 @@
818
819 irq = au_ffs(intc0_req1) - 1;
820 intc0_req1 &= ~(1<<irq);
821 -#ifdef CONFIG_PM
822 - if (irq == AU1000_TOY_MATCH2_INT) {
823 - mask_and_ack_rise_edge_irq(irq);
824 - counter0_irq(irq, NULL, regs);
825 - local_enable_irq(irq);
826 - }
827 - else
828 -#endif
829 - {
830 - do_IRQ(irq, regs);
831 - }
832 + do_IRQ(irq, regs);
833 }
834
835
836 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/common/Makefile
837 --- linux-2.4.32-rc1/arch/mips/au1000/common/Makefile 2005-01-19 15:09:26.000000000 +0100
838 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/Makefile 2005-01-30 09:01:27.000000000 +0100
839 @@ -19,9 +19,9 @@
840 export-objs = prom.o clocks.o power.o usbdev.o
841
842 obj-y := prom.o int-handler.o irq.o puts.o time.o reset.o cputable.o \
843 - au1xxx_irqmap.o clocks.o power.o setup.o sleeper.o dma.o dbdma.o
844 + au1xxx_irqmap.o clocks.o power.o setup.o sleeper.o dma.o dbdma.o gpio.o
845
846 -export-objs += dma.o dbdma.o
847 +export-objs += dma.o dbdma.o gpio.o
848
849 obj-$(CONFIG_AU1X00_USB_DEVICE) += usbdev.o
850 obj-$(CONFIG_KGDB) += dbg_io.o
851 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/pci_fixup.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/pci_fixup.c
852 --- linux-2.4.32-rc1/arch/mips/au1000/common/pci_fixup.c 2005-01-19 15:09:26.000000000 +0100
853 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/pci_fixup.c 2004-12-03 09:00:32.000000000 +0100
854 @@ -75,9 +75,13 @@
855
856 #ifdef CONFIG_NONCOHERENT_IO
857 /*
858 - * Set the NC bit in controller for pre-AC silicon
859 + * Set the NC bit in controller for Au1500 pre-AC silicon
860 */
861 - au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
862 + u32 prid = read_c0_prid();
863 + if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
864 + au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
865 + printk("Non-coherent PCI accesses enabled\n");
866 + }
867 printk("Non-coherent PCI accesses enabled\n");
868 #endif
869
870 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/pci_ops.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/pci_ops.c
871 --- linux-2.4.32-rc1/arch/mips/au1000/common/pci_ops.c 2004-02-18 14:36:30.000000000 +0100
872 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/pci_ops.c 2005-02-27 23:14:24.000000000 +0100
873 @@ -162,6 +162,7 @@
874 static int config_access(unsigned char access_type, struct pci_dev *dev,
875 unsigned char where, u32 * data)
876 {
877 + int error = PCIBIOS_SUCCESSFUL;
878 #if defined( CONFIG_SOC_AU1500 ) || defined( CONFIG_SOC_AU1550 )
879 unsigned char bus = dev->bus->number;
880 unsigned int dev_fn = dev->devfn;
881 @@ -170,7 +171,6 @@
882 unsigned long offset, status;
883 unsigned long cfg_base;
884 unsigned long flags;
885 - int error = PCIBIOS_SUCCESSFUL;
886 unsigned long entryLo0, entryLo1;
887
888 if (device > 19) {
889 @@ -205,9 +205,8 @@
890 last_entryLo0 = last_entryLo1 = 0xffffffff;
891 }
892
893 - /* Since the Au1xxx doesn't do the idsel timing exactly to spec,
894 - * many board vendors implement their own off-chip idsel, so call
895 - * it now. If it doesn't succeed, may as well bail out at this point.
896 + /* Allow board vendors to implement their own off-chip idsel.
897 + * If it doesn't succeed, may as well bail out at this point.
898 */
899 if (board_pci_idsel) {
900 if (board_pci_idsel(device, 1) == 0) {
901 @@ -271,8 +270,11 @@
902 }
903
904 local_irq_restore(flags);
905 - return error;
906 +#else
907 + /* Fake out Config space access with no responder */
908 + *data = 0xFFFFFFFF;
909 #endif
910 + return error;
911 }
912 #endif
913
914 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/power.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/power.c
915 --- linux-2.4.32-rc1/arch/mips/au1000/common/power.c 2005-01-19 15:09:26.000000000 +0100
916 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/power.c 2005-04-07 02:37:19.000000000 +0200
917 @@ -50,7 +50,6 @@
918
919 static void calibrate_delay(void);
920
921 -extern void set_au1x00_speed(unsigned int new_freq);
922 extern unsigned int get_au1x00_speed(void);
923 extern unsigned long get_au1x00_uart_baud_base(void);
924 extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
925 @@ -116,6 +115,7 @@
926 sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
927 sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
928
929 +#ifndef CONFIG_SOC_AU1200
930 /* Shutdown USB host/device.
931 */
932 sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
933 @@ -127,6 +127,7 @@
934
935 sleep_usbdev_enable = au_readl(USBD_ENABLE);
936 au_writel(0, USBD_ENABLE); au_sync();
937 +#endif
938
939 /* Save interrupt controller state.
940 */
941 @@ -212,14 +213,12 @@
942 int au_sleep(void)
943 {
944 unsigned long wakeup, flags;
945 - extern void save_and_sleep(void);
946 + extern unsigned int save_and_sleep(void);
947
948 spin_lock_irqsave(&pm_lock,flags);
949
950 save_core_regs();
951
952 - flush_cache_all();
953 -
954 /** The code below is all system dependent and we should probably
955 ** have a function call out of here to set this up. You need
956 ** to configure the GPIO or timer interrupts that will bring
957 @@ -227,27 +226,26 @@
958 ** For testing, the TOY counter wakeup is useful.
959 **/
960
961 -#if 0
962 +#if 1
963 au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
964
965 /* gpio 6 can cause a wake up event */
966 wakeup = au_readl(SYS_WAKEMSK);
967 wakeup &= ~(1 << 8); /* turn off match20 wakeup */
968 - wakeup |= 1 << 6; /* turn on gpio 6 wakeup */
969 + wakeup = 1 << 5; /* turn on gpio 6 wakeup */
970 #else
971 - /* For testing, allow match20 to wake us up.
972 - */
973 + /* For testing, allow match20 to wake us up. */
974 #ifdef SLEEP_TEST_TIMEOUT
975 wakeup_counter0_set(sleep_ticks);
976 #endif
977 wakeup = 1 << 8; /* turn on match20 wakeup */
978 wakeup = 0;
979 #endif
980 - au_writel(1, SYS_WAKESRC); /* clear cause */
981 + au_writel(0, SYS_WAKESRC); /* clear cause */
982 au_sync();
983 au_writel(wakeup, SYS_WAKEMSK);
984 au_sync();
985 -
986 + DPRINTK("Entering sleep!\n");
987 save_and_sleep();
988
989 /* after a wakeup, the cpu vectors back to 0x1fc00000 so
990 @@ -255,6 +253,7 @@
991 */
992 restore_core_regs();
993 spin_unlock_irqrestore(&pm_lock, flags);
994 + DPRINTK("Leaving sleep!\n");
995 return 0;
996 }
997
998 @@ -285,7 +284,6 @@
999
1000 if (retval)
1001 return retval;
1002 -
1003 au_sleep();
1004 retval = pm_send_all(PM_RESUME, (void *) 0);
1005 }
1006 @@ -296,7 +294,6 @@
1007 void *buffer, size_t * len)
1008 {
1009 int retval = 0;
1010 - void au1k_wait(void);
1011
1012 if (!write) {
1013 *len = 0;
1014 @@ -305,119 +302,9 @@
1015 if (retval)
1016 return retval;
1017 suspend_mode = 1;
1018 - au1k_wait();
1019 - retval = pm_send_all(PM_RESUME, (void *) 0);
1020 - }
1021 - return retval;
1022 -}
1023
1024 -
1025 -static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
1026 - void *buffer, size_t * len)
1027 -{
1028 - int retval = 0, i;
1029 - unsigned long val, pll;
1030 -#define TMPBUFLEN 64
1031 -#define MAX_CPU_FREQ 396
1032 - char buf[TMPBUFLEN], *p;
1033 - unsigned long flags, intc0_mask, intc1_mask;
1034 - unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
1035 - old_refresh;
1036 - unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
1037 -
1038 - spin_lock_irqsave(&pm_lock, flags);
1039 - if (!write) {
1040 - *len = 0;
1041 - } else {
1042 - /* Parse the new frequency */
1043 - if (*len > TMPBUFLEN - 1) {
1044 - spin_unlock_irqrestore(&pm_lock, flags);
1045 - return -EFAULT;
1046 - }
1047 - if (copy_from_user(buf, buffer, *len)) {
1048 - spin_unlock_irqrestore(&pm_lock, flags);
1049 - return -EFAULT;
1050 - }
1051 - buf[*len] = 0;
1052 - p = buf;
1053 - val = simple_strtoul(p, &p, 0);
1054 - if (val > MAX_CPU_FREQ) {
1055 - spin_unlock_irqrestore(&pm_lock, flags);
1056 - return -EFAULT;
1057 - }
1058 -
1059 - pll = val / 12;
1060 - if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */
1061 - /* revisit this for higher speed cpus */
1062 - spin_unlock_irqrestore(&pm_lock, flags);
1063 - return -EFAULT;
1064 - }
1065 -
1066 - old_baud_base = get_au1x00_uart_baud_base();
1067 - old_cpu_freq = get_au1x00_speed();
1068 -
1069 - new_cpu_freq = pll * 12 * 1000000;
1070 - new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
1071 - set_au1x00_speed(new_cpu_freq);
1072 - set_au1x00_uart_baud_base(new_baud_base);
1073 -
1074 - old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
1075 - new_refresh =
1076 - ((old_refresh * new_cpu_freq) /
1077 - old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
1078 -
1079 - au_writel(pll, SYS_CPUPLL);
1080 - au_sync_delay(1);
1081 - au_writel(new_refresh, MEM_SDREFCFG);
1082 - au_sync_delay(1);
1083 -
1084 - for (i = 0; i < 4; i++) {
1085 - if (au_readl
1086 - (UART_BASE + UART_MOD_CNTRL +
1087 - i * 0x00100000) == 3) {
1088 - old_clk =
1089 - au_readl(UART_BASE + UART_CLK +
1090 - i * 0x00100000);
1091 - // baud_rate = baud_base/clk
1092 - baud_rate = old_baud_base / old_clk;
1093 - /* we won't get an exact baud rate and the error
1094 - * could be significant enough that our new
1095 - * calculation will result in a clock that will
1096 - * give us a baud rate that's too far off from
1097 - * what we really want.
1098 - */
1099 - if (baud_rate > 100000)
1100 - baud_rate = 115200;
1101 - else if (baud_rate > 50000)
1102 - baud_rate = 57600;
1103 - else if (baud_rate > 30000)
1104 - baud_rate = 38400;
1105 - else if (baud_rate > 17000)
1106 - baud_rate = 19200;
1107 - else
1108 - (baud_rate = 9600);
1109 - // new_clk = new_baud_base/baud_rate
1110 - new_clk = new_baud_base / baud_rate;
1111 - au_writel(new_clk,
1112 - UART_BASE + UART_CLK +
1113 - i * 0x00100000);
1114 - au_sync_delay(10);
1115 - }
1116 - }
1117 + retval = pm_send_all(PM_RESUME, (void *) 0);
1118 }
1119 -
1120 -
1121 - /* We don't want _any_ interrupts other than
1122 - * match20. Otherwise our calibrate_delay()
1123 - * calculation will be off, potentially a lot.
1124 - */
1125 - intc0_mask = save_local_and_disable(0);
1126 - intc1_mask = save_local_and_disable(1);
1127 - local_enable_irq(AU1000_TOY_MATCH2_INT);
1128 - spin_unlock_irqrestore(&pm_lock, flags);
1129 - calibrate_delay();
1130 - restore_local_and_enable(0, intc0_mask);
1131 - restore_local_and_enable(1, intc1_mask);
1132 return retval;
1133 }
1134
1135 @@ -425,7 +312,6 @@
1136 static struct ctl_table pm_table[] = {
1137 {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend},
1138 {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep},
1139 - {CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq},
1140 {0}
1141 };
1142
1143 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/reset.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/reset.c
1144 --- linux-2.4.32-rc1/arch/mips/au1000/common/reset.c 2005-01-19 15:09:26.000000000 +0100
1145 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/reset.c 2005-03-19 08:17:51.000000000 +0100
1146 @@ -37,8 +37,6 @@
1147 #include <asm/system.h>
1148 #include <asm/au1000.h>
1149
1150 -extern int au_sleep(void);
1151 -
1152 void au1000_restart(char *command)
1153 {
1154 /* Set all integrated peripherals to disabled states */
1155 @@ -144,6 +142,26 @@
1156 au_writel(0x00, 0xb1900064); /* sys_auxpll */
1157 au_writel(0x00, 0xb1900100); /* sys_pininputen */
1158 break;
1159 + case 0x04000000: /* Au1200 */
1160 + au_writel(0x00, 0xb400300c); /* ddma */
1161 + au_writel(0x00, 0xb1a00004); /* psc 0 */
1162 + au_writel(0x00, 0xb1b00004); /* psc 1 */
1163 + au_writel(0x00d02000, 0xb4020004); /* ehci, ohci, udc, otg */
1164 + au_writel(0x00, 0xb5000004); /* lcd */
1165 + au_writel(0x00, 0xb060000c); /* sd0 */
1166 + au_writel(0x00, 0xb068000c); /* sd1 */
1167 + au_writel(0x00, 0xb1100100); /* swcnt */
1168 + au_writel(0x00, 0xb0300000); /* aes */
1169 + au_writel(0x00, 0xb4004000); /* cim */
1170 + au_writel(0x00, 0xb1100100); /* uart0_enable */
1171 + au_writel(0x00, 0xb1200100); /* uart1_enable */
1172 + au_writel(0x00, 0xb1900020); /* sys_freqctrl0 */
1173 + au_writel(0x00, 0xb1900024); /* sys_freqctrl1 */
1174 + au_writel(0x00, 0xb1900028); /* sys_clksrc */
1175 + au_writel(0x10, 0xb1900060); /* sys_cpupll */
1176 + au_writel(0x00, 0xb1900064); /* sys_auxpll */
1177 + au_writel(0x00, 0xb1900100); /* sys_pininputen */
1178 + break;
1179
1180 default:
1181 break;
1182 @@ -163,32 +181,23 @@
1183
1184 void au1000_halt(void)
1185 {
1186 -#if defined(CONFIG_MIPS_PB1550)
1187 - /* power off system */
1188 - printk("\n** Powering off Pb1550\n");
1189 - au_writew(au_readw(0xAF00001C) | (3<<14), 0xAF00001C);
1190 - au_sync();
1191 - while(1); /* should not get here */
1192 -#endif
1193 - printk(KERN_NOTICE "\n** You can safely turn off the power\n");
1194 -#ifdef CONFIG_MIPS_MIRAGE
1195 - au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
1196 -#endif
1197 -#ifdef CONFIG_PM
1198 - au_sleep();
1199 -
1200 - /* should not get here */
1201 - printk(KERN_ERR "Unable to put cpu in sleep mode\n");
1202 - while(1);
1203 -#else
1204 - while (1)
1205 + /* Use WAIT in a low-power infinite spin loop */
1206 + while (1) {
1207 __asm__(".set\tmips3\n\t"
1208 "wait\n\t"
1209 ".set\tmips0");
1210 -#endif
1211 + }
1212 }
1213
1214 void au1000_power_off(void)
1215 {
1216 + extern void board_power_off (void);
1217 +
1218 + printk(KERN_NOTICE "\n** You can safely turn off the power\n");
1219 +
1220 + /* Give board a chance to power-off */
1221 + board_power_off();
1222 +
1223 + /* If board can't power-off, spin forever */
1224 au1000_halt();
1225 }
1226 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/setup.c
1227 --- linux-2.4.32-rc1/arch/mips/au1000/common/setup.c 2005-01-19 15:09:26.000000000 +0100
1228 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/setup.c 2005-01-30 09:01:27.000000000 +0100
1229 @@ -174,6 +174,40 @@
1230 initrd_end = (unsigned long)&__rd_end;
1231 #endif
1232
1233 +#if defined(CONFIG_SOC_AU1200)
1234 +#ifdef CONFIG_USB_EHCI_HCD
1235 + if ((argptr = strstr(argptr, "usb_ehci=")) == NULL) {
1236 + char usb_args[80];
1237 + argptr = prom_getcmdline();
1238 + memset(usb_args, 0, sizeof(usb_args));
1239 + sprintf(usb_args, " usb_ehci=base:0x%x,len:0x%x,irq:%d",
1240 + USB_EHCI_BASE, USB_EHCI_LEN, AU1000_USB_HOST_INT);
1241 + strcat(argptr, usb_args);
1242 + }
1243 +#ifdef CONFIG_USB_AMD5536UDC
1244 + /* enable EHC + OHC + UDC clocks, memory and bus mastering */
1245 +/* au_writel( 0x00DF207F, USB_MSR_BASE + 4); */
1246 + au_writel( 0xC0DF207F, USB_MSR_BASE + 4); // incl. prefetch
1247 +#else
1248 + /* enable EHC + OHC clocks, memory and bus mastering */
1249 +/* au_writel( 0x00DB200F, USB_MSR_BASE + 4); */
1250 + au_writel( 0xC0DB200F, USB_MSR_BASE + 4); /* incl. prefetch */
1251 +#endif
1252 + udelay(1000);
1253 +
1254 +#else /* CONFIG_USB_EHCI_HCD */
1255 +
1256 +#ifdef CONFIG_USB_AMD5536UDC
1257 +#ifndef CONFIG_USB_OHCI
1258 + /* enable UDC clocks, memory and bus mastering */
1259 +/* au_writel( 0x00DC2070, USB_MSR_BASE + 4); */
1260 + au_writel( 0xC0DC2070, USB_MSR_BASE + 4); // incl. prefetch
1261 + udelay(1000);
1262 +#endif
1263 +#endif
1264 +#endif /* CONFIG_USB_EHCI_HCD */
1265 +#endif /* CONFIG_SOC_AU1200 */
1266 +
1267 #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
1268 #ifdef CONFIG_USB_OHCI
1269 if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
1270 @@ -187,19 +221,38 @@
1271 #endif
1272
1273 #ifdef CONFIG_USB_OHCI
1274 - // enable host controller and wait for reset done
1275 +#if defined(CONFIG_SOC_AU1200)
1276 +#ifndef CONFIG_USB_EHCI_HCD
1277 +#ifdef CONFIG_USB_AMD5536UDC
1278 + /* enable OHC + UDC clocks, memory and bus mastering */
1279 +/* au_writel( 0x00DD2073, USB_MSR_BASE + 4); */
1280 + au_writel( 0xC0DD2073, USB_MSR_BASE + 4); // incl. prefetch
1281 +#else
1282 + /* enable OHC clocks, memory and bus mastering */
1283 + au_writel( 0x00D12003, USB_MSR_BASE + 4);
1284 +#endif
1285 + udelay(1000);
1286 +printk("DEBUG: Reading Au1200 USB2 reg 0x%x\n", au_readl(USB_MSR_BASE + 4));
1287 +#endif
1288 +#else
1289 + /* Au1000, Au1500, Au1100, Au1550 */
1290 + /* enable host controller and wait for reset done */
1291 au_writel(0x08, USB_HOST_CONFIG);
1292 udelay(1000);
1293 au_writel(0x0E, USB_HOST_CONFIG);
1294 udelay(1000);
1295 - au_readl(USB_HOST_CONFIG); // throw away first read
1296 + au_readl(USB_HOST_CONFIG); /* throw away first read */
1297 while (!(au_readl(USB_HOST_CONFIG) & 0x10))
1298 au_readl(USB_HOST_CONFIG);
1299 +#endif /* CONFIG_SOC_AU1200 */
1300 #endif
1301 -#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
1302 +#else
1303 +
1304 +#endif /* defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) */
1305 +
1306
1307 #ifdef CONFIG_FB
1308 - // Needed if PCI video card in use
1309 + /* Needed if PCI video card in use */
1310 conswitchp = &dummy_con;
1311 #endif
1312
1313 @@ -209,8 +262,7 @@
1314 #endif
1315
1316 #ifdef CONFIG_BLK_DEV_IDE
1317 - /* Board setup takes precedence for unique devices.
1318 - */
1319 + /* Board setup takes precedence for unique devices. */
1320 if ((ide_ops == NULL) || (ide_ops == &no_ide_ops))
1321 ide_ops = &std_ide_ops;
1322 #endif
1323 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/sleeper.S linux-2.4.32-rc1.mips/arch/mips/au1000/common/sleeper.S
1324 --- linux-2.4.32-rc1/arch/mips/au1000/common/sleeper.S 2004-02-18 14:36:30.000000000 +0100
1325 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/sleeper.S 2005-01-30 09:01:27.000000000 +0100
1326 @@ -15,17 +15,48 @@
1327 #include <asm/addrspace.h>
1328 #include <asm/regdef.h>
1329 #include <asm/stackframe.h>
1330 +#include <asm/au1000.h>
1331 +
1332 +/*
1333 + * Note: This file is *not* conditional on CONFIG_PM since Alchemy sleep
1334 + * need not be tied to any particular power management scheme.
1335 + */
1336 +
1337 + .extern ___flush_cache_all
1338
1339 .text
1340 - .set macro
1341 - .set noat
1342 .align 5
1343
1344 -/* Save all of the processor general registers and go to sleep.
1345 - * A wakeup condition will get us back here to restore the registers.
1346 +/*
1347 + * Save the processor general registers and go to sleep. A wakeup
1348 + * condition will get us back here to restore the registers.
1349 */
1350 -LEAF(save_and_sleep)
1351
1352 +/* still need to fix alignment issues here */
1353 +save_and_sleep_frmsz = 48
1354 +NESTED(save_and_sleep, save_and_sleep_frmsz, ra)
1355 + .set noreorder
1356 + .set nomacro
1357 + .set noat
1358 + subu sp, save_and_sleep_frmsz
1359 + sw ra, save_and_sleep_frmsz-4(sp)
1360 + sw s0, save_and_sleep_frmsz-8(sp)
1361 + sw s1, save_and_sleep_frmsz-12(sp)
1362 + sw s2, save_and_sleep_frmsz-16(sp)
1363 + sw s3, save_and_sleep_frmsz-20(sp)
1364 + sw s4, save_and_sleep_frmsz-24(sp)
1365 + sw s5, save_and_sleep_frmsz-28(sp)
1366 + sw s6, save_and_sleep_frmsz-32(sp)
1367 + sw s7, save_and_sleep_frmsz-36(sp)
1368 + sw s8, save_and_sleep_frmsz-40(sp)
1369 + sw gp, save_and_sleep_frmsz-44(sp)
1370 +
1371 + /* We only need to save the registers that the calling function
1372 + * hasn't saved for us. 0 is always zero. 8 - 15, 24 and 25 are
1373 + * temporaries and can be used without saving. 26 and 27 are reserved
1374 + * for interrupt/trap handling and expected to change. 29 is the
1375 + * stack pointer which is handled as a special case here.
1376 + */
1377 subu sp, PT_SIZE
1378 sw $1, PT_R1(sp)
1379 sw $2, PT_R2(sp)
1380 @@ -34,14 +65,6 @@
1381 sw $5, PT_R5(sp)
1382 sw $6, PT_R6(sp)
1383 sw $7, PT_R7(sp)
1384 - sw $8, PT_R8(sp)
1385 - sw $9, PT_R9(sp)
1386 - sw $10, PT_R10(sp)
1387 - sw $11, PT_R11(sp)
1388 - sw $12, PT_R12(sp)
1389 - sw $13, PT_R13(sp)
1390 - sw $14, PT_R14(sp)
1391 - sw $15, PT_R15(sp)
1392 sw $16, PT_R16(sp)
1393 sw $17, PT_R17(sp)
1394 sw $18, PT_R18(sp)
1395 @@ -50,32 +73,47 @@
1396 sw $21, PT_R21(sp)
1397 sw $22, PT_R22(sp)
1398 sw $23, PT_R23(sp)
1399 - sw $24, PT_R24(sp)
1400 - sw $25, PT_R25(sp)
1401 - sw $26, PT_R26(sp)
1402 - sw $27, PT_R27(sp)
1403 sw $28, PT_R28(sp)
1404 - sw $29, PT_R29(sp)
1405 sw $30, PT_R30(sp)
1406 sw $31, PT_R31(sp)
1407 +#define PT_C0STATUS PT_LO
1408 +#define PT_CONTEXT PT_HI
1409 +#define PT_PAGEMASK PT_EPC
1410 +#define PT_CONFIG PT_BVADDR
1411 mfc0 k0, CP0_STATUS
1412 - sw k0, 0x20(sp)
1413 + sw k0, PT_C0STATUS(sp) // 0x20
1414 mfc0 k0, CP0_CONTEXT
1415 - sw k0, 0x1c(sp)
1416 + sw k0, PT_CONTEXT(sp) // 0x1c
1417 mfc0 k0, CP0_PAGEMASK
1418 - sw k0, 0x18(sp)
1419 + sw k0, PT_PAGEMASK(sp) // 0x18
1420 mfc0 k0, CP0_CONFIG
1421 - sw k0, 0x14(sp)
1422 + sw k0, PT_CONFIG(sp) // 0x14
1423 +
1424 + .set macro
1425 + .set at
1426 +
1427 + li t0, SYS_SLPPWR
1428 + sw zero, 0(t0) /* Get the processor ready to sleep */
1429 + sync
1430
1431 /* Now set up the scratch registers so the boot rom will
1432 * return to this point upon wakeup.
1433 + * sys_scratch0 : SP
1434 + * sys_scratch1 : RA
1435 + */
1436 + li t0, SYS_SCRATCH0
1437 + li t1, SYS_SCRATCH1
1438 + sw sp, 0(t0)
1439 + la k0, resume_from_sleep
1440 + sw k0, 0(t1)
1441 +
1442 +/*
1443 + * Flush DCACHE to make sure context is in memory
1444 */
1445 - la k0, 1f
1446 - lui k1, 0xb190
1447 - ori k1, 0x18
1448 - sw sp, 0(k1)
1449 - ori k1, 0x1c
1450 - sw k0, 0(k1)
1451 + la t1,___flush_cache_all /* _flush_cache_all is a function pointer */
1452 + lw t0,0(t1)
1453 + jal t0
1454 + nop
1455
1456 /* Put SDRAM into self refresh. Preload instructions into cache,
1457 * issue a precharge, then auto refresh, then sleep commands to it.
1458 @@ -88,30 +126,65 @@
1459 cache 0x14, 96(t0)
1460 .set mips0
1461
1462 + /* Put SDRAM to sleep */
1463 sdsleep:
1464 - lui k0, 0xb400
1465 - sw zero, 0x001c(k0) /* Precharge */
1466 - sw zero, 0x0020(k0) /* Auto refresh */
1467 - sw zero, 0x0030(k0) /* SDRAM sleep */
1468 + li a0, MEM_PHYS_ADDR
1469 + or a0, a0, 0xA0000000
1470 +#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || defined(CONFIG_SOC_AU1500)
1471 + lw k0, MEM_SDMODE0(a0)
1472 + sw zero, MEM_SDPRECMD(a0) /* Precharge */
1473 + sw zero, MEM_SDAUTOREF(a0) /* Auto Refresh */
1474 + sw zero, MEM_SDSLEEP(a0) /* Sleep */
1475 sync
1476 -
1477 - lui k1, 0xb190
1478 - sw zero, 0x0078(k1) /* get ready to sleep */
1479 +#endif
1480 +#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
1481 + sw zero, MEM_SDPRECMD(a0) /* Precharge */
1482 + sw zero, MEM_SDSREF(a0)
1483 +
1484 + #lw t0, MEM_SDSTAT(a0)
1485 + #and t0, t0, 0x01000000
1486 + li t0, 0x01000000
1487 +refresh_not_set:
1488 + lw t1, MEM_SDSTAT(a0)
1489 + and t2, t1, t0
1490 + beq zero, t2, refresh_not_set
1491 + nop
1492 +
1493 + li t0, ~0x30000000
1494 + lw t1, MEM_SDCONFIGA(a0)
1495 + and t1, t0, t1
1496 + sw t1, MEM_SDCONFIGA(a0)
1497 sync
1498 - sw zero, 0x007c(k1) /* Put processor to sleep */
1499 +#endif
1500 +
1501 + li t0, SYS_SLEEP
1502 + sw zero, 0(t0) /* Put processor to sleep */
1503 sync
1504 + nop
1505 + nop
1506 + nop
1507 + nop
1508 + nop
1509 + nop
1510 + nop
1511 + nop
1512 +
1513
1514 /* This is where we return upon wakeup.
1515 * Reload all of the registers and return.
1516 */
1517 -1: nop
1518 - lw k0, 0x20(sp)
1519 +resume_from_sleep:
1520 + nop
1521 + .set nomacro
1522 + .set noat
1523 +
1524 + lw k0, PT_C0STATUS(sp) // 0x20
1525 mtc0 k0, CP0_STATUS
1526 - lw k0, 0x1c(sp)
1527 + lw k0, PT_CONTEXT(sp) // 0x1c
1528 mtc0 k0, CP0_CONTEXT
1529 - lw k0, 0x18(sp)
1530 + lw k0, PT_PAGEMASK(sp) // 0x18
1531 mtc0 k0, CP0_PAGEMASK
1532 - lw k0, 0x14(sp)
1533 + lw k0, PT_CONFIG(sp) // 0x14
1534 mtc0 k0, CP0_CONFIG
1535 lw $1, PT_R1(sp)
1536 lw $2, PT_R2(sp)
1537 @@ -120,14 +193,6 @@
1538 lw $5, PT_R5(sp)
1539 lw $6, PT_R6(sp)
1540 lw $7, PT_R7(sp)
1541 - lw $8, PT_R8(sp)
1542 - lw $9, PT_R9(sp)
1543 - lw $10, PT_R10(sp)
1544 - lw $11, PT_R11(sp)
1545 - lw $12, PT_R12(sp)
1546 - lw $13, PT_R13(sp)
1547 - lw $14, PT_R14(sp)
1548 - lw $15, PT_R15(sp)
1549 lw $16, PT_R16(sp)
1550 lw $17, PT_R17(sp)
1551 lw $18, PT_R18(sp)
1552 @@ -136,15 +201,36 @@
1553 lw $21, PT_R21(sp)
1554 lw $22, PT_R22(sp)
1555 lw $23, PT_R23(sp)
1556 - lw $24, PT_R24(sp)
1557 - lw $25, PT_R25(sp)
1558 - lw $26, PT_R26(sp)
1559 - lw $27, PT_R27(sp)
1560 lw $28, PT_R28(sp)
1561 - lw $29, PT_R29(sp)
1562 lw $30, PT_R30(sp)
1563 lw $31, PT_R31(sp)
1564 +
1565 + .set macro
1566 + .set at
1567 +
1568 + /* clear the wake source, but save it as the return value of the function */
1569 + li t0, SYS_WAKESRC
1570 + lw v0, 0(t0)
1571 + sw v0, PT_R2(sp)
1572 + sw zero, 0(t0)
1573 +
1574 addiu sp, PT_SIZE
1575
1576 + lw gp, save_and_sleep_frmsz-44(sp)
1577 + lw s8, save_and_sleep_frmsz-40(sp)
1578 + lw s7, save_and_sleep_frmsz-36(sp)
1579 + lw s6, save_and_sleep_frmsz-32(sp)
1580 + lw s5, save_and_sleep_frmsz-28(sp)
1581 + lw s4, save_and_sleep_frmsz-24(sp)
1582 + lw s3, save_and_sleep_frmsz-20(sp)
1583 + lw s2, save_and_sleep_frmsz-16(sp)
1584 + lw s1, save_and_sleep_frmsz-12(sp)
1585 + lw s0, save_and_sleep_frmsz-8(sp)
1586 + lw ra, save_and_sleep_frmsz-4(sp)
1587 +
1588 + addu sp, save_and_sleep_frmsz
1589 jr ra
1590 + nop
1591 + .set reorder
1592 END(save_and_sleep)
1593 +
1594 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/common/time.c linux-2.4.32-rc1.mips/arch/mips/au1000/common/time.c
1595 --- linux-2.4.32-rc1/arch/mips/au1000/common/time.c 2005-01-19 15:09:26.000000000 +0100
1596 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/common/time.c 2005-04-08 10:33:17.000000000 +0200
1597 @@ -50,7 +50,6 @@
1598 #include <linux/mc146818rtc.h>
1599 #include <linux/timex.h>
1600
1601 -extern void startup_match20_interrupt(void);
1602 extern void do_softirq(void);
1603 extern volatile unsigned long wall_jiffies;
1604 unsigned long missed_heart_beats = 0;
1605 @@ -59,14 +58,14 @@
1606 static unsigned long r4k_cur; /* What counter should be at next timer irq */
1607 extern rwlock_t xtime_lock;
1608 int no_au1xxx_32khz;
1609 -void (*au1k_wait_ptr)(void);
1610 +extern int allow_au1k_wait; /* default off for CP0 Counter */
1611
1612 /* Cycle counter value at the previous timer interrupt.. */
1613 static unsigned int timerhi = 0, timerlo = 0;
1614
1615 #ifdef CONFIG_PM
1616 #define MATCH20_INC 328
1617 -extern void startup_match20_interrupt(void);
1618 +extern void startup_match20_interrupt(void (*handler)(int, void *, struct pt_regs *));
1619 static unsigned long last_pc0, last_match20;
1620 #endif
1621
1622 @@ -385,7 +384,6 @@
1623 {
1624 unsigned int est_freq;
1625 extern unsigned long (*do_gettimeoffset)(void);
1626 - extern void au1k_wait(void);
1627
1628 printk("calculating r4koff... ");
1629 r4k_offset = cal_r4koff();
1630 @@ -437,9 +435,6 @@
1631 au_writel(0, SYS_TOYWRITE);
1632 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
1633
1634 - au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
1635 - au_writel(~0, SYS_WAKESRC);
1636 - au_sync();
1637 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
1638
1639 /* setup match20 to interrupt once every 10ms */
1640 @@ -447,13 +442,13 @@
1641 au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
1642 au_sync();
1643 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
1644 - startup_match20_interrupt();
1645 + startup_match20_interrupt(counter0_irq);
1646
1647 do_gettimeoffset = do_fast_pm_gettimeoffset;
1648
1649 /* We can use the real 'wait' instruction.
1650 */
1651 - au1k_wait_ptr = au1k_wait;
1652 + allow_au1k_wait = 1;
1653 }
1654
1655 #else
1656 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/board_setup.c
1657 --- linux-2.4.32-rc1/arch/mips/au1000/db1x00/board_setup.c 2005-01-19 15:09:26.000000000 +0100
1658 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/board_setup.c 2005-03-19 08:17:51.000000000 +0100
1659 @@ -46,10 +46,22 @@
1660 #include <asm/au1000.h>
1661 #include <asm/db1x00.h>
1662
1663 -extern struct rtc_ops no_rtc_ops;
1664 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) && defined(CONFIG_MIPS_DB1550)
1665 +#include <asm/au1xxx_dbdma.h>
1666 +extern struct ide_ops *ide_ops;
1667 +extern struct ide_ops au1xxx_ide_ops;
1668 +extern u32 au1xxx_ide_virtbase;
1669 +extern u64 au1xxx_ide_physbase;
1670 +extern int au1xxx_ide_irq;
1671 +
1672 +/* Ddma */
1673 +chan_tab_t *ide_read_ch, *ide_write_ch;
1674 +u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma
1675 +
1676 +dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 };
1677 +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */
1678
1679 -/* not correct for db1550 */
1680 -static BCSR * const bcsr = (BCSR *)0xAE000000;
1681 +extern struct rtc_ops no_rtc_ops;
1682
1683 void board_reset (void)
1684 {
1685 @@ -57,6 +69,13 @@
1686 au_writel(0x00000000, 0xAE00001C);
1687 }
1688
1689 +void board_power_off (void)
1690 +{
1691 +#ifdef CONFIG_MIPS_MIRAGE
1692 + au_writel((1 << 26) | (1 << 10), GPIO2_OUTPUT);
1693 +#endif
1694 +}
1695 +
1696 void __init board_setup(void)
1697 {
1698 u32 pin_func;
1699 @@ -108,8 +127,42 @@
1700 au_writel(0x02000200, GPIO2_OUTPUT);
1701 #endif
1702
1703 +#if defined(CONFIG_AU1XXX_SMC91111)
1704 +#define CPLD_CONTROL (0xAF00000C)
1705 + {
1706 + extern uint32_t au1xxx_smc91111_base;
1707 + extern unsigned int au1xxx_smc91111_irq;
1708 + extern int au1xxx_smc91111_nowait;
1709 +
1710 + au1xxx_smc91111_base = 0xAC000300;
1711 + au1xxx_smc91111_irq = AU1000_GPIO_8;
1712 + au1xxx_smc91111_nowait = 1;
1713 +
1714 + /* set up the Static Bus timing - only 396Mhz */
1715 + bcsr->resets |= 0x7;
1716 + au_writel(0x00010003, MEM_STCFG0);
1717 + au_writel(0x000c00c0, MEM_STCFG2);
1718 + au_writel(0x85E1900D, MEM_STTIME2);
1719 + }
1720 +#endif /* end CONFIG_SMC91111 */
1721 au_sync();
1722
1723 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX) && defined(CONFIG_MIPS_DB1550)
1724 + /*
1725 + * Iniz IDE parameters
1726 + */
1727 + ide_ops = &au1xxx_ide_ops;
1728 + au1xxx_ide_irq = DAUGHTER_CARD_IRQ;
1729 + au1xxx_ide_physbase = AU1XXX_ATA_PHYS_ADDR;
1730 + au1xxx_ide_virtbase = KSEG1ADDR(AU1XXX_ATA_PHYS_ADDR);
1731 +
1732 + /*
1733 + * change PIO or PIO+Ddma
1734 + * check the GPIO-6 pin condition. db1550:s6_dot
1735 + */
1736 + switch4ddma = (au_readl(SYS_PINSTATERD) & (1 << 6)) ? 1 : 0;
1737 +#endif
1738 +
1739 #ifdef CONFIG_MIPS_DB1000
1740 printk("AMD Alchemy Au1000/Db1000 Board\n");
1741 #endif
1742 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/irqmap.c
1743 --- linux-2.4.32-rc1/arch/mips/au1000/db1x00/irqmap.c 2005-01-19 15:09:26.000000000 +0100
1744 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/irqmap.c 2005-01-30 09:06:19.000000000 +0100
1745 @@ -53,6 +53,7 @@
1746 #ifdef CONFIG_MIPS_DB1550
1747 { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 IRQ#
1748 { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 1 IRQ#
1749 + { AU1000_GPIO_8, INTC_INT_LOW_LEVEL, 0 }, // Daughtercard IRQ#
1750 #else
1751 { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 Fully_Interted#
1752 { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, // PCMCIA Card 0 STSCHG#
1753 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/Makefile
1754 --- linux-2.4.32-rc1/arch/mips/au1000/db1x00/Makefile 2005-01-19 15:09:26.000000000 +0100
1755 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/Makefile 2005-01-30 09:06:19.000000000 +0100
1756 @@ -17,4 +17,11 @@
1757 obj-y := init.o board_setup.o irqmap.o
1758 obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o
1759
1760 +ifdef CONFIG_MIPS_DB1100
1761 +ifdef CONFIG_MMC
1762 +obj-y += mmc_support.o
1763 +export-objs += mmc_support.o
1764 +endif
1765 +endif
1766 +
1767 include $(TOPDIR)/Rules.make
1768 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/db1x00/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/mmc_support.c
1769 --- linux-2.4.32-rc1/arch/mips/au1000/db1x00/mmc_support.c 1970-01-01 01:00:00.000000000 +0100
1770 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/db1x00/mmc_support.c 2005-01-30 09:07:01.000000000 +0100
1771 @@ -0,0 +1,126 @@
1772 +/*
1773 + * BRIEF MODULE DESCRIPTION
1774 + *
1775 + * MMC support routines for DB1100.
1776 + *
1777 + *
1778 + * Copyright (c) 2003-2004 Embedded Edge, LLC.
1779 + * Author: Embedded Edge, LLC.
1780 + * Contact: dan@embeddededge.com
1781 + *
1782 + * This program is free software; you can redistribute it and/or modify it
1783 + * under the terms of the GNU General Public License as published by the
1784 + * Free Software Foundation; either version 2 of the License, or (at your
1785 + * option) any later version.
1786 + *
1787 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1788 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1789 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1790 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1791 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1792 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1793 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1794 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1795 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1796 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1797 + *
1798 + * You should have received a copy of the GNU General Public License along
1799 + * with this program; if not, write to the Free Software Foundation, Inc.,
1800 + * 675 Mass Ave, Cambridge, MA 02139, USA.
1801 + *
1802 + */
1803 +
1804 +
1805 +#include <linux/config.h>
1806 +#include <linux/kernel.h>
1807 +#include <linux/module.h>
1808 +#include <linux/init.h>
1809 +
1810 +#include <asm/irq.h>
1811 +#include <asm/au1000.h>
1812 +#include <asm/au1100_mmc.h>
1813 +#include <asm/db1x00.h>
1814 +
1815 +
1816 +/* SD/MMC controller support functions */
1817 +
1818 +/*
1819 + * Detect card.
1820 + */
1821 +void mmc_card_inserted(int _n_, int *_res_)
1822 +{
1823 + u32 gpios = au_readl(SYS_PINSTATERD);
1824 + u32 emptybit = (_n_) ? (1<<20) : (1<<19);
1825 + *_res_ = ((gpios & emptybit) == 0);
1826 +}
1827 +
1828 +/*
1829 + * Check card write protection.
1830 + */
1831 +void mmc_card_writable(int _n_, int *_res_)
1832 +{
1833 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
1834 + unsigned long mmc_wp, board_specific;
1835 +
1836 + if (_n_) {
1837 + mmc_wp = BCSR_BOARD_SD1_WP;
1838 + } else {
1839 + mmc_wp = BCSR_BOARD_SD0_WP;
1840 + }
1841 +
1842 + board_specific = au_readl((unsigned long)(&bcsr->specific));
1843 +
1844 + if (!(board_specific & mmc_wp)) {/* low means card writable */
1845 + *_res_ = 1;
1846 + } else {
1847 + *_res_ = 0;
1848 + }
1849 +}
1850 +
1851 +/*
1852 + * Apply power to card slot.
1853 + */
1854 +void mmc_power_on(int _n_)
1855 +{
1856 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
1857 + unsigned long mmc_pwr, board_specific;
1858 +
1859 + if (_n_) {
1860 + mmc_pwr = BCSR_BOARD_SD1_PWR;
1861 + } else {
1862 + mmc_pwr = BCSR_BOARD_SD0_PWR;
1863 + }
1864 +
1865 + board_specific = au_readl((unsigned long)(&bcsr->specific));
1866 + board_specific |= mmc_pwr;
1867 +
1868 + au_writel(board_specific, (int)(&bcsr->specific));
1869 + au_sync_delay(1);
1870 +}
1871 +
1872 +/*
1873 + * Remove power from card slot.
1874 + */
1875 +void mmc_power_off(int _n_)
1876 +{
1877 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
1878 + unsigned long mmc_pwr, board_specific;
1879 +
1880 + if (_n_) {
1881 + mmc_pwr = BCSR_BOARD_SD1_PWR;
1882 + } else {
1883 + mmc_pwr = BCSR_BOARD_SD0_PWR;
1884 + }
1885 +
1886 + board_specific = au_readl((unsigned long)(&bcsr->specific));
1887 + board_specific &= ~mmc_pwr;
1888 +
1889 + au_writel(board_specific, (int)(&bcsr->specific));
1890 + au_sync_delay(1);
1891 +}
1892 +
1893 +EXPORT_SYMBOL(mmc_card_inserted);
1894 +EXPORT_SYMBOL(mmc_card_writable);
1895 +EXPORT_SYMBOL(mmc_power_on);
1896 +EXPORT_SYMBOL(mmc_power_off);
1897 +
1898 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/au1200_ibutton.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/au1200_ibutton.c
1899 --- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/au1200_ibutton.c 1970-01-01 01:00:00.000000000 +0100
1900 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/au1200_ibutton.c 2005-02-03 07:35:29.000000000 +0100
1901 @@ -0,0 +1,270 @@
1902 +/* ----------------------------------------------------------------------
1903 + * mtwilson_keys.c
1904 + *
1905 + * Copyright (C) 2003 Intrinsyc Software Inc.
1906 + *
1907 + * Intel Personal Media Player buttons
1908 + *
1909 + * This program is free software; you can redistribute it and/or modify
1910 + * it under the terms of the GNU General Public License version 2 as
1911 + * published by the Free Software Foundation.
1912 + *
1913 + * May 02, 2003 : Initial version [FB]
1914 + *
1915 + ------------------------------------------------------------------------*/
1916 +
1917 +#include <linux/config.h>
1918 +#include <linux/module.h>
1919 +#include <linux/kernel.h>
1920 +#include <linux/init.h>
1921 +#include <linux/fs.h>
1922 +#include <linux/sched.h>
1923 +#include <linux/miscdevice.h>
1924 +#include <linux/errno.h>
1925 +#include <linux/poll.h>
1926 +#include <linux/delay.h>
1927 +#include <linux/input.h>
1928 +
1929 +#include <asm/au1000.h>
1930 +#include <asm/uaccess.h>
1931 +#include <asm/au1xxx_gpio.h>
1932 +#include <asm/irq.h>
1933 +#include <asm/keyboard.h>
1934 +#include <linux/time.h>
1935 +
1936 +#define DRIVER_VERSION "V1.0"
1937 +#define DRIVER_AUTHOR "FIC"
1938 +#define DRIVER_DESC "FIC Travis Media Player Button Driver"
1939 +#define DRIVER_NAME "Au1200Button"
1940 +
1941 +#define BUTTON_MAIN (1<<1)
1942 +#define BUTTON_SELECT (1<<6)
1943 +#define BUTTON_GUIDE (1<<12)
1944 +#define BUTTON_DOWN (1<<17)
1945 +#define BUTTON_LEFT (1<<19)
1946 +#define BUTTON_RIGHT (1<<26)
1947 +#define BUTTON_UP (1<<28)
1948 +
1949 +#define BUTTON_MASK (\
1950 + BUTTON_MAIN \
1951 + | BUTTON_SELECT \
1952 + | BUTTON_GUIDE \
1953 + | BUTTON_DOWN \
1954 + | BUTTON_LEFT \
1955 + | BUTTON_RIGHT \
1956 + | BUTTON_UP \
1957 + )
1958 +
1959 +#define BUTTON_INVERT (\
1960 + BUTTON_MAIN \
1961 + | 0 \
1962 + | BUTTON_GUIDE \
1963 + | 0 \
1964 + | 0 \
1965 + | 0 \
1966 + | 0 \
1967 + )
1968 +
1969 +char button_map[32]={0,KEY_S,0,0,0,0,KEY_ENTER,0,0,0,0,0,KEY_G,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1970 +//char button_map[32]={0,0,0,0,0,0,KEY_ENTER,0,0,0,0,0,KEY_G,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1971 +
1972 +//char button_map[32]={0,KEY_TAB,0,0,0,0,KEY_M,0,0,0,0,0,KEY_S,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1973 +//char button_map[32]={0,0,0,0,0,0,KEY_M,0,0,0,0,0,KEY_S,0,0,0,0,KEY_DOWN,0,KEY_LEFT,0,0,0,0,0,0,KEY_RIGHT,0,KEY_UP,0,0,0};
1974 +
1975 +#define BUTTON_COUNT (sizeof (button_map) / sizeof (button_map[0]))
1976 +
1977 +struct input_dev dev;
1978 +struct timeval cur_tv;
1979 +
1980 +static unsigned int old_tv_usec = 0;
1981 +
1982 +static unsigned int read_button_state(void)
1983 +{
1984 + unsigned int state;
1985 +
1986 + state = au_readl(SYS_PINSTATERD) & BUTTON_MASK; /* get gpio status */
1987 +
1988 + state ^= BUTTON_INVERT; /* invert main & guide button */
1989 +
1990 + /* printk("au1200_ibutton.c: button state [0x%X]\r\n",state); */
1991 + return state;
1992 +}
1993 +
1994 +//This function returns 0 if the allowed microseconds have elapsed since the last call to ths function, otherwise it returns 1 to indicate a bounce condition
1995 +static unsigned int bounce()
1996 +{
1997 +
1998 + unsigned int elapsed_time;
1999 +
2000 + do_gettimeofday (&cur_tv);
2001 +
2002 + if (!old_tv_usec) {
2003 + old_tv_usec = cur_tv.tv_usec;
2004 + return 0;
2005 + }
2006 +
2007 + if(cur_tv.tv_usec > old_tv_usec) {
2008 + /* If there hasn't been rollover */
2009 + elapsed_time = ((cur_tv.tv_usec - old_tv_usec));
2010 + }
2011 + else {
2012 + /* Accounting for rollover */
2013 + elapsed_time = ((1000000 - old_tv_usec + cur_tv.tv_usec));
2014 + }
2015 +
2016 + if (elapsed_time > 250000) {
2017 + old_tv_usec = 0; /* reset the bounce time */
2018 + return 0;
2019 + }
2020 +
2021 + return 1;
2022 +}
2023 +
2024 +/* button interrupt handler */
2025 +static void button_interrupt(int irq, void *dev, struct pt_regs *regs)
2026 +{
2027 +
2028 + unsigned int i,bit_mask, key_choice;
2029 + u32 button_state;
2030 +
2031 + /* Report state to upper level */
2032 +
2033 + button_state = read_button_state() & BUTTON_MASK; /* get new gpio status */
2034 +
2035 + /* Return if this is a repeated (bouncing) event */
2036 + if(bounce())
2037 + return;
2038 +
2039 + /* we want to make keystrokes */
2040 + for( i=0; i< BUTTON_COUNT; i++) {
2041 + bit_mask = 1<<i;
2042 + if (button_state & bit_mask) {
2043 + key_choice = button_map[i];
2044 + /* toggle key down */
2045 + input_report_key(dev, key_choice, 1);
2046 + /* toggle key up */
2047 + input_report_key(dev, key_choice, 0);
2048 + printk("ibutton gpio %d stat %x scan code %d\r\n",
2049 + i, button_state, key_choice);
2050 + /* Only report the first key event; it doesn't make
2051 + * sense for two keys to be pressed at the same time,
2052 + * and causes problems with the directional keys
2053 + * return;
2054 + */
2055 + }
2056 + }
2057 +}
2058 +
2059 +static int
2060 +button_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
2061 +{
2062 + static int prev_scancode;
2063 +
2064 + printk( "ibutton.c: translate: scancode=%x raw_mode=%x\n",
2065 + scancode, raw_mode);
2066 +
2067 + if (scancode == 0xe0 || scancode == 0xe1) {
2068 + prev_scancode = scancode;
2069 + return 0;
2070 + }
2071 +
2072 + if (scancode == 0x00 || scancode == 0xff) {
2073 + prev_scancode = 0;
2074 + return 0;
2075 + }
2076 +
2077 + *keycode = scancode;
2078 +
2079 + return 1;
2080 +}
2081 +
2082 +/* init button hardware */
2083 +static int button_hw_init(void)
2084 +{
2085 + unsigned int ipinfunc=0;
2086 +
2087 + printk("au1200_ibutton.c: Initializing buttons hardware\n");
2088 +
2089 + // initialize GPIO pin function assignments
2090 +
2091 + ipinfunc = au_readl(SYS_PINFUNC);
2092 +
2093 + ipinfunc &= ~(SYS_PINFUNC_DMA | SYS_PINFUNC_S0A | SYS_PINFUNC_S0B);
2094 + au_writel( ipinfunc ,SYS_PINFUNC);
2095 +
2096 + ipinfunc |= (SYS_PINFUNC_S0C);
2097 + au_writel( ipinfunc ,SYS_PINFUNC);
2098 +
2099 + return 0;
2100 +}
2101 +
2102 +/* button driver init */
2103 +static int __init button_init(void)
2104 +{
2105 + int ret, i;
2106 + unsigned int flag=0;
2107 +
2108 + printk("au1200_ibutton.c: button_init()\r\n");
2109 +
2110 + button_hw_init();
2111 +
2112 + /* register all button irq handler */
2113 +
2114 + for(i=0; i< sizeof(button_map)/sizeof(button_map[0]); i++)
2115 + {
2116 + /* register irq <-- gpio 1 ,6 ,12 , 17 ,19 , 26 ,28 */
2117 + if(button_map[i] != 0)
2118 + {
2119 + ret = request_irq(AU1000_GPIO_0 + i ,
2120 + &button_interrupt , SA_INTERRUPT ,
2121 + DRIVER_NAME , &dev);
2122 + if(ret) flag |= 1<<i;
2123 + }
2124 + }
2125 +
2126 + printk("au1200_ibutton.c: request_irq,ret:0x%x\r\n",ret);
2127 +
2128 + if (ret) {
2129 + printk("au1200_ibutton.c: request_irq:%X failed\r\n",flag);
2130 + return ret;
2131 + }
2132 +
2133 + dev.name = DRIVER_NAME;
2134 + dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
2135 +
2136 + for (i=0;i<sizeof(button_map)/sizeof(button_map[0]);i++)
2137 + {
2138 + dev.keybit[LONG(button_map[i])] |= BIT(button_map[i]);
2139 + }
2140 +
2141 + input_register_device(&dev);
2142 +
2143 + /* ready to receive interrupts */
2144 +
2145 + return 0;
2146 +}
2147 +
2148 +/* button driver exit */
2149 +static void __exit button_exit(void)
2150 +{
2151 + int i;
2152 +
2153 + for(i=0;i<sizeof(button_map)/sizeof(button_map[0]);i++)
2154 + {
2155 + if(button_map[i] != 0)
2156 + {
2157 + free_irq( AU1000_GPIO_0 + i, &dev);
2158 + }
2159 + }
2160 +
2161 + input_unregister_device(&dev);
2162 +
2163 + printk("au1200_ibutton.c: button_exit()\r\n");
2164 +}
2165 +
2166 +module_init(button_init);
2167 +module_exit(button_exit);
2168 +
2169 +MODULE_AUTHOR( DRIVER_AUTHOR );
2170 +MODULE_DESCRIPTION( DRIVER_DESC );
2171 +MODULE_LICENSE("GPL");
2172 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/au1xxx_dock.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/au1xxx_dock.c
2173 --- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/au1xxx_dock.c 1970-01-01 01:00:00.000000000 +0100
2174 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/au1xxx_dock.c 2005-01-30 09:01:27.000000000 +0100
2175 @@ -0,0 +1,261 @@
2176 +/*
2177 + * Copyright (C) 2003 Metrowerks, All Rights Reserved.
2178 + *
2179 + * This program is free software; you can redistribute it and/or modify
2180 + * it under the terms of the GNU General Public License version 2 as
2181 + * published by the Free Software Foundation.
2182 + */
2183 +
2184 +#include <linux/config.h>
2185 +#include <linux/module.h>
2186 +#include <linux/init.h>
2187 +#include <linux/fs.h>
2188 +#include <linux/sched.h>
2189 +#include <linux/miscdevice.h>
2190 +#include <linux/errno.h>
2191 +#include <linux/poll.h>
2192 +#include <asm/au1000.h>
2193 +#include <asm/uaccess.h>
2194 +#include <asm/au1xxx_gpio.h>
2195 +
2196 +
2197 +#if defined(CONFIG_MIPS_FICMMP)
2198 + #define DOCK_GPIO 215
2199 +#else
2200 + #error Unsupported Au1xxx Platform
2201 +#endif
2202 +
2203 +#define MAKE_FLAG 0x20
2204 +
2205 +#undef DEBUG
2206 +
2207 +#define DEBUG 0
2208 +//#define DEBUG 1
2209 +
2210 +#if DEBUG
2211 +#define DPRINTK(format, args...) printk(__FUNCTION__ ": " format, ## args)
2212 +#else
2213 +#define DPRINTK(format, args...) do { } while (0)
2214 +#endif
2215 +
2216 +/* Please note that this driver is based on a timer and is not interrupt
2217 + * driven. If you are going to make use of this driver, you will need to have
2218 + * your application open the dock listing from the /dev directory first.
2219 + */
2220 +
2221 +struct au1xxx_dock {
2222 + struct fasync_struct *fasync;
2223 + wait_queue_head_t read_wait;
2224 + int open_count;
2225 + unsigned int debounce;
2226 + unsigned int current;
2227 + unsigned int last;
2228 +};
2229 +
2230 +static struct au1xxx_dock dock_info;
2231 +
2232 +
2233 +static void dock_timer_periodic(void *data);
2234 +
2235 +static struct tq_struct dock_task = {
2236 + routine: dock_timer_periodic,
2237 + data: NULL
2238 +};
2239 +
2240 +static int cleanup_flag = 0;
2241 +static DECLARE_WAIT_QUEUE_HEAD(cleanup_wait_queue);
2242 +
2243 +
2244 +static unsigned int read_dock_state(void)
2245 +{
2246 + u32 state;
2247 +
2248 + state = au1xxx_gpio_read(DOCK_GPIO);
2249 +
2250 + /* printk( "Current Dock State: %d\n", state ); */
2251 +
2252 + return state;
2253 +}
2254 +
2255 +
2256 +static void dock_timer_periodic(void *data)
2257 +{
2258 + struct au1xxx_dock *dock = (struct au1xxx_dock *)data;
2259 + unsigned long dock_state;
2260 +
2261 + /* If cleanup wants us to die */
2262 + if (cleanup_flag) {
2263 + /* now cleanup_module can return */
2264 + wake_up(&cleanup_wait_queue);
2265 + } else {
2266 + /* put ourselves back in the task queue */
2267 + queue_task(&dock_task, &tq_timer);
2268 + }
2269 +
2270 + /* read current dock */
2271 + dock_state = read_dock_state();
2272 +
2273 + /* if dock states hasn't changed */
2274 + /* save time and be done. */
2275 + if (dock_state == dock->current) {
2276 + return;
2277 + }
2278 +
2279 + if (dock_state == dock->debounce) {
2280 + dock->current = dock_state;
2281 + } else {
2282 + dock->debounce = dock_state;
2283 + }
2284 + if (dock->current != dock->last) {
2285 + if (waitqueue_active(&dock->read_wait)) {
2286 + wake_up_interruptible(&dock->read_wait);
2287 + }
2288 + }
2289 +}
2290 +
2291 +
2292 +static ssize_t au1xxx_dock_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
2293 +{
2294 + struct au1xxx_dock *dock = filp->private_data;
2295 + char event[3];
2296 + int last;
2297 + int cur;
2298 + int err;
2299 +
2300 +try_again:
2301 +
2302 + while (dock->current == dock->last) {
2303 + if (filp->f_flags & O_NONBLOCK) {
2304 + return -EAGAIN;
2305 + }
2306 + interruptible_sleep_on(&dock->read_wait);
2307 + if (signal_pending(current)) {
2308 + return -ERESTARTSYS;
2309 + }
2310 + }
2311 +
2312 + cur = dock->current;
2313 + last = dock->last;
2314 +
2315 + if(cur != last)
2316 + {
2317 + event[0] = cur ? 'D' : 'U';
2318 + event[1] = '\r';
2319 + event[2] = '\n';
2320 + }
2321 + else
2322 + goto try_again;
2323 +
2324 + dock->last = cur;
2325 + err = copy_to_user(buffer, &event, 3);
2326 + if (err) {
2327 + return err;
2328 + }
2329 +
2330 + return 3;
2331 +}
2332 +
2333 +
2334 +static int au1xxx_dock_open(struct inode *inode, struct file *filp)
2335 +{
2336 + struct au1xxx_dock *dock = &dock_info;
2337 +
2338 + MOD_INC_USE_COUNT;
2339 +
2340 + filp->private_data = dock;
2341 +
2342 + if (dock->open_count++ == 0) {
2343 + dock_task.data = dock;
2344 + cleanup_flag = 0;
2345 + queue_task(&dock_task, &tq_timer);
2346 + }
2347 +
2348 + return 0;
2349 +}
2350 +
2351 +
2352 +static unsigned int au1xxx_dock_poll(struct file *filp, poll_table *wait)
2353 +{
2354 + struct au1xxx_dock *dock = filp->private_data;
2355 + int ret = 0;
2356 +
2357 + DPRINTK("start\n");
2358 + poll_wait(filp, &dock->read_wait, wait);
2359 + if (dock->current != dock->last) {
2360 + ret = POLLIN | POLLRDNORM;
2361 + }
2362 + return ret;
2363 +}
2364 +
2365 +
2366 +static int au1xxx_dock_release(struct inode *inode, struct file *filp)
2367 +{
2368 + struct au1xxx_dock *dock = filp->private_data;
2369 +
2370 + DPRINTK("start\n");
2371 +
2372 + if (--dock->open_count == 0) {
2373 + cleanup_flag = 1;
2374 + sleep_on(&cleanup_wait_queue);
2375 + }
2376 + MOD_DEC_USE_COUNT;
2377 +
2378 + return 0;
2379 +}
2380 +
2381 +
2382 +
2383 +static struct file_operations au1xxx_dock_fops = {
2384 + owner: THIS_MODULE,
2385 + read: au1xxx_dock_read,
2386 + poll: au1xxx_dock_poll,
2387 + open: au1xxx_dock_open,
2388 + release: au1xxx_dock_release,
2389 +};
2390 +
2391 +/*
2392 + * The au1xxx dock is a misc device:
2393 + * Major 10 char
2394 + * Minor 22 /dev/dock
2395 + *
2396 + * This is /dev/misc/dock if devfs is used.
2397 + */
2398 +
2399 +static struct miscdevice au1xxx_dock_dev = {
2400 + minor: 23,
2401 + name: "dock",
2402 + fops: &au1xxx_dock_fops,
2403 +};
2404 +
2405 +static int __init au1xxx_dock_init(void)
2406 +{
2407 + struct au1xxx_dock *dock = &dock_info;
2408 + int ret;
2409 +
2410 + DPRINTK("Initializing dock driver\n");
2411 + dock->open_count = 0;
2412 + cleanup_flag = 0;
2413 + init_waitqueue_head(&dock->read_wait);
2414 +
2415 +
2416 + /* yamon configures GPIO pins for the dock
2417 + * no initialization needed
2418 + */
2419 +
2420 + ret = misc_register(&au1xxx_dock_dev);
2421 +
2422 + DPRINTK("dock driver fully initialized.\n");
2423 +
2424 + return ret;
2425 +}
2426 +
2427 +
2428 +static void __exit au1xxx_dock_exit(void)
2429 +{
2430 + DPRINTK("unloading dock driver\n");
2431 + misc_deregister(&au1xxx_dock_dev);
2432 +}
2433 +
2434 +
2435 +module_init(au1xxx_dock_init);
2436 +module_exit(au1xxx_dock_exit);
2437 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/board_setup.c
2438 --- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/board_setup.c 1970-01-01 01:00:00.000000000 +0100
2439 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/board_setup.c 2005-03-19 08:17:51.000000000 +0100
2440 @@ -0,0 +1,226 @@
2441 +/*
2442 + *
2443 + * BRIEF MODULE DESCRIPTION
2444 + * Alchemy Pb1200 board setup.
2445 + *
2446 + * This program is free software; you can redistribute it and/or modify it
2447 + * under the terms of the GNU General Public License as published by the
2448 + * Free Software Foundation; either version 2 of the License, or (at your
2449 + * option) any later version.
2450 + *
2451 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2452 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2453 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2454 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2455 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2456 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2457 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2458 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2459 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2460 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2461 + *
2462 + * You should have received a copy of the GNU General Public License along
2463 + * with this program; if not, write to the Free Software Foundation, Inc.,
2464 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2465 + */
2466 +#include <linux/config.h>
2467 +#include <linux/init.h>
2468 +#include <linux/sched.h>
2469 +#include <linux/ioport.h>
2470 +#include <linux/mm.h>
2471 +#include <linux/console.h>
2472 +#include <linux/mc146818rtc.h>
2473 +#include <linux/delay.h>
2474 +#include <linux/ide.h>
2475 +
2476 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
2477 +#include <linux/ide.h>
2478 +#endif
2479 +
2480 +#include <asm/cpu.h>
2481 +#include <asm/bootinfo.h>
2482 +#include <asm/irq.h>
2483 +#include <asm/keyboard.h>
2484 +#include <asm/mipsregs.h>
2485 +#include <asm/reboot.h>
2486 +#include <asm/pgtable.h>
2487 +#include <asm/au1000.h>
2488 +#include <asm/ficmmp.h>
2489 +#include <asm/au1xxx_dbdma.h>
2490 +#include <asm/au1xxx_gpio.h>
2491 +
2492 +extern struct rtc_ops no_rtc_ops;
2493 +
2494 +/* value currently in the board configuration register */
2495 +u16 ficmmp_config = 0;
2496 +
2497 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
2498 +extern struct ide_ops *ide_ops;
2499 +extern struct ide_ops au1xxx_ide_ops;
2500 +extern u32 au1xxx_ide_virtbase;
2501 +extern u64 au1xxx_ide_physbase;
2502 +extern int au1xxx_ide_irq;
2503 +
2504 +u32 led_base_addr;
2505 +/* Ddma */
2506 +chan_tab_t *ide_read_ch, *ide_write_ch;
2507 +u32 au1xxx_ide_ddma_enable = 0, switch4ddma = 1; // PIO+ddma
2508 +
2509 +dbdev_tab_t new_dbdev_tab_element = { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 };
2510 +#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX */
2511 +
2512 +void board_reset (void)
2513 +{
2514 + au_writel(0, 0xAD80001C);
2515 +}
2516 +
2517 +void board_power_off (void)
2518 +{
2519 +}
2520 +
2521 +void __init board_setup(void)
2522 +{
2523 + char *argptr = NULL;
2524 + u32 pin_func;
2525 + rtc_ops = &no_rtc_ops;
2526 +
2527 + ficmmp_config_init(); //Initialize FIC control register
2528 +
2529 +#if 0
2530 + /* Enable PSC1 SYNC for AC97. Normaly done in audio driver,
2531 + * but it is board specific code, so put it here.
2532 + */
2533 + pin_func = au_readl(SYS_PINFUNC);
2534 + au_sync();
2535 + pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
2536 + au_writel(pin_func, SYS_PINFUNC);
2537 +
2538 + au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
2539 + au_sync();
2540 +#endif
2541 +
2542 +#if defined( CONFIG_I2C_ALGO_AU1550 )
2543 + {
2544 + u32 freq0, clksrc;
2545 +
2546 + /* Select SMBUS in CPLD */
2547 + /* bcsr->resets &= ~(BCSR_RESETS_PCS0MUX); */
2548 +
2549 + pin_func = au_readl(SYS_PINFUNC);
2550 + au_sync();
2551 + pin_func &= ~(3<<17 | 1<<4);
2552 + /* Set GPIOs correctly */
2553 + pin_func |= 2<<17;
2554 + au_writel(pin_func, SYS_PINFUNC);
2555 + au_sync();
2556 +
2557 + /* The i2c driver depends on 50Mhz clock */
2558 + freq0 = au_readl(SYS_FREQCTRL0);
2559 + au_sync();
2560 + freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
2561 + freq0 |= (3<<SYS_FC_FRDIV1_BIT);
2562 + /* 396Mhz / (3+1)*2 == 49.5Mhz */
2563 + au_writel(freq0, SYS_FREQCTRL0);
2564 + au_sync();
2565 + freq0 |= SYS_FC_FE1;
2566 + au_writel(freq0, SYS_FREQCTRL0);
2567 + au_sync();
2568 +
2569 + clksrc = au_readl(SYS_CLKSRC);
2570 + au_sync();
2571 + clksrc &= ~0x01f00000;
2572 + /* bit 22 is EXTCLK0 for PSC0 */
2573 + clksrc |= (0x3 << 22);
2574 + au_writel(clksrc, SYS_CLKSRC);
2575 + au_sync();
2576 + }
2577 +#endif
2578 +
2579 +#ifdef CONFIG_FB_AU1200
2580 + argptr = prom_getcmdline();
2581 + strcat(argptr, " video=au1200fb:");
2582 +#endif
2583 +
2584 +#if defined(CONFIG_BLK_DEV_IDE_AU1XXX)
2585 + /*
2586 + * Iniz IDE parameters
2587 + */
2588 + ide_ops = &au1xxx_ide_ops;
2589 + au1xxx_ide_irq = FICMMP_IDE_INT;
2590 + au1xxx_ide_physbase = AU1XXX_ATA_PHYS_ADDR;
2591 + au1xxx_ide_virtbase = KSEG1ADDR(AU1XXX_ATA_PHYS_ADDR);
2592 + switch4ddma = 0;
2593 + /*
2594 + ide_ops = &au1xxx_ide_ops;
2595 + au1xxx_ide_irq = FICMMP_IDE_INT;
2596 + au1xxx_ide_base = KSEG1ADDR(AU1XXX_ATA_BASE);
2597 + */
2598 + au1xxx_gpio_write(9, 1);
2599 + printk("B4001010: %X\n", *((u32*)0xB4001010));
2600 + printk("B4001014: %X\n", *((u32*)0xB4001014));
2601 + printk("B4001018: %X\n", *((u32*)0xB4001018));
2602 + printk("B1900100: %X\n", *((u32*)0xB1900100));
2603 +
2604 +#if 0
2605 + ficmmp_config_clear(FICMMP_CONFIG_IDERST);
2606 + mdelay(100);
2607 + ficmmp_config_set(FICMMP_CONFIG_IDERST);
2608 + mdelay(100);
2609 +#endif
2610 + /*
2611 + * change PIO or PIO+Ddma
2612 + * check the GPIO-5 pin condition. pb1200:s18_dot
2613 + */
2614 +/* switch4ddma = 0; //(au_readl(SYS_PINSTATERD) & (1 << 5)) ? 1 : 0; */
2615 +#endif
2616 +
2617 + /* The Pb1200 development board uses external MUX for PSC0 to
2618 + support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
2619 + */
2620 +#if defined(CONFIG_AU1550_PSC_SPI) && defined(CONFIG_I2C_ALGO_AU1550)
2621 + #error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
2622 + Refer to Pb1200 documentation.
2623 +#elif defined( CONFIG_AU1550_PSC_SPI )
2624 + //bcsr->resets |= BCSR_RESETS_PCS0MUX;
2625 +#elif defined( CONFIG_I2C_ALGO_AU1550 )
2626 + //bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
2627 +#endif
2628 + au_sync();
2629 +
2630 + printk("FIC Multimedia Player Board\n");
2631 + au1xxx_gpio_tristate(5);
2632 + printk("B1900100: %X\n", *((volatile u32*)0xB1900100));
2633 + printk("B190002C: %X\n", *((volatile u32*)0xB190002C));
2634 +}
2635 +
2636 +int
2637 +board_au1200fb_panel (void)
2638 +{
2639 + au1xxx_gpio_tristate(6);
2640 +
2641 + if (au1xxx_gpio_read(12) == 0)
2642 + return 9; /* FS453_640x480 (Composite/S-Video) */
2643 + else
2644 + return 7; /* Sharp 320x240 TFT */
2645 +}
2646 +
2647 +int
2648 +board_au1200fb_panel_init (void)
2649 +{
2650 + /*Enable data buffers*/
2651 + ficmmp_config_clear(FICMMP_CONFIG_LCMDATAOUT);
2652 + /*Take LCD out of reset*/
2653 + ficmmp_config_set(FICMMP_CONFIG_LCMPWREN | FICMMP_CONFIG_LCMEN);
2654 + return 0;
2655 +}
2656 +
2657 +int
2658 +board_au1200fb_panel_shutdown (void)
2659 +{
2660 + /*Disable data buffers*/
2661 + ficmmp_config_set(FICMMP_CONFIG_LCMDATAOUT);
2662 + /*Put LCD in reset, remove power*/
2663 + ficmmp_config_clear(FICMMP_CONFIG_LCMEN | FICMMP_CONFIG_LCMPWREN);
2664 + return 0;
2665 +}
2666 +
2667 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/init.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/init.c
2668 --- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/init.c 1970-01-01 01:00:00.000000000 +0100
2669 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/init.c 2005-01-30 09:01:27.000000000 +0100
2670 @@ -0,0 +1,76 @@
2671 +/*
2672 + *
2673 + * BRIEF MODULE DESCRIPTION
2674 + * PB1200 board setup
2675 + *
2676 + * This program is free software; you can redistribute it and/or modify it
2677 + * under the terms of the GNU General Public License as published by the
2678 + * Free Software Foundation; either version 2 of the License, or (at your
2679 + * option) any later version.
2680 + *
2681 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2682 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2683 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2684 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2685 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2686 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2687 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2688 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2689 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2690 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2691 + *
2692 + * You should have received a copy of the GNU General Public License along
2693 + * with this program; if not, write to the Free Software Foundation, Inc.,
2694 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2695 + */
2696 +
2697 +#include <linux/init.h>
2698 +#include <linux/mm.h>
2699 +#include <linux/sched.h>
2700 +#include <linux/bootmem.h>
2701 +#include <asm/addrspace.h>
2702 +#include <asm/bootinfo.h>
2703 +#include <linux/config.h>
2704 +#include <linux/string.h>
2705 +#include <linux/kernel.h>
2706 +#include <linux/sched.h>
2707 +
2708 +int prom_argc;
2709 +char **prom_argv, **prom_envp;
2710 +extern void __init prom_init_cmdline(void);
2711 +extern char *prom_getenv(char *envname);
2712 +
2713 +const char *get_system_type(void)
2714 +{
2715 + return "FIC Multimedia Player (Au1200)";
2716 +}
2717 +
2718 +u32 mae_memsize = 0;
2719 +
2720 +int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
2721 +{
2722 + unsigned char *memsize_str;
2723 + unsigned long memsize;
2724 +
2725 + prom_argc = argc;
2726 + prom_argv = argv;
2727 + prom_envp = envp;
2728 +
2729 + mips_machgroup = MACH_GROUP_ALCHEMY;
2730 + mips_machtype = MACH_PB1000; /* set the platform # */
2731 + prom_init_cmdline();
2732 +
2733 + memsize_str = prom_getenv("memsize");
2734 + if (!memsize_str) {
2735 + memsize = 0x08000000;
2736 + } else {
2737 + memsize = simple_strtol(memsize_str, NULL, 0);
2738 + }
2739 +
2740 + /* reserved 32MB for MAE driver */
2741 + memsize -= (32 * 1024 * 1024);
2742 + add_memory_region(0, memsize, BOOT_MEM_RAM);
2743 + mae_memsize = memsize; /* for drivers/char/au1xxx_mae.c */
2744 + return 0;
2745 +}
2746 +
2747 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/irqmap.c
2748 --- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/irqmap.c 1970-01-01 01:00:00.000000000 +0100
2749 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/irqmap.c 2005-01-30 09:01:27.000000000 +0100
2750 @@ -0,0 +1,61 @@
2751 +/*
2752 + * BRIEF MODULE DESCRIPTION
2753 + * Au1xxx irq map table
2754 + *
2755 + * This program is free software; you can redistribute it and/or modify it
2756 + * under the terms of the GNU General Public License as published by the
2757 + * Free Software Foundation; either version 2 of the License, or (at your
2758 + * option) any later version.
2759 + *
2760 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2761 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2762 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2763 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2764 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2765 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2766 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2767 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2768 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2769 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2770 + *
2771 + * You should have received a copy of the GNU General Public License along
2772 + * with this program; if not, write to the Free Software Foundation, Inc.,
2773 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2774 + */
2775 +#include <linux/errno.h>
2776 +#include <linux/init.h>
2777 +#include <linux/irq.h>
2778 +#include <linux/kernel_stat.h>
2779 +#include <linux/module.h>
2780 +#include <linux/signal.h>
2781 +#include <linux/sched.h>
2782 +#include <linux/types.h>
2783 +#include <linux/interrupt.h>
2784 +#include <linux/ioport.h>
2785 +#include <linux/timex.h>
2786 +#include <linux/slab.h>
2787 +#include <linux/random.h>
2788 +#include <linux/delay.h>
2789 +
2790 +#include <asm/bitops.h>
2791 +#include <asm/bootinfo.h>
2792 +#include <asm/io.h>
2793 +#include <asm/mipsregs.h>
2794 +#include <asm/system.h>
2795 +#include <asm/au1000.h>
2796 +#include <asm/ficmmp.h>
2797 +
2798 +au1xxx_irq_map_t au1xxx_irq_map[] = {
2799 + { FICMMP_IDE_INT, INTC_INT_HIGH_LEVEL, 0 },
2800 + { AU1XXX_SMC91111_IRQ, INTC_INT_HIGH_LEVEL, 0 },
2801 + { AU1000_GPIO_1 , INTC_INT_FALL_EDGE, 0 }, // main button
2802 + { AU1000_GPIO_6 , INTC_INT_RISE_EDGE, 0 }, // select button
2803 + { AU1000_GPIO_12, INTC_INT_FALL_EDGE, 0 }, // guide button
2804 + { AU1000_GPIO_17, INTC_INT_RISE_EDGE, 0 }, // down button
2805 + { AU1000_GPIO_19, INTC_INT_RISE_EDGE, 0 }, // left button
2806 + { AU1000_GPIO_26, INTC_INT_RISE_EDGE, 0 }, // right button
2807 + { AU1000_GPIO_28, INTC_INT_RISE_EDGE, 0 }, // up button
2808 +};
2809 +
2810 +int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
2811 +
2812 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/ficmmp/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/Makefile
2813 --- linux-2.4.32-rc1/arch/mips/au1000/ficmmp/Makefile 1970-01-01 01:00:00.000000000 +0100
2814 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/ficmmp/Makefile 2005-01-30 09:01:27.000000000 +0100
2815 @@ -0,0 +1,25 @@
2816 +#
2817 +# Copyright 2000 MontaVista Software Inc.
2818 +# Author: MontaVista Software, Inc.
2819 +# ppopov@mvista.com or source@mvista.com
2820 +#
2821 +# Makefile for the Alchemy Semiconductor FIC board.
2822 +#
2823 +# Note! Dependencies are done automagically by 'make dep', which also
2824 +# removes any old dependencies. DON'T put your own dependencies here
2825 +# unless it's something special (ie not a .c file).
2826 +#
2827 +
2828 +USE_STANDARD_AS_RULE := true
2829 +
2830 +O_TARGET := ficmmp.o
2831 +
2832 +obj-y := init.o board_setup.o irqmap.o au1200_ibutton.o au1xxx_dock.o
2833 +
2834 +ifdef CONFIG_MMC
2835 +obj-y += mmc_support.o
2836 +export-objs +=mmc_support.o
2837 +endif
2838 +
2839 +
2840 +include $(TOPDIR)/Rules.make
2841 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/board_setup.c
2842 --- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/board_setup.c 2005-01-19 15:09:26.000000000 +0100
2843 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/board_setup.c 2005-03-19 08:17:51.000000000 +0100
2844 @@ -51,12 +51,19 @@
2845 {
2846 }
2847
2848 +void board_power_off (void)
2849 +{
2850 +}
2851 +
2852 void __init board_setup(void)
2853 {
2854 u32 pin_func;
2855
2856 rtc_ops = &no_rtc_ops;
2857
2858 + /* Set GPIO14 high to make CD/DAT1 high for MMC to work */
2859 + au_writel(1<<14, SYS_OUTPUTSET);
2860 +
2861 #ifdef CONFIG_AU1X00_USB_DEVICE
2862 // 2nd USB port is USB device
2863 pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
2864 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/buttons.c linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/buttons.c
2865 --- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/buttons.c 1970-01-01 01:00:00.000000000 +0100
2866 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/buttons.c 2005-02-11 22:09:55.000000000 +0100
2867 @@ -0,0 +1,308 @@
2868 +/*
2869 + * Copyright (C) 2003 Metrowerks, All Rights Reserved.
2870 + *
2871 + * This program is free software; you can redistribute it and/or modify
2872 + * it under the terms of the GNU General Public License version 2 as
2873 + * published by the Free Software Foundation.
2874 + */
2875 +
2876 +#include <linux/config.h>
2877 +#include <linux/module.h>
2878 +#include <linux/init.h>
2879 +#include <linux/fs.h>
2880 +#include <linux/sched.h>
2881 +#include <linux/miscdevice.h>
2882 +#include <linux/errno.h>
2883 +#include <linux/poll.h>
2884 +#include <asm/au1000.h>
2885 +#include <asm/uaccess.h>
2886 +
2887 +#define BUTTON_SELECT (1<<1)
2888 +#define BUTTON_1 (1<<2)
2889 +#define BUTTON_2 (1<<3)
2890 +#define BUTTON_ONOFF (1<<6)
2891 +#define BUTTON_3 (1<<7)
2892 +#define BUTTON_4 (1<<8)
2893 +#define BUTTON_LEFT (1<<9)
2894 +#define BUTTON_DOWN (1<<10)
2895 +#define BUTTON_RIGHT (1<<11)
2896 +#define BUTTON_UP (1<<12)
2897 +
2898 +#define BUTTON_MASK (\
2899 + BUTTON_SELECT \
2900 + | BUTTON_1 \
2901 + | BUTTON_2 \
2902 + | BUTTON_ONOFF \
2903 + | BUTTON_3 \
2904 + | BUTTON_4 \
2905 + | BUTTON_LEFT \
2906 + | BUTTON_DOWN \
2907 + | BUTTON_RIGHT \
2908 + | BUTTON_UP \
2909 + )
2910 +
2911 +#define BUTTON_INVERT (\
2912 + BUTTON_SELECT \
2913 + | BUTTON_1 \
2914 + | BUTTON_2 \
2915 + | BUTTON_3 \
2916 + | BUTTON_4 \
2917 + | BUTTON_LEFT \
2918 + | BUTTON_DOWN \
2919 + | BUTTON_RIGHT \
2920 + | BUTTON_UP \
2921 + )
2922 +
2923 +
2924 +
2925 +#define MAKE_FLAG 0x20
2926 +
2927 +#undef DEBUG
2928 +
2929 +#define DEBUG 0
2930 +//#define DEBUG 1
2931 +
2932 +#if DEBUG
2933 +#define DPRINTK(format, args...) printk(__FUNCTION__ ": " format, ## args)
2934 +#else
2935 +#define DPRINTK(format, args...) do { } while (0)
2936 +#endif
2937 +
2938 +/* Please note that this driver is based on a timer and is not interrupt
2939 + * driven. If you are going to make use of this driver, you will need to have
2940 + * your application open the buttons listing from the /dev directory first.
2941 + */
2942 +
2943 +struct hydrogen3_buttons {
2944 + struct fasync_struct *fasync;
2945 + wait_queue_head_t read_wait;
2946 + int open_count;
2947 + unsigned int debounce;
2948 + unsigned int current;
2949 + unsigned int last;
2950 +};
2951 +
2952 +static struct hydrogen3_buttons buttons_info;
2953 +
2954 +
2955 +static void button_timer_periodic(void *data);
2956 +
2957 +static struct tq_struct button_task = {
2958 + routine: button_timer_periodic,
2959 + data: NULL
2960 +};
2961 +
2962 +static int cleanup_flag = 0;
2963 +static DECLARE_WAIT_QUEUE_HEAD(cleanup_wait_queue);
2964 +
2965 +
2966 +static unsigned int read_button_state(void)
2967 +{
2968 + unsigned long state;
2969 +
2970 + state = inl(SYS_PINSTATERD) & BUTTON_MASK;
2971 + state ^= BUTTON_INVERT;
2972 +
2973 + DPRINTK( "Current Button State: %d\n", state );
2974 +
2975 + return state;
2976 +}
2977 +
2978 +
2979 +static void button_timer_periodic(void *data)
2980 +{
2981 + struct hydrogen3_buttons *buttons = (struct hydrogen3_buttons *)data;
2982 + unsigned long button_state;
2983 +
2984 + // If cleanup wants us to die
2985 + if (cleanup_flag) {
2986 + wake_up(&cleanup_wait_queue); // now cleanup_module can return
2987 + } else {
2988 + queue_task(&button_task, &tq_timer); // put ourselves back in the task queue
2989 + }
2990 +
2991 + // read current buttons
2992 + button_state = read_button_state();
2993 +
2994 + // if no buttons are down and nothing to do then
2995 + // save time and be done.
2996 + if ((button_state == 0) && (buttons->current == 0)) {
2997 + return;
2998 + }
2999 +
3000 + if (button_state == buttons->debounce) {
3001 + buttons->current = button_state;
3002 + } else {
3003 + buttons->debounce = button_state;
3004 + }
3005 +// printk("0x%04x\n", button_state);
3006 + if (buttons->current != buttons->last) {
3007 + if (waitqueue_active(&buttons->read_wait)) {
3008 + wake_up_interruptible(&buttons->read_wait);
3009 + }
3010 + }
3011 +}
3012 +
3013 +
3014 +static ssize_t hydrogen3_buttons_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
3015 +{
3016 + struct hydrogen3_buttons *buttons = filp->private_data;
3017 + char events[16];
3018 + int index;
3019 + int last;
3020 + int cur;
3021 + int bit;
3022 + int bit_mask;
3023 + int err;
3024 +
3025 + DPRINTK("start\n");
3026 +
3027 +try_again:
3028 +
3029 + while (buttons->current == buttons->last) {
3030 + if (filp->f_flags & O_NONBLOCK) {
3031 + return -EAGAIN;
3032 + }
3033 + interruptible_sleep_on(&buttons->read_wait);
3034 + if (signal_pending(current)) {
3035 + return -ERESTARTSYS;
3036 + }
3037 + }
3038 +
3039 + cur = buttons->current;
3040 + last = buttons->last;
3041 +
3042 + index = 0;
3043 + bit_mask = 1;
3044 + for (bit = 0; (bit < 16) && count; bit++) {
3045 + if ((cur ^ last) & bit_mask) {
3046 + if (cur & bit_mask) {
3047 + events[index] = (bit | MAKE_FLAG) + 'A';
3048 + last |= bit_mask;
3049 + } else {
3050 + events[index] = bit + 'A';
3051 + last &= ~bit_mask;
3052 + }
3053 + index++;
3054 + count--;
3055 + }
3056 + bit_mask <<= 1;
3057 + }
3058 + buttons->last = last;
3059 +
3060 + if (index == 0) {
3061 + goto try_again;
3062 + }
3063 +
3064 + err = copy_to_user(buffer, events, index);
3065 + if (err) {
3066 + return err;
3067 + }
3068 +
3069 + return index;
3070 +}
3071 +
3072 +
3073 +static int hydrogen3_buttons_open(struct inode *inode, struct file *filp)
3074 +{
3075 + struct hydrogen3_buttons *buttons = &buttons_info;
3076 +
3077 + DPRINTK("start\n");
3078 + MOD_INC_USE_COUNT;
3079 +
3080 + filp->private_data = buttons;
3081 +
3082 + if (buttons->open_count++ == 0) {
3083 + button_task.data = buttons;
3084 + cleanup_flag = 0;
3085 + queue_task(&button_task, &tq_timer);
3086 + }
3087 +
3088 + return 0;
3089 +}
3090 +
3091 +
3092 +static unsigned int hydrogen3_buttons_poll(struct file *filp, poll_table *wait)
3093 +{
3094 + struct hydrogen3_buttons *buttons = filp->private_data;
3095 + int ret = 0;
3096 +
3097 + DPRINTK("start\n");
3098 + poll_wait(filp, &buttons->read_wait, wait);
3099 + if (buttons->current != buttons->last) {
3100 + ret = POLLIN | POLLRDNORM;
3101 + }
3102 + return ret;
3103 +}
3104 +
3105 +
3106 +static int hydrogen3_buttons_release(struct inode *inode, struct file *filp)
3107 +{
3108 + struct hydrogen3_buttons *buttons = filp->private_data;
3109 +
3110 + DPRINTK("start\n");
3111 +
3112 + if (--buttons->open_count == 0) {
3113 + cleanup_flag = 1;
3114 + sleep_on(&cleanup_wait_queue);
3115 + }
3116 + MOD_DEC_USE_COUNT;
3117 +
3118 + return 0;
3119 +}
3120 +
3121 +
3122 +
3123 +static struct file_operations hydrogen3_buttons_fops = {
3124 + owner: THIS_MODULE,
3125 + read: hydrogen3_buttons_read,
3126 + poll: hydrogen3_buttons_poll,
3127 + open: hydrogen3_buttons_open,
3128 + release: hydrogen3_buttons_release,
3129 +};
3130 +
3131 +/*
3132 + * The hydrogen3 buttons is a misc device:
3133 + * Major 10 char
3134 + * Minor 22 /dev/buttons
3135 + *
3136 + * This is /dev/misc/buttons if devfs is used.
3137 + */
3138 +
3139 +static struct miscdevice hydrogen3_buttons_dev = {
3140 + minor: 22,
3141 + name: "buttons",
3142 + fops: &hydrogen3_buttons_fops,
3143 +};
3144 +
3145 +static int __init hydrogen3_buttons_init(void)
3146 +{
3147 + struct hydrogen3_buttons *buttons = &buttons_info;
3148 + int ret;
3149 +
3150 + DPRINTK("Initializing buttons driver\n");
3151 + buttons->open_count = 0;
3152 + cleanup_flag = 0;
3153 + init_waitqueue_head(&buttons->read_wait);
3154 +
3155 +
3156 + // yamon configures GPIO pins for the buttons
3157 + // no initialization needed
3158 +
3159 + ret = misc_register(&hydrogen3_buttons_dev);
3160 +
3161 + DPRINTK("Buttons driver fully initialized.\n");
3162 +
3163 + return ret;
3164 +}
3165 +
3166 +
3167 +static void __exit hydrogen3_buttons_exit(void)
3168 +{
3169 + DPRINTK("unloading buttons driver\n");
3170 + misc_deregister(&hydrogen3_buttons_dev);
3171 +}
3172 +
3173 +
3174 +module_init(hydrogen3_buttons_init);
3175 +module_exit(hydrogen3_buttons_exit);
3176 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/Makefile
3177 --- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/Makefile 2005-01-19 15:09:26.000000000 +0100
3178 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/Makefile 2005-02-11 22:09:55.000000000 +0100
3179 @@ -14,6 +14,11 @@
3180
3181 O_TARGET := hydrogen3.o
3182
3183 -obj-y := init.o board_setup.o irqmap.o
3184 +obj-y := init.o board_setup.o irqmap.o buttons.o
3185 +
3186 +ifdef CONFIG_MMC
3187 +obj-y += mmc_support.o
3188 +export-objs +=mmc_support.o
3189 +endif
3190
3191 include $(TOPDIR)/Rules.make
3192 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/mmc_support.c
3193 --- linux-2.4.32-rc1/arch/mips/au1000/hydrogen3/mmc_support.c 1970-01-01 01:00:00.000000000 +0100
3194 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/hydrogen3/mmc_support.c 2005-02-02 05:27:06.000000000 +0100
3195 @@ -0,0 +1,89 @@
3196 +/*
3197 + * BRIEF MODULE DESCRIPTION
3198 + *
3199 + * MMC support routines for Hydrogen3.
3200 + *
3201 + *
3202 + * Copyright (c) 2003-2004 Embedded Edge, LLC.
3203 + * Author: Embedded Edge, LLC.
3204 + * Contact: dan@embeddededge.com
3205 + *
3206 + * This program is free software; you can redistribute it and/or modify it
3207 + * under the terms of the GNU General Public License as published by the
3208 + * Free Software Foundation; either version 2 of the License, or (at your
3209 + * option) any later version.
3210 + *
3211 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3212 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3213 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
3214 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3215 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3216 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3217 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3218 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3219 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3220 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3221 + *
3222 + * You should have received a copy of the GNU General Public License along
3223 + * with this program; if not, write to the Free Software Foundation, Inc.,
3224 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3225 + *
3226 + */
3227 +
3228 +
3229 +#include <linux/config.h>
3230 +#include <linux/kernel.h>
3231 +#include <linux/module.h>
3232 +#include <linux/init.h>
3233 +
3234 +#include <asm/irq.h>
3235 +#include <asm/au1000.h>
3236 +#include <asm/au1100_mmc.h>
3237 +
3238 +#define GPIO_17_WP 0x20000
3239 +
3240 +/* SD/MMC controller support functions */
3241 +
3242 +/*
3243 + * Detect card.
3244 + */
3245 +void mmc_card_inserted(int _n_, int *_res_)
3246 +{
3247 + u32 gpios = au_readl(SYS_PINSTATERD);
3248 + u32 emptybit = (1<<16);
3249 + *_res_ = ((gpios & emptybit) == 0);
3250 +}
3251 +
3252 +/*
3253 + * Check card write protection.
3254 + */
3255 +void mmc_card_writable(int _n_, int *_res_)
3256 +{
3257 + unsigned long mmc_wp, board_specific;
3258 + board_specific = au_readl(SYS_OUTPUTSET);
3259 + mmc_wp=GPIO_17_WP;
3260 + if (!(board_specific & mmc_wp)) {/* low means card writable */
3261 + *_res_ = 1;
3262 + } else {
3263 + *_res_ = 0;
3264 + }
3265 +}
3266 +/*
3267 + * Apply power to card slot.
3268 + */
3269 +void mmc_power_on(int _n_)
3270 +{
3271 +}
3272 +
3273 +/*
3274 + * Remove power from card slot.
3275 + */
3276 +void mmc_power_off(int _n_)
3277 +{
3278 +}
3279 +
3280 +EXPORT_SYMBOL(mmc_card_inserted);
3281 +EXPORT_SYMBOL(mmc_card_writable);
3282 +EXPORT_SYMBOL(mmc_power_on);
3283 +EXPORT_SYMBOL(mmc_power_off);
3284 +
3285 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/mtx-1/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/board_setup.c
3286 --- linux-2.4.32-rc1/arch/mips/au1000/mtx-1/board_setup.c 2004-02-18 14:36:30.000000000 +0100
3287 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/board_setup.c 2004-11-26 09:37:16.000000000 +0100
3288 @@ -48,6 +48,12 @@
3289
3290 extern struct rtc_ops no_rtc_ops;
3291
3292 +void board_reset (void)
3293 +{
3294 + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
3295 + au_writel(0x00000000, 0xAE00001C);
3296 +}
3297 +
3298 void __init board_setup(void)
3299 {
3300 rtc_ops = &no_rtc_ops;
3301 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/mtx-1/irqmap.c linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/irqmap.c
3302 --- linux-2.4.32-rc1/arch/mips/au1000/mtx-1/irqmap.c 2005-01-19 15:09:26.000000000 +0100
3303 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/mtx-1/irqmap.c 2004-11-26 09:37:16.000000000 +0100
3304 @@ -72,10 +72,10 @@
3305 * A B C D
3306 */
3307 {
3308 - {INTA, INTB, INTC, INTD}, /* IDSEL 0 */
3309 - {INTA, INTB, INTC, INTD}, /* IDSEL 1 */
3310 - {INTA, INTB, INTC, INTD}, /* IDSEL 2 */
3311 - {INTA, INTB, INTC, INTD}, /* IDSEL 3 */
3312 + {INTA, INTB, INTX, INTX}, /* IDSEL 0 */
3313 + {INTB, INTA, INTX, INTX}, /* IDSEL 1 */
3314 + {INTC, INTD, INTX, INTX}, /* IDSEL 2 */
3315 + {INTD, INTC, INTX, INTX}, /* IDSEL 3 */
3316 };
3317 const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4;
3318 return PCI_IRQ_TABLE_LOOKUP;
3319 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1000/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1000/board_setup.c
3320 --- linux-2.4.32-rc1/arch/mips/au1000/pb1000/board_setup.c 2005-01-19 15:09:26.000000000 +0100
3321 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1000/board_setup.c 2005-03-19 08:17:51.000000000 +0100
3322 @@ -58,6 +58,10 @@
3323 {
3324 }
3325
3326 +void board_power_off (void)
3327 +{
3328 +}
3329 +
3330 void __init board_setup(void)
3331 {
3332 u32 pin_func, static_cfg0;
3333 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1100/board_setup.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/board_setup.c
3334 --- linux-2.4.32-rc1/arch/mips/au1000/pb1100/board_setup.c 2005-01-19 15:09:26.000000000 +0100
3335 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/board_setup.c 2005-03-19 08:17:51.000000000 +0100
3336 @@ -62,6 +62,10 @@
3337 au_writel(0x00000000, 0xAE00001C);
3338 }
3339
3340 +void board_power_off (void)
3341 +{
3342 +}
3343 +
3344 void __init board_setup(void)
3345 {
3346 u32 pin_func;
3347 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1100/Makefile linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/Makefile
3348 --- linux-2.4.32-rc1/arch/mips/au1000/pb1100/Makefile 2003-08-25 13:44:39.000000000 +0200
3349 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/Makefile 2005-01-30 09:10:29.000000000 +0100
3350 @@ -16,4 +16,10 @@
3351
3352 obj-y := init.o board_setup.o irqmap.o
3353
3354 +
3355 +ifdef CONFIG_MMC
3356 +obj-y += mmc_support.o
3357 +export-objs += mmc_support.o
3358 +endif
3359 +
3360 include $(TOPDIR)/Rules.make
3361 diff -Nur linux-2.4.32-rc1/arch/mips/au1000/pb1100/mmc_support.c linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/mmc_support.c
3362 --- linux-2.4.32-rc1/arch/mips/au1000/pb1100/mmc_support.c 1970-01-01 01:00:00.000000000 +0100
3363 +++ linux-2.4.32-rc1.mips/arch/mips/au1000/pb1100/mmc_support.c 2005-01-30 09:10:29.000000000 +0100
3364 @@ -0,0 +1,126 @@
3365 +/*
3366 + * BRIEF MODULE DESCRIPTION
3367 + *
3368 + * MMC support routines for PB1100.
3369 + *
3370 + *
3371 + * Copyright (c) 2003-2004 Embedded Edge, LLC.
3372 + * Author: Embedded Edge, LLC.
3373 + * Contact: dan@embeddededge.com
3374 + *
3375 + * This program is free software; you can redistribute it and/or modify it
3376 + * under the terms of the GNU General Public License as published by the
3377 + * Free Software Foundation; either version 2 of the License, or (at your
3378 + * option) any later version.
3379 + *
3380 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3381 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3382 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
3383 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3384 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3385 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
3386 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
3387 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3388 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3389 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3390 + *
3391 + * You should have received a copy of the GNU General Public License along
3392 + * with this program; if not, write to the Free Software Foundation, Inc.,
3393 + * 675 Mass Ave, Cambridge, MA 02139, USA.
3394 + *
3395 + */
3396 +
3397 +
3398 +#include <linux/config.h>
3399 +#include <linux/kernel.h>
3400 +#include <linux/module.h>
3401 +#include <linux/init.h>
3402 +
3403 +#include <asm/irq.h>
3404 +#include <asm/au1000.h>
3405 +#include <asm/au1100_mmc.h>
3406 +#include <asm/pb1100.h>
3407 +
3408 +
3409 +/* SD/MMC controller support functions */
3410 +
3411 +/*
3412 + * Detect card.
3413 + */
3414 +void mmc_card_inserted(int _n_, int *_res_)
3415 +{
3416 + u32 gpios = au_readl(SYS_PINSTATERD);
3417 + u32 emptybit = (_n_) ? (1<<15) : (1<<14);
3418 + *_res_ = ((gpios & emptybit) == 0);
3419 +}
3420 +
3421 +/*
3422 + * Check card write protection.
3423 + */
3424 +void mmc_card_writable(int _n_, int *_res_)
3425 +{
3426 + BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
3427 + unsigned long mmc_wp, board_specific;
3428 +
3429 + if (_n_) {
3430 + mmc_wp = BCSR_PCMCIA_SD1_WP;
3431 + } else {
3432 + mmc_wp = BCSR_PCMCIA_SD0_WP;
3433 + }
3434 +
3435 + board_specific = au_readl((unsigned long)(&bcsr->pcmcia));
3436 +