1 --- linux-2.6.5/kernel/printk.c~heh 2004-04-03 22:38:24.000000000 -0500
2 +++ linux-2.6.5/kernel/printk.c 2004-04-30 20:57:36.000000000 -0400
4 printk_ratelimit_burst);
6 EXPORT_SYMBOL(printk_ratelimit);
8 +#include <linux/sysrq.h>
11 +show_msg_info(int key, struct pt_regs *regs, struct tty_struct *tty)
13 + call_console_drivers(log_end - logged_chars, log_end);
16 +static struct sysrq_key_op msg_info_op = {
17 + .handler = show_msg_info,
18 + .help_msg = "Dumpmsgs",
19 + .action_msg = "Kernel Messages",
22 +static int __init dbg_init(void)
24 + register_sysrq_key('d', &msg_info_op);
28 +__initcall(dbg_init);
29 --- linux-2.6.5/kernel/resource.c~heh 2004-04-03 22:37:36.000000000 -0500
30 +++ linux-2.6.5/kernel/resource.c 2004-04-30 20:57:36.000000000 -0400
33 struct resource *tmp, **p;
37 p = &old->parent->child;
41 EXPORT_SYMBOL(adjust_resource);
44 + * Given an existing resource, change its start and size to match the
45 + * arguments. Returns -EBUSY if it can't fit. Existing children of
46 + * the resource are assumed to be immutable.
48 +int reallocate_resource(struct resource *res, unsigned long start, unsigned long size)
50 + struct resource *tmp, *parent = res->parent;
51 + unsigned long end = start + size - 1;
52 + int result = -EBUSY;
54 + write_lock(&resource_lock);
56 + if ((start < parent->start) || (end > parent->end))
59 + for (tmp = res->child; tmp; tmp = tmp->sibling) {
60 + if ((tmp->start < start) || (tmp->end > end))
64 + if (res->sibling && (res->sibling->start <= end))
67 + tmp = parent->child;
69 + while (tmp->sibling != res)
71 + if (start <= tmp->end)
80 + write_unlock(&resource_lock);
85 * This is compatibility stuff for IO resources.
87 * Note how this, unlike the above, knows about
88 --- linux-2.6.5/include/asm-arm/mach/irq.h~heh 2004-04-03 22:36:54.000000000 -0500
89 +++ linux-2.6.5/include/asm-arm/mach/irq.h 2004-04-30 20:57:36.000000000 -0400
95 + * Architectures are expected to define NR_IRQ_DEVICES and
96 + * NR_IRQ_DEVICE_SHIFT if they wish to use dynamic IRQs.
98 +#ifndef NR_IRQ_DEVICES
99 +#define NR_IRQ_DEVICES 1
101 +#define NR_IRQ_PER_DEVICE (1 << (NR_IRQ_DEVICE_SHIFT - 1))
103 +#define IRQ_DEVICE(i) ((i) >> NR_IRQ_DEVICE_SHIFT)
104 +#define IRQ_INDEX(i) ((i) & (NR_IRQ_PER_GROUP - 1))
105 +#define TO_IRQ(g,i) (((g) << NR_IRQ_DEVICE_SHIFT) + (i))
107 typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
108 typedef void (*irq_control_t)(unsigned int);
110 --- linux-2.6.5/include/asm-arm/arch-pxa/uncompress.h~heh 2004-04-03 22:36:17.000000000 -0500
111 +++ linux-2.6.5/include/asm-arm/arch-pxa/uncompress.h 2004-04-30 20:57:36.000000000 -0400
113 #define FFUART ((volatile unsigned long *)0x40100000)
114 #define BTUART ((volatile unsigned long *)0x40200000)
115 #define STUART ((volatile unsigned long *)0x40700000)
116 +#define HWUART ((volatile unsigned long *)0x41600000)
120 --- linux-2.6.5/include/asm-arm/arch-pxa/dma.h~heh 2004-04-03 22:38:18.000000000 -0500
121 +++ linux-2.6.5/include/asm-arm/arch-pxa/dma.h 2004-04-30 20:57:36.000000000 -0400
123 * Note: this structure must always be aligned to a 16-byte boundary.
127 - volatile u32 ddadr; /* Points to the next descriptor + flags */
128 - volatile u32 dsadr; /* DSADR value for the current transfer */
129 - volatile u32 dtadr; /* DTADR value for the current transfer */
130 - volatile u32 dcmd; /* DCMD value for the current transfer */
131 +typedef struct pxa_dma_desc {
132 + u32 ddadr; /* Points to the next descriptor + flags */
133 + u32 dsadr; /* DSADR value for the current transfer */
134 + u32 dtadr; /* DTADR value for the current transfer */
135 + u32 dcmd; /* DCMD value for the current transfer */
139 --- linux-2.6.5/include/asm-arm/arch-pxa/serial.h~heh 2004-04-03 22:37:06.000000000 -0500
140 +++ linux-2.6.5/include/asm-arm/arch-pxa/serial.h 2004-04-30 20:57:36.000000000 -0400
142 io_type: SERIAL_IO_MEM, \
144 flags: STD_COM_FLAGS, \
147 + xmit_fifo_size: 64, \
148 + baud_base: BAUD_BASE, \
149 + iomem_base: &HWUART, \
150 + iomem_reg_shift: 2, \
151 + io_type: SERIAL_IO_MEM, \
153 + flags: STD_COM_FLAGS, \
156 #define EXTRA_SERIAL_PORT_DEFNS
157 --- linux-2.6.5/include/asm-arm/arch-pxa/pxa-regs.h~heh 2004-04-03 22:37:36.000000000 -0500
158 +++ linux-2.6.5/include/asm-arm/arch-pxa/pxa-regs.h 2004-04-30 20:57:36.000000000 -0400
159 @@ -124,26 +124,26 @@
160 #define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
161 #define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
162 #define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
163 -#define DRCMR15 __REG(0x4000013c) /* Reserved */
164 -#define DRCMR16 __REG(0x40000140) /* Reserved */
165 +#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for NSSP receive Request */
166 +#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for NSSP transmit Request */
167 #define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
168 #define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
169 #define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
170 #define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */
171 #define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */
172 #define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */
173 -#define DRCMR23 __REG(0x4000015c) /* Reserved */
174 -#define DRCMR24 __REG(0x40000160) /* Reserved */
175 +#define DRCMR23 __REG(0x4000015c) /* Request to Channel Map Register for ASSP receive Request */
176 +#define DRCMR24 __REG(0x40000160) /* Request to Channel Map Register for ASSP transmit Request */
177 #define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */
178 #define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */
179 #define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */
180 #define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */
181 -#define DRCMR29 __REG(0x40000174) /* Reserved */
182 +#define DRCMR29 __REG(0x40000174) /* Request to Channel Map Register for HWUART receive Request */
183 #define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */
184 #define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */
185 #define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */
186 #define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */
187 -#define DRCMR34 __REG(0x40000188) /* Reserved */
188 +#define DRCMR34 __REG(0x40000188) /* Request to Channel Map Register for HWUART transmit Request */
189 #define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */
190 #define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */
191 #define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
192 @@ -163,12 +163,16 @@
193 #define DRCMRTXPCDR DRCMR12
194 #define DRCMRRXSSDR DRCMR13
195 #define DRCMRTXSSDR DRCMR14
196 +#define DRCMRRXNSSPDR DRCMR15
197 +#define DRCMRTXNSSPDR DRCMR16
198 #define DRCMRRXICDR DRCMR17
199 #define DRCMRTXICDR DRCMR18
200 #define DRCMRRXSTRBR DRCMR19
201 #define DRCMRTXSTTHR DRCMR20
202 #define DRCMRRXMMC DRCMR21
203 #define DRCMRTXMMC DRCMR22
204 +#define DRCMRRXASSPDR DRCMR23
205 +#define DRCMRTXASSPDR DRCMR24
207 #define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
208 #define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */
210 #define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
211 #define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
213 +/* Hardware UART (HWUART) */
214 +#define HWUART HWRBR
215 +#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */
216 +#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */
217 +#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */
218 +#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */
219 +#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */
220 +#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */
221 +#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */
222 +#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */
223 +#define HWMSR __REG(0x41600018) /* Reserved */
224 +#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */
225 +#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */
226 +#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
227 +#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
229 /* Standard UART (STUART) */
231 #define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */
232 @@ -1078,6 +1098,111 @@
236 + * NSSP Serial Port Registers (Network SSP)
239 +#define NSSCR0 __REG(0x41400000) /* NSSP Control Register 0 */
240 +#define NSSCR1 __REG(0x41400004) /* NSSP Control Register 1 */
241 +#define NSSSR __REG(0x41400008) /* NSSP Status Register */
242 +#define NSSITR __REG(0x4140000C) /* NSSP Interrupt Test Register */
243 +#define NSSDR __REG(0x41400010) /* (Write / Read) NSSP Data Write Register/NSSP Data Read Register */
244 +#define NSSTO __REG(0x41400028) /* NSSP Time Out Register */
245 +#define NSSPSP __REG(0x4140002C) /* NSSP Programable Serial Port Register*/
249 + * ASSP Serial Port Registers (Audio SSP)
252 +#define ASSCR0 __REG(0x41500000) /* ASSP Control Register 0 */
253 +#define ASSCR1 __REG(0x41500004) /* ASSP Control Register 1 */
254 +#define ASSSR __REG(0x41500008) /* ASSP Status Register */
255 +#define ASSITR __REG(0x4150000C) /* ASSP Interrupt Test Register */
256 +#define ASSDR __REG(0x41500010) /* (Write / Read) ASSP Data Write Register/ASSP Data Read Register */
257 +#define ASSTO __REG(0x41500028) /* ASSP Time Out Register */
258 +#define ASSPSP __REG(0x4150002C) /* ASSP Programable Serial Port Register*/
262 + * Bit definitions for SSP, NSSP and ASSP registers
263 + * - note that some bits are only available on the NSSP and ASSP
266 +#define SSCR0_EDSS (1 << 20) /* ext. data size select */
267 +#define SSCR0_SCR_MASK 0x000fff00 /* [19:8] secrial clock rate */
268 +#define SSCR0_SCR(x) (((x)<<8) & XSSCR0_SCR_MASK)
269 +#define SSCR0_SSE (1 << 7) /* sync ser port enable */
270 +#define SSCR0_FRF_MASK 0x00000030 /* [5:4] frame format */
271 +#define SSCR0_FRF(x) (((x)<<4) & XSSCR0_FRF_MASK)
272 +#define SSCR0_FRF_SPI 0x00000000 /* ser peripheral i/f */
273 +#define SSCR0_FRF_TISSP 0x00000010 /* TI sync ser port */
274 +#define SSCR0_FRF_MICROWAVE 0x00000020 /* microwire */
275 +#define SSCR0_FRF_PSP 0x00000030 /* prog ser protocol */
276 +#define SSCR0_DSS_MASK 0x0000000f /* data size select */
277 +#define SSCR0_DSS(x) ((x) & XSSCR0_DSS_MASK)
279 +#define SSCR1_TTELP (1 << 31) /* tx hi-z later phase */
280 +#define SSCR1_TTE (1 << 30) /* tx hi-z enable */
281 +#define SSCR1_EBCEI (1 << 29) /* bit count error int mask */
282 +#define SSCR1_SCFR (1 << 28) /* slave clock free running */
283 +#define SSCR1_SCLKDIR (1 << 25) /* ssp clock direction */
284 +#define SSCR1_SFRMDIR (1 << 24) /* ssp frame direction */
285 +#define SSCR1_RWOT (1 << 23) /* rx without transmit */
286 +#define SSCR1_TSRE (1 << 21) /* tx req enable */
287 +#define SSCR1_RSRE (1 << 20) /* rx req enable */
288 +#define SSCR1_TINTE (1 << 19) /* timeout int enable */
289 +#define SSCR1_STRF (1 << 15) /* select fifo for efwr */
290 +#define SSCR1_EFWR (1 << 14) /* fifo write/read enable */
291 +#define SSCR1_RFT_MASK 0x00003c00 /* [13:10] rx fifo threshold */
292 +#define SSCR1_RFT(x) (((x)<<10) & XSSCR1_RFT_MASK)
293 +#define SSCR1_TFT_MASK 0x000003c0 /* [9:6] tx fifo threshold */
294 +#define SSCR1_TFT(x) (((x)<<6) & XSSCR1_TFT_MASK)
295 +#define SSCR1_MWDS (1 << 5) /* microwire tx data size */
296 +#define SSCR1_SPH (1 << 4) /* SPI SSPSCLK phase */
297 +#define SSCR1_SPO (1 << 3) /* motorolla SPI polarity */
298 +#define SSCR1_LBM (1 << 2) /* loop-back mode */
299 +#define SSCR1_TIE (1 << 1) /* tx fifo int enable */
300 +#define SSCR1_RIE (1 << 0) /* rx fifo int enable */
302 +#define SSPSP_DMYSTOP_MASK 0x01800000 /* [24:23] dummy stop */
303 +#define SSPSP_DMYSTOP(x) (((x)<<23) & XSSPSP_DMYSTOP_MASK)
304 +#define SSPSP_SFRMWDTH_MASK 0x007f0000 /* [22:16] serial frame width */
305 +#define SSPSP_SFRMWDTH(x) (((x)<<16) & XSSPSP_SFRMWDTH_MASK)
306 +#define SSPSP_SFRMDLY_MASK 0x0000fe00 /* [15:9] serial frame delay */
307 +#define SSPSP_SFRMDLY(x) (((x)<<9) & XSSPSP_SFRMDLY_MASK)
308 +#define SSPSP_DMYSTRT_MASK 0x00000180 /* [8:7] dummy start */
309 +#define SSPSP_DMYSTRT(x) (((x)<<7) & XSSPSP_DMYSTRT_MASK)
310 +#define SSPSP_STRTDLY_MASK 0x00000070 /* [6:4] three-bit start delay */
311 +#define SSPSP_STRTDLY(x) (((x)<<4) & XSSPSP_STRTDLY_MASK)
312 +#define SSPSP_ETDS (1 << 3) /* end of tx data state */
313 +#define SSPSP_SFRMP (1 << 2) /* serial frame polarity */
314 +#define SSPSP_SCMODE_MASK 0x00000003 /* bit-rate clock mode */
315 +#define SSPSP_SCMODE(x) ((x) & XSSPSP_SCMODE_MASK)
317 +#define SSTO_TIMEOUT_MASK 0x00ffffff /* [23:0] timeout */
318 +#define SSTO_TIMEOUT(x) ((x) & XSSTO_TIMEOUT_MASK)
320 +#define SSITR_TROR (1 << 7) /* test rx fifo overrun */
321 +#define SSITR_TRFS (1 << 6) /* test rx fifo serv req */
322 +#define SSITR_TTFS (1 << 5) /* test tx fifo serv req */
324 +#define SSSR_BCE (1 << 23) /* bit count error */
325 +#define SSSR_CSS (1 << 22) /* clock sync stat */
326 +#define SSSR_TUR (1 << 21) /* tx fifo underrun */
327 +#define SSSR_TINT (1 << 19) /* rx timeout int */
328 +#define SSSR_RFL_MASK 0x0000f000 /* rx fifo level */
329 +#define SSSR_RFL(x) (((x)<<16) & XSSSR_RFL_MASK)
330 +#define SSSR_TFL_MASK 0x00000f00 /* tx fifo level */
331 +#define SSSR_TFL(x) (((x)<<8) & XSSSR_TFL_MASK)
332 +#define SSSR_ROR (1 << 7) /* rx fifo overrun */
333 +#define SSSR_RFS (1 << 6) /* rx fifo serv request */
334 +#define SSSR_TFS (1 << 5) /* tx fifo serv req */
335 +#define SSSR_BSY (1 << 4) /* SSP busy */
336 +#define SSSR_RNE (1 << 3) /* rx fifo not empty */
337 +#define SSSR_TNF (1 << 2) /* tx fifo not full */
341 * MultiMediaCard (MMC) controller
344 @@ -1122,6 +1247,7 @@
345 #define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
346 #define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
347 #define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
348 +#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */
349 #define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
350 #define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */
351 #define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */
352 --- linux-2.6.5/include/asm-arm/page.h~heh 2004-04-03 22:36:25.000000000 -0500
353 +++ linux-2.6.5/include/asm-arm/page.h 2004-04-30 20:57:36.000000000 -0400
358 +#ifdef CONFIG_CPU_COPY_V6
360 +# define MULTI_USER 1
367 #error Unknown user operations model
369 --- linux-2.6.5/include/asm-arm/thread_info.h~heh 2004-04-03 22:37:06.000000000 -0500
370 +++ linux-2.6.5/include/asm-arm/thread_info.h 2004-04-30 20:57:36.000000000 -0400
373 #define TI_CPU_DOMAIN 24
374 #define TI_CPU_SAVE 28
375 -#define TI_USED_MATH 76
376 -#define TI_FPSTATE (TI_USED_MATH+16)
377 +#define TI_USED_CP 76
378 +#define TI_FPSTATE (TI_USED_CP+16)
382 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
383 +++ linux-2.6.5/include/asm-arm/rtc.h 2004-04-30 20:57:36.000000000 -0400
386 + * linux/include/asm-arm/rtc.h
388 + * Copyright (C) 2003 Deep Blue Solutions Ltd.
390 + * This program is free software; you can redistribute it and/or modify
391 + * it under the terms of the GNU General Public License version 2 as
392 + * published by the Free Software Foundation.
394 +#ifndef ASMARM_RTC_H
395 +#define ASMARM_RTC_H
400 + struct module *owner;
402 + void (*release)(void);
403 + int (*ioctl)(unsigned int, unsigned long);
405 + void (*read_time)(struct rtc_time *);
406 + int (*set_time)(struct rtc_time *);
407 + void (*read_alarm)(struct rtc_wkalrm *);
408 + int (*set_alarm)(struct rtc_wkalrm *);
409 + int (*proc)(char *buf);
412 +void rtc_time_to_tm(unsigned long, struct rtc_time *);
413 +int rtc_tm_to_time(struct rtc_time *, unsigned long *);
414 +void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *);
415 +void rtc_update(unsigned long, unsigned long);
416 +int register_rtc(struct rtc_ops *);
417 +void unregister_rtc(struct rtc_ops *);
419 +static inline int rtc_periodic_alarm(struct rtc_time *tm)
421 + return (tm->tm_year == -1) ||
422 + ((unsigned)tm->tm_mon >= 12) ||
423 + ((unsigned)(tm->tm_mday - 1) >= 31) ||
424 + ((unsigned)tm->tm_hour > 23) ||
425 + ((unsigned)tm->tm_min > 59) ||
426 + ((unsigned)tm->tm_sec > 59);
430 --- linux-2.6.5/include/linux/serial.h~heh 2004-04-03 22:36:26.000000000 -0500
431 +++ linux-2.6.5/include/linux/serial.h 2004-04-30 20:57:36.000000000 -0400
433 #define SERIAL_IO_HUB6 1
434 #define SERIAL_IO_MEM 2
436 -struct serial_uart_config {
438 - int dfl_xmit_fifo_size;
442 -#define UART_CLEAR_FIFO 0x01
443 -#define UART_USE_FIFO 0x02
444 -#define UART_STARTECH 0x04
445 -#define UART_NATSEMI 0x08
448 * Definitions for async_struct (and serial_struct) flags field
450 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
451 +++ linux-2.6.5/include/linux/i2c-pxa.h 2004-04-30 20:57:36.000000000 -0400
456 + * Copyright (C) 2002 Intrinsyc Software Inc.
458 + * This program is free software; you can redistribute it and/or modify
459 + * it under the terms of the GNU General Public License version 2 as
460 + * published by the Free Software Foundation.
466 +struct i2c_algo_pxa_data
468 + void (*write_byte) (u8 value);
469 + u8 (*read_byte) (void);
470 + void (*start) (void);
471 + void (*repeat_start) (void);
472 + void (*stop) (void);
473 + void (*abort) (void);
474 + int (*wait_bus_not_busy) (void);
475 + int (*wait_for_interrupt) (int wait_type);
476 + void (*transfer) (int lastbyte, int receive, int midbyte);
477 + void (*reset) (void);
483 +#define DEF_TIMEOUT 3
484 +#define BUS_ERROR (-EREMOTEIO)
485 +#define ACK_DELAY 0 /* time to delay before checking bus error */
486 +#define MAX_MESSAGES 65536 /* maximum number of messages to send */
488 +#define I2C_SLEEP_TIMEOUT 2 /* time to sleep for on i2c transactions */
489 +#define I2C_RETRY (-2000) /* an error has occurred retry transmit */
490 +#define I2C_TRANSMIT 1
491 +#define I2C_RECEIVE 0
492 +#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */
493 +#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) /* ICR initialization value */
494 +/* ICR initialize bit values
496 +* 15. FM 0 (100 Khz operation)
497 +* 14. UR 0 (No unit reset)
498 +* 13. SADIE 0 (Disables the unit from interrupting on slave addresses
499 +* matching its slave address)
500 +* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration
502 +* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode)
503 +* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent)
504 +* 9. IRFIE 1 (Enable interrupts from full buffer received)
505 +* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty)
506 +* 7. GCD 1 (Disables i2c unit response to general call messages as a slave)
507 +* 6. IUE 0 (Disable unit until we change settings)
508 +* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL)
509 +* 4. MA 0 (Only send stop with the ICR stop bit)
510 +* 3. TB 0 (We are not transmitting a byte initially)
511 +* 2. ACKNAK 0 (Send an ACK after the unit receives a byte)
512 +* 1. STOP 0 (Do not send a STOP)
513 +* 0. START 0 (Do not send a START)
517 +#define I2C_ISR_INIT 0x7FF /* status register init */
518 +/* I2C status register init values
520 + * 10. BED 1 (Clear bus error detected)
521 + * 9. SAD 1 (Clear slave address detected)
522 + * 7. IRF 1 (Clear IDBR Receive Full)
523 + * 6. ITE 1 (Clear IDBR Transmit Empty)
524 + * 5. ALD 1 (Clear Arbitration Loss Detected)
525 + * 4. SSD 1 (Clear Slave Stop Detected)
529 --- linux-2.6.5/include/linux/ioport.h~heh 2004-04-03 22:36:26.000000000 -0500
530 +++ linux-2.6.5/include/linux/ioport.h 2004-04-30 20:57:36.000000000 -0400
532 void (*alignf)(void *, struct resource *,
533 unsigned long, unsigned long),
535 +extern int reallocate_resource(struct resource *res, unsigned long start, unsigned long size);
536 int adjust_resource(struct resource *res, unsigned long start,
539 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
540 +++ linux-2.6.5/include/linux/switches.h 2004-04-30 20:57:36.000000000 -0400
543 + * linux/include/linux/switches.h
545 + * Copyright (C) 2000 John Dorsey
547 + * This program is free software; you can redistribute it and/or modify
548 + * it under the terms of the GNU General Public License version 2 as
549 + * published by the Free Software Foundation.
551 + * 23 October 2000 - created.
554 +#if !defined(_LINUX_SWITCHES_H)
555 +#define _LINUX_SWITCHES_H
557 +#define SWITCHES_MASK_SIZE (128)
559 +typedef unsigned long switches_bitfield;
561 +#define SWITCHES_BITS (sizeof(switches_bitfield) * 8)
562 +#define SWITCHES_NUM_FIELDS (SWITCHES_MASK_SIZE / SWITCHES_BITS)
563 +#define SWITCHES_FIELD_SELECT(i) ((i) / SWITCHES_BITS)
564 +#define SWITCHES_FIELD_MASK(i) ((switches_bitfield)(1 << (i) % \
567 +typedef struct switches_mask_t {
568 + unsigned int count;
569 + switches_bitfield events[SWITCHES_NUM_FIELDS];
570 + switches_bitfield states[SWITCHES_NUM_FIELDS];
573 +#define SWITCHES_ZERO(m) \
575 + unsigned int sz_i; \
577 + for(sz_i = 0; sz_i < SWITCHES_NUM_FIELDS; ++sz_i) \
578 + (m)->events[sz_i] = (m)->states[sz_i] = 0; \
581 +/* `s' is the state of the switch, either 0 or non-zero: */
582 +#define SWITCHES_SET(m, i, s) \
584 + ((m)->events[SWITCHES_FIELD_SELECT((i))] |= \
585 + SWITCHES_FIELD_MASK((i))); \
587 + ((m)->states[SWITCHES_FIELD_SELECT((i))] |= \
588 + SWITCHES_FIELD_MASK((i))); \
590 + ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
591 + ~SWITCHES_FIELD_MASK((i))); \
595 +/* Should only use to clear an event set by SWITCHES_SET(): */
596 +#define SWITCHES_CLEAR(m, i) \
598 + ((m)->events[SWITCHES_FIELD_SELECT((i))] &= \
599 + ~SWITCHES_FIELD_MASK((i))); \
600 + ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
601 + ~SWITCHES_FIELD_MASK((i))); \
605 +#define SWITCHES_COUNT(m) ((m)->count)
607 +/* Returns 0 or non-zero: */
608 +#define SWITCHES_EVENT(m, i) \
609 +((m)->events[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
611 +/* Returns 0 or non-zero: */
612 +#define SWITCHES_STATE(m, i) \
613 +((m)->states[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
615 +#endif /* !defined(_LINUX_SWITCHES_H) */
616 --- linux-2.6.5/include/linux/serial_reg.h~heh 2004-04-03 22:37:38.000000000 -0500
617 +++ linux-2.6.5/include/linux/serial_reg.h 2004-04-30 20:57:36.000000000 -0400
620 * These are the definitions for the Modem Control Register
622 +#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C750) */
623 #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
624 #define UART_MCR_OUT2 0x08 /* Out2 complement */
625 #define UART_MCR_OUT1 0x04 /* Out1 complement */
627 #define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */
630 + * The Intel PXA2xx chip defines those bits
632 +#define UART_IER_DMAE 0x80 /* DMA Requests Enable */
633 +#define UART_IER_UUE 0x40 /* UART Unit Enable */
634 +#define UART_IER_NRZE 0x20 /* NRZ coding Enable */
635 +#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */
637 +#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */
639 +#define UART_FCR_PXAR1 0x00 /* receive FIFO treshold = 1 */
640 +#define UART_FCR_PXAR8 0x40 /* receive FIFO treshold = 8 */
641 +#define UART_FCR_PXAR16 0x80 /* receive FIFO treshold = 16 */
642 +#define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */
645 * These are the definitions for the Extended Features Register
646 * (StarTech 16C660 only, when DLAB=1)
648 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
649 +++ linux-2.6.5/include/linux/mmc/card.h 2004-04-30 20:57:36.000000000 -0400
652 + * linux/include/linux/mmc/card.h
654 + * This program is free software; you can redistribute it and/or modify
655 + * it under the terms of the GNU General Public License version 2 as
656 + * published by the Free Software Foundation.
658 + * Card driver specific definitions.
660 +#ifndef LINUX_MMC_CARD_H
661 +#define LINUX_MMC_CARD_H
663 +#include <linux/mmc/mmc.h>
666 + unsigned int manfid;
667 + unsigned int serial;
669 + unsigned char hwrev;
670 + unsigned char fwrev;
671 + unsigned char month;
672 + unsigned char year;
676 + unsigned char mmc_prot;
677 + unsigned short cmdclass;
678 + unsigned short tacc_clks;
679 + unsigned int tacc_ns;
680 + unsigned int max_dtr;
681 + unsigned int read_blkbits;
682 + unsigned int capacity;
691 + struct list_head node; /* node in hosts devices list */
692 + struct mmc_host *host; /* the host this device belongs to */
693 + struct device dev; /* the device */
694 + unsigned int rca; /* relative card address of device */
695 + unsigned int state; /* (our) card state */
696 +#define MMC_STATE_PRESENT (1<<0)
697 +#define MMC_STATE_DEAD (1<<1)
698 + struct mmc_cid cid; /* card identification */
699 + struct mmc_csd csd; /* card specific */
702 +#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
703 +#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
705 +#define mmc_card_name(c) ((c)->cid.prod_name)
706 +#define mmc_card_id(c) ((c)->dev.bus_id)
708 +#define mmc_list_to_card(l) container_of(l, struct mmc_card, node)
709 +#define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev)
710 +#define mmc_set_drvdata(c,d) dev_set_drvdata(&(c)->dev, d)
713 + * MMC device driver (e.g., Flash card, I/O card...)
716 + struct device_driver drv;
717 + int (*probe)(struct mmc_card *);
718 + void (*remove)(struct mmc_card *);
719 + int (*suspend)(struct mmc_card *, u32);
720 + int (*resume)(struct mmc_card *);
723 +extern int mmc_register_driver(struct mmc_driver *);
724 +extern void mmc_unregister_driver(struct mmc_driver *);
726 +static inline int mmc_card_claim_host(struct mmc_card *card)
728 + return __mmc_claim_host(card->host, card);
731 +#define mmc_card_release_host(c) mmc_release_host((c)->host)
734 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
735 +++ linux-2.6.5/include/linux/mmc/mmc.h 2004-04-30 20:57:36.000000000 -0400
738 + * linux/include/linux/mmc/mmc.h
740 + * This program is free software; you can redistribute it and/or modify
741 + * it under the terms of the GNU General Public License version 2 as
742 + * published by the Free Software Foundation.
747 +#include <linux/list.h>
748 +#include <linux/interrupt.h>
749 +#include <linux/device.h>
755 +struct mmc_command {
759 + unsigned int flags; /* expected response type */
760 +#define MMC_RSP_NONE (0 << 0)
761 +#define MMC_RSP_SHORT (1 << 0)
762 +#define MMC_RSP_LONG (2 << 0)
763 +#define MMC_RSP_MASK (3 << 0)
764 +#define MMC_RSP_CRC (1 << 3) /* expect valid crc */
765 +#define MMC_RSP_BUSY (1 << 4) /* card may send busy */
767 + unsigned int retries; /* max number of retries */
768 + unsigned int error; /* command error */
770 +#define MMC_ERR_NONE 0
771 +#define MMC_ERR_TIMEOUT 1
772 +#define MMC_ERR_BADCRC 2
773 +#define MMC_ERR_FIFO 3
774 +#define MMC_ERR_FAILED 4
775 +#define MMC_ERR_INVALID 5
777 + struct mmc_data *data; /* data segment associated with cmd */
778 + struct mmc_request *req; /* assoicated request */
782 + unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
783 + unsigned int timeout_clks; /* data timeout (in clocks) */
784 + unsigned int blksz_bits; /* data block size */
785 + unsigned int blocks; /* number of blocks */
786 + struct request *rq; /* request structure */
787 + unsigned int error; /* data error */
788 + unsigned int flags;
790 +#define MMC_DATA_WRITE (1 << 8)
791 +#define MMC_DATA_READ (1 << 9)
792 +#define MMC_DATA_STREAM (1 << 10)
794 + unsigned int bytes_xfered;
796 + struct mmc_command *stop; /* stop command */
797 + struct mmc_request *req; /* assoicated request */
800 +struct mmc_request {
801 + struct mmc_command *cmd;
802 + struct mmc_data *data;
803 + struct mmc_command *stop;
805 + void *done_data; /* completion data */
806 + void (*done)(struct mmc_request *);/* completion function */
812 +extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
813 +extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
815 +extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card);
817 +static inline void mmc_claim_host(struct mmc_host *host)
819 + __mmc_claim_host(host, (struct mmc_card *)-1);
822 +extern void mmc_release_host(struct mmc_host *host);
825 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
826 +++ linux-2.6.5/include/linux/mmc/host.h 2004-04-30 20:57:36.000000000 -0400
829 + * linux/include/linux/mmc/host.h
831 + * This program is free software; you can redistribute it and/or modify
832 + * it under the terms of the GNU General Public License version 2 as
833 + * published by the Free Software Foundation.
835 + * Host driver specific definitions.
837 +#ifndef LINUX_MMC_HOST_H
838 +#define LINUX_MMC_HOST_H
840 +#include <linux/mmc/mmc.h>
843 + unsigned int clock; /* clock rate */
844 + unsigned short vdd; /* supply (units of 10mV) */
845 + unsigned char bus_mode; /* command output mode */
847 +#define MMC_BUSMODE_OPENDRAIN 1
848 +#define MMC_BUSMODE_PUSHPULL 2
850 + unsigned char power_mode; /* power supply mode */
852 +#define MMC_POWER_OFF 0
853 +#define MMC_POWER_UP 1
854 +#define MMC_POWER_ON 2
857 +struct mmc_host_ops {
858 + void (*request)(struct mmc_host *host, struct mmc_request *req);
859 + void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
865 + struct device *dev;
866 + struct mmc_host_ops *ops;
867 + unsigned int f_min;
868 + unsigned int f_max;
872 + unsigned int host_num; /* host number */
873 + struct mmc_ios ios; /* current io bus settings */
874 + u32 ocr; /* the current OCR setting */
876 + struct list_head cards; /* devices attached to this host */
878 + wait_queue_head_t wq;
879 + spinlock_t lock; /* card_busy lock */
880 + struct mmc_card *card_busy; /* the MMC card claiming host */
881 + struct mmc_card *card_selected; /* the selected MMC card */
884 +extern int mmc_init_host(struct mmc_host *);
885 +extern int mmc_add_host(struct mmc_host *);
886 +extern void mmc_remove_host(struct mmc_host *);
887 +extern int mmc_suspend_host(struct mmc_host *, u32);
888 +extern int mmc_resume_host(struct mmc_host *);
890 +extern void mmc_detect_change(struct mmc_host *);
891 +extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
895 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
896 +++ linux-2.6.5/include/linux/mmc/protocol.h 2004-04-30 20:57:36.000000000 -0400
899 + * Header for MultiMediaCard (MMC)
901 + * Copyright 2002 Hewlett-Packard Company
903 + * Use consistent with the GNU GPL is permitted,
904 + * provided that this copyright notice is
905 + * preserved in its entirety in all copies and derived works.
907 + * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
908 + * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
909 + * FITNESS FOR ANY PARTICULAR PURPOSE.
911 + * Many thanks to Alessandro Rubini and Jonathan Corbet!
913 + * Based strongly on code by:
915 + * Author: Yong-iL Joh <tolkien@mizi.com>
916 + * Date : $Date: 2002/06/18 12:37:30 $
918 + * Author: Andrew Christian
922 +#ifndef MMC_MMC_PROTOCOL_H
923 +#define MMC_MMC_PROTOCOL_H
925 +/* Standard MMC commands (3.1) type argument response */
927 +#define MMC_GO_IDLE_STATE 0 /* bc */
928 +#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
929 +#define MMC_ALL_SEND_CID 2 /* bcr R2 */
930 +#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
931 +#define MMC_SET_DSR 4 /* bc [31:16] RCA */
932 +#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
933 +#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
934 +#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
935 +#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
936 +#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
937 +#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
938 +#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
941 +#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
942 +#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
943 +#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
946 +#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
949 +#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
950 +#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
951 +#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
952 +#define MMC_PROGRAM_CID 26 /* adtc R1 */
953 +#define MMC_PROGRAM_CSD 27 /* adtc R1 */
956 +#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
957 +#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
958 +#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
961 +#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
962 +#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
963 +#define MMC_ERASE 37 /* ac R1b */
966 +#define MMC_FAST_IO 39 /* ac <Complex> R4 */
967 +#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
970 +#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
973 +#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
974 +#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
981 + r : detected and set for the actual command response
982 + x : detected and set during command execution. the host must poll
983 + the card by sending status command in order to read these bits.
985 + a : according to the card state
986 + b : always related to the previous command. Reception of
987 + a valid command will clear it (with a delay of one command)
991 +#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
992 +#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
993 +#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
994 +#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
995 +#define R1_ERASE_PARAM (1 << 27) /* ex, c */
996 +#define R1_WP_VIOLATION (1 << 26) /* erx, c */
997 +#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
998 +#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
999 +#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
1000 +#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
1001 +#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
1002 +#define R1_CC_ERROR (1 << 20) /* erx, c */
1003 +#define R1_ERROR (1 << 19) /* erx, c */
1004 +#define R1_UNDERRUN (1 << 18) /* ex, c */
1005 +#define R1_OVERRUN (1 << 17) /* ex, c */
1006 +#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
1007 +#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
1008 +#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
1009 +#define R1_ERASE_RESET (1 << 13) /* sr, c */
1010 +#define R1_STATUS(x) (x & 0xFFFFE000)
1011 +#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
1012 +#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
1013 +#define R1_APP_CMD (1 << 7) /* sr, c */
1015 +/* These are unpacked versions of the actual responses */
1025 + u8 read_bl_partial;
1026 + u8 write_blk_misalign;
1027 + u8 read_blk_misalign;
1030 + u8 vdd_r_curr_min;
1031 + u8 vdd_r_curr_max;
1032 + u8 vdd_w_curr_min;
1033 + u8 vdd_w_curr_max;
1036 + struct { /* MMC system specification version 3.1 */
1037 + u8 erase_grp_size;
1038 + u8 erase_grp_mult;
1040 + struct { /* MMC system specification version 2.2 */
1042 + u8 erase_grp_size;
1050 + u8 write_bl_partial;
1051 + u8 file_format_grp;
1053 + u8 perm_write_protect;
1054 + u8 tmp_write_protect;
1059 +#define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */
1060 +#define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */
1061 +#define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */
1062 +#define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */
1063 +#define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */
1064 +#define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */
1065 +#define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */
1066 +#define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */
1067 +#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
1068 +#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
1069 +#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
1070 +#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
1071 +#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
1072 +#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
1073 +#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
1074 +#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
1075 +#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
1076 +#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
1077 +#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
1078 +#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
1079 +#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
1080 +#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
1081 +#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
1082 +#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
1083 +#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
1087 + * CSD field definitions
1090 +#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
1091 +#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
1092 +#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */
1094 +#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
1095 +#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
1096 +#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
1097 +#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */
1099 +#endif /* MMC_MMC_PROTOCOL_H */
1101 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
1102 +++ linux-2.6.5/include/linux/l3/algo-bit.h 2004-04-30 20:57:36.000000000 -0400
1105 + * linux/include/linux/l3/algo-bit.h
1107 + * Copyright (C) 2001 Russell King, All Rights Reserved.
1109 + * This program is free software; you can redistribute it and/or modify
1110 + * it under the terms of the GNU General Public License as published by
1111 + * the Free Software Foundation; either version 2 of the License.
1113 + * L3 Bus bit-banging algorithm. Derived from i2c-algo-bit.h by
1116 +#ifndef L3_ALGO_BIT_H
1117 +#define L3_ALGO_BIT_H 1
1119 +#include <linux/l3/l3.h>
1121 +struct l3_algo_bit_data {
1122 + void (*setdat) (void *data, int state);
1123 + void (*setclk) (void *data, int state);
1124 + void (*setmode)(void *data, int state);
1125 + void (*setdir) (void *data, int in); /* set data direction */
1126 + int (*getdat) (void *data);
1130 + /* bus timings (us) */
1139 +int l3_bit_add_bus(struct l3_adapter *);
1140 +int l3_bit_del_bus(struct l3_adapter *);
1143 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
1144 +++ linux-2.6.5/include/linux/l3/l3.h 2004-04-30 20:57:36.000000000 -0400
1147 + * linux/include/linux/l3/l3.h
1149 + * Copyright (C) 2001 Russell King, All Rights Reserved.
1151 + * This program is free software; you can redistribute it and/or modify
1152 + * it under the terms of the GNU General Public License as published by
1153 + * the Free Software Foundation; either version 2 of the License.
1155 + * Derived from i2c.h by Simon G. Vogl
1161 + unsigned char addr; /* slave address */
1162 + unsigned char flags;
1163 +#define L3_M_RD 0x01
1164 +#define L3_M_NOADDR 0x02
1165 + unsigned short len; /* msg length */
1166 + unsigned char *buf; /* pointer to msg data */
1171 +#include <linux/types.h>
1172 +#include <linux/list.h>
1176 +struct l3_algorithm {
1177 + /* textual description */
1180 + /* perform bus transactions */
1181 + int (*xfer)(struct l3_adapter *, struct l3_msg msgs[], int num);
1187 + * l3_adapter is the structure used to identify a physical L3 bus along
1188 + * with the access algorithms necessary to access it.
1190 +struct l3_adapter {
1192 + * This name is used to uniquely identify the adapter.
1193 + * It should be the same as the module name.
1198 + * the algorithm to access the bus
1200 + struct l3_algorithm *algo;
1203 + * Algorithm specific data
1208 + * This may be NULL, or should point to the module struct
1210 + struct module *owner;
1213 + * private data for the adapter
1218 + * Our lock. Unlike the i2c layer, we allow this to be used for
1219 + * other stuff, like the i2c layer lock. Some people implement
1220 + * i2c stuff using the same signals as the l3 bus.
1222 + struct semaphore *lock;
1225 + * List of all adapters.
1227 + struct list_head adapters;
1230 +extern int l3_add_adapter(struct l3_adapter *);
1231 +extern int l3_del_adapter(struct l3_adapter *);
1232 +extern void l3_put_adapter(struct l3_adapter *);
1233 +extern struct l3_adapter *l3_get_adapter(const char *name);
1235 +extern int l3_write(struct l3_adapter *, int, const char *, int);
1236 +extern int l3_read(struct l3_adapter *, int, char *, int);
1241 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
1242 +++ linux-2.6.5/include/linux/l3/uda1341.h 2004-04-30 20:57:36.000000000 -0400
1245 + * linux/include/linux/l3/uda1341.h
1247 + * Philips UDA1341 mixer device driver
1249 + * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
1251 + * This program is free software; you can redistribute it and/or
1252 + * modify it under the terms of the GNU General Public License.
1255 +#define UDA1341_NAME "uda1341"
1257 +struct uda1341_cfg {
1258 + unsigned int fs:16;
1259 + unsigned int format:3;
1263 +#define FMT_LSB16 1
1264 +#define FMT_LSB18 2
1265 +#define FMT_LSB20 3
1267 +#define FMT_LSB16MSB 5
1268 +#define FMT_LSB18MSB 6
1269 +#define FMT_LSB20MSB 7
1271 +#define L3_UDA1341_CONFIGURE 0x13410001
1274 + unsigned int left:8;
1275 + unsigned int right:8;
1276 + unsigned int unused:8;
1277 + unsigned int channel:8;
1280 +#define L3_SET_VOLUME 0x13410002
1281 +#define L3_SET_TREBLE 0x13410003
1282 +#define L3_SET_BASS 0x13410004
1283 +#define L3_SET_GAIN 0x13410005
1286 + unsigned int level:8;
1287 + unsigned int enable:1;
1288 + unsigned int attack:7;
1289 + unsigned int decay:8;
1290 + unsigned int channel:8;
1293 +#define L3_INPUT_AGC 0x13410006
1297 +int uda1341_configure(struct uda1341 *uda, struct uda1341_cfg *conf);
1298 +int uda1341_mixer_ctl(struct uda1341 *uda, int cmd, void *arg);
1299 +int uda1341_open(struct uda1341 *uda);
1300 +void uda1341_close(struct uda1341 *uda);
1302 +struct uda1341 *uda1341_attach(const char *adapter);
1303 +void uda1341_detach(struct uda1341 *uda);
1305 --- linux-2.6.5/include/linux/i2c-id.h~heh 2004-04-03 22:36:16.000000000 -0500
1306 +++ linux-2.6.5/include/linux/i2c-id.h 2004-04-30 20:57:36.000000000 -0400
1308 #define I2C_ALGO_BITHS 0x130000 /* enhanced bit style adapters */
1309 #define I2C_ALGO_OCP_IOP3XX 0x140000 /* XSCALE IOP3XX On-chip I2C alg */
1311 +#define I2C_ALGO_PXA 0x200000 /* Intel PXA I2C algorithm */
1312 #define I2C_ALGO_EXP 0x800000 /* experimental */
1314 #define I2C_ALGO_MASK 0xff0000 /* Mask for algorithms */
1315 --- linux-2.6.5/include/linux/serial_core.h~heh 2004-04-03 22:36:18.000000000 -0500
1316 +++ linux-2.6.5/include/linux/serial_core.h 2004-04-30 20:57:36.000000000 -0400
1318 * along with this program; if not, write to the Free Software
1319 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1321 - * $Id: serial_core.h,v 1.49 2002/07/20 18:06:32 rmk Exp $
1322 + * $Id: serial_core.h,v 1.53 2002/08/02 12:55:08 rmk Exp $
1327 spinlock_t lock; /* port lock */
1328 unsigned int iobase; /* in/out[bwl] */
1329 char *membase; /* read/write[bwl] */
1330 - unsigned int irq; /* irq number */
1331 - unsigned int uartclk; /* base uart clock */
1332 unsigned char fifosize; /* tx fifo size */
1333 unsigned char x_char; /* xon/xoff char */
1334 unsigned char regshift; /* reg offset shift */
1337 unsigned int read_status_mask; /* driver specific */
1338 unsigned int ignore_status_mask; /* driver specific */
1340 struct uart_info *info; /* pointer to parent info */
1341 struct uart_icount icount; /* statistics */
1347 -#define UPF_HUP_NOTIFY (1 << 0)
1348 #define UPF_FOURPORT (1 << 1)
1349 #define UPF_SAK (1 << 2)
1350 #define UPF_SPD_MASK (0x1030)
1351 @@ -212,9 +210,12 @@
1352 unsigned int timeout; /* character-based timeout */
1353 unsigned int type; /* port type */
1354 struct uart_ops *ops;
1355 + unsigned int uartclk; /* base uart clock */
1356 unsigned int custom_divisor;
1357 + unsigned int irq; /* irq number */
1358 unsigned int line; /* port index */
1359 unsigned long mapbase; /* for ioremap */
1360 + struct device *dev; /* parent device */
1361 unsigned char hub6; /* this should be in the 8250 driver */
1362 unsigned char unused[3];
1364 --- linux-2.6.5/include/linux/vmalloc.h~heh 2004-04-03 22:38:23.000000000 -0500
1365 +++ linux-2.6.5/include/linux/vmalloc.h 2004-04-30 20:57:36.000000000 -0400
1367 * Lowlevel-APIs (not for driver use!)
1369 extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
1370 +extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
1371 + unsigned long start, unsigned long end);
1372 extern struct vm_struct *remove_vm_area(void *addr);
1373 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
1374 struct page ***pages);
1375 --- linux-2.6.5/include/linux/mm.h~heh 2004-04-03 22:36:15.000000000 -0500
1376 +++ linux-2.6.5/include/linux/mm.h 2004-04-30 20:57:36.000000000 -0400
1377 @@ -655,5 +655,12 @@
1378 int in_gate_area(struct task_struct *task, unsigned long addr);
1382 +#define memc_update_addr(x,y,z)
1383 +#define memc_update_mm(x)
1384 +#define memc_clear(x,y)
1387 #endif /* __KERNEL__ */
1388 #endif /* _LINUX_MM_H */
1390 --- linux-2.6.5/init/do_mounts.c~heh 2004-04-03 22:36:56.000000000 -0500
1391 +++ linux-2.6.5/init/do_mounts.c 2004-04-30 20:57:36.000000000 -0400
1393 root_device_name += 5;
1396 - is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
1397 + is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR || MAJOR(ROOT_DEV) == 31;
1401 --- linux-2.6.5/fs/binfmt_aout.c~heh 2004-04-03 22:36:26.000000000 -0500
1402 +++ linux-2.6.5/fs/binfmt_aout.c 2004-04-30 20:57:36.000000000 -0400
1403 @@ -432,7 +432,11 @@
1405 send_sig(SIGTRAP, current, 0);
1410 + return regs->ARM_r0;
1414 static int load_aout_library(struct file *file)
1415 @@ -462,8 +466,11 @@
1417 /* For QMAGIC, the starting address is 0x20 into the page. We mask
1418 this off to get the starting address for the page */
1420 - start_addr = ex.a_entry & 0xfffff000;
1422 + start_addr = ex.a_entry & 0xfffff000;
1424 + start_addr = ex.a_entry & 0xffff8000;
1427 if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
1428 static unsigned long error_time;
1429 --- linux-2.6.5/mm/slab.c~heh 2004-04-03 22:37:41.000000000 -0500
1430 +++ linux-2.6.5/mm/slab.c 2004-04-30 20:57:36.000000000 -0400
1431 @@ -2115,12 +2115,12 @@
1433 * Called with disabled ints.
1435 -static inline void __cache_free (kmem_cache_t *cachep, void* objp)
1436 +static inline void __cache_free (kmem_cache_t *cachep, void* objp, void *caller)
1438 struct array_cache *ac = ac_data(cachep);
1441 - objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
1442 + objp = cache_free_debugcheck(cachep, objp, caller /*__builtin_return_address(0)*/);
1444 if (likely(ac->avail < ac->limit)) {
1445 STATS_INC_FREEHIT(cachep);
1446 @@ -2289,7 +2289,7 @@
1447 unsigned long flags;
1449 local_irq_save(flags);
1450 - __cache_free(cachep, objp);
1451 + __cache_free(cachep, objp, __builtin_return_address(0));
1452 local_irq_restore(flags);
1455 @@ -2312,7 +2312,7 @@
1456 local_irq_save(flags);
1457 kfree_debugcheck(objp);
1458 c = GET_PAGE_CACHE(virt_to_page(objp));
1459 - __cache_free(c, (void*)objp);
1460 + __cache_free(c, (void*)objp, __builtin_return_address(0));
1461 local_irq_restore(flags);
1464 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
1465 +++ linux-2.6.5/Documentation/l3/structure 2004-04-30 20:57:36.000000000 -0400
1470 +The structure of the driver is as follows:
1472 + +----------+ +----------+ +----------+
1473 + | client 1 | | client 2 | | client 3 |
1474 + +-----^----+ +----^-----+ +----^-----+
1476 + +-----v--------------v---------------v-----+
1478 + +-----^-------+ +-------^-----+
1480 + +-----v----+ | | +----v-----+
1481 + | device | | | | device |
1482 + | driver 1 | | | | driver 2 |
1483 + +-----^----+ | | +----^-----+
1485 + +-----v-------+ +-------v-----+
1487 + +-----------------^----^-------------------+
1499 +Clients talk to the core to attach device drivers and bus adapters, and
1500 +to instruct device drivers to perform actions. Device drivers then talk
1501 +to the core to perform L3 bus transactions via the algorithm driver and
1502 +ultimately bus driver.
1503 --- linux-2.6.5/arch/arm/kernel/debug.S~heh 2004-04-03 22:36:55.000000000 -0500
1504 +++ linux-2.6.5/arch/arm/kernel/debug.S 2004-04-30 20:57:36.000000000 -0400
1505 @@ -192,6 +192,20 @@
1507 @ if all ports are inactive, then there is nothing we can do
1509 + ldr r1, [\rx, #UTCR2]
1512 + strne r1, [\rx, #UTCR3]
1514 + strne r1, [\rx, #UTCR0]
1516 + strne r1, [\rx, #UTCR2]
1518 + strne r1, [\rx, #UTCR1]
1520 + strne r1, [\rx, #UTCR3]
1522 + strne r1, [\rx, #UTSR0]
1525 .macro senduart,rd,rx
1528 #elif defined(CONFIG_ARCH_INTEGRATOR)
1530 -#include <asm/hardware/serial_amba.h>
1531 +#include <asm/hardware/amba_serial.h>
1534 mrc p15, 0, \rx, c1, c0
1538 .macro senduart,rd,rx
1539 - strb \rd, [\rx, #AMBA_UARTDR]
1540 + strb \rd, [\rx, #UART01x_DR]
1543 .macro waituart,rd,rx
1544 --- linux-2.6.5/arch/arm/kernel/entry-armv.S~heh 2004-04-03 22:36:54.000000000 -0500
1545 +++ linux-2.6.5/arch/arm/kernel/entry-armv.S 2004-04-30 20:57:36.000000000 -0400
1546 @@ -1181,6 +1181,9 @@
1547 * get out of that mode without clobbering one register.
1549 vector_FIQ: disable_fiq
1551 + orr r13, r13, #PSR_F_BIT
1555 /*=============================================================================
1556 --- linux-2.6.5/arch/arm/kernel/irq.c~heh 2004-04-03 22:36:12.000000000 -0500
1557 +++ linux-2.6.5/arch/arm/kernel/irq.c 2004-04-30 20:57:36.000000000 -0400
1559 #define MAX_IRQ_CNT 100000
1561 static volatile unsigned long irq_err_count;
1562 -static spinlock_t irq_controller_lock;
1563 static LIST_HEAD(irq_pending);
1565 struct irqdesc irq_desc[NR_IRQS];
1566 void (*init_arch_irq)(void) __initdata = NULL;
1568 +#if NR_IRQ_DEVICES > 1
1569 +struct irq_device {
1572 + struct irq_desc *irqs;
1575 +static struct irq_device irq_devices[NR_IRQ_DEVICES] = {
1577 + .lock = SPIN_LOCK_UNLOCKED,
1578 + .nr_irqs = NR_IRQS,
1582 +#define IRQ_LOCK(irq) (&irq_devices[IRQ_DEVICE(irq)].lock)
1583 +#define IRQ_DESC(irq) (&irq_devices[IRQ_DEVICE(irq)].irqs[IRQ_INDEX(irq)])
1584 +#define IRQ_VALID(irq) (IRQ_DEVICE(irq) < NR_IRQ_DEVICES && \
1585 + IRQ_INDEX(irq) < irq_devices[IRQ_DEVICE(irq)].nr_irqs)
1587 +static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
1588 +#define IRQ_LOCK(irq) (&irq_controller_lock)
1589 +#define IRQ_DESC(irq) (&irq_desc[irq])
1590 +#define IRQ_VALID(irq) ((irq) < NR_IRQS)
1594 * Dummy mask/unmask handler
1596 @@ -95,13 +119,13 @@
1598 void disable_irq(unsigned int irq)
1600 - struct irqdesc *desc = irq_desc + irq;
1601 + struct irqdesc *desc = IRQ_DESC(irq);
1602 unsigned long flags;
1604 - spin_lock_irqsave(&irq_controller_lock, flags);
1605 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1606 desc->disable_depth++;
1607 list_del_init(&desc->pend);
1608 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1609 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1613 @@ -116,10 +140,10 @@
1615 void enable_irq(unsigned int irq)
1617 - struct irqdesc *desc = irq_desc + irq;
1618 + struct irqdesc *desc = IRQ_DESC(irq);
1619 unsigned long flags;
1621 - spin_lock_irqsave(&irq_controller_lock, flags);
1622 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1623 if (unlikely(!desc->disable_depth)) {
1624 printk("enable_irq(%u) unbalanced from %p\n", irq,
1625 __builtin_return_address(0));
1627 list_add(&desc->pend, &irq_pending);
1630 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1631 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1635 @@ -148,24 +172,24 @@
1637 void enable_irq_wake(unsigned int irq)
1639 - struct irqdesc *desc = irq_desc + irq;
1640 + struct irqdesc *desc = IRQ_DESC(irq);
1641 unsigned long flags;
1643 - spin_lock_irqsave(&irq_controller_lock, flags);
1644 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1645 if (desc->chip->wake)
1646 desc->chip->wake(irq, 1);
1647 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1648 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1651 void disable_irq_wake(unsigned int irq)
1653 - struct irqdesc *desc = irq_desc + irq;
1654 + struct irqdesc *desc = IRQ_DESC(irq);
1655 unsigned long flags;
1657 - spin_lock_irqsave(&irq_controller_lock, flags);
1658 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1659 if (desc->chip->wake)
1660 desc->chip->wake(irq, 0);
1661 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1662 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1665 int show_interrupts(struct seq_file *p, void *v)
1667 unsigned long flags;
1670 - spin_lock_irqsave(&irq_controller_lock, flags);
1671 - action = irq_desc[i].action;
1672 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1673 + action = IRQ_DESC(i)->action;
1681 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1682 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1683 } else if (i == NR_IRQS) {
1684 #ifdef CONFIG_ARCH_ACORN
1685 show_fiq_list(p, v);
1687 unsigned int status;
1690 - spin_unlock(&irq_controller_lock);
1691 + spin_unlock(IRQ_LOCK(irq));
1693 if (!(action->flags & SA_INTERRUPT))
1696 if (status & SA_SAMPLE_RANDOM)
1697 add_interrupt_randomness(irq);
1699 - spin_lock_irq(&irq_controller_lock);
1700 + spin_lock_irq(IRQ_LOCK(irq));
1705 desc = &bad_irq_desc;
1708 - spin_lock(&irq_controller_lock);
1709 + spin_lock(IRQ_LOCK(irq));
1710 desc->handle(irq, desc, regs);
1714 if (!list_empty(&irq_pending))
1715 do_pending_irqs(regs);
1717 - spin_unlock(&irq_controller_lock);
1718 + spin_unlock(IRQ_LOCK(irq));
1723 struct irqdesc *desc;
1724 unsigned long flags;
1726 - if (irq >= NR_IRQS) {
1727 + if (!IRQ_VALID(irq)) {
1728 printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
1731 @@ -481,12 +505,12 @@
1733 handle = do_bad_IRQ;
1735 - desc = irq_desc + irq;
1736 + desc = IRQ_DESC(irq);
1738 if (is_chained && desc->chip == &bad_chip)
1739 printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
1741 - spin_lock_irqsave(&irq_controller_lock, flags);
1742 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1743 if (handle == do_bad_IRQ) {
1744 desc->chip->mask(irq);
1745 desc->chip->ack(irq);
1747 desc->disable_depth = 0;
1748 desc->chip->unmask(irq);
1750 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1751 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1754 void set_irq_chip(unsigned int irq, struct irqchip *chip)
1756 struct irqdesc *desc;
1757 unsigned long flags;
1759 - if (irq >= NR_IRQS) {
1760 + if (!IRQ_VALID(irq)) {
1761 printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
1764 @@ -515,10 +539,10 @@
1768 - desc = irq_desc + irq;
1769 - spin_lock_irqsave(&irq_controller_lock, flags);
1770 + desc = IRQ_DESC(irq);
1771 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1773 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1774 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1777 int set_irq_type(unsigned int irq, unsigned int type)
1778 @@ -527,16 +551,21 @@
1779 unsigned long flags;
1782 - if (irq >= NR_IRQS) {
1783 + if (!IRQ_VALID(irq)) {
1784 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
1788 - desc = irq_desc + irq;
1789 + desc = IRQ_DESC(irq);
1790 + if (!desc->action && desc->handle != do_bad_IRQ) {
1791 + printk(KERN_ERR "Setting type of unclaimed IRQ%d from ", irq);
1792 + print_symbol("%s\n", (unsigned long)__builtin_return_address(0));
1795 if (desc->chip->type) {
1796 - spin_lock_irqsave(&irq_controller_lock, flags);
1797 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1798 ret = desc->chip->type(irq, type);
1799 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1800 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1804 @@ -547,17 +576,17 @@
1805 struct irqdesc *desc;
1806 unsigned long flags;
1808 - if (irq >= NR_IRQS) {
1809 + if (!IRQ_VALID(irq)) {
1810 printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
1814 - desc = irq_desc + irq;
1815 - spin_lock_irqsave(&irq_controller_lock, flags);
1816 + desc = IRQ_DESC(irq);
1817 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1818 desc->valid = (iflags & IRQF_VALID) != 0;
1819 desc->probe_ok = (iflags & IRQF_PROBE) != 0;
1820 desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;
1821 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1822 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1825 int setup_irq(unsigned int irq, struct irqaction *new)
1826 @@ -587,13 +616,13 @@
1828 * The following block of code has to be executed atomically
1830 - desc = irq_desc + irq;
1831 - spin_lock_irqsave(&irq_controller_lock, flags);
1832 + desc = IRQ_DESC(irq);
1833 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1835 if ((old = *p) != NULL) {
1836 /* Can't share interrupts unless both agree to */
1837 if (!(old->flags & new->flags & SA_SHIRQ)) {
1838 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1839 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1847 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1848 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1853 unsigned long retval;
1854 struct irqaction *action;
1856 - if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
1857 + if (!IRQ_VALID(irq) || !IRQ_DESC(irq)->valid || !handler ||
1858 (irq_flags & SA_SHIRQ && !dev_id))
1861 @@ -700,14 +729,14 @@
1862 struct irqaction * action, **p;
1863 unsigned long flags;
1865 - if (irq >= NR_IRQS || !irq_desc[irq].valid) {
1866 + if (!IRQ_VALID(irq) || !IRQ_DESC(irq)->valid) {
1867 printk(KERN_ERR "Trying to free IRQ%d\n",irq);
1872 - spin_lock_irqsave(&irq_controller_lock, flags);
1873 - for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
1874 + spin_lock_irqsave(IRQ_LOCK(irq), flags);
1875 + for (p = &IRQ_DESC(irq)->action; (action = *p) != NULL; p = &action->next) {
1876 if (action->dev_id != dev_id)
1883 - spin_unlock_irqrestore(&irq_controller_lock, flags);
1884 + spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1887 printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
1888 @@ -747,19 +776,18 @@
1889 * first snaffle up any unassigned but
1890 * probe-able interrupts
1892 - spin_lock_irq(&irq_controller_lock);
1893 for (i = 0; i < NR_IRQS; i++) {
1894 - if (!irq_desc[i].probe_ok || irq_desc[i].action)
1897 - irq_desc[i].probing = 1;
1898 - irq_desc[i].triggered = 0;
1899 - if (irq_desc[i].chip->type)
1900 - irq_desc[i].chip->type(i, IRQT_PROBE);
1901 - irq_desc[i].chip->unmask(i);
1903 + spin_lock_irq(IRQ_LOCK(i));
1904 + if (irq_desc[i].probe_ok && !irq_desc[i].action) {
1905 + irq_desc[i].probing = 1;
1906 + irq_desc[i].triggered = 0;
1907 + if (irq_desc[i].chip->type)
1908 + irq_desc[i].chip->type(i, IRQT_PROBE);
1909 + irq_desc[i].chip->unmask(i);
1912 + spin_unlock_irq(IRQ_LOCK(i));
1914 - spin_unlock_irq(&irq_controller_lock);
1917 * wait for spurious interrupts to mask themselves out again
1918 @@ -770,14 +798,14 @@
1920 * now filter out any obviously spurious interrupts
1922 - spin_lock_irq(&irq_controller_lock);
1923 for (i = 0; i < NR_IRQS; i++) {
1924 + spin_lock_irq(IRQ_LOCK(i));
1925 if (irq_desc[i].probing && irq_desc[i].triggered) {
1926 irq_desc[i].probing = 0;
1929 + spin_unlock_irq(IRQ_LOCK(i));
1931 - spin_unlock_irq(&irq_controller_lock);
1935 @@ -788,11 +816,13 @@
1937 unsigned int mask = 0, i;
1939 - spin_lock_irq(&irq_controller_lock);
1940 - for (i = 0; i < 16 && i < NR_IRQS; i++)
1941 - if (irq_desc[i].probing && irq_desc[i].triggered)
1942 + for (i = 0; i < 16 && i < NR_IRQS; i++) {
1943 + struct irqdesc *desc = IRQ_DESC(i);
1944 + spin_lock_irq(IRQ_LOCK(i));
1945 + if (desc->probing && desc->triggered)
1947 - spin_unlock_irq(&irq_controller_lock);
1948 + spin_unlock_irq(IRQ_LOCK(i));
1953 @@ -813,23 +843,21 @@
1954 * look at the interrupts, and find exactly one
1955 * that we were probing has been triggered
1957 - spin_lock_irq(&irq_controller_lock);
1958 for (i = 0; i < NR_IRQS; i++) {
1959 - if (irq_desc[i].probing &&
1960 - irq_desc[i].triggered) {
1961 + struct irqdesc *desc = IRQ_DESC(i);
1963 + spin_lock_irq(IRQ_LOCK(i));
1964 + if (desc->probing && desc->triggered) {
1965 if (irq_found != NO_IRQ) {
1966 + spin_unlock_irq(IRQ_LOCK(i));
1973 + spin_unlock_irq(IRQ_LOCK(i));
1976 - if (irq_found == -1)
1977 - irq_found = NO_IRQ;
1979 - spin_unlock_irq(&irq_controller_lock);
1984 --- linux-2.6.5/arch/arm/kernel/bios32.c~heh 2004-04-03 22:36:56.000000000 -0500
1985 +++ linux-2.6.5/arch/arm/kernel/bios32.c 2004-04-30 20:57:36.000000000 -0400
1990 - pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
1992 list_for_each_entry(sys, &hw->buses, node) {
1993 struct pci_bus *bus = sys->bus;
1995 @@ -581,6 +579,11 @@
1996 pci_bus_assign_resources(bus);
2001 + pci_bus_fixup_irqs(bus, pcibios_swizzle, pcibios_map_irq);
2004 * Tell drivers about devices found.
2006 pci_bus_add_devices(bus);
2007 --- linux-2.6.5/arch/arm/kernel/traps.c~heh 2004-04-03 22:36:57.000000000 -0500
2008 +++ linux-2.6.5/arch/arm/kernel/traps.c 2004-04-30 20:57:36.000000000 -0400
2009 @@ -206,33 +206,43 @@
2010 c_backtrace(fp, 0x10);
2013 -spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
2016 - * This function is protected against re-entrancy.
2018 -NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
2019 +static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
2021 - struct task_struct *tsk = current;
2022 + struct task_struct *tsk = thread->task;
2023 static int die_counter;
2025 - console_verbose();
2026 - spin_lock_irq(&die_lock);
2027 - bust_spinlocks(1);
2029 printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
2031 printk("CPU: %d\n", smp_processor_id());
2033 printk("Process %s (pid: %d, stack limit = 0x%p)\n",
2034 - tsk->comm, tsk->pid, tsk->thread_info + 1);
2035 + tsk->comm, tsk->pid, thread + 1);
2037 if (!user_mode(regs) || in_interrupt()) {
2038 dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info);
2039 dump_backtrace(regs, tsk);
2044 +void nmi_watchdog(struct thread_info *thread, struct pt_regs *regs)
2046 + __die("NMI watchdog", 0, thread, regs);
2049 +spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
2052 + * This function is protected against re-entrancy.
2054 +NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
2056 + struct thread_info *thread = current_thread_info();
2058 + console_verbose();
2059 + spin_lock_irq(&die_lock);
2060 + bust_spinlocks(1);
2061 + __die(str, err, thread, regs);
2063 spin_unlock_irq(&die_lock);
2065 --- linux-2.6.5/arch/arm/Kconfig~heh 2004-04-03 22:37:07.000000000 -0500
2066 +++ linux-2.6.5/arch/arm/Kconfig 2004-04-30 20:57:36.000000000 -0400
2070 bool "Support CPU clock change (EXPERIMENTAL)"
2071 - depends on (ARCH_SA1100 || ARCH_INTEGRATOR) && EXPERIMENTAL
2072 + depends on (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_PXA) && EXPERIMENTAL
2074 CPU clock scaling allows you to change the clock speed of the
2075 running CPU on the fly. This is a nice method to save battery power,
2076 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
2077 +++ linux-2.6.5/arch/arm/fastfpe/entry.S 2004-04-30 20:57:36.000000000 -0400
2080 +At entry the registers contain the following information:
2082 +r14 return address for undefined exception return
2083 +r9 return address for return from exception
2084 +r13 user registers on stack, offset 0 up to offset 4*15 contains
2085 + registers r0..15, then the psr
2086 +r10 FP workspace 35 words (init, reg[8][4], fpsr, fpcr)
2090 +/*---------------------------------------------------------------------------*/
2094 + .word 0, 0x00000000, 0, 0x80000000 @ 0
2095 + .word 0, 0x80000000, 0, 0 @ 1
2096 + .word 0, 0x80000000, 0, 1 @ 2
2097 + .word 0, 0xc0000000, 0, 1 @ 3
2098 + .word 0, 0x80000000, 0, 2 @ 4
2099 + .word 0, 0xa0000000, 0, 2 @ 5
2100 + .word 0, 0x80000000, 0, -1 @ 0.5
2101 + .word 0, 0xa0000000, 0, 3 @ 10
2122 +/*---------------------------------------------------------------------------*/
2125 + .globl fastfpe_enter
2128 + str r14,[r4] @ to free one register
2129 + add r10,r10,#4 @ to make the code simpler
2130 + mov r4, r0 @ r4=trapped instruction
2131 + and r1,r4,#0x00000f00 @ r1=coprocessor << 8
2133 + cmp r1,#1<<8 @ copro 1 ?
2139 + and r1,r4,#0x0f000000
2140 + cmp r1,#0x0c000000 @ CPDT with post indexing
2141 + cmpne r1,#0x0d000000 @ CPDT with pre indexing
2146 + and r1,r4,#0x0f000000
2147 + cmp r1,#0x0e000000 @ CPDO
2148 + beq CPDO_CPRT_enter
2149 + cmp r1,#0x0c000000 @ CPDT with post indexing
2150 + cmpne r1,#0x0d000000 @ CPDT with pre indexing
2154 +/*---------------------------------------------------------------------------*/
2156 + .globl fastfpe_next
2163 + ldr r0,=fp_cond @ check condition of next instruction
2164 + ldr r1,[r13,#64] @ psr containing flags
2167 + ldr r0,[r0,r2,lsl#2]
2170 + beq next_after_cond @ must not necessarily have been an
2171 + @ FP instruction !
2172 + and r1,r4,#0x0f000000 @ Test for copro instruction
2173 + cmp r1,#0x0c000000
2174 + rsbgts r0,r1,#0x0e000000 @ cmpgt #0x0e000000,r1
2175 + movlt pc,r9 @ next is no copro instruction, return
2177 + ands r1,r4,#0x00000f00 @ r1 = coprocessor << 8
2179 + movge pc,r9 @ copro = 0 or >=3, return
2181 + str r5,[r13,#60] @ save updated pc
2184 +/*---------------------------------------------------------------------------*/
2190 +/*---------------------------------------------------------------------------*/
2193 + and r5,r4,#0x000f0000 @ r5=base register number << 16
2194 + ldr r6,[r13,r5,lsr#14] @ r6=base address
2195 + cmp r5,#0x000f0000 @ base register = pc ?
2197 + and r7,r4,#0x000000ff @ r7=offset value
2199 + tst r4,#0x00800000 @ up or down?
2200 + addne r7,r6,r7,lsl#2
2201 + subeq r7,r6,r7,lsl#2 @ r6=base address +/- offset
2202 + tst r4,#0x01000000 @ preindexing ?
2204 + tst r4,#0x00200000 @ write back ?
2205 + cmpne r5,#0x000f0000 @ base register = pc ?
2206 + strne r7,[r13,r5,lsr#14]
2208 + and r0,r4,#0x00007000 @ r0=fp register number << 12
2209 + add r0,r10,r0,lsr#8 @ r0=address of fp register
2211 + tst r4,#0x00008000
2212 + orrne r1,r1,#1 @ T0
2213 + tst r4,#0x00400000
2214 + orrne r1,r1,#2 @ T1
2215 + tst r4,#0x00100000
2216 + orrne r1,r1,#4 @ L/S
2218 + add pc,pc,r1,lsl#2
2220 + b CPDT_store_single @ these functions get
2221 + b CPDT_store_double @ r0=address of fp register
2222 + b CPDT_store_extended @ r6=address of data
2223 + b undefined @ CPDT_store_decimal
2224 + b CPDT_load_single
2225 + b CPDT_load_double
2226 + b CPDT_load_extended
2227 + b undefined @ CPDT_load_decimal
2229 +/*---------------------------------------------------------------------------*/
2232 + and r5,r4,#0x000f0000 @ r5=base register number << 16
2233 + ldr r6,[r13,r5,lsr#14] @ r6=base address
2234 + cmp r5,#0x000f0000 @ base register = pc ?
2236 + and r7,r4,#0x000000ff @ r7=offset value
2238 + tst r4,#0x00800000 @ up or down?
2239 + addne r7,r6,r7,lsl#2
2240 + subeq r7,r6,r7,lsl#2 @ r7=base address +/- offset
2241 + tst r4,#0x01000000 @ preindexing ?
2243 + tst r4,#0x00200000 @ write back ?
2244 + cmpne r5,#0x000f0000 @ base register = pc ?
2245 + strne r7,[r13,r5,lsr#14]
2247 + and r0,r4,#0x00007000 @ r0=fp register number << 12
2248 + and r1,r4,#0x00008000
2249 + mov r1,r1,lsr#15 @ N0
2250 + and r2,r4,#0x00400000
2251 + orrs r1,r1,r2,lsr#21 @ N1
2252 + addeq r1,r1,#4 @ r1=register count
2254 + tst r4,#0x00100000 @ load/store
2258 +/*---------------------------------------------------------------------------*/
2261 + tst r4,#0x00000010
2264 + and r0,r4,#0x00007000
2265 + add r0,r10,r0,lsr#8 @ r0=address of Fd
2266 + and r1,r4,#0x00070000
2267 + add r1,r10,r1,lsr#12 @ r1=address of Fn
2268 + tst r4,#0x00000008
2270 + and r2,r4,#0x00000007
2271 + add r2,r10,r2,lsl#4 @ r2=address of Fm
2274 + and r3,r4,#0x00f00000
2275 + tst r4,#0x00008000
2276 + orrne r3,r3,#0x01000000
2278 + add pc,pc,r3,lsr#18
2288 + b undefined @ CPDO_rmf
2315 + and r3,r4,#0x00000007
2316 + add r2,r2,r3,lsl#4
2319 +/*---------------------------------------------------------------------------*/
2322 + and r0,r4,#0x0000f000 @ r0=Rd<<12
2323 + and r1,r4,#0x00070000
2324 + add r1,r10,r1,lsr#12 @ r1=address of Fn
2325 + tst r4,#0x00000008
2327 + and r2,r4,#0x00000007
2328 + add r2,r10,r2,lsl#4 @ r2=address of Fm
2331 + and r3,r4,#0x00f00000
2333 + add pc,pc,r3,lsr#18
2354 + and r3,r4,#0x00000007
2355 + add r2,r2,r3,lsl#4
2358 +/*---------------------------------------------------------------------------*/
2360 + @ The fetch of the next instruction to emulate could fault
2362 + .section .fixup,"ax"
2367 + .section __ex_table,"a"
2372 +/*---------------------------------------------------------------------------*/
2373 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
2374 +++ linux-2.6.5/arch/arm/fastfpe/module.c 2004-04-30 20:57:36.000000000 -0400
2377 + Fast Floating Point Emulator
2378 + (c) Peter Teichmann <mail@peter-teichmann.de>
2380 + This program is free software; you can redistribute it and/or modify
2381 + it under the terms of the GNU General Public License as published by
2382 + the Free Software Foundation; either version 2 of the License, or
2383 + (at your option) any later version.
2385 + This program is distributed in the hope that it will be useful,
2386 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2387 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2388 + GNU General Public License for more details.
2390 + You should have received a copy of the GNU General Public License
2391 + along with this program; if not, write to the Free Software
2392 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2395 +#include <linux/module.h>
2396 +#include <linux/types.h>
2397 +#include <linux/kernel.h>
2398 +#include <linux/signal.h>
2399 +#include <linux/sched.h>
2400 +#include <linux/init.h>
2401 +#include <linux/errno.h>
2404 +#define kern_fp_enter fp_enter
2406 +extern char fpe_type[];
2409 +static void (*orig_fp_enter)(void); /* old kern_fp_enter value */
2410 +extern void (*kern_fp_enter)(void); /* current FP handler */
2411 +extern void fastfpe_enter(void); /* forward declarations */
2413 +static int __init fpe_init(void)
2415 + if (fpe_type[0] && strcmp(fpe_type, "fastfpe"))
2418 + printk("Fast Floating Point Emulator V0.9 (c) Peter Teichmann.\n");
2420 + /* Save pointer to the old FP handler and then patch ourselves in */
2421 + orig_fp_enter = kern_fp_enter;
2422 + kern_fp_enter = fastfpe_enter;
2427 +static void __exit fpe_exit(void)
2429 + /* Restore the values we saved earlier. */
2430 + kern_fp_enter = orig_fp_enter;
2433 +module_init(fpe_init);
2434 +module_exit(fpe_exit);
2436 +MODULE_AUTHOR("Peter Teichmann <mail@peter-teichmann.de>");
2437 +MODULE_DESCRIPTION("Fast floating point emulator with full precision");
2438 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
2439 +++ linux-2.6.5/arch/arm/fastfpe/CPDO.S 2004-04-30 20:57:36.000000000 -0400
2442 +The FP structure has 4 words reserved for each register, the first is used just
2443 +for the sign in bit 31, the second and third are for the mantissa (unsigned
2444 +integer, high 32 bit first) and the fourth is the exponent (signed integer).
2445 +The mantissa is always normalized.
2447 +If the exponent is 0x80000000, that is the most negative value, the number
2448 +represented is 0 and both mantissa words are also 0.
2450 +If the exponent is 0x7fffffff, that is the biggest positive value, the number
2451 +represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
2452 +a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
2454 +Decimal and packed decimal numbers are not supported yet.
2456 +The parameters to these functions are r0=destination pointer, r1 and r2
2457 +source pointers. r4 is the instruction. They may use r0-r8 and r14. They return
2458 +to fastfpe_next, except CPDO_rnf_core which expects the return address in r14.
2461 +/*---------------------------------------------------------------------------*/
2465 + ldmia r1,{r1,r3,r5,r7}
2466 + ldmia r2,{r2,r4,r6,r8}
2468 + cmp r7,#0x7fffffff
2469 + cmpne r8,#0x7fffffff
2470 + beq CPDO_adf_extra
2494 + orr r5,r5,r3,lsl r8
2495 + mov r3,r3,lsr r2 @ 1. op normalized
2512 + orr r6,r6,r4,lsl r8
2513 + mov r4,r4,lsr r2 @ 2. op normalized
2517 + adcs r3,r3,r4 @ do addition
2522 + mov r5,r5,rrx @ correct for overflow
2525 + cmp r7,#0x20000000
2528 + stmia r0,{r1,r3,r5,r7}
2532 + cmp r7,#0x7fffffff @ was it the 1st ?
2533 + bne CPDO_infnan_2 @ no it was the 2nd
2534 + cmp r8,#0x7fffffff @ if 1st, 2nd too ?
2535 + bne CPDO_infnan_1 @ no only 1st
2541 +/*---------------------------------------------------------------------------*/
2544 + stmia r0,{r1,r3,r5,r7}
2548 + stmia r0,{r2,r4,r6,r8}
2556 + mov r2,#0x40000000 @ create non signalling NaN
2563 + mov r4,#0x7fffffff
2565 + stmia r0,{r1,r2,r3,r4}
2573 + mov r4,#0x80000000
2574 + stmia r0,{r1,r2,r3,r4}
2577 +/*---------------------------------------------------------------------------*/
2581 + ldmia r1,{r1,r3,r5,r7}
2582 + ldmia r2,{r2,r4,r6,r8}
2585 + cmp r7,#0x7fffffff
2586 + cmpne r8,#0x7fffffff
2587 + beq CPDO_suf_extra
2593 + subs r2,r7,r8 @ determine greater number
2594 + bgt CPDO_suf_2nd @ first number is greater
2595 + blt CPDO_suf_1st @ second number is greater
2596 + cmp r3,r4 @ also mantissa is important
2598 + bhi CPDO_suf_2nd @ first number is greater
2602 + eor r1,r1,#0x80000000 @ second number is greater, invert sign
2613 + b CPDO_suf_1st_sub
2618 + orr r5,r5,r3,lsl r8
2619 + mov r3,r3,lsr r2 @ 1. op normalized
2622 + subs r5,r6,r5 @ do subtraction
2635 + b CPDO_suf_2nd_sub
2640 + orr r6,r6,r4,lsl r8
2641 + mov r4,r4,lsr r2 @ 2. op normalized
2645 + sbc r3,r3,r4 @ do subtraction
2648 + teq r3,#0 @ normalize 32bit
2653 + cmp r3,#0x00010000 @ 16bit
2654 + movcc r3,r3,lsl#16
2655 + orrcc r3,r3,r5,lsr#16
2656 + movcc r5,r5,lsl#16
2659 + cmp r3,#0x01000000 @ 8bit
2661 + orrcc r3,r3,r5,lsr#24
2665 + cmp r3,#0x10000000 @ 4bit
2667 + orrcc r3,r3,r5,lsr#28
2671 + cmp r3,#0x40000000 @ 2bit
2673 + orrcc r3,r3,r5,lsr#30
2677 + cmp r3,#0x80000000 @ 1bit
2679 + orrcc r3,r3,r5,lsr#31
2683 + cmp r7,#0xe0000000
2686 + stmia r0,{r1,r3,r5,r7}
2690 + cmp r7,#0x7fffffff @ was it the 1st ?
2691 + eorne r2,r2,#0x80000000 @ change sign, might have been INF
2692 + bne CPDO_infnan_2 @ no it was the 2nd
2693 + cmp r8,#0x7fffffff @ if 1st, 2nd too ?
2694 + bne CPDO_infnan_1 @ no only 1st
2698 + b CPDO_nan @ here is difference with adf !
2700 +/*---------------------------------------------------------------------------*/
2705 + ldmia r1,{r2,r4,r6,r8}
2706 + ldmia r3,{r1,r3,r5,r7}
2709 +/*---------------------------------------------------------------------------*/
2713 + ldmia r1,{r1,r3,r5,r7}
2714 + ldmia r2,{r2,r4,r6,r8}
2716 + cmp r7,#0x7fffffff
2717 + cmpne r8,#0x7fffffff
2718 + beq CPDO_muf_extra
2725 + umull r14,r3,r6,r3
2726 + adds r7,r7,r3 @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14
2729 + adds r14,r14,r4 @ r2|r7|r14 += #0|r3|r4
2733 + adds r14,r14,r3 @ r2|r7|r14 += #0|#0|r3
2748 + cmp r8,#0x20000000
2750 + cmp r8,#0xe0000000
2752 + stmia r0,{r1,r2,r7,r8}
2756 + cmp r7,#0x7fffffff @ was it the first?
2757 + bne CPDO_muf_extra_2nd @ no, so it was the second
2758 + cmp r8,#0x7fffffff @ yes, second too?
2759 + bne CPDO_muf_extra_1st @ no, only first
2760 + orr r3,r3,r4 @ if both inf -> inf, otherwise nan
2761 + eor r1,r1,r2 @ sign for the inf case
2764 +CPDO_muf_extra_1st:
2765 + cmp r3,#0 @ is it a nan?
2767 + cmp r8,#0x80000000 @ is the second 0?
2769 + eor r1,r1,r2 @ correct sign for inf
2772 +CPDO_muf_extra_2nd:
2773 + cmp r4,#0 @ is it a nan?
2775 + cmp r7,#0x80000000 @ is the first 0?
2777 + eor r1,r1,r2 @ correct sign for inf
2780 +/*---------------------------------------------------------------------------*/
2784 + ldmia r1,{r1,r3,r5,r7}
2785 + ldmia r2,{r2,r4,r6,r8}
2788 + cmp r7,#0x7fffffff
2789 + cmpne r8,#0x7fffffff
2790 + beq CPDO_dvf_extra
2791 + cmp r8,#0x80000000
2795 + cmp r7,#0x80000000
2805 + bcs CPDO_dvf_loop_
2812 + bcs CPDO_dvf_anyway
2842 + cmp R7,#0x80000000
2843 + beq CPDO_nan @ first also 0 -> nan
2844 + eor r1,r1,r2 @ otherwise calculatesign for inf
2848 + cmp r7,#0x7fffffff @ was it the first?
2849 + bne CPDO_dvf_extra_2nd @ no, so it was the second
2850 + cmp r8,#0x7fffffff @ yes, second too?
2851 + bne CPDO_dvf_extra_1st @ no, only first
2853 + beq CPDO_nan @ if both inf -> create nan
2854 + b CPDO_nan_12 @ otherwise keep nan
2856 +CPDO_dvf_extra_1st:
2857 + eor r1,r1,r2 @ correct sign for inf
2860 +CPDO_dvf_extra_2nd:
2861 + cmp r4,#0 @ is it a nan?
2863 + eor r1,r1,r2 @ correct sign for zero
2866 +/*---------------------------------------------------------------------------*/
2871 + ldmia r1,{r2,r4,r6,r8}
2872 + ldmia r3,{r1,r3,r5,r7}
2875 +/*---------------------------------------------------------------------------*/
2881 +/*---------------------------------------------------------------------------*/
2885 +/*---------------------------------------------------------------------------*/
2889 + ldmia r2,{r1,r2,r3,r4}
2890 + stmia r0,{r1,r2,r3,r4}
2893 +/*---------------------------------------------------------------------------*/
2897 + ldmia r2,{r1,r2,r3,r4}
2898 + eor r1,r1,#0x80000000
2899 + stmia r0,{r1,r2,r3,r4}
2902 +/*---------------------------------------------------------------------------*/
2906 + ldmia r2,{r1,r2,r3,r4}
2907 + bic r1,r1,#0x80000000
2908 + stmia r0,{r1,r2,r3,r4}
2911 +/*---------------------------------------------------------------------------*/
2915 + ldmia r2,{r1,r2,r3,r4}
2918 + cmp r4,#0x7fffffff
2919 + beq CPDO_store_1234
2921 + tst r4,r4,lsr#1 @carry=exponent bit 0
2922 + bcc CPDO_sqt_exponenteven
2924 + adcs r2,r2,r2 @carry is needed in loop!
2925 +CPDO_sqt_exponenteven:
2929 + mov r4,#0x80000000
2931 + sub r2,r2,#0x80000000
2933 + mov r8,#0x40000000
2934 + mov r14,#0x80000000
2937 + b CPDO_sqt_loop1_first
2941 +CPDO_sqt_loop1_first:
2942 + add r6,r4,r8,lsr r1 @r7 const = r5
2943 + bcs CPDO_sqt_loop1_1
2945 + cmpeq r3,r5 @r5 for r7
2946 + bcc CPDO_sqt_loop1_0
2948 + orr r4,r4,r14,lsr r1
2949 + subs r3,r3,r5 @r5 for r7
2954 + ble CPDO_sqt_loop1
2958 + bcs CPDO_sqt_between_1
2959 + adds r7,r5,#0x80000000
2963 + bcc CPDO_sqt_between_0
2964 +CPDO_sqt_between_1:
2965 + orr r4,r4,#0x00000001
2968 + subs r3,r3,#0x80000000
2970 +CPDO_sqt_between_0:
2976 + bcs CPDO_sqt_loop2_1
2977 + adds r7,r5,r8,lsr r1
2981 + bcc CPDO_sqt_loop2_0
2983 + orr r5,r5,r14,lsr r1
2986 + subs r3,r3,r8,lsr r1
2991 + ble CPDO_sqt_loop2
2995 + bcs CPDO_sqt_after_1
2998 + bcc CPDO_sqt_after_0
3000 + orr r5,r5,#0x00000001
3004 + stmia r0,{r1,r4,r5}
3007 +/*---------------------------------------------------------------------------*/
3011 + ldmia r2,{r1,r2,r3,r5}
3015 + stmia r0,{r1,r2,r3,r5}
3018 +/*---------------------------------------------------------------------------*/
3020 + .globl CPDO_rnd_core
3022 + and r4,r4,#0x00000060
3023 + add pc,pc,r4,lsr#3
3035 + mov r4,#0x40000000
3039 + adds r2,r2,r4,lsr r5
3041 + b CPDO_rnd_end_norm
3046 + adds r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly
3049 + b CPDO_rnd_end_norm
3052 + tst r1,#0x80000000
3053 + bne CPDO_rnd_M_entry
3056 + blt CPDO_rnd_P_small
3059 + mov r4,#0x7fffffff
3063 + adds r3,r3,#0xffffffff
3064 + adcs r2,r2,r4,lsr r5
3066 + b CPDO_rnd_end_norm
3069 + cmp r5,#0x80000000
3074 + tst r1,#0x80000000
3075 + bne CPDO_rnd_P_entry
3097 + bmi CPDO_rnd_end_2
3110 + mov r2,#0x80000000
3119 + mov r5,#0x80000000
3122 +/*---------------------------------------------------------------------------*/
3123 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
3124 +++ linux-2.6.5/arch/arm/fastfpe/CPRT.S 2004-04-30 20:57:36.000000000 -0400
3127 +The FP structure has 4 words reserved for each register, the first is used
3129 +for the sign in bit 31, the second and third are for the mantissa (unsigned
3130 +integer, high 32 bit first) and the fourth is the exponent (signed integer).
3131 +The mantissa is always normalized.
3133 +If the exponent is 0x80000000, that is the most negative value, the number
3134 +represented is 0 and both mantissa words are also 0.
3136 +If the exponent is 0x7fffffff, that is the biggest positive value, the
3138 +represented is infinity if the high 32 mantissa bit are also 0, otherwise it
3140 +a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
3142 +Decimal and packed decimal numbers are not supported yet.
3145 +/*---------------------------------------------------------------------------*/
3150 + add r0,r13,r0,lsr#10
3156 + ands r0,r2,#0x80000000
3160 + cmp r2,#0x00010000
3161 + movcc r2,r2,lsl#16
3164 + cmp r2,#0x01000000
3168 + cmp r2,#0x10000000
3172 + cmp r2,#0x40000000
3176 + cmp r2,#0x80000000
3180 + stmia r1,{r0,r2,r3,r4}
3185 + mov r4,#0x80000000
3186 + stmia r1,{r0,r2,r3,r4}
3189 +/*---------------------------------------------------------------------------*/
3193 + ldmia r2,{r1,r2,r3,r5}
3197 + add r0,r13,r0,lsr#10
3205 + tst r1,#0x80000000
3217 + mov r2,#0x80000000
3218 + tst r1,#0x80000000
3223 +/*---------------------------------------------------------------------------*/
3229 +/*---------------------------------------------------------------------------*/
3233 + add r0,r13,r0,lsr#10
3234 + mov r1,#0x02000000 @ Software Emulation, not Acorn FPE
3238 +/*---------------------------------------------------------------------------*/
3242 + ldmia r1,{r1,r3,r5,r7}
3243 + ldmia r2,{r2,r4,r6,r8}
3246 + ldr r0,[r13,#16*4]
3248 + cmp r7,#0x7fffffff
3249 + bic r0,r0,#0xf0000000
3251 + cmpeq r3,#0xffffffff
3252 + beq CPRT_cmf_unordered
3253 + cmp r8,#0x7fffffff
3254 + cmpeq r4,#0xffffffff
3255 + beq CPRT_cmf_unordered
3258 + beq CPRT_cmf_equalsign
3261 +CPRT_cmf_equalsign:
3263 + beq CPRT_cmf_equalexponent
3267 +CPRT_cmf_equalexponent:
3270 + beq CPRT_cmf_equal
3275 + cmp r7,#0x80000000 @ (0.0 == -0.0)?
3277 + beq CPRT_cmf_equal
3278 + tst r1,#0x80000000
3279 + orreq r0,r0,#0x20000000
3280 + orrne r0,r0,#0x80000000
3281 + str r0,[r13,#16*4]
3285 + tst r1,#0x80000000
3286 + orrne r0,r0,#0x20000000
3287 + orreq r0,r0,#0x80000000
3288 + str r0,[r13,#16*4]
3292 + orr r0,r0,#0x60000000
3293 + str r0,[r13,#16*4]
3296 +CPRT_cmf_unordered:
3297 + orr r0,r0,#0x10000000
3298 + str r0,[r13,#16*4]
3301 +/*---------------------------------------------------------------------------*/
3305 + ldmia r1,{r1,r3,r5,r7}
3306 + ldmia r2,{r2,r4,r6,r8}
3307 + eor r2,r2,#0x80000000
3310 +/*---------------------------------------------------------------------------*/
3311 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
3312 +++ linux-2.6.5/arch/arm/fastfpe/CPDT.S 2004-04-30 20:57:36.000000000 -0400
3315 +The FP structure has 4 words reserved for each register, the first is used just
3316 +for the sign in bit 31, the second and third are for the mantissa (unsigned
3317 +integer, high 32 bit first) and the fourth is the exponent (signed integer).
3318 +The mantissa is always normalized.
3320 +If the exponent is 0x80000000, that is the most negative value, the number
3321 +represented is 0 and both mantissa words are also 0.
3323 +If the exponent is 0x7fffffff, that is the biggest positive value, the number
3324 +represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
3325 +a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
3327 +Decimal and packed decimal numbers are not supported yet.
3330 +/*---------------------------------------------------------------------------*/
3332 + .globl CPDT_load_single
3336 + and r2,r1,#0x80000000 @ r2 = sign
3340 + beq CPDT_ls_e0 @ exponent = 0; zero/denormalized
3342 + beq CPDT_ls_e255 @ exponent = 255; infinity/NaN
3344 + sub r5,r5,#127 @ r5 = exponent, remove normalized bias
3347 + orr r3,r3,#0x80000000
3348 + mov r4,#0 @ r3,r4 = mantissa
3355 + beq CPDT_load_zero
3360 + tst r3,#0x80000000
3363 + beq CPDT_ls_e0_norm
3372 + mov r5,#0x7fffffff
3379 + mov r5,#0x80000000
3383 +/*---------------------------------------------------------------------------*/
3385 + .globl CPDT_load_double
3390 + and r2,r1,#0x80000000 @ r2 = sign
3394 + beq CPDT_ld_e0 @ exponent = 0; zero/denormalized
3397 + beq CPDT_ld_e2047 @ exponent = 2047; infinity/NaN
3400 + sub r5,r5,#1024 @ r5 = exponent, remove normalized bias
3403 + orr r3,r3,#0x80000000
3404 + orr r3,r3,r6,lsr #21
3405 + mov r4,r6,lsl#11 @ r3,r4 = mantissa
3412 + orr r3,r3,r6,lsr#20
3415 + beq CPDT_load_zero
3421 + tst r3,#0x80000000
3423 + moveqs r4,r4,lsl#1
3425 + beq CPDT_ld_e0_norm
3432 + orr r3,r3,r6,lsr#1
3433 + bic r6,r6,#0x80000000
3434 + orr r3,r3,r6 @ to get all fraction bits !
3436 + mov r5,#0x7fffffff
3440 +/*---------------------------------------------------------------------------*/
3442 + .globl CPDT_load_extended
3443 +CPDT_load_extended:
3448 + and r2,r1,#0x80000000
3449 + bics r5,r1,#0x80000000
3453 + beq CPDT_le_e32767
3464 + beq CPDT_load_zero
3472 + orr r3,r3,r4,lsr#1
3473 + bic r4,r4,#0x80000000
3475 + mov r5,#0x7fffffff
3479 +/*---------------------------------------------------------------------------*/
3481 + .globl CPDT_load_decimal
3486 +/*---------------------------------------------------------------------------*/
3488 + .globl CPDT_store_single
3497 + adds r2,r2,#1<<7 @ round to nearest
3498 + bcs CPDT_ss_rnd_ovfl @ very very seldom taken
3502 + orr r1,r1,r4,lsl#23
3504 + bic r2,r2,#0x80000000
3505 + orr r1,r1,r2,lsr#8
3515 + mov r2,#0x80000000
3524 +CPDT_ss_unnormalize:
3527 + bne CPDT_ss_unnormalize
3529 + orr r1,r1,r2,lsr#8
3536 + cmp r4,#0x7fffffff
3541 + orr r1,r1,#0x00200000 @ for safety so that it is not INF
3542 + orr r1,r1,r2,lsr#9 @ get highest bit of mantissa
3545 + orr r1,r1,#0x7f000000
3546 + orr r1,r1,#0x00800000
3550 +/*---------------------------------------------------------------------------*/
3552 + .globl CPDT_store_double
3556 + cmp r4,#1024 @ this check has to be first, or
3557 + bge CPDT_sd_e2047 @ overflow can occur on second !
3559 + cmp r0,#-1023+3 @ cmp with -1023
3562 + adds r3,r3,#1<<10 @ round to nearest
3564 + bcs CPDT_sd_rnd_ovfl @ very very seldom taken
3569 + orr r1,r1,r4,lsl#20
3571 + bic r2,r2,#0x80000000
3572 + orr r1,r1,r2,lsr#11
3575 + orr r2,r2,r3,lsr#11
3585 + mov r2,#0x80000000
3590 + add r0,r4,#1075-1024
3596 +CPDT_sd_unnormalize:
3600 + bne CPDT_sd_unnormalize
3602 + orr r1,r1,r2,lsr#11
3604 + orr r2,r2,r3,lsr#11
3615 + cmp r4,#0x7fffffff
3620 + orr r1,r1,#0x00040000 @ for safety so that it is not INF
3621 + orr r1,r1,r2,lsr#12 @ get highest bit of mantissa
3624 + orr r1,r1,#0x7f000000
3625 + orr r1,r1,#0x00f00000
3629 +/*---------------------------------------------------------------------------*/
3631 + .globl CPDT_store_extended
3632 +CPDT_store_extended:
3635 + cmp r4,#16384 @ this check has to be first, or
3636 + bge CPDT_se_e32767 @ overflow can occur with second !
3649 + add r0,r4,#16446-16384
3655 +CPDT_se_unnormalize:
3659 + bne CPDT_se_unnormalize
3671 + cmp r4,#0x7fffffff
3677 + orr r2,r2,#0x20000000
3680 + orr r1,r1,#0x00007f00
3681 + orr r1,r1,#0x000000ff
3685 +/*---------------------------------------------------------------------------*/
3687 + .globl CPDT_store_decimal
3688 +CPDT_store_decimal:
3692 +/*---------------------------------------------------------------------------*/
3696 + add r2,r10,r0,lsr#8
3699 + bic r3,r3,#0x80000000
3713 +/*---------------------------------------------------------------------------*/
3717 + add r2,r10,r0,lsr#8
3719 + and r3,r4,#0x80000000
3726 + cmp r3,#0x80000000 @ does the exp indicate zero?
3727 + biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized'
3728 + beq CPDT_lfm_storer4
3729 + cmp r3,#0x7fffffff @ does the exp indicate inf or NaN?
3730 + biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized'
3731 + beq CPDT_lfm_storer4
3732 + orrne r4,r4,#0x80000000 @ otherwise, set normalized bit
3743 +/*---------------------------------------------------------------------------*/
3744 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
3745 +++ linux-2.6.5/arch/arm/fastfpe/Makefile 2004-04-30 20:57:36.000000000 -0400
3748 +# linux/arch/arm/fastfpe/Makefile
3750 +# Copyright (C) Peter Teichmann
3758 +fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o
3760 +obj-$(CONFIG_FPE_FASTFPE) += fastfpe.o
3761 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
3762 +++ linux-2.6.5/arch/arm/common/rtctime.c 2004-04-30 20:57:36.000000000 -0400
3765 + * linux/arch/arm/common/rtctime.c
3767 + * Copyright (C) 2003 Deep Blue Solutions Ltd.
3768 + * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre.
3769 + * Based on rtc.c by Paul Gortmaker
3771 + * This program is free software; you can redistribute it and/or modify
3772 + * it under the terms of the GNU General Public License version 2 as
3773 + * published by the Free Software Foundation.
3775 +#include <linux/module.h>
3776 +#include <linux/kernel.h>
3777 +#include <linux/time.h>
3778 +#include <linux/rtc.h>
3779 +#include <linux/poll.h>
3780 +#include <linux/proc_fs.h>
3781 +#include <linux/miscdevice.h>
3782 +#include <linux/spinlock.h>
3783 +#include <linux/device.h>
3785 +#include <asm/rtc.h>
3786 +#include <asm/semaphore.h>
3788 +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
3789 +static struct fasync_struct *rtc_async_queue;
3792 + * rtc_lock protects rtc_irq_data
3794 +static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
3795 +static unsigned long rtc_irq_data;
3798 + * rtc_sem protects rtc_inuse and rtc_ops
3800 +static DECLARE_MUTEX(rtc_sem);
3801 +static unsigned long rtc_inuse;
3802 +static struct rtc_ops *rtc_ops;
3804 +#define rtc_epoch 1900UL
3806 +static const unsigned char days_in_month[] = {
3807 + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3810 +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
3811 +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
3813 +static int month_days(unsigned int month, unsigned int year)
3815 + return days_in_month[month] + (LEAP_YEAR(year) && month == 1);
3819 + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
3821 +void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
3823 + int days, month, year;
3825 + days = time / 86400;
3826 + time -= days * 86400;
3828 + tm->tm_wday = (days + 4) % 7;
3830 + year = 1970 + days / 365;
3831 + days -= (year - 1970) * 365
3832 + + LEAPS_THRU_END_OF(year - 1)
3833 + - LEAPS_THRU_END_OF(1970 - 1);
3836 + days += 365 + LEAP_YEAR(year);
3838 + tm->tm_year = year - 1900;
3839 + tm->tm_yday = days + 1;
3841 + for (month = 0; month < 11; month++) {
3844 + newdays = days - month_days(month, year);
3849 + tm->tm_mon = month;
3850 + tm->tm_mday = days + 1;
3852 + tm->tm_hour = time / 3600;
3853 + time -= tm->tm_hour * 3600;
3854 + tm->tm_min = time / 60;
3855 + tm->tm_sec = time - tm->tm_min * 60;
3859 + * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
3861 +int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
3863 + unsigned int yrs = tm->tm_year + 1900;
3868 + tm->tm_mon >= 12 ||
3869 + tm->tm_mday < 1 ||
3870 + tm->tm_mday > month_days(tm->tm_mon, yrs) ||
3871 + tm->tm_hour >= 24 ||
3872 + tm->tm_min >= 60 ||
3876 + *time = mktime(yrs, tm->tm_mon + 1, tm->tm_mday,
3877 + tm->tm_hour, tm->tm_min, tm->tm_sec);
3883 + * Calculate the next alarm time given the requested alarm time mask
3884 + * and the current time.
3886 + * FIXME: for now, we just copy the alarm time because we're lazy (and
3887 + * is therefore buggy - setting a 10am alarm at 8pm will not result in
3888 + * the alarm triggering.)
3890 +void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
3892 + next->tm_year = now->tm_year;
3893 + next->tm_mon = now->tm_mon;
3894 + next->tm_mday = now->tm_mday;
3895 + next->tm_hour = alrm->tm_hour;
3896 + next->tm_min = alrm->tm_min;
3897 + next->tm_sec = alrm->tm_sec;
3900 +static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
3902 + memset(tm, 0, sizeof(struct rtc_time));
3903 + ops->read_time(tm);
3906 +static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
3908 + return ops->set_time(tm);
3911 +static inline void rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
3913 + memset(alrm, 0, sizeof(struct rtc_wkalrm));
3914 + ops->read_alarm(alrm);
3917 +static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
3919 + return ops->set_alarm(alrm);
3922 +void rtc_update(unsigned long num, unsigned long events)
3924 + spin_lock(&rtc_lock);
3925 + rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
3926 + spin_unlock(&rtc_lock);
3928 + wake_up_interruptible(&rtc_wait);
3929 + kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
3934 +rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
3936 + DECLARE_WAITQUEUE(wait, current);
3937 + unsigned long data;
3940 + if (count < sizeof(unsigned long))
3943 + add_wait_queue(&rtc_wait, &wait);
3945 + __set_current_state(TASK_INTERRUPTIBLE);
3947 + spin_lock_irq(&rtc_lock);
3948 + data = rtc_irq_data;
3950 + spin_unlock_irq(&rtc_lock);
3956 + if (file->f_flags & O_NONBLOCK) {
3960 + if (signal_pending(current)) {
3961 + ret = -ERESTARTSYS;
3966 + set_current_state(TASK_RUNNING);
3967 + remove_wait_queue(&rtc_wait, &wait);
3970 + ret = put_user(data, (unsigned long *)buf);
3972 + ret = sizeof(unsigned long);
3977 +static unsigned int rtc_poll(struct file *file, poll_table *wait)
3979 + unsigned long data;
3981 + poll_wait(file, &rtc_wait, wait);
3983 + spin_lock_irq(&rtc_lock);
3984 + data = rtc_irq_data;
3985 + spin_unlock_irq(&rtc_lock);
3987 + return data != 0 ? POLLIN | POLLRDNORM : 0;
3990 +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
3991 + unsigned long arg)
3993 + struct rtc_ops *ops = file->private_data;
3994 + struct rtc_time tm;
3995 + struct rtc_wkalrm alrm;
3999 + case RTC_ALM_READ:
4000 + rtc_read_alarm(ops, &alrm);
4001 + ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm));
4007 + ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm));
4010 + alrm.time.tm_mday = -1;
4011 + alrm.time.tm_mon = -1;
4012 + alrm.time.tm_year = -1;
4013 + alrm.time.tm_wday = -1;
4014 + alrm.time.tm_yday = -1;
4015 + alrm.time.tm_isdst = -1;
4017 + ret = rtc_set_alarm(ops, &alrm);
4023 + rtc_read_time(ops, &tm);
4024 + ret = copy_to_user((void *)arg, &tm, sizeof(tm));
4029 + case RTC_SET_TIME:
4030 + if (!capable(CAP_SYS_TIME)) {
4034 + ret = copy_from_user(&tm, (void *)arg, sizeof(tm));
4036 + ret = rtc_set_time(ops, &tm);
4042 + case RTC_EPOCH_SET:
4044 + * There were no RTC clocks before 1900.
4050 + if (!capable(CAP_SYS_TIME)) {
4059 + case RTC_EPOCH_READ:
4060 + ret = put_user(rtc_epoch, (unsigned long *)arg);
4063 + case RTC_WKALM_SET:
4064 + ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm));
4066 + ret = rtc_set_alarm(ops, &alrm);
4071 + case RTC_WKALM_RD:
4072 + rtc_read_alarm(ops, &alrm);
4073 + ret = copy_to_user((void *)arg, &alrm, sizeof(alrm));
4079 + ret = ops->ioctl(cmd, arg);
4084 +static int rtc_open(struct inode *inode, struct file *file)
4092 + } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
4095 + file->private_data = rtc_ops;
4097 + ret = rtc_ops->open ? rtc_ops->open() : 0;
4099 + spin_lock_irq(&rtc_lock);
4101 + spin_unlock_irq(&rtc_lock);
4111 +static int rtc_release(struct inode *inode, struct file *file)
4113 + struct rtc_ops *ops = file->private_data;
4118 + spin_lock_irq(&rtc_lock);
4120 + spin_unlock_irq(&rtc_lock);
4122 + module_put(rtc_ops->owner);
4128 +static int rtc_fasync(int fd, struct file *file, int on)
4130 + return fasync_helper(fd, file, on, &rtc_async_queue);
4133 +static struct file_operations rtc_fops = {
4134 + .owner = THIS_MODULE,
4135 + .llseek = no_llseek,
4138 + .ioctl = rtc_ioctl,
4140 + .release = rtc_release,
4141 + .fasync = rtc_fasync,
4144 +static struct miscdevice rtc_miscdev = {
4145 + .minor = RTC_MINOR,
4147 + .fops = &rtc_fops,
4151 +static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
4153 + struct rtc_ops *ops = data;
4154 + struct rtc_wkalrm alrm;
4155 + struct rtc_time tm;
4159 + rtc_read_time(ops, &tm);
4162 + "rtc_time\t: %02d:%02d:%02d\n"
4163 + "rtc_date\t: %04d-%02d-%02d\n"
4164 + "rtc_epoch\t: %04lu\n",
4165 + tm.tm_hour, tm.tm_min, tm.tm_sec,
4166 + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
4169 + rtc_read_alarm(ops, &alrm);
4170 + p += sprintf(p, "alrm_time\t: ");
4171 + if ((unsigned int)alrm.time.tm_hour <= 24)
4172 + p += sprintf(p, "%02d:", alrm.time.tm_hour);
4174 + p += sprintf(p, "**:");
4175 + if ((unsigned int)alrm.time.tm_min <= 59)
4176 + p += sprintf(p, "%02d:", alrm.time.tm_min);
4178 + p += sprintf(p, "**:");
4179 + if ((unsigned int)alrm.time.tm_sec <= 59)
4180 + p += sprintf(p, "%02d\n", alrm.time.tm_sec);
4182 + p += sprintf(p, "**\n");
4184 + p += sprintf(p, "alrm_date\t: ");
4185 + if ((unsigned int)alrm.time.tm_year <= 200)
4186 + p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);
4188 + p += sprintf(p, "****-");
4189 + if ((unsigned int)alrm.time.tm_mon <= 11)
4190 + p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
4192 + p += sprintf(p, "**-");
4193 + if ((unsigned int)alrm.time.tm_mday <= 31)
4194 + p += sprintf(p, "%02d\n", alrm.time.tm_mday);
4196 + p += sprintf(p, "**\n");
4197 + p += sprintf(p, "alrm_wakeup\t: %s\n", alrm.enabled ? "yes" : "no");
4198 + p += sprintf(p, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no");
4201 + p += ops->proc(p);
4203 + len = (p - page) - off;
4206 + *eof = len <= count;
4207 + *start = page + off;
4212 +int register_rtc(struct rtc_ops *ops)
4217 + if (rtc_ops == NULL) {
4220 + ret = misc_register(&rtc_miscdev);
4222 + create_proc_read_entry("driver/rtc", 0, 0,
4223 + rtc_read_proc, ops);
4230 +void unregister_rtc(struct rtc_ops *rtc)
4233 + if (rtc == rtc_ops) {
4234 + remove_proc_entry("driver/rtc", NULL);
4235 + misc_deregister(&rtc_miscdev);
4241 +EXPORT_SYMBOL(rtc_time_to_tm);
4242 +EXPORT_SYMBOL(rtc_tm_to_time);
4243 +EXPORT_SYMBOL(rtc_update);
4244 +EXPORT_SYMBOL(register_rtc);
4245 +EXPORT_SYMBOL(unregister_rtc);
4246 --- linux-2.6.5/arch/arm/common/Makefile~heh 2004-04-03 22:36:57.000000000 -0500
4247 +++ linux-2.6.5/arch/arm/common/Makefile 2004-04-30 20:57:36.000000000 -0400
4249 # Makefile for the linux kernel.
4252 -obj-y += platform.o
4253 +obj-y += platform.o rtctime.o
4254 obj-$(CONFIG_ARM_AMBA) += amba.o
4255 obj-$(CONFIG_ICST525) += icst525.o
4256 obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o
4257 --- linux-2.6.5/arch/arm/mach-pxa/generic.c~heh 2004-04-03 22:36:53.000000000 -0500
4258 +++ linux-2.6.5/arch/arm/mach-pxa/generic.c 2004-04-30 20:57:36.000000000 -0400
4260 /* virtual physical length type */
4261 { 0xf6000000, 0x20000000, 0x01000000, MT_DEVICE }, /* PCMCIA0 IO */
4262 { 0xf7000000, 0x30000000, 0x01000000, MT_DEVICE }, /* PCMCIA1 IO */
4263 - { 0xf8000000, 0x40000000, 0x01400000, MT_DEVICE }, /* Devs */
4264 + { 0xf8000000, 0x40000000, 0x01800000, MT_DEVICE }, /* Devs */
4265 { 0xfa000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
4266 { 0xfc000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
4267 { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */
4268 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
4269 +++ linux-2.6.5/arch/arm/mach-pxa/cpu-pxa.c 2004-04-30 20:57:36.000000000 -0400
4272 + * linux/arch/arm/mach-pxa/cpu-pxa.c
4274 + * Copyright (C) 2002,2003 Intrinsyc Software
4276 + * This program is free software; you can redistribute it and/or modify
4277 + * it under the terms of the GNU General Public License as published by
4278 + * the Free Software Foundation; either version 2 of the License, or
4279 + * (at your option) any later version.
4281 + * This program is distributed in the hope that it will be useful,
4282 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4283 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4284 + * GNU General Public License for more details.
4286 + * You should have received a copy of the GNU General Public License
4287 + * along with this program; if not, write to the Free Software
4288 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4291 + * 31-Jul-2002 : Initial version [FB]
4292 + * 29-Jan-2003 : added PXA255 support [FB]
4293 + * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
4296 + * This driver may change the memory bus clock rate, but will not do any
4297 + * platform specific access timing changes... for example if you have flash
4298 + * memory connected to CS0, you will need to register a platform specific
4299 + * notifier which will adjust the memory access strobes to maintain a
4300 + * minimum strobe width.
4304 +#include <linux/kernel.h>
4305 +#include <linux/module.h>
4306 +#include <linux/sched.h>
4307 +#include <linux/init.h>
4308 +#include <linux/cpufreq.h>
4310 +#include <asm/hardware.h>
4315 + static unsigned int freq_debug = DEBUG;
4316 + MODULE_PARM(freq_debug, "i");
4317 + MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
4319 + #define freq_debug 0
4325 + unsigned int membus;
4326 + unsigned int cccr;
4327 + unsigned int div2;
4330 +/* Define the refresh period in mSec for the SDRAM and the number of rows */
4331 +#define SDRAM_TREF 64 /* standard 64ms SDRAM */
4332 +#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
4333 +#define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32))
4335 +#define CCLKCFG_TURBO 0x1
4336 +#define CCLKCFG_FCS 0x2
4337 +#define PXA25x_MIN_FREQ 99500
4338 +#define PXA25x_MAX_FREQ 398100
4339 +#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
4340 +#define MDREFR_DRI_MASK 0xFFF
4343 +/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
4344 +static pxa_freqs_t pxa255_run_freqs[] =
4346 + /* CPU MEMBUS CCCR DIV2*/
4347 + { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
4348 + {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
4349 + {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
4350 + {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
4351 + {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
4352 + {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
4355 +#define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t))
4357 +static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
4359 +/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
4360 +static pxa_freqs_t pxa255_turbo_freqs[] =
4362 + /* CPU MEMBUS CCCR DIV2*/
4363 + { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
4364 + {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
4365 + {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
4366 + {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
4367 + {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
4370 +#define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t))
4372 +static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
4374 +/* find a valid frequency point */
4375 +static int pxa_verify_policy(struct cpufreq_policy *policy)
4378 + struct cpufreq_frequency_table *pxa_freqs_table;
4380 + if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
4381 + pxa_freqs_table = pxa255_run_freq_table;
4382 + } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
4383 + pxa_freqs_table = pxa255_turbo_freq_table;
4384 + } else if (policy->policy == CPUFREQ_POLICY_GOVERNOR) {
4385 + pxa_freqs_table = pxa255_run_freq_table;
4387 + printk("CPU PXA: Unknown policy found. "
4388 + "Using CPUFREQ_POLICY_PERFORMANCE\n");
4389 + pxa_freqs_table = pxa255_run_freq_table;
4391 + ret=cpufreq_frequency_table_verify(policy, pxa_freqs_table);
4394 + printk("Verified CPU policy: %dKhz min to %dKhz max\n",
4395 + policy->min, policy->max);
4401 +static int pxa_set_target(struct cpufreq_policy *policy,
4402 + unsigned int target_freq,
4403 + unsigned int relation)
4406 + unsigned long cpus_allowed;
4407 + int cpu = policy->cpu;
4408 + struct cpufreq_freqs freqs;
4409 + pxa_freqs_t *pxa_freq_settings;
4410 + struct cpufreq_frequency_table *pxa_freqs_table;
4411 + unsigned long flags;
4412 + unsigned int unused;
4413 + unsigned int preset_mdrefr, postset_mdrefr;
4416 + * Save this threads cpus_allowed mask.
4418 + cpus_allowed = current->cpus_allowed;
4421 + * Bind to the specified CPU. When this call returns,
4422 + * we should be running on the right CPU.
4424 + set_cpus_allowed(current, 1 << cpu);
4425 + BUG_ON(cpu != smp_processor_id());
4427 + /* Get the current policy */
4428 + if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
4429 + pxa_freq_settings = pxa255_run_freqs;
4430 + pxa_freqs_table = pxa255_run_freq_table;
4431 + }else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
4432 + pxa_freq_settings = pxa255_turbo_freqs;
4433 + pxa_freqs_table = pxa255_turbo_freq_table;
4434 + }else if (policy->policy == CPUFREQ_POLICY_GOVERNOR) {
4435 + pxa_freq_settings = pxa255_run_freqs;
4436 + pxa_freqs_table = pxa255_run_freq_table;
4438 + printk("CPU PXA: Unknown policy found. "
4439 + "Using CPUFREQ_POLICY_PERFORMANCE\n");
4440 + pxa_freq_settings = pxa255_run_freqs;
4441 + pxa_freqs_table = pxa255_run_freq_table;
4444 + /* Lookup the next frequency */
4445 + if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
4446 + target_freq, relation, &idx)) {
4450 + freqs.old = policy->cur;
4451 + freqs.new = pxa_freq_settings[idx].khz;
4452 + freqs.cpu = policy->cpu;
4454 + printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
4455 + freqs.new/1000, (pxa_freq_settings[idx].div2) ?
4456 + (pxa_freq_settings[idx].membus/2000) :
4457 + (pxa_freq_settings[idx].membus/1000));
4460 + void *ramstart = phys_to_virt(0xa0000000);
4463 + * Tell everyone what we're about to do...
4464 + * you should add a notify client with any platform specific
4465 + * Vcc changing capability
4467 + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
4469 + /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
4470 + * we need to preset the smaller DRI before the change. If we're speeding
4471 + * up we need to set the larger DRI value after the change.
4473 + preset_mdrefr = postset_mdrefr = MDREFR;
4474 + if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
4475 + preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
4476 + MDREFR_DRI(pxa_freq_settings[idx].membus);
4478 + postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
4479 + MDREFR_DRI(pxa_freq_settings[idx].membus);
4481 + /* If we're dividing the memory clock by two for the SDRAM clock, this
4482 + * must be set prior to the change. Clearing the divide must be done
4483 + * after the change.
4485 + if(pxa_freq_settings[idx].div2) {
4486 + preset_mdrefr |= MDREFR_DB2_MASK;
4487 + postset_mdrefr |= MDREFR_DB2_MASK;
4489 + postset_mdrefr &= ~MDREFR_DB2_MASK;
4492 + local_irq_save(flags);
4494 + /* Set new the CCCR */
4495 + CCCR = pxa_freq_settings[idx].cccr;
4497 + __asm__ __volatile__(" \
4498 + ldr r4, [%1] ; /* load MDREFR */ \
4502 + str %4, [%1] ; /* preset the MDREFR */ \
4503 + mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \
4504 + str %5, [%1] ; /* postset the MDREFR */ \
4511 + : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), \
4512 + "r" (preset_mdrefr), "r" (postset_mdrefr)
4514 + local_irq_restore(flags);
4517 + * Restore the CPUs allowed mask.
4519 + set_cpus_allowed(current, cpus_allowed);
4522 + * Tell everyone what we've just done...
4523 + * you should add a notify client with any platform specific
4524 + * SDRAM refresh timer adjustments
4526 + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
4531 +static int pxa_cpufreq_init(struct cpufreq_policy *policy)
4533 + unsigned long cpus_allowed;
4534 + unsigned int cpu = policy->cpu;
4537 + cpus_allowed = current->cpus_allowed;
4539 + set_cpus_allowed(current, 1 << cpu);
4540 + BUG_ON(cpu != smp_processor_id());
4542 + /* set default policy and cpuinfo */
4543 + policy->policy = CPUFREQ_POLICY_PERFORMANCE;
4544 + policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
4545 + policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
4546 + policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
4547 + policy->cur = get_clk_frequency_khz(0); /* current freq */
4548 + policy->min = policy->max = policy->cur;
4550 + /* Generate the run cpufreq_frequency_table struct */
4551 + for(i=0;i<NUM_RUN_FREQS;i++) {
4552 + pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
4553 + pxa255_run_freq_table[i].index = i;
4555 + pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
4556 + /* Generate the turbo cpufreq_frequency_table struct */
4557 + for(i=0;i<NUM_TURBO_FREQS;i++) {
4558 + pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
4559 + pxa255_turbo_freq_table[i].index = i;
4561 + pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
4563 + set_cpus_allowed(current, cpus_allowed);
4564 + printk(KERN_INFO "PXA CPU frequency change support initialized\n");
4569 +static struct cpufreq_driver pxa_cpufreq_driver = {
4570 + .verify = pxa_verify_policy,
4571 + .target = pxa_set_target,
4572 + .init = pxa_cpufreq_init,
4576 +static int __init pxa_cpu_init(void)
4578 + return cpufreq_register_driver(&pxa_cpufreq_driver);
4581 +static void __exit pxa_cpu_exit(void)
4583 + cpufreq_unregister_driver(&pxa_cpufreq_driver);
4587 +MODULE_AUTHOR ("Intrinsyc Software Inc.");
4588 +MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
4589 +MODULE_LICENSE("GPL");
4590 +module_init(pxa_cpu_init);
4591 +module_exit(pxa_cpu_exit);
4593 --- linux-2.6.5/arch/arm/boot/compressed/misc.c~heh 2004-04-03 22:37:37.000000000 -0500
4594 +++ linux-2.6.5/arch/arm/boot/compressed/misc.c 2004-04-30 20:57:36.000000000 -0400
4598 #define OF(args) args
4599 -#define STATIC static
4602 typedef unsigned char uch;
4603 typedef unsigned short ush;
4604 @@ -122,12 +122,12 @@
4605 #define WSIZE 0x8000 /* Window size must be at least 32k, */
4606 /* and a power of two */
4608 -static uch *inbuf; /* input buffer */
4609 -static uch window[WSIZE]; /* Sliding window buffer */
4610 +unsigned char *inbuf; /* input buffer */
4611 +unsigned char window[WSIZE]; /* Sliding window buffer */
4613 -static unsigned insize; /* valid bytes in inbuf */
4614 -static unsigned inptr; /* index of next byte to be processed in inbuf */
4615 -static unsigned outcnt; /* bytes in output buffer */
4616 +unsigned int insize; /* valid bytes in inbuf */
4617 +unsigned int inptr; /* index of next byte to be processed in inbuf */
4618 +unsigned int outcnt; /* bytes in output buffer */
4620 /* gzip flag byte */
4621 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
4623 extern char input_data[];
4624 extern char input_data_end[];
4626 -static uch *output_data;
4627 -static ulg output_ptr;
4628 -static ulg bytes_out;
4629 +unsigned char *output_data;
4630 +unsigned long output_ptr;
4631 +unsigned long bytes_out;
4633 static void *malloc(int size);
4634 static void free(void *where);
4636 static void puts(const char *);
4639 -static ulg free_mem_ptr;
4640 -static ulg free_mem_ptr_end;
4641 +unsigned long free_mem_ptr;
4642 +unsigned long free_mem_ptr_end;
4644 #define HEAP_SIZE 0x2000
4646 --- linux-2.6.5/arch/arm/mm/ioremap.c~heh 2004-04-03 22:37:36.000000000 -0500
4647 +++ linux-2.6.5/arch/arm/mm/ioremap.c 2004-04-30 20:57:36.000000000 -0400
4649 * virtual space. One should *only* use readl, writel, memcpy_toio and
4650 * so on with such remapped areas.
4652 - * Because the ARM only has a 32-bit address space we can't address the
4653 - * whole of the (physical) PCI space at once. PCI huge-mode addressing
4654 - * allows us to circumvent this restriction by splitting PCI space into
4655 - * two 2GB chunks and mapping only one at a time into processor memory.
4656 - * We use MMU protection domains to trap any attempt to access the bank
4657 - * that is not currently mapped. (This isn't fully implemented yet.)
4658 + * ioremap support tweaked to allow support for large page mappings. We
4659 + * have several issues that needs to be resolved first however:
4661 + * 1. We need set_pte, or something like set_pte to understand large
4664 + * 2. we need the unmap_* functions to likewise understand large page
4667 #include <linux/errno.h>
4668 #include <linux/mm.h>
4669 +#include <linux/slab.h>
4670 #include <linux/vmalloc.h>
4672 #include <asm/page.h>
4673 @@ -29,31 +32,162 @@
4675 #include <asm/tlbflush.h>
4677 -static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
4678 - unsigned long phys_addr, pgprot_t pgprot)
4679 +extern rwlock_t vmlist_lock;
4680 +extern struct vm_struct *vmlist;
4682 +static struct vm_struct *
4683 +get_io_vm_area(unsigned long size, unsigned long align, unsigned long flags)
4685 + struct vm_struct **p, *tmp, *area;
4686 + unsigned long addr;
4688 + area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL);
4694 + size += PAGE_SIZE;
4695 + addr = VMALLOC_START;
4696 + write_lock(&vmlist_lock);
4697 + for (p = &vmlist; (tmp = *p); p = &tmp->next) {
4698 + if ((unsigned long)tmp->addr < addr)
4700 + if ((size + addr) < addr)
4702 + if (size + addr <= (unsigned long) tmp->addr)
4704 + addr = tmp->size + (unsigned long) tmp->addr;
4705 + if ((addr + align) < addr)
4707 + addr = (addr + align) & ~align;
4708 + if (addr > VMALLOC_END - size)
4711 + area->flags = flags;
4712 + area->addr = (void *)addr;
4713 + area->size = size;
4716 + write_unlock(&vmlist_lock);
4720 + write_unlock(&vmlist_lock);
4725 +static inline void unmap_area_pte(pmd_t *pmd, unsigned long address, unsigned long size)
4730 + if (pmd_none(*pmd))
4732 + if (pmd_bad(*pmd)) {
4737 + ptep = pte_offset_kernel(pmd, address);
4738 address &= ~PMD_MASK;
4739 end = address + size;
4742 - if (address >= end)
4745 - if (!pte_none(*pte)) {
4746 - printk("remap_area_pte: page already exists\n");
4749 + pte = ptep_get_and_clear(ptep);
4750 + address += PAGE_SIZE;
4752 + if (pte_none(pte))
4754 + if (pte_present(pte)) {
4755 + unsigned long pfn = pte_pfn(pte);
4756 + struct page *page;
4758 + if (!pfn_valid(pfn))
4760 + page = pfn_to_page(pfn);
4761 + if (!PageReserved(page))
4762 + __free_page(page);
4765 - set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot));
4766 + printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n");
4767 + } while (address < end);
4770 +static inline void unmap_area_pmd(pgd_t *dir, unsigned long address, unsigned long size)
4773 + unsigned long end;
4775 + if (pgd_none(*dir))
4777 + if (pgd_bad(*dir)) {
4782 + pmd = pmd_offset(dir, address);
4783 + address &= ~PGDIR_MASK;
4784 + end = address + size;
4785 + if (end > PGDIR_SIZE)
4788 + unmap_area_pte(pmd, address, end - address);
4789 + address = (address + PMD_SIZE) & PMD_MASK;
4791 + } while (address < end);
4795 +unmap_area_pages(unsigned long address, unsigned long size)
4797 + unsigned long start = address;
4798 + unsigned long end = address + size;
4801 + dir = pgd_offset_k(address);
4802 + flush_cache_vunmap(start, end);
4804 + unmap_area_pmd(dir, address, end - address);
4805 + address = (address + PGDIR_SIZE) & PGDIR_MASK;
4807 + } while (address && (address < end));
4808 + flush_tlb_kernel_range(start, end);
4812 +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
4813 + unsigned long pfn, pgprot_t pgprot)
4815 + unsigned long end;
4817 + address &= ~PMD_MASK;
4818 + end = address + size;
4819 + if (end > PMD_SIZE)
4821 + BUG_ON(address >= end);
4823 + if (!pte_none(*pte))
4826 + set_pte(pte, pfn_pte(pfn, pgprot));
4827 address += PAGE_SIZE;
4828 - phys_addr += PAGE_SIZE;
4831 } while (address && (address < end));
4835 + printk("remap_area_pte: page already exists\n");
4839 -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
4840 - unsigned long phys_addr, unsigned long flags)
4842 +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
4843 + unsigned long pfn, unsigned long flags)
4847 @@ -64,51 +198,53 @@
4848 if (end > PGDIR_SIZE)
4851 - phys_addr -= address;
4852 - if (address >= end)
4854 + pfn -= address >> PAGE_SHIFT;
4855 + BUG_ON(address >= end);
4857 pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
4859 pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
4862 - remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
4863 + remap_area_pte(pte, address, end - address, pfn + (address >> PAGE_SHIFT), pgprot);
4864 address = (address + PMD_SIZE) & PMD_MASK;
4866 } while (address && (address < end));
4870 -static int remap_area_pages(unsigned long address, unsigned long phys_addr,
4871 - unsigned long size, unsigned long flags)
4873 +remap_area_pages(unsigned long start, unsigned long pfn,
4874 + unsigned long size, unsigned long flags)
4877 + unsigned long address = start;
4878 + unsigned long end = start + size;
4881 - unsigned long end = address + size;
4883 - phys_addr -= address;
4884 + pfn -= address >> PAGE_SHIFT;
4885 dir = pgd_offset(&init_mm, address);
4886 - flush_cache_all();
4887 - if (address >= end)
4889 + BUG_ON(address >= end);
4890 spin_lock(&init_mm.page_table_lock);
4893 - pmd = pmd_alloc(&init_mm, dir, address);
4896 + pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
4901 if (remap_area_pmd(pmd, address, end - address,
4902 - phys_addr + address, flags))
4903 + pfn + (address >> PAGE_SHIFT), flags)) {
4909 address = (address + PGDIR_SIZE) & PGDIR_MASK;
4911 } while (address && (address < end));
4913 spin_unlock(&init_mm.page_table_lock);
4916 + flush_cache_vmap(start, end);
4921 @@ -146,11 +282,11 @@
4925 - area = get_vm_area(size, VM_IOREMAP);
4926 + area = get_io_vm_area(size, align, VM_IOREMAP);
4930 - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
4931 + if (remap_area_pages((unsigned long) addr, phys_addr >> PAGE_SHIFT, size, flags)) {
4935 @@ -159,5 +295,26 @@
4937 void __iounmap(void *addr)
4939 - vfree((void *) (PAGE_MASK & (unsigned long) addr));
4940 + struct vm_struct **p, *tmp;
4945 + if ((PAGE_SIZE - 1) & (unsigned long)addr) {
4946 + printk(KERN_ERR "Trying to iounmap() bad address (%p)\n", addr);
4950 + write_lock(&vmlist_lock);
4951 + for (p = &vmlist; (tmp = *p); p = &tmp->next) {
4952 + if (tmp->addr == addr) {
4954 + unmap_area_pages((unsigned long) tmp->addr, tmp->size);
4955 + write_unlock(&vmlist_lock);
4960 + write_unlock(&vmlist_lock);
4961 + printk(KERN_ERR "Trying to iounmap nonexistent area (%p)\n", addr);
4963 --- linux-2.6.5/arch/arm/mm/proc-xscale.S~heh 2004-04-03 22:38:05.000000000 -0500
4964 +++ linux-2.6.5/arch/arm/mm/proc-xscale.S 2004-04-30 20:57:36.000000000 -0400
4965 @@ -563,11 +563,62 @@
4966 movne r2, #0 @ no -> fault
4968 str r2, [r0] @ hardware version
4970 + @ We try to map 64K page entries when possible.
4971 + @ We do that for kernel space only since the usage pattern from
4972 + @ the setting of VM area is quite simple. User space is not worth
4973 + @ the implied complexity because of ever randomly changing PTEs
4974 + @ (page aging, swapout, etc) requiring constant coherency checks.
4975 + @ Since PTEs are usually set in increasing order, we test the
4976 + @ possibility for a large page only when given the last PTE of a
4978 + tsteq r1, #L_PTE_USER
4979 + andeq r1, r0, #(15 << 2)
4980 + teqeq r1, #(15 << 2)
4984 mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
4985 mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
4988 + @ See if we have 16 identical PTEs but with consecutive base addresses
4989 +1: bic r3, r2, #0x0000f000
4990 + mov r1, #0x0000f000
4994 + subs r1, r1, #0x00001000
4995 + ldr r2, [r0, #-4]!
5000 + @ Now create our LARGE PTE from the current EXT one.
5001 + bic r3, r3, #PTE_TYPE_MASK
5002 + orr r3, r3, #PTE_TYPE_LARGE
5003 + and r2, r3, #0x30 @ EXT_AP --> LARGE_AP0
5004 + orr r2, r2, r2, lsl #2 @ add LARGE_AP1
5005 + orr r2, r2, r2, lsl #4 @ add LARGE_AP3 + LARGE_AP2
5006 + and r1, r3, #0x3c0 @ EXT_TEX
5007 + bic r3, r3, #0x3c0
5008 + orr r2, r2, r1, lsl #(12 - 6) @ --> LARGE_TEX
5009 + orr r2, r2, r3 @ add remaining bits
5011 + @ then put it in the pagetable
5013 +3: strd r2, [r0], #8
5014 + tst r0, #(15 << 2)
5017 + @ Then sync the 2 corresponding cache lines
5018 + sub r0, r0, #(16 << 2)
5019 + mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
5020 +4: orr r0, r0, #(15 << 2)
5021 + mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
5023 + mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
5028 --- linux-2.6.5/arch/arm/mach-sa1100/Makefile~heh 2004-04-03 22:38:26.000000000 -0500
5029 +++ linux-2.6.5/arch/arm/mach-sa1100/Makefile 2004-04-30 20:57:36.000000000 -0400
5034 -obj-y := generic.o irq.o dma.o
5035 +obj-y := generic.o irq.o dma.o nmi-oopser.o
5040 obj-$(CONFIG_LEDS) += $(led-y)
5042 # SA1110 USB client support
5043 -#obj-$(CONFIG_SA1100_USB) += usb/
5044 +obj-$(CONFIG_SA1100_USB) += usb/
5046 # Miscelaneous functions
5047 obj-$(CONFIG_PM) += pm.o sleep.o
5048 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
5049 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/strings.h 2004-04-30 20:57:36.000000000 -0400
5054 + * Copyright (C) 2002 Russell King.
5056 + * USB device string handling, built upon usb buffers.
5058 +#ifndef USBDEV_STRINGS_H
5059 +#define USBDEV_STRINGS_H
5061 +#include <linux/spinlock.h>
5065 +#define NR_STRINGS 8
5067 +struct usb_string_descriptor;
5071 + struct usb_buf *buf[NR_STRINGS];
5074 +#define usbc_string_desc(buf) ((struct usb_string_descriptor *)(buf)->data)
5076 +void usbc_string_from_cstr(struct usb_buf *buf, const char *str);
5077 +struct usb_buf *usbc_string_alloc(int len);
5078 +void usbc_string_free(struct usb_buf *buf);
5080 +int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf);
5081 +void usbc_string_del(struct usbc_strs *table, int nr);
5084 + * Note: usbc_string_find() increments the buffer use count.
5085 + * You must call usbb_put() after use.
5088 +usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx);
5090 +void usbc_string_free_all(struct usbc_strs *table);
5091 +void usbc_string_init(struct usbc_strs *table);
5094 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
5095 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_ctl.h 2004-04-30 20:57:36.000000000 -0400
5098 + * Copyright (C) Compaq Computer Corporation, 1998, 1999
5099 + * Copyright (C) Extenex Corporation 2001
5103 + * PRIVATE interface used to share info among components of the SA-1100 USB
5104 + * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
5105 + * should use sa1100_usb.h.
5112 +#include <asm/dma.h> /* dmach_t */
5116 +struct usb_stats_t {
5117 + unsigned long ep0_fifo_write_failures;
5118 + unsigned long ep0_bytes_written;
5119 + unsigned long ep0_fifo_read_failures;
5120 + unsigned long ep0_bytes_read;
5125 + struct usb_client *client;
5126 + dma_regs_t *dmach_tx, *dmach_rx;
5128 + unsigned char address;
5129 + struct usb_stats_t stats;
5133 +extern struct usb_info_t usbd_info;
5136 + * Function Prototypes
5138 +enum { kError=-1, kEvSuspend=0, kEvReset=1,
5139 + kEvResume=2, kEvAddress=3, kEvConfig=4, kEvDeConfig=5 };
5140 +int usbctl_next_state_on_event( int event );
5142 +/* endpoint zero */
5143 +void ep0_reset(void);
5144 +void ep0_int_hndlr(void);
5147 +int ep1_recv(void);
5148 +int ep1_init(dma_regs_t *dma);
5149 +void ep1_int_hndlr(int status);
5150 +void ep1_reset(void);
5151 +void ep1_stall(void);
5154 +void ep2_reset(void);
5155 +int ep2_init(dma_regs_t *dma);
5156 +void ep2_int_hndlr(int status);
5157 +void ep2_stall(void);
5159 +#define UDC_write(reg, val) { \
5164 + printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
5165 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5168 + } while((reg) != (val)); \
5171 +#define UDC_set(reg, val) { \
5176 + printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
5177 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5180 + } while(!((reg) & (val))); \
5183 +#define UDC_clear(reg, val) { \
5186 + (reg) &= ~(val); \
5188 + printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
5189 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5192 + } while((reg) & (val)); \
5195 +#define UDC_flip(reg, val) { \
5201 + printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
5202 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5205 + } while(((reg) & (val))); \
5209 +#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
5210 +#endif /* _USB_CTL_H */
5211 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
5212 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_send.c 2004-04-30 20:57:36.000000000 -0400
5215 + * Generic xmit layer for the SA1100 USB client function
5216 + * Copyright (c) 2001 by Nicolas Pitre
5218 + * This code was loosely inspired by the original version which was
5219 + * Copyright (c) Compaq Computer Corporation, 1998-1999
5221 + * This program is free software; you can redistribute it and/or modify
5222 + * it under the terms of the GNU General Public License version 2 as
5223 + * published by the Free Software Foundation.
5225 + * This is still work in progress...
5227 + * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
5228 + * 15/03/2001 - ep2_start now sets UDCAR to overcome something that is hardware
5229 + * bug, I think. green@iXcelerator.com
5232 +#include <linux/module.h>
5233 +#include <linux/pci.h>
5234 +#include <linux/errno.h>
5235 +#include <linux/delay.h> // for the massive_attack hack 28Feb01ww
5236 +#include <linux/usb_ch9.h>
5238 +#include <asm/dma.h>
5240 +#include "usbdev.h"
5241 +#include "sa1100_usb.h"
5242 +#include "sa1100usb.h"
5244 +static unsigned int ep2_curdmalen;
5245 +static unsigned int ep2_remain;
5247 +static struct sausb_dev *ep2_dev;
5249 +static void udc_set_cs2(u32 val, u32 mask, u32 check)
5256 + if ((Ser0UDCCS2 & mask) == check)
5258 + } while (i++ < 10000);
5260 + printk("UDC: UDCCS2 write timed out: val=0x%08x\n", val);
5263 +/* set feature stall executing, async */
5264 +static void ep2_start(struct sausb_dev *usb)
5266 + ep2_curdmalen = min(ep2_remain, usb->ep[1].maxpktsize);
5267 + if (ep2_curdmalen == 0)
5271 + * must do this _before_ queue buffer..
5272 + * stop NAKing IN tokens
5274 + udc_set_cs2(usb->ep[1].udccs | UDCCS2_TPC, UDCCS2_TPC, 0);
5276 + UDC_write(Ser0UDCIMP, ep2_curdmalen - 1);
5278 + /* Remove if never seen...8Mar01ww */
5280 + int massive_attack = 20;
5281 + while (Ser0UDCIMP != ep2_curdmalen - 1 && massive_attack--) {
5282 + printk("usbsnd: Oh no you don't! Let me spin...");
5284 + printk("and try again...\n");
5285 + UDC_write(Ser0UDCIMP, ep2_curdmalen - 1);
5287 + if (massive_attack != 20) {
5288 + if (Ser0UDCIMP != ep2_curdmalen - 1)
5289 + printk("usbsnd: Massive attack FAILED. %d\n",
5290 + 20 - massive_attack);
5292 + printk("usbsnd: Massive attack WORKED. %d\n",
5293 + 20 - massive_attack);
5296 + /* End remove if never seen... 8Mar01ww */
5299 + * fight stupid silicon bug
5301 + Ser0UDCAR = usb->ctl->address;
5303 + sa1100_start_dma(usb->ep[1].dmach, usb->ep[1].pktdma, ep2_curdmalen);
5306 +static void udc_ep2_done(struct sausb_dev *usb, int flag)
5308 + int size = usb->ep[1].buflen - ep2_remain;
5310 + if (!usb->ep[1].buflen)
5313 + dma_unmap_single(usb->dev, usb->ep[1].bufdma, usb->ep[1].buflen,
5316 + usb->ep[1].bufdma = 0;
5317 + usb->ep[1].buflen = 0;
5318 + usb->ep[1].pktdma = 0;
5320 + if (usb->ep[1].cb_func)
5321 + usb->ep[1].cb_func(usb->ep[1].cb_data, flag, size);
5325 + * Initialisation. Clear out the status.
5327 +void udc_ep2_init(struct sausb_dev *usb)
5331 + usb->ep[1].udccs = UDCCS2_FST;
5333 + BUG_ON(usb->ep[1].buflen);
5334 + BUG_ON(usb->ep[1].pktlen);
5336 + sa1100_reset_dma(usb->ep[1].dmach);
5340 + * Note: rev A0-B2 chips don't like FST
5342 +void udc_ep2_halt(struct sausb_dev *usb, int halt)
5344 + usb->ep[1].host_halt = halt;
5347 + usb->ep[1].udccs |= UDCCS2_FST;
5348 + udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
5350 + sa1100_clear_dma(usb->ep[1].dmach);
5352 + udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
5353 + udc_set_cs2(0, UDCCS2_FST, 0);
5354 + udc_set_cs2(UDCCS2_SST, UDCCS2_SST, 0);
5356 + usb->ep[1].udccs &= ~UDCCS2_FST;
5358 + udc_ep2_done(usb, -EINTR);
5363 + * This gets called when we receive a SET_CONFIGURATION packet to EP0.
5364 + * We were configured. We can now send packets to the host.
5366 +void udc_ep2_config(struct sausb_dev *usb, unsigned int maxpktsize)
5369 + * We shouldn't be transmitting anything...
5371 + BUG_ON(usb->ep[1].buflen);
5372 + BUG_ON(usb->ep[1].pktlen);
5375 + * Set our configuration.
5377 + usb->ep[1].maxpktsize = maxpktsize;
5378 + usb->ep[1].configured = 1;
5381 + * Clear any pending TPC status.
5383 + udc_set_cs2(UDCCS2_TPC, UDCCS2_TPC, 0);
5386 + * Enable EP2 interrupts.
5388 + usb->udccr &= ~UDCCR_TIM;
5389 + UDC_write(Ser0UDCCR, usb->udccr);
5391 + usb->ep[1].udccs = 0;
5395 + * We saw a reset from the attached hub, or were deconfigured.
5396 + * This means we are no longer configured.
5398 +void udc_ep2_reset(struct sausb_dev *usb)
5401 + * Disable EP2 interrupts.
5403 + usb->udccr |= UDCCR_TIM;
5404 + UDC_write(Ser0UDCCR, usb->udccr);
5406 + usb->ep[1].configured = 0;
5407 + usb->ep[1].maxpktsize = 0;
5409 + sa1100_reset_dma(usb->ep[1].dmach);
5410 + udc_ep2_done(usb, -EINTR);
5413 +void udc_ep2_int_hndlr(struct sausb_dev *usb)
5415 + u32 status = Ser0UDCCS2;
5417 + // check for stupid silicon bug.
5418 + if (Ser0UDCAR != usb->ctl->address)
5419 + Ser0UDCAR = usb->ctl->address;
5421 + udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0);
5423 + if (!(status & UDCCS2_TPC)) {
5424 + printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
5428 + sa1100_stop_dma(usb->ep[1].dmach);
5430 + if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
5431 + printk("usb_send: transmit error %x\n", status);
5432 + usb->ep[1].fifo_errs ++;
5433 + udc_ep2_done(usb, -EIO);
5436 +#if 1 // 22Feb01ww/Oleg
5437 + imp = ep2_curdmalen;
5439 + // this is workaround for case when setting
5440 + // of Ser0UDCIMP was failed
5441 + imp = Ser0UDCIMP + 1;
5443 + usb->ep[1].pktdma += imp;
5444 + ep2_remain -= imp;
5446 + usb->ep[1].bytes += imp;
5447 + usb->ep[1].packets++;
5449 + sa1100_clear_dma(usb->ep[1].dmach);
5451 + if (ep2_remain != 0) {
5454 + udc_ep2_done(usb, 0);
5459 +int udc_ep2_send(struct sausb_dev *usb, char *buf, int len)
5461 + unsigned long flags;
5465 + if (!buf || len == 0)
5468 + dma = dma_map_single(usb->dev, buf, len, DMA_TO_DEVICE);
5470 + spin_lock_irqsave(&usb->lock, flags);
5472 + if (!usb->ep[1].configured) {
5477 + if (usb->ep[1].buflen) {
5482 + usb->ep[1].bufdma = dma;
5483 + usb->ep[1].buflen = len;
5484 + usb->ep[1].pktdma = dma;
5487 + sa1100_clear_dma(usb->ep[1].dmach);
5492 + spin_unlock_irqrestore(&usb->lock, flags);
5495 + dma_unmap_single(usb->dev, dma, len, DMA_TO_DEVICE);
5500 +void udc_ep2_send_reset(struct sausb_dev *usb)
5502 + sa1100_reset_dma(usb->ep[1].dmach);
5503 + udc_ep2_done(usb, -EINTR);
5506 +int udc_ep2_idle(struct sausb_dev *usb)
5508 + if (!usb->ep[1].configured)
5511 + if (usb->ep[1].buflen)
5516 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
5517 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-char.c 2004-04-30 20:57:36.000000000 -0400
5520 + * (C) Copyright 2000-2001 Extenex Corporation
5522 + * This program is free software; you can redistribute it and/or modify
5523 + * it under the terms of the GNU General Public License as published by
5524 + * the Free Software Foundation; either version 2 of the License, or
5525 + * (at your option) any later version.
5527 + * This program is distributed in the hope that it will be useful,
5528 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5529 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5530 + * GNU General Public License for more details.
5532 + * You should have received a copy of the GNU General Public License
5533 + * along with this program; if not, write to the Free Software
5534 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
5538 + * Miscellaneous character device interface for SA1100 USB function
5542 + * The SA1100 function driver ported from the Compaq Itsy project
5543 + * has an interface, usb-eth.c, to feed network packets over the
5544 + * usb wire and into the Linux TCP/IP stack.
5546 + * This file replaces that one with a simple character device
5547 + * interface that allows unstructured "byte pipe" style reads and
5548 + * writes over the USB bulk endpoints by userspace programs.
5550 + * A new define, CONFIG_SA1100_USB_NETLINK, has been created that,
5551 + * when set, (the default) causes the ethernet interface to be used.
5552 + * When not set, this more pedestrian character interface is linked
5555 + * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
5557 + * ward.willats@extenex.com
5560 + * - Can't dma into ring buffer directly with dma_map/unmap usb_recv
5561 + * uses and get bytes out at the same time DMA is going on. Investigate:
5562 + * a) changing usb_recv to use alloc_consistent() at client request; or
5563 + * b) non-ring-buffer based data structures. In the meantime, I am using
5564 + * a bounce buffer. Simple, but wasteful.
5567 +#include <linux/module.h>
5568 +#include <linux/config.h>
5569 +#include <linux/miscdevice.h>
5570 +#include <linux/slab.h>
5571 +#include <linux/init.h>
5572 +#include <linux/cache.h>
5573 +#include <linux/poll.h>
5574 +#include <linux/circ_buf.h>
5575 +#include <linux/timer.h>
5576 +#include <linux/usb_ch9.h>
5578 +#include <asm/io.h>
5579 +#include <asm/semaphore.h>
5580 +#include <asm/page.h>
5581 +#include <asm/mach-types.h>
5583 +#include "usb-char.h"
5584 +#include "client.h"
5588 +//////////////////////////////////////////////////////////////////////////////
5590 +//////////////////////////////////////////////////////////////////////////////
5592 +#define VERSION "0.4"
5595 +#define VERBOSITY 1
5598 +# define PRINTK(x, a...) printk (x, ## a)
5600 +# define PRINTK(x, a...) /**/
5603 +//////////////////////////////////////////////////////////////////////////////
5604 +// Globals - Macros - Enums - Structures
5605 +//////////////////////////////////////////////////////////////////////////////
5607 +#define MIN( a, b ) ((a)<(b)?(a):(b))
5610 +typedef int bool; enum { false = 0, true = 1 };
5612 +static const char pszMe[] = "usbchr: ";
5614 +static wait_queue_head_t wq_read;
5615 +static wait_queue_head_t wq_write;
5616 +static wait_queue_head_t wq_poll;
5618 +/* Serialze multiple writers onto the transmit hardware
5619 +.. since we sleep the writer during transmit to stay in
5620 +.. sync. (Multiple writers don't make much sense, but..) */
5621 +static DECLARE_MUTEX( xmit_sem );
5623 +// size of usb DATA0/1 packets. 64 is standard maximum
5624 +// for bulk transport, though most hosts seem to be able
5625 +// to handle larger.
5626 +#define TX_PACKET_SIZE 64
5627 +#define RX_PACKET_SIZE 64
5628 +#define RBUF_SIZE (4*PAGE_SIZE)
5630 +static struct wcirc_buf {
5634 +} rx_ring = { NULL, 0, 0 };
5637 + unsigned long cnt_rx_complete;
5638 + unsigned long cnt_rx_errors;
5639 + unsigned long bytes_rx;
5640 + unsigned long cnt_tx_timeouts;
5641 + unsigned long cnt_tx_errors;
5642 + unsigned long bytes_tx;
5646 +static char * tx_buf = NULL;
5647 +static char * packet_buffer = NULL;
5648 +static int sending = 0;
5649 +static int usb_ref_count = 0;
5650 +static int last_tx_result = 0;
5651 +static int last_rx_result = 0;
5652 +static int last_tx_size = 0;
5653 +static struct timer_list tx_timer;
5655 +//////////////////////////////////////////////////////////////////////////////
5657 +//////////////////////////////////////////////////////////////////////////////
5658 +static char * what_the_f( int e );
5659 +static void free_txrx_buffers( void );
5660 +static void twiddle_descriptors(struct usb_client *client);
5661 +static int usbc_open( struct inode *pInode, struct file *pFile );
5662 +static void rx_done_callback_packet_buffer(void *data, int flag, int size );
5664 +static void tx_timeout( unsigned long );
5665 +static void tx_done_callback(void *data, int flag, int size );
5667 +static ssize_t usbc_read( struct file *, char *, size_t, loff_t * );
5668 +static ssize_t usbc_write( struct file *, const char *, size_t, loff_t * );
5669 +static unsigned int usbc_poll( struct file *pFile, poll_table * pWait );
5670 +static int usbc_ioctl( struct inode *pInode, struct file *pFile,
5671 + unsigned int nCmd, unsigned long argument );
5672 +static int usbc_close( struct inode *pInode, struct file *pFile );
5674 +#ifdef CONFIG_SA1100_EXTENEX1
5675 +static void extenex_configured_notify_proc( void );
5677 +//////////////////////////////////////////////////////////////////////////////
5679 +//////////////////////////////////////////////////////////////////////////////
5681 +static char * what_the_f( int e )
5689 + p = "ENODEV - usb not in config state";
5692 + p = "EBUSY - another request on the hardware";
5698 + p = "EINTR - interrupted\n";
5701 + p = "EPIPE - zero length xfer\n";
5710 +static void free_txrx_buffers( void )
5712 + if ( rx_ring.buf != NULL ) {
5713 + kfree( rx_ring.buf );
5714 + rx_ring.buf = NULL;
5716 + if ( packet_buffer != NULL ) {
5717 + kfree( packet_buffer );
5718 + packet_buffer = NULL;
5720 + if ( tx_buf != NULL ) {
5726 +/* twiddle_descriptors()
5727 + * It is between open() and start(). Setup descriptors.
5729 +static void twiddle_descriptors(struct usb_client *client)
5731 + struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
5733 + cdb->ep1.wMaxPacketSize = cpu_to_le16(RX_PACKET_SIZE);
5734 + cdb->ep2.wMaxPacketSize = cpu_to_le16(TX_PACKET_SIZE);
5736 +#ifdef CONFIG_SA1100_EXTENEX1
5737 + if (machine_is_extenex1()) {
5740 + cdb->cfg.bmAttributes = USB_CONFIG_SELFPOWERED;
5741 + cdb->cfg.MaxPower = 0;
5743 + nr = sa1100_usb_add_string(client->ctl, "HHT Bulk Transfer");
5746 + cdb->intf.iInterface = nr;
5751 +//////////////////////////////////////////////////////////////////////////////
5753 +//////////////////////////////////////////////////////////////////////////////
5754 +static void kick_start_rx( void )
5756 + if ( usb_ref_count ) {
5757 + int total_space = CIRC_SPACE( rx_ring.in, rx_ring.out, RBUF_SIZE );
5758 + if ( total_space >= RX_PACKET_SIZE ) {
5759 + sa1100_usb_recv_set_callback(rx_done_callback_packet_buffer, NULL);
5760 + sa1100_usb_recv( packet_buffer, RX_PACKET_SIZE);
5765 + * rx_done_callback_packet_buffer()
5766 + * We have completed a DMA xfer into the temp packet buffer.
5770 + * on init, -EAGAIN
5771 + * on reset, -EINTR
5773 + * on short packet -EPIPE
5776 +rx_done_callback_packet_buffer(void *data, int flag, int size )
5778 + charstats.cnt_rx_complete++;
5780 + if ( flag == 0 || flag == -EPIPE ) {
5783 + charstats.bytes_rx += size;
5785 + n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
5786 + n = MIN( n, size );
5789 + memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n );
5790 + rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1);
5791 + memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size );
5792 + rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1);
5794 + wake_up_interruptible( &wq_read );
5795 + wake_up_interruptible( &wq_poll );
5797 + last_rx_result = 0;
5801 + } else if ( flag != -EAGAIN ) {
5802 + charstats.cnt_rx_errors++;
5803 + last_rx_result = flag;
5804 + wake_up_interruptible( &wq_read );
5805 + wake_up_interruptible( &wq_poll );
5807 + else /* init, start a read */
5812 +static void tx_timeout( unsigned long unused )
5814 + printk( "%stx timeout\n", pszMe );
5815 + sa1100_usb_send_reset();
5816 + charstats.cnt_tx_timeouts++;
5820 +// on init, -EAGAIN
5821 +// on reset, -EINTR
5823 +static void tx_done_callback(void *data, int flags, int size )
5826 + charstats.bytes_tx += size;
5828 + charstats.cnt_tx_errors++;
5829 + last_tx_size = size;
5830 + last_tx_result = flags;
5832 + wake_up_interruptible( &wq_write );
5833 + wake_up_interruptible( &wq_poll );
5837 +static struct usb_client usbc_client = {
5838 + .name = "usb-char",
5841 + * USB client identification for host use in CPU endian.
5851 +#ifdef CONFIG_SA1100_EXTENEX1
5852 +#include "../../../drivers/char/ex_gpio.h"
5853 +static void extenex_state_change(void *data, int state, int oldstate)
5855 + if (exgpio_play_string( "440,1:698,1") == -EAGAIN)
5856 + printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe );
5860 +//////////////////////////////////////////////////////////////////////////////
5862 +//////////////////////////////////////////////////////////////////////////////
5864 +static int usbc_open(struct inode *pInode, struct file *pFile)
5868 + PRINTK( KERN_DEBUG "%sopen()\n", pszMe );
5870 +#ifdef CONFIG_SA1100_EXTENEX1
5871 + if (machine_is_extenex1()) {
5872 + usbc_client.vendor = 0x0c9f;
5873 + usbc_client.product = 0x0100;
5874 + usbc_client.version = 0x0001;
5875 + usbc_client.manufacturer_str = "Extenex";
5876 + usbc_client.product_str = "Handheld Theater";
5877 + usbc_client.serial_str = "00000000";
5878 + usbc_client.state_change = extenex_state_change;
5882 + /* start usb core */
5883 + retval = usbctl_open(&usbc_client);
5887 + /* allocate memory */
5888 + if ( usb_ref_count == 0 ) {
5889 + tx_buf = (char*) kmalloc( TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
5890 + if ( tx_buf == NULL ) {
5891 + printk( "%sARGHH! COULD NOT ALLOCATE TX BUFFER\n", pszMe );
5895 + (char*) kmalloc( RBUF_SIZE, GFP_KERNEL );
5897 + if ( rx_ring.buf == NULL ) {
5898 + printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe );
5903 + (char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
5905 + if ( packet_buffer == NULL ) {
5906 + printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe );
5909 + rx_ring.in = rx_ring.out = 0;
5910 + memset( &charstats, 0, sizeof( charstats ) );
5912 + last_tx_result = 0;
5916 + /* modify default descriptors */
5917 + twiddle_descriptors(&usbc_client);
5919 + retval = usbctl_start(&usbc_client);
5921 + printk( "%sAGHH! Could not USB core\n", pszMe );
5922 + free_txrx_buffers();
5925 + usb_ref_count++; /* must do _before_ kick_start() */
5926 + MOD_INC_USE_COUNT;
5931 + free_txrx_buffers();
5936 + * Read endpoint. Note that you can issue a read to an
5937 + * unconfigured endpoint. Eventually, the host may come along
5938 + * and configure underneath this module and data will appear.
5940 +static ssize_t usbc_read( struct file *pFile, char *pUserBuffer,
5941 + size_t stCount, loff_t *pPos )
5944 + unsigned long flags;
5945 + DECLARE_WAITQUEUE( wait, current );
5947 + PRINTK( KERN_DEBUG "%sread()\n", pszMe );
5949 + local_irq_save(flags);
5950 + if ( last_rx_result == 0 ) {
5951 + local_irq_restore( flags );
5952 + } else { /* an error happended and receiver is paused */
5953 + local_irq_restore( flags );
5954 + last_rx_result = 0;
5958 + add_wait_queue( &wq_read, &wait );
5960 + ssize_t bytes_avail;
5961 + ssize_t bytes_to_end;
5963 + set_current_state( TASK_INTERRUPTIBLE );
5965 + /* snap ring buf state */
5966 + local_irq_save( flags );
5967 + bytes_avail = CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE );
5968 + bytes_to_end = CIRC_CNT_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
5969 + local_irq_restore( flags );
5971 + if ( bytes_avail != 0 ) {
5972 + ssize_t bytes_to_move = MIN( stCount, bytes_avail );
5973 + retval = 0; // will be bytes transfered
5974 + if ( bytes_to_move != 0 ) {
5975 + size_t n = MIN( bytes_to_end, bytes_to_move );
5976 + if ( copy_to_user( pUserBuffer,
5977 + &rx_ring.buf[ rx_ring.out ],
5982 + bytes_to_move -= n;
5984 + // might go 1 char off end, so wrap
5985 + rx_ring.out = ( rx_ring.out + n ) & (RBUF_SIZE-1);
5986 + if ( copy_to_user( pUserBuffer + n,
5987 + &rx_ring.buf[ rx_ring.out ],
5993 + rx_ring.out += bytes_to_move; // cannot wrap
5994 + retval += bytes_to_move;
5999 + else if ( last_rx_result ) {
6000 + retval = last_rx_result;
6003 + else if ( pFile->f_flags & O_NONBLOCK ) { // no data, can't sleep
6007 + else if ( signal_pending( current ) ) { // no data, can sleep, but signal
6008 + retval = -ERESTARTSYS;
6011 + schedule(); // no data, can sleep
6013 + set_current_state( TASK_RUNNING );
6014 + remove_wait_queue( &wq_read, &wait );
6017 + printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) );
6022 + * Write endpoint. This routine attempts to break the passed in buffer
6023 + * into usb DATA0/1 packet size chunks and send them to the host.
6024 + * (The lower-level driver tries to do this too, but easier for us
6025 + * to manage things here.)
6027 + * We are at the mercy of the host here, in that it must send an IN
6028 + * token to us to pull this data back, so hopefully some higher level
6029 + * protocol is expecting traffic to flow in that direction so the host
6030 + * is actually polling us. To guard against hangs, a 5 second timeout
6033 + * This routine takes some care to only report bytes sent that have
6034 + * actually made it across the wire. Thus we try to stay in lockstep
6035 + * with the completion routine and only have one packet on the xmit
6036 + * hardware at a time. Multiple simultaneous writers will get
6037 + * "undefined" results.
6040 +static ssize_t usbc_write( struct file *pFile, const char * pUserBuffer,
6041 + size_t stCount, loff_t *pPos )
6043 + ssize_t retval = 0;
6044 + ssize_t stSent = 0;
6046 + DECLARE_WAITQUEUE( wait, current );
6048 + PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount );
6050 + down( &xmit_sem ); // only one thread onto the hardware at a time
6052 + while( stCount != 0 && retval == 0 ) {
6053 + int nThisTime = MIN( TX_PACKET_SIZE, stCount );
6054 + copy_from_user( tx_buf, pUserBuffer, nThisTime );
6055 + sending = nThisTime;
6056 + sa1100_usb_send_set_callback(tx_done_callback, NULL);
6057 + retval = sa1100_usb_send( tx_buf, nThisTime);
6058 + if ( retval < 0 ) {
6059 + char * p = what_the_f( retval );
6060 + printk( "%sCould not queue xmission. rc=%d - %s\n",
6061 + pszMe, retval, p );
6065 + /* now have something on the diving board */
6066 + add_wait_queue( &wq_write, &wait );
6067 + tx_timer.expires = jiffies + ( HZ * 5 );
6068 + add_timer( &tx_timer );
6070 + set_current_state( TASK_INTERRUPTIBLE );
6071 + if ( sending == 0 ) { /* it jumped into the pool */
6072 + del_timer( &tx_timer );
6073 + retval = last_tx_result;
6074 + if ( retval == 0 ) {
6075 + stSent += last_tx_size;
6076 + pUserBuffer += last_tx_size;
6077 + stCount -= last_tx_size;
6080 + printk( "%sxmission error rc=%d - %s\n",
6081 + pszMe, retval, what_the_f(retval) );
6084 + else if ( signal_pending( current ) ) {
6085 + del_timer( &tx_timer );
6086 + printk( "%ssignal\n", pszMe );
6087 + retval = -ERESTARTSYS;
6092 + set_current_state( TASK_RUNNING );
6093 + remove_wait_queue( &wq_write, &wait );
6098 + if ( 0 == retval )
6103 +static unsigned int usbc_poll( struct file *pFile, poll_table * pWait )
6105 + unsigned int retval = 0;
6107 + PRINTK( KERN_DEBUG "%poll()\n", pszMe );
6109 + poll_wait( pFile, &wq_poll, pWait );
6111 + if ( CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ) )
6112 + retval |= POLLIN | POLLRDNORM;
6113 + if ( sa1100_usb_xmitter_avail() )
6114 + retval |= POLLOUT | POLLWRNORM;
6118 +static int usbc_ioctl( struct inode *pInode, struct file *pFile,
6119 + unsigned int nCmd, unsigned long argument )
6125 + case USBC_IOC_FLUSH_RECEIVER:
6126 + sa1100_usb_recv_reset();
6127 + rx_ring.in = rx_ring.out = 0;
6130 + case USBC_IOC_FLUSH_TRANSMITTER:
6131 + sa1100_usb_send_reset();
6134 + case USBC_IOC_FLUSH_ALL:
6135 + sa1100_usb_recv_reset();
6136 + rx_ring.in = rx_ring.out = 0;
6137 + sa1100_usb_send_reset();
6141 + retval = -ENOIOCTLCMD;
6149 +static int usbc_close( struct inode *pInode, struct file * pFile )
6151 + PRINTK( KERN_DEBUG "%sclose()\n", pszMe );
6152 + if ( --usb_ref_count == 0 ) {
6153 + down( &xmit_sem );
6154 + usbctl_stop(&usbc_client);
6155 + free_txrx_buffers();
6156 + del_timer( &tx_timer );
6157 + usbctl_close(&usbc_client);
6160 + MOD_DEC_USE_COUNT;
6164 +//////////////////////////////////////////////////////////////////////////////
6166 +//////////////////////////////////////////////////////////////////////////////
6168 +static struct file_operations usbc_fops = {
6169 + owner: THIS_MODULE,
6172 + write: usbc_write,
6174 + ioctl: usbc_ioctl,
6175 + release: usbc_close,
6178 +static struct miscdevice usbc_misc_device = {
6188 +static int __init usbc_init( void )
6192 +#if !defined( CONFIG_ARCH_SA1100 )
6196 + if ( (rc = misc_register( &usbc_misc_device )) != 0 ) {
6197 + printk( KERN_WARNING "%sCould not register device 10, "
6198 + "%d. (%d)\n", pszMe, USBC_MINOR, rc );
6202 + // initialize wait queues
6203 + init_waitqueue_head( &wq_read );
6204 + init_waitqueue_head( &wq_write );
6205 + init_waitqueue_head( &wq_poll );
6207 + // initialize tx timeout timer
6208 + init_timer( &tx_timer );
6209 + tx_timer.function = tx_timeout;
6211 + printk( KERN_INFO "USB Function Character Driver Interface"
6212 + " - %s, (C) 2001, Extenex Corp.\n", VERSION
6218 +static void __exit usbc_exit( void )
6222 +module_init(usbc_init);
6223 +module_exit(usbc_exit);
6227 +MODULE_LICENSE("GPL");
6228 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
6229 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-eth.c 2004-04-30 20:57:36.000000000 -0400
6232 + * Network driver for the SA1100 USB client function
6233 + * Copyright (c) 2001 by Nicolas Pitre
6235 + * This code was loosely inspired by the original initial ethernet test driver
6236 + * Copyright (c) Compaq Computer Corporation, 1999
6238 + * This program is free software; you can redistribute it and/or modify
6239 + * it under the terms of the GNU General Public License version 2 as
6240 + * published by the Free Software Foundation.
6243 + * - DMA needs 8 byte aligned buffer, but causes inefficiencies
6245 + * - stall endpoint operations appeared to be very unstable.
6249 + * Define RX_NO_COPY if you want data to arrive directly into the
6250 + * receive network buffers, instead of arriving into bounce buffer
6251 + * and then get copied to network buffer.
6253 + * Since the SA1100 DMA engine is unable to cope with unaligned
6254 + * buffer addresses, we need to use bounce buffers or suffer the
6255 + * alignment trap performance hit.
6259 +#include <linux/module.h>
6260 +#include <linux/init.h>
6261 +#include <linux/kernel.h>
6262 +#include <linux/errno.h>
6263 +#include <linux/netdevice.h>
6264 +#include <linux/etherdevice.h>
6265 +#include <linux/skbuff.h>
6266 +#include <linux/random.h>
6267 +#include <linux/usb_ch9.h>
6269 +#include "client.h"
6272 +#define ETHERNET_VENDOR_ID 0x049f
6273 +#define ETHERNET_PRODUCT_ID 0x505A
6274 +#define MAX_PACKET 32768
6277 + * This is our usb "packet size", and must match the host "packet size".
6279 +static int usb_rsize = 64;
6280 +static int usb_wsize = 64;
6283 + struct net_device dev;
6284 + struct usb_client client;
6285 + struct sk_buff *cur_tx_skb;
6286 + struct sk_buff *next_tx_skb;
6287 + struct sk_buff *cur_rx_skb;
6288 + struct sk_buff *next_rx_skb;
6290 + char *dmabuf; // dma expects it's buffers to be aligned on 8 bytes boundary
6292 + struct net_device_stats stats;
6296 +static int usbeth_change_mtu(struct net_device *dev, int new_mtu)
6298 + if (new_mtu <= sizeof(struct ethhdr) || new_mtu > MAX_PACKET)
6301 + // no second zero-length packet read wanted after mtu-sized packets
6302 + if (((new_mtu + sizeof(struct ethhdr)) % usb_rsize) == 0)
6305 + dev->mtu = new_mtu;
6309 +static struct sk_buff *usb_new_recv_skb(struct usbe_info *usbe)
6311 + struct sk_buff *skb;
6313 + skb = alloc_skb(2 + sizeof(struct ethhdr) + usbe->dev.mtu,
6317 + skb_reserve(skb, 2);
6322 +static void usbeth_recv_callback(void *data, int flag, int len)
6324 + struct usbe_info *usbe = data;
6325 + struct sk_buff *skb;
6326 + unsigned int size;
6329 + skb = usbe->cur_rx_skb;
6331 + /* flag validation */
6336 + * Make sure we have enough room left in the buffer.
6338 + if (len > skb_tailroom(skb)) {
6339 + usbe->stats.rx_over_errors++;
6340 + usbe->stats.rx_errors++;
6345 + * If the packet is smaller than usb_rsize bytes, the packet
6346 + * is complete, and we need to use the next receive buffer.
6348 + if (len != usb_rsize)
6349 + usbe->cur_rx_skb = usbe->next_rx_skb;
6352 + * Put the data onto the socket buffer and resume USB receive.
6355 + memcpy(skb_put(skb, len), usbe->dmabuf, len);
6356 + buf = usbe->dmabuf;
6359 + skb_put(skb, len);
6360 + buf = usbe->cur_rx_skb->tail;
6361 + size = skb_tailroom(usbe->cur_rx_skb);
6363 + usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
6365 + if (len == usb_rsize)
6369 + * A frame must contain at least an ethernet header.
6371 + if (skb->len < sizeof(struct ethhdr)) {
6372 + usbe->stats.rx_length_errors++;
6373 + usbe->stats.rx_errors++;
6378 + * MAC must match our address or the broadcast address.
6379 + * Really, we should let any packet through, otherwise
6380 + * things that rely on multicast won't work.
6382 + if (memcmp(skb->data, usbe->dev.dev_addr, ETH_ALEN) &&
6383 + memcmp(skb->data, usbe->dev.broadcast, ETH_ALEN)) {
6384 + usbe->stats.rx_frame_errors++;
6385 + usbe->stats.rx_errors++;
6390 + * We're going to consume this SKB. Get a new skb to
6391 + * replace it with. IF this fails, we'd better recycle
6392 + * the one we have.
6394 + usbe->next_rx_skb = usb_new_recv_skb(usbe);
6395 + if (!usbe->next_rx_skb) {
6396 + if (net_ratelimit())
6397 + printk(KERN_ERR "%s: can't allocate new rx skb\n",
6399 + usbe->stats.rx_dropped++;
6403 +// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ?
6405 + usbe->stats.rx_packets++;
6406 + usbe->stats.rx_bytes += skb->len;
6407 + usbe->dev.last_rx = jiffies;
6409 + skb->dev = &usbe->dev;
6410 + skb->protocol = eth_type_trans(skb, &usbe->dev);
6411 + skb->ip_summed = CHECKSUM_NONE;
6413 + if (netif_rx(skb) == NET_RX_DROP)
6414 + usbe->stats.rx_dropped++;
6419 + * Oops, IO error, or stalled.
6422 + case -EIO: /* aborted transfer */
6423 + usbe->stats.rx_errors++;
6426 + case -EPIPE: /* fifo screwed/no data */
6427 + usbe->stats.rx_fifo_errors++;
6428 + usbe->stats.rx_errors++;
6431 + case -EINTR: /* reset */
6434 + case -EAGAIN: /* initialisation */
6442 + buf = usbe->dmabuf;
6446 + size = skb_tailroom(skb);
6448 + usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
6453 + usbe->next_rx_skb = skb;
6460 + * Note that the receiver expects the last packet to be a non-multiple
6461 + * of its rsize. If the packet length is a muliple of wsize (and
6462 + * therefore the remote rsize) tweak the length.
6464 +static void usbeth_send(struct sk_buff *skb, struct usbe_info *usbe)
6466 + unsigned int len = skb->len;
6469 + if ((len % usb_wsize) == 0)
6472 + ret = usbctl_ep_queue_buffer(usbe->client.ctl, 2, skb->data, len);
6474 + printk(KERN_ERR "%s: tx dropping packet: %d\n",
6475 + usbe->dev.name, ret);
6478 + * If the USB core can't accept the packet, we drop it.
6480 + dev_kfree_skb_irq(skb);
6482 + usbe->cur_tx_skb = NULL;
6483 + usbe->stats.tx_carrier_errors++;
6485 + usbe->dev.trans_start = jiffies;
6489 +static void usbeth_send_callback(void *data, int flag, int size)
6491 + struct usbe_info *usbe = data;
6492 + struct sk_buff *skb = usbe->cur_tx_skb;
6496 + usbe->stats.tx_packets++;
6497 + usbe->stats.tx_bytes += skb->len;
6500 + usbe->stats.tx_errors++;
6503 + usbe->stats.tx_dropped++;
6507 + dev_kfree_skb_irq(skb);
6509 + skb = usbe->cur_tx_skb = usbe->next_tx_skb;
6510 + usbe->next_tx_skb = NULL;
6513 + usbeth_send(skb, usbe);
6515 + netif_wake_queue(&usbe->dev);
6518 +static int usbeth_xmit(struct sk_buff *skb, struct net_device *dev)
6520 + struct usbe_info *usbe = dev->priv;
6521 + unsigned long flags;
6523 + if (usbe->next_tx_skb) {
6524 + printk(KERN_ERR "%s: called with next_tx_skb != NULL\n",
6529 + local_irq_save(flags);
6530 + if (usbe->cur_tx_skb) {
6531 + usbe->next_tx_skb = skb;
6532 + netif_stop_queue(dev);
6534 + usbe->cur_tx_skb = skb;
6536 + usbeth_send(skb, usbe);
6538 + local_irq_restore(flags);
6543 + * Transmit timed out. Reset the endpoint, and re-queue the pending
6544 + * packet. If we have a free transmit slot, wake the transmit queue.
6546 +static void usbeth_xmit_timeout(struct net_device *dev)
6548 + struct usbe_info *usbe = dev->priv;
6549 + unsigned long flags;
6551 + usbctl_ep_reset(usbe->client.ctl, 2);
6553 + local_irq_save(flags);
6554 + if (usbe->cur_tx_skb)
6555 + usbeth_send(usbe->cur_tx_skb, usbe);
6557 + if (usbe->next_tx_skb == NULL)
6558 + netif_wake_queue(dev);
6560 + usbe->stats.tx_errors++;
6561 + local_irq_restore(flags);
6564 +static int usbeth_open(struct net_device *dev)
6566 + struct usbe_info *usbe = dev->priv;
6567 + unsigned char *buf;
6568 + unsigned int size;
6570 + usbctl_ep_set_callback(usbe->client.ctl, 2, usbeth_send_callback, usbe);
6571 + usbctl_ep_set_callback(usbe->client.ctl, 1, usbeth_recv_callback, usbe);
6573 + usbe->cur_tx_skb = usbe->next_tx_skb = NULL;
6574 + usbe->cur_rx_skb = usb_new_recv_skb(usbe);
6575 + usbe->next_rx_skb = usb_new_recv_skb(usbe);
6576 + if (!usbe->cur_rx_skb || !usbe->next_rx_skb) {
6577 + printk(KERN_ERR "%s: can't allocate new skb\n",
6579 + if (usbe->cur_rx_skb)
6580 + kfree_skb(usbe->cur_rx_skb);
6581 + if (usbe->next_rx_skb)
6582 + kfree_skb(usbe->next_rx_skb);
6586 + buf = usbe->dmabuf;
6589 + buf = usbe->cur_rx_skb->tail;
6590 + size = skb_tailroom(usbe->cur_rx_skb);
6592 + usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
6594 + if (netif_carrier_ok(dev))
6595 + netif_start_queue(dev);
6600 +static int usbeth_close(struct net_device *dev)
6602 + struct usbe_info *usbe = dev->priv;
6604 + netif_stop_queue(dev);
6606 + usbctl_ep_set_callback(usbe->client.ctl, 2, NULL, NULL);
6607 + usbctl_ep_set_callback(usbe->client.ctl, 1, NULL, NULL);
6608 + usbctl_ep_reset(usbe->client.ctl, 2);
6609 + usbctl_ep_reset(usbe->client.ctl, 1);
6611 + if (usbe->cur_tx_skb)
6612 + kfree_skb(usbe->cur_tx_skb);
6613 + if (usbe->next_tx_skb)
6614 + kfree_skb(usbe->next_tx_skb);
6615 + if (usbe->cur_rx_skb)
6616 + kfree_skb(usbe->cur_rx_skb);
6617 + if (usbe->next_rx_skb)
6618 + kfree_skb(usbe->next_rx_skb);
6623 +static struct net_device_stats *usbeth_stats(struct net_device *dev)
6625 + struct usbe_info *usbe = dev->priv;
6627 + return &usbe->stats;
6630 +static int __init usbeth_probe(struct net_device *dev)
6632 + u8 node_id[ETH_ALEN];
6634 + SET_MODULE_OWNER(dev);
6637 + * Assign the hardware address of the board:
6638 + * generate it randomly, as there can be many such
6639 + * devices on the bus.
6641 + get_random_bytes(node_id, sizeof node_id);
6642 + node_id[0] &= 0xfe; // clear multicast bit
6643 + memcpy(dev->dev_addr, node_id, sizeof node_id);
6646 + dev->flags &= ~IFF_MULTICAST;
6647 + dev->flags &= ~IFF_BROADCAST;
6648 + //dev->flags |= IFF_NOARP;
6654 + * This is called when something in the upper usb client layers
6655 + * changes that affects the endpoint connectivity state (eg,
6656 + * connection or disconnection from the host.) We probably want
6657 + * to do some more handling here, like kicking off a pending
6658 + * transmission if we're running?
6660 +static void usbeth_state_change(void *data, int state, int oldstate)
6662 + struct usbe_info *usbe = data;
6664 + if (state == USB_STATE_CONFIGURED) {
6665 + netif_carrier_on(&usbe->dev);
6666 + if (netif_running(&usbe->dev))
6667 + netif_wake_queue(&usbe->dev);
6669 + if (netif_running(&usbe->dev))
6670 + netif_stop_queue(&usbe->dev);
6671 + netif_carrier_off(&usbe->dev);
6675 +static struct usbe_info usbe_info = {
6678 + .init = usbeth_probe,
6679 + .get_stats = usbeth_stats,
6680 + .watchdog_timeo = 1 * HZ,
6681 + .open = usbeth_open,
6682 + .stop = usbeth_close,
6683 + .hard_start_xmit = usbeth_xmit,
6684 + .change_mtu = usbeth_change_mtu,
6685 + .tx_timeout = usbeth_xmit_timeout,
6686 + .priv = &usbe_info,
6690 + .priv = &usbe_info,
6691 + .state_change = usbeth_state_change,
6694 + * USB client identification for host use in CPU endian.
6696 + .vendor = ETHERNET_VENDOR_ID,
6697 + .product = ETHERNET_PRODUCT_ID,
6699 + .class = 0xff, /* vendor specific */
6703 + .product_str = "SA1100 USB NIC",
6707 +static int __init usbeth_init(void)
6712 + usbe_info.dmabuf = kmalloc(usb_rsize, GFP_KERNEL | GFP_DMA);
6713 + if (!usbe_info.dmabuf)
6717 + if (register_netdev(&usbe_info.dev) != 0) {
6719 + kfree(usbe_info.dmabuf);
6724 + rc = usbctl_open(&usbe_info.client);
6726 + struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
6728 + cdb->ep1.wMaxPacketSize = cpu_to_le16(usb_rsize);
6729 + cdb->ep2.wMaxPacketSize = cpu_to_le16(usb_wsize);
6731 + rc = usbctl_start(&usbe_info.client);
6733 + usbctl_close(&usbe_info.client);
6737 + unregister_netdev(&usbe_info.dev);
6739 + kfree(usbe_info.dmabuf);
6746 +static void __exit usbeth_cleanup(void)
6748 + usbctl_stop(&usbe_info.client);
6749 + usbctl_close(&usbe_info.client);
6751 + unregister_netdev(&usbe_info.dev);
6753 + kfree(usbe_info.dmabuf);
6757 +module_init(usbeth_init);
6758 +module_exit(usbeth_cleanup);
6760 +MODULE_DESCRIPTION("USB client ethernet driver");
6761 +MODULE_PARM(usb_rsize, "1i");
6762 +MODULE_PARM_DESC(usb_rsize, "number of bytes in packets from host to sa11x0");
6763 +MODULE_PARM(usb_wsize, "1i");
6764 +MODULE_PARM_DESC(usb_wsize, "number of bytes in packets from sa11x0 to host");
6765 +MODULE_LICENSE("GPL");
6766 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
6767 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_recv.c 2004-04-30 20:57:36.000000000 -0400
6770 + * Generic receive layer for the SA1100 USB client function
6771 + * Copyright (c) 2001 by Nicolas Pitre
6773 + * This code was loosely inspired by the original version which was
6774 + * Copyright (c) Compaq Computer Corporation, 1998-1999
6776 + * This program is free software; you can redistribute it and/or modify
6777 + * it under the terms of the GNU General Public License version 2 as
6778 + * published by the Free Software Foundation.
6780 + * This is still work in progress...
6782 + * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
6785 +#include <linux/module.h>
6786 +#include <linux/pci.h>
6787 +#include <linux/errno.h>
6788 +#include <linux/usb_ch9.h>
6790 +#include <asm/byteorder.h>
6791 +#include <asm/dma.h>
6793 +#include "sa1100_usb.h"
6794 +#include "sa1100usb.h"
6799 +static void dump_buf(struct sausb_dev *usb, const char *prefix)
6801 + printk("%s: buf [dma=%08x len=%3d] pkt [cpu=%08x dma=%08x len=%3d rem=%3d]\n",
6803 + usb->ep[0].bufdma,
6804 + usb->ep[0].buflen,
6805 + (unsigned int)usb->ep[0].pktcpu,
6806 + usb->ep[0].pktdma,
6807 + usb->ep[0].pktlen,
6808 + usb->ep[0].pktrem);
6812 +static void udc_ep1_done(struct sausb_dev *usb, int flag, int size)
6814 +// printk("UDC: rxd: %3d %3d\n", flag, size);
6815 + dump_buf(usb, "UDC: rxd");
6817 + if (!usb->ep[0].buflen)
6820 + dma_unmap_single(usb->dev, usb->ep[0].bufdma, usb->ep[0].buflen,
6823 + usb->ep[0].bufdma = 0;
6824 + usb->ep[0].buflen = 0;
6825 + usb->ep[0].pktcpu = NULL;
6826 + usb->ep[0].pktdma = 0;
6827 + usb->ep[0].pktlen = 0;
6828 + usb->ep[0].pktrem = 0;
6830 + if (usb->ep[0].cb_func)
6831 + usb->ep[0].cb_func(usb->ep[0].cb_data, flag, size);
6835 + * Initialisation. Clear out the status, and set FST.
6837 +void udc_ep1_init(struct sausb_dev *usb)
6839 + sa1100_reset_dma(usb->ep[0].dmach);
6841 + UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC);
6843 + BUG_ON(usb->ep[0].buflen);
6844 + BUG_ON(usb->ep[0].pktlen);
6847 +void udc_ep1_halt(struct sausb_dev *usb, int halt)
6850 + /* force stall at UDC */
6851 + UDC_set(Ser0UDCCS1, UDCCS1_FST);
6853 + sa1100_reset_dma(usb->ep[0].dmach);
6855 + UDC_clear(Ser0UDCCS1, UDCCS1_FST);
6857 + udc_ep1_done(usb, -EINTR, 0);
6862 + * This gets called when we receive a SET_CONFIGURATION packet to EP0.
6863 + * We were configured. We can now accept packets from the host.
6865 +void udc_ep1_config(struct sausb_dev *usb, unsigned int maxpktsize)
6867 + usb->ep[0].maxpktsize = maxpktsize;
6868 + usb->ep[0].configured = 1;
6870 + Ser0UDCOMP = maxpktsize - 1;
6872 + sa1100_reset_dma(usb->ep[0].dmach);
6873 + udc_ep1_done(usb, -EINTR, 0);
6876 + * Enable EP1 interrupts.
6878 + usb->udccr &= ~UDCCR_RIM;
6879 + UDC_write(Ser0UDCCR, usb->udccr);
6883 + * We saw a reset from the attached hub. This means we are no
6884 + * longer configured, and as far as the rest of the world is
6885 + * concerned, we don't exist.
6887 +void udc_ep1_reset(struct sausb_dev *usb)
6890 + * Disable EP1 interrupts.
6892 + usb->udccr |= UDCCR_RIM;
6893 + UDC_write(Ser0UDCCR, usb->udccr);
6895 + usb->ep[0].configured = 0;
6896 + usb->ep[0].maxpktsize = 0;
6898 + sa1100_reset_dma(usb->ep[0].dmach);
6899 + udc_ep1_done(usb, -EINTR, 0);
6902 +void udc_ep1_int_hndlr(struct sausb_dev *usb)
6904 + dma_addr_t dma_addr;
6906 + u32 status = Ser0UDCCS1;
6908 + dump_buf(usb, "UDC: int");
6911 + printk("UDC: usbrx: in ISR but naking [0x%02x]\n", status);
6915 + if (!(status & UDCCS1_RPC))
6916 + /* you can get here if we are holding NAK */
6919 + if (!usb->ep[0].buflen) {
6920 + printk("UDC: usb_recv: RPC for non-existent buffer [0x%02x]\n", status);
6925 + sa1100_stop_dma(usb->ep[0].dmach);
6927 + dma_addr = sa1100_get_dma_pos(usb->ep[0].dmach);
6930 + * We've finished with the DMA for this packet.
6932 + sa1100_clear_dma(usb->ep[0].dmach);
6934 + if (status & UDCCS1_SST) {
6935 + printk("UDC: usb_recv: stall sent\n");
6936 + UDC_flip(Ser0UDCCS1, UDCCS1_SST);
6939 + * UDC aborted current transfer, so we do.
6941 + * It would be better to re-queue this buffer IMHO. It
6942 + * hasn't gone anywhere yet. --rmk
6944 + UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
6945 + udc_ep1_done(usb, -EIO, 0);
6949 + if (status & UDCCS1_RPE) {
6950 + printk("UDC: usb_recv: RPError %x\n", status);
6951 + UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
6952 + udc_ep1_done(usb, -EIO, 0);
6956 + len = dma_addr - usb->ep[0].pktdma;
6958 + printk("UDC: usb_recv: dma_addr (%x) < pktdma (%x)\n",
6959 + dma_addr, usb->ep[0].pktdma);
6963 + if (len > usb->ep[0].pktlen)
6964 + len = usb->ep[0].pktlen;
6967 + * If our transfer was smaller, and we have bytes left in
6968 + * the FIFO, we need to read them out manually.
6970 + if (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE)) {
6973 + dma_sync_single(usb->dev, usb->ep[0].pktdma + len,
6974 + usb->ep[0].pktlen - len, DMA_FROM_DEVICE);
6976 + buf = (char *)usb->ep[0].pktcpu + len;
6979 + *buf++ = Ser0UDCDR;
6981 + } while (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE));
6984 + * Note: knowing the internals of this macro is BAD, but we
6985 + * need this to cause the data to be written back to memory.
6987 + dma_sync_single(usb->dev, usb->ep[0].pktdma + len,
6988 + usb->ep[0].pktlen - len, DMA_TO_DEVICE);
6992 + * If the FIFO still contains data, something's definitely wrong.
6994 + if (Ser0UDCCS1 & UDCCS1_RNE) {
6995 + printk("UDC: usb_recv: fifo screwed, shouldn't contain data\n");
6996 + usb->ep[0].fifo_errs++;
6998 + udc_ep1_done(usb, -EPIPE, 0);
7006 + usb->ep[0].bytes += len;
7007 + usb->ep[0].packets ++;
7011 + * Update remaining byte count for this buffer.
7013 + usb->ep[0].pktrem -= len;
7016 + * If we received a full-sized packet, and there's more
7017 + * data remaining, th, queue up another receive.
7019 + if (len == usb->ep[0].pktlen && usb->ep[0].pktrem != 0) {
7020 + usb->ep[0].pktcpu += len;
7021 + usb->ep[0].pktdma += len;
7022 + usb->ep[0].pktlen = min(usb->ep[0].pktrem, usb->ep[0].maxpktsize);
7023 + sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].pktdma, usb->ep[0].pktlen);
7025 + * Clear RPC to receive next packet.
7027 + UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
7028 + dump_buf(usb, "UDC: req");
7033 + udc_ep1_done(usb, 0, usb->ep[0].buflen - usb->ep[0].pktrem);
7036 +int udc_ep1_queue_buffer(struct sausb_dev *usb, char *buf, unsigned int len)
7038 + unsigned long flags;
7042 + if (!buf || len == 0)
7045 + dma = dma_map_single(usb->dev, buf, len, DMA_FROM_DEVICE);
7047 + spin_lock_irqsave(&usb->lock, flags);
7049 + if (usb->ep[0].buflen) {
7054 + sa1100_clear_dma(usb->ep[0].dmach);
7056 + usb->ep[0].bufdma = dma;
7057 + usb->ep[0].buflen = len;
7058 + usb->ep[0].pktcpu = buf;
7059 + usb->ep[0].pktdma = dma;
7060 + usb->ep[0].pktlen = min(len, usb->ep[0].maxpktsize);
7061 + usb->ep[0].pktrem = len;
7063 + sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].bufdma, usb->ep[0].buflen);
7064 + dump_buf(usb, "UDC: que");
7067 + /* turn off NAK of OUT packets, if set */
7068 + UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
7074 + spin_unlock_irqrestore(&usb->lock, flags);
7077 + dma_unmap_single(usb->dev, dma, len, DMA_FROM_DEVICE);
7082 +void udc_ep1_recv_reset(struct sausb_dev *usb)
7084 + sa1100_reset_dma(usb->ep[0].dmach);
7085 + udc_ep1_done(usb, -EINTR, 0);
7087 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
7088 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/buffer.c 2004-04-30 20:57:36.000000000 -0400
7093 + * Copyright (C) 2002 Russell King.
7095 +#include <linux/module.h>
7096 +#include <linux/slab.h>
7097 +#include <linux/init.h>
7099 +#include "buffer.h"
7101 +static LIST_HEAD(buffers);
7103 +struct usb_buf *usbb_alloc(int size, int gfp)
7105 + unsigned long flags;
7106 + struct usb_buf *buf;
7108 + buf = kmalloc(sizeof(struct usb_buf) + size, gfp);
7110 + atomic_set(&buf->users, 1);
7111 + local_irq_save(flags);
7112 + list_add(&buf->list, &buffers);
7113 + local_irq_restore(flags);
7115 + buf->data = (unsigned char *) (buf + 1);
7116 + buf->head = (unsigned char *) (buf + 1);
7122 +void __usbb_free(struct usb_buf *buf)
7124 + unsigned long flags;
7125 + local_irq_save(flags);
7126 + list_del(&buf->list);
7127 + local_irq_restore(flags);
7131 +EXPORT_SYMBOL(usbb_alloc);
7132 +EXPORT_SYMBOL(__usbb_free);
7134 +static void __exit usbb_exit(void)
7136 + if (!list_empty(&buffers)) {
7137 + struct list_head *l, *n;
7138 + printk("usbb: buffers not freed:\n");
7140 + list_for_each_safe(l, n, &buffers) {
7141 + struct usb_buf *b = list_entry(l, struct usb_buf, list);
7143 + printk(" %p: alloced from %p count %d\n",
7144 + b, b->alloced_by, atomic_read(&b->users));
7151 +module_exit(usbb_exit);
7153 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
7154 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-char.h 2004-04-30 20:57:36.000000000 -0400
7157 + * Copyright (C) 2001 Extenex Corporation
7161 + * Character device emulation client for SA-1100 client usb core.
7166 +#ifndef _USB_CHAR_H
7167 +#define _USB_CHAR_H
7169 +#define USBC_MAJOR 10 /* miscellaneous character device */
7170 +#define USBC_MINOR 240 /* in the "reserved for local use" range */
7172 +#define USBC_MAGIC 0x8E
7174 +/* zap everything in receive ring buffer */
7175 +#define USBC_IOC_FLUSH_RECEIVER _IO( USBC_MAGIC, 0x01 )
7177 +/* reset transmitter */
7178 +#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 )
7180 +/* do both of above */
7181 +#define USBC_IOC_FLUSH_ALL _IO( USBC_MAGIC, 0x03 )
7188 +#endif /* _USB_CHAR_H */
7190 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
7191 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/buffer.h 2004-04-30 20:57:36.000000000 -0400
7194 + * usb/buffer.h: USB client buffers
7196 + * Copyright (C) 2002 Russell King.
7198 + * Loosely based on linux/skbuff.h
7200 +#ifndef USBDEV_BUFFER_H
7201 +#define USBDEV_BUFFER_H
7203 +#include <linux/list.h>
7207 + struct list_head list;
7209 + unsigned char *data;
7210 + unsigned char *head;
7214 +extern struct usb_buf *usbb_alloc(int size, int gfp);
7215 +extern void __usbb_free(struct usb_buf *);
7217 +static inline struct usb_buf *usbb_get(struct usb_buf *buf)
7219 + atomic_inc(&buf->users);
7223 +static inline void usbb_put(struct usb_buf *buf)
7225 + if (atomic_dec_and_test(&buf->users))
7229 +static inline void *usbb_push(struct usb_buf *buf, int len)
7231 + unsigned char *b = buf->head;
7238 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
7239 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100usb.c 2004-04-30 20:57:36.000000000 -0400
7241 +#include <linux/module.h>
7242 +#include <linux/delay.h>
7243 +#include <linux/interrupt.h>
7244 +#include <linux/usb_ch9.h>
7245 +#include <linux/init.h>
7246 +#include <linux/proc_fs.h>
7247 +#include <linux/spinlock.h>
7248 +#include <linux/device.h>
7250 +#include <asm/mach-types.h>
7251 +#include <asm/io.h>
7252 +#include <asm/dma.h>
7253 +#include <asm/irq.h>
7255 +#include "buffer.h"
7256 +#include "usbdev.h"
7257 +#include "sa1100_usb.h"
7258 +#include "sa1100usb.h"
7261 +#define DPRINTK(fmt, args...) printk( fmt , ## args)
7263 +#define DPRINTK(fmt, args...)
7266 +static inline void pcs(const char *prefix)
7269 + __u32 foo = Ser0UDCCS0;
7271 + DPRINTK("%s UDCAR: %d\n", prefix, Ser0UDCAR);
7273 + printk("UDC: %s: %08x [ %s%s%s%s%s%s]\n", prefix,
7275 + foo & UDCCS0_SE ? "SE " : "",
7276 + foo & UDCCS0_DE ? "DE " : "",
7277 + foo & UDCCS0_FST ? "FST " : "",
7278 + foo & UDCCS0_SST ? "SST " : "",
7279 + foo & UDCCS0_IPR ? "IPR " : "",
7280 + foo & UDCCS0_OPR ? "OPR " : "");
7285 + * soft_connect_hook()
7287 + * Some devices have platform-specific circuitry to make USB
7288 + * not seem to be plugged in, even when it is. This allows
7289 + * software to control when a device 'appears' on the USB bus
7290 + * (after Linux has booted and this driver has loaded, for
7291 + * example). If you have such a circuit, control it here.
7293 +static inline void soft_connect_hook(int enable)
7295 +#ifdef CONFIG_SA1100_EXTENEX1
7296 + if (machine_is_extenex1()) {
7298 + PPDR |= PPC_USB_SOFT_CON;
7299 + PPSR |= PPC_USB_SOFT_CON;
7301 + PPSR &= ~PPC_USB_SOFT_CON;
7302 + PPDR &= ~PPC_USB_SOFT_CON;
7309 + * disable the UDC at the source
7311 +static inline void udc_disable(struct sausb_dev *usb)
7313 + soft_connect_hook(0);
7315 + usb->udccr = UDCCR_UDD | UDCCR_SUSIM;
7317 + UDC_write(Ser0UDCCR, usb->udccr);
7321 + * Clear any pending write from the EP0 write buffer.
7323 +static void ep0_clear_write(struct sausb_dev *usb)
7325 + struct usb_buf *buf;
7328 + usb->wrint = NULL;
7329 + usb->wrbuf = NULL;
7330 + usb->wrptr = NULL;
7337 +static int udc_start(void *priv)
7339 + struct sausb_dev *usb = priv;
7341 + usb->ep[0].maxpktsize = 0;
7342 + usb->ep[1].maxpktsize = 0;
7345 + * start UDC internal machinery running, but mask interrupts.
7347 + usb->udccr = UDCCR_SUSIM | UDCCR_TIM | UDCCR_RIM | UDCCR_EIM |
7349 + UDC_write(Ser0UDCCR, usb->udccr);
7354 + * clear all interrupt sources
7356 + Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR |
7357 + UDCSR_RIR | UDCSR_TIR | UDCSR_SUSIR;
7360 + * flush DMA and fire through some -EAGAINs
7362 + udc_ep1_init(usb);
7363 + udc_ep2_init(usb);
7366 + * enable any platform specific hardware
7368 + soft_connect_hook(1);
7371 + * Enable resume, suspend and endpoint 0 interrupts. Leave
7372 + * endpoint 1 and 2 interrupts masked.
7374 + * If you are unplugged you will immediately get a suspend
7375 + * interrupt. If you are plugged and have a soft connect-circuit,
7376 + * you will get a reset. If you are plugged without a soft-connect,
7377 + * I think you also get suspend.
7379 + usb->udccr &= ~(UDCCR_SUSIM | UDCCR_EIM | UDCCR_RESIM);
7380 + UDC_write(Ser0UDCCR, usb->udccr);
7385 +static int udc_stop(void *priv)
7387 + struct sausb_dev *usb = priv;
7389 + ep0_clear_write(usb);
7391 + /* mask everything */
7394 + udc_ep1_reset(usb);
7395 + udc_ep2_reset(usb);
7407 + * some voodo I am adding, since the vanilla macros just aren't doing it
7411 +#define ABORT_BITS (UDCCS0_SST | UDCCS0_SE)
7412 +#define OK_TO_WRITE (!(Ser0UDCCS0 & ABORT_BITS))
7413 +#define BOTH_BITS (UDCCS0_IPR | UDCCS0_DE)
7415 +static void set_de(void)
7420 + if (OK_TO_WRITE) {
7421 + Ser0UDCCS0 |= UDCCS0_DE;
7423 + DPRINTK("UDC: quitting set DE because SST or SE set\n");
7426 + if (Ser0UDCCS0 & UDCCS0_DE)
7430 + printk("UDC: Dangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n",
7431 + UDCCS0_DE, Ser0UDCCS0);
7437 +static void set_ipr(void)
7442 + if (OK_TO_WRITE) {
7443 + Ser0UDCCS0 |= UDCCS0_IPR;
7445 + DPRINTK("UDC: Quitting set IPR because SST or SE set\n");
7448 + if (Ser0UDCCS0 & UDCCS0_IPR)
7452 + printk("UDC: Dangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n",
7453 + UDCCS0_IPR, Ser0UDCCS0);
7459 +static void set_ipr_and_de(void)
7464 + if (OK_TO_WRITE) {
7465 + Ser0UDCCS0 |= BOTH_BITS;
7467 + DPRINTK("UDC: Quitting set IPR/DE because SST or SE set\n");
7470 + if ((Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS)
7474 + printk("UDC: Dangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n",
7475 + UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0);
7481 +static inline void set_cs_bits(__u32 bits)
7483 + if (bits & (UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST | UDCCS0_SST))
7484 + Ser0UDCCS0 = bits;
7485 + else if ((bits & BOTH_BITS) == BOTH_BITS)
7487 + else if (bits & UDCCS0_IPR)
7489 + else if (bits & UDCCS0_DE)
7494 + * udc_ep0_write_fifo()
7496 + * Stick bytes in the 8 bytes endpoint zero FIFO. This version uses a
7497 + * variety of tricks to make sure the bytes are written correctly:
7498 + * 1. The count register is checked to see if the byte went in,
7499 + * and the write is attempted again if not.
7500 + * 2. An overall counter is used to break out so we don't hang in
7501 + * those (rare) cases where the UDC reverses direction of the
7502 + * FIFO underneath us without notification (in response to host
7503 + * aborting a setup transaction early).
7505 +static void udc_ep0_write_fifo(struct sausb_dev *usb)
7507 + unsigned int bytes_this_time = min(usb->wrlen, 8U);
7508 + int bytes_written = 0;
7510 + DPRINTK("WF=%d: ", bytes_this_time);
7512 + while (bytes_this_time--) {
7516 + DPRINTK("%2.2X ", *usb->wrptr);
7518 + cwc = Ser0UDCWC & 15;
7522 + Ser0UDCD0 = *usb->wrptr;
7523 + udelay(20); /* voodo 28Feb01ww */
7524 + } while ((Ser0UDCWC & 15) == cwc && --i);
7527 + printk("UDC: udc_ep0_write_fifo: write failure\n");
7528 + usb->ep0_wr_fifo_errs++;
7534 + usb->wrlen -= bytes_written;
7536 + /* following propagation voodo so maybe caller writing IPR in
7537 + ..a moment might actually get it to stick 28Feb01ww */
7540 + usb->ep0_wr_bytes += bytes_written;
7541 + DPRINTK("L=%d WCR=%8.8X\n", usb->wrlen, Ser0UDCWC);
7547 + * Read 1-8 bytes out of FIFO and put in request. Called to do the
7548 + * initial read of setup requests from the host. Return number of
7551 + * Like write fifo above, this driver uses multiple reads checked
7552 + * against the count register with an overall timeout.
7555 +udc_ep0_read_fifo(struct sausb_dev *usb, struct usb_ctrlrequest *request, int sz)
7557 + unsigned char *pOut = (unsigned char *) request;
7558 + unsigned int fifo_count, bytes_read = 0;
7560 + fifo_count = Ser0UDCWC & 15;
7562 + DPRINTK("RF=%d ", fifo_count);
7563 + BUG_ON(fifo_count > sz);
7565 + while (fifo_count--) {
7569 + cwc = Ser0UDCWC & 15;
7573 + *pOut = (unsigned char) Ser0UDCD0;
7575 + } while ((Ser0UDCWC & 15) == cwc && --i);
7578 + printk(KERN_ERR "UDC: udc_ep0_read_fifo: read failure\n");
7579 + usb->ep0_rd_fifo_errs++;
7586 + DPRINTK("fc=%d\n", bytes_read);
7587 + usb->ep0_rd_bytes += bytes_read;
7588 + usb->ep0_rd_packets ++;
7589 + return bytes_read;
7592 +static void ep0_sh_write_data(struct sausb_dev *usb)
7595 + * If bytes left is zero, we are coming in on the
7596 + * interrupt after the last packet went out. And
7597 + * we know we don't have to empty packet this
7598 + * transfer so just set DE and we are done
7600 + set_cs_bits(UDCCS0_DE);
7603 +static void ep0_sh_write_with_empty_packet(struct sausb_dev *usb)
7606 + * If bytes left is zero, we are coming in on the
7607 + * interrupt after the last packet went out.
7608 + * We must do short packet suff, so set DE and IPR
7610 + set_cs_bits(UDCCS0_IPR | UDCCS0_DE);
7611 + DPRINTK("UDC: sh_write_empty: Sent empty packet\n");
7614 +static int udc_clear_opr(void)
7621 + Ser0UDCCS0 = UDCCS0_SO;
7622 + is_clear = !(Ser0UDCCS0 & UDCCS0_OPR);
7625 + } while (!is_clear);
7630 +static int udc_ep0_queue(void *priv, struct usb_buf *buf,
7631 + unsigned int req_len)
7633 + struct sausb_dev *usb = priv;
7634 + __u32 cs_reg_bits = UDCCS0_IPR;
7636 + DPRINTK("a=%d r=%d\n", buf->len, req_len);
7639 + * thou shalt not enter data phase until
7640 + * Out Packet Ready is clear
7642 + if (!udc_clear_opr()) {
7643 + printk("UDC: SO did not clear OPR\n");
7644 + set_cs_bits(UDCCS0_DE | UDCCS0_SO);
7649 + usb->ep0_wr_packets++;
7652 + usb->wrptr = buf->data;
7653 + usb->wrlen = min(buf->len, req_len);
7655 + udc_ep0_write_fifo(usb);
7657 + if (usb->wrlen == 0) {
7659 + * out in one, so data end
7661 + cs_reg_bits |= UDCCS0_DE;
7662 + ep0_clear_write(usb);
7663 + } else if (buf->len < req_len) {
7665 + * we are going to short-change host
7666 + * so need nul to not stall
7668 + usb->wrint = ep0_sh_write_with_empty_packet;
7671 + * we have as much or more than requested
7673 + usb->wrint = ep0_sh_write_data;
7677 + * note: IPR was set uncondtionally at start of routine
7679 + set_cs_bits(cs_reg_bits);
7684 + * When SO and DE sent, UDC will enter status phase and ack, propagating
7685 + * new address to udc core. Next control transfer will be on the new
7688 + * You can't see the change in a read back of CAR until then (about 250us
7689 + * later, on my box). The original Intel driver sets S0 and DE and code
7690 + * to check that address has propagated here. I tried this, but it would
7691 + * only sometimes work! The rest of the time it would never propagate and
7692 + * we'd spin forever. So now I just set it and pray...
7694 +static void udc_set_address(void *priv, unsigned int addr)
7699 +static void udc_set_config(void *priv, struct cdb *cdb)
7701 + struct sausb_dev *usb = priv;
7704 + udc_ep1_config(usb, le16_to_cpu(cdb->ep1.wMaxPacketSize));
7705 + udc_ep2_config(usb, le16_to_cpu(cdb->ep2.wMaxPacketSize));
7707 + udc_ep1_reset(usb);
7708 + udc_ep2_reset(usb);
7712 +static unsigned int udc_ep_get_status(void *priv, unsigned int ep)
7714 + unsigned int status;
7718 + status = (Ser0UDCCS0 & UDCCS0_FST) ? 1 : 0;
7722 + status = (Ser0UDCCS1 & UDCCS1_FST) ? 1 : 0;
7726 + status = (Ser0UDCCS2 & UDCCS2_FST) ? 1 : 0;
7730 + printk(KERN_ERR "UDC: get_status: bad end point %d\n", ep);
7738 +static void udc_ep_halt(void *priv, unsigned int ep, int halt)
7740 + struct sausb_dev *usb = priv;
7742 + printk("UDC: ep%d %s halt\n", ep, halt ? "set" : "clear");
7746 + udc_ep1_halt(usb, halt);
7750 + udc_ep2_halt(usb, halt);
7755 +static int udc_ep_queue(void *priv, unsigned int ep, char *buf, unsigned int len)
7757 + struct sausb_dev *usb = priv;
7758 + int ret = -EINVAL;
7762 + ret = udc_ep1_queue_buffer(usb, buf, len);
7765 + ret = udc_ep2_send(usb, buf, len);
7772 +static void udc_ep_reset(void *priv, unsigned int ep)
7774 + struct sausb_dev *usb = priv;
7778 + udc_ep1_recv_reset(usb);
7781 + udc_ep2_send_reset(usb);
7786 +static void udc_ep_callback(void *priv, unsigned int ep, usb_callback_t cb, void *data)
7788 + struct sausb_dev *usb = priv;
7789 + unsigned long flags;
7791 + if (ep == 1 || ep == 2) {
7794 + spin_lock_irqsave(&usb->lock, flags);
7795 + usb->ep[ep].cb_func = cb;
7796 + usb->ep[ep].cb_data = data;
7797 + spin_unlock_irqrestore(&usb->lock, flags);
7801 +static int udc_ep_idle(void *priv, unsigned int ep)
7803 + struct sausb_dev *usb = priv;
7804 + int ret = -EINVAL;
7810 + ret = udc_ep2_idle(usb);
7817 +static struct usbc_driver usb_sa1100_drv = {
7818 + .owner = THIS_MODULE,
7820 + .start = udc_start,
7822 + .ep0_queue = udc_ep0_queue,
7823 + .set_address = udc_set_address,
7824 + .set_config = udc_set_config,
7825 + .ep_get_status = udc_ep_get_status,
7826 + .ep_halt = udc_ep_halt,
7827 + .ep_queue = udc_ep_queue,
7828 + .ep_reset = udc_ep_reset,
7829 + .ep_callback = udc_ep_callback,
7830 + .ep_idle = udc_ep_idle,
7835 + * udc_ep0_read_packet()
7837 + * This setup handler is the "idle" state of endpoint zero. It looks for
7838 + * OPR (OUT packet ready) to see if a setup request has been been received
7839 + * from the host. Requests without a return data phase are immediately
7840 + * handled. Otherwise, the handler may be set to one of the sh_write_xxxx
7841 + * data pumpers if more than 8 bytes need to get back to the host.
7843 +static void udc_ep0_read_packet(struct sausb_dev *usb, u32 cs_reg_in)
7845 + struct usb_ctrlrequest req;
7846 + int n, ret = RET_NOACTION;
7849 + * A control request has been received by EP0.
7850 + * Read the request.
7852 + n = udc_ep0_read_fifo(usb, &req, sizeof(req));
7854 + if (n == sizeof(req)) {
7855 + ret = usbctl_parse_request(usb->ctl, &req);
7858 + * The request wasn't fully received. Force a
7861 + set_cs_bits(UDCCS0_FST | UDCCS0_SO);
7862 + printk("UDC: fifo read error: wanted %d bytes got %d\n",
7868 + case RET_NOACTION:
7872 + set_cs_bits(UDCCS0_DE | UDCCS0_SO);
7875 + case RET_REQERROR:
7877 + * Send stall PID to host.
7879 + set_cs_bits(UDCCS0_DE | UDCCS0_SO | UDCCS0_FST);
7885 + * HACK DEBUG 3Mar01ww
7886 + * Well, maybe not, it really seems to help! 08Mar01ww
7888 +static void core_kicker(struct sausb_dev *usb)
7890 + __u32 car = Ser0UDCAR;
7891 + __u32 imp = Ser0UDCIMP;
7892 + __u32 omp = Ser0UDCOMP;
7894 + UDC_set(Ser0UDCCR, UDCCR_UDD);
7896 + UDC_clear(Ser0UDCCR, UDCCR_UDD);
7903 +static void enable_resume_mask_suspend(struct sausb_dev *usb)
7907 + usb->udccr |= UDCCR_SUSIM;
7911 + Ser0UDCCR = usb->udccr;
7913 + if (Ser0UDCCR == usb->udccr)
7915 + if (Ser0UDCSR & UDCSR_RSTIR)
7917 + } while (i++ < 50);
7920 + printk("UDC: enable_resume: could not set SUSIM 0x%08x\n",
7923 + usb->udccr &= ~UDCCR_RESIM;
7927 + Ser0UDCCR = usb->udccr;
7929 + if (Ser0UDCCR == usb->udccr)
7931 + if (Ser0UDCSR & UDCSR_RSTIR)
7933 + } while (i++ < 50);
7936 + printk("UDC: enable_resume: could not clear RESIM 0x%08x\n",
7940 +static void enable_suspend_mask_resume(struct sausb_dev *usb)
7944 + usb->udccr |= UDCCR_RESIM;
7948 + Ser0UDCCR = usb->udccr;
7950 + if (Ser0UDCCR == usb->udccr)
7952 + if (Ser0UDCSR & UDCSR_RSTIR)
7954 + } while (i++ < 50);
7957 + printk("UDC: enable_resume: could not set RESIM 0x%08x\n",
7960 + usb->udccr &= ~UDCCR_SUSIM;
7964 + Ser0UDCCR = usb->udccr;
7966 + if (Ser0UDCCR == usb->udccr)
7968 + if (Ser0UDCSR & UDCSR_RSTIR)
7970 + } while (i++ < 50);
7973 + printk("UDC: enable_resume: could not clear SUSIM 0x%08x\n",
7978 + * Reset received from HUB (or controller just went nuts and reset by
7979 + * itself!) so UDC core has been reset, track this state here
7981 +static void udc_reset(struct sausb_dev *usb)
7983 + if (usbctl_reset(usb->ctl)) {
7984 + ep0_clear_write(usb);
7987 + * Clean up endpoints.
7989 + udc_ep1_reset(usb);
7990 + udc_ep2_reset(usb);
7994 + * mask reset ints, they flood during sequence, enable
7995 + * suspend and resume
7997 + usb->udccr = (usb->udccr & ~(UDCCR_SUSIM | UDCCR_RESIM)) | UDCCR_REM;
7998 + Ser0UDCCR = usb->udccr;
8002 + * handle interrupt for endpoint zero
8004 +static void udc_ep0_int_hndlr(struct sausb_dev *usb)
8010 + cs_reg_in = Ser0UDCCS0;
8013 + * If "setup end" has been set, the usb controller has terminated
8014 + * a setup transaction before we set DE. This happens during
8015 + * enumeration with some hosts. For example, the host will ask for
8016 + * our device descriptor and specify a return of 64 bytes. When we
8017 + * hand back the first 8, the host will know our max packet size
8018 + * and turn around and issue a new setup immediately. This causes
8019 + * the UDC to auto-ack the new setup and set SE. We must then
8020 + * "unload" (process) the new setup, which is what will happen
8021 + * after this preamble is finished executing.
8023 + if (cs_reg_in & UDCCS0_SE) {
8024 + DPRINTK("UDC: early termination of setup\n");
8029 + set_cs_bits(UDCCS0_SSE);
8032 + * Clear any pending write.
8034 + ep0_clear_write(usb);
8038 + * UDC sent a stall due to a protocol violation.
8040 + if (cs_reg_in & UDCCS0_SST) {
8041 + usb->ep0_stall_sent++;
8043 + DPRINTK("UDC: write_preamble: UDC sent stall\n");
8046 + * Clear sent stall
8048 + set_cs_bits(UDCCS0_SST);
8051 + * Clear any pending write.
8053 + ep0_clear_write(usb);
8056 + switch (cs_reg_in & (UDCCS0_OPR | UDCCS0_IPR)) {
8057 + case UDCCS0_OPR | UDCCS0_IPR:
8058 + DPRINTK("UDC: write_preamble: see OPR. Stopping write to "
8059 + "handle new SETUP\n");
8062 + * very rarely, you can get OPR and
8063 + * leftover IPR. Try to clear
8065 + UDC_clear(Ser0UDCCS0, UDCCS0_IPR);
8068 + * Clear any pending write.
8070 + ep0_clear_write(usb);
8075 + * A new setup request is pending. Handle
8076 + * it. Note that we don't try to read a
8077 + * packet if SE was set and OPR is clear.
8079 + udc_ep0_read_packet(usb, cs_reg_in);
8084 + if (usb->wrlen != 0) {
8088 + udc_ep0_write_fifo(usb);
8092 + if (usb->wrlen == 0) {
8098 + ep0_clear_write(usb);
8104 + DPRINTK("UDC: IPR set, not writing\n");
8105 + usb->ep0_early_irqs++;
8112 +static irqreturn_t udc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
8114 + struct sausb_dev *usb = dev_id;
8115 + u32 status = Ser0UDCSR;
8118 + * ReSeT Interrupt Request - UDC has been reset
8120 + if (status & UDCSR_RSTIR) {
8124 + * clear all pending sources
8126 + UDC_flip(Ser0UDCSR, status);
8127 + return IRQ_HANDLED;
8131 + * else we have done something other than reset,
8132 + * so be sure reset enabled
8134 + usb->udccr &= ~UDCCR_REM;
8135 + UDC_write(Ser0UDCCR, usb->udccr);
8138 + * RESume Interrupt Request
8140 + if (status & UDCSR_RESIR) {
8141 + usbctl_resume(usb->ctl);
8143 + enable_suspend_mask_resume(usb);
8147 + * SUSpend Interrupt Request
8149 + if (status & UDCSR_SUSIR) {
8150 + usbctl_suspend(usb->ctl);
8151 + enable_resume_mask_suspend(usb);
8155 + * clear all pending sources
8157 + UDC_flip(Ser0UDCSR, status);
8159 + if (status & UDCSR_EIR)
8160 + udc_ep0_int_hndlr(usb);
8162 + if (status & UDCSR_RIR)
8163 + udc_ep1_int_hndlr(usb);
8165 + if (status & UDCSR_TIR)
8166 + udc_ep2_int_hndlr(usb);
8168 + return IRQ_HANDLED;
8171 +#ifdef CONFIG_PROC_FS
8173 +#define SAY( fmt, args... ) p += sprintf(p, fmt, ## args )
8174 +#define SAYV( num ) p += sprintf(p, num_fmt, "Value", num )
8175 +#define SAYC( label, yn ) p += sprintf(p, yn_fmt, label, yn )
8176 +#define SAYS( label, v ) p += sprintf(p, cnt_fmt, label, v )
8179 +udc_read_proc(char *page, char **start, off_t off, int cnt, int *eof,
8182 + struct sausb_dev *usb = data;
8187 + p += usbctl_proc_info(usb->ctl, p);
8188 + p += sprintf(p, "\nUDC:\n");
8190 + p += sprintf(p, "Address\t: %d (0x%02x)\n", v, v);
8192 + p += sprintf(p, "IN max\t: %d (0x%02x)\n", v + 1, v);
8194 + p += sprintf(p, "OUT max\t: %d (0x%02x)\n", v + 1, v);
8196 + p += sprintf(p, "UDCCR\t: 0x%02x "
8197 + "[ %cSUSIM %cTIM %cRIM %cEIM %cRESIM %cUDA %cUDD ] "
8200 + v & UDCCR_SUSIM ? '+' : '-', v & UDCCR_TIM ? '+' : '-',
8201 + v & UDCCR_RIM ? '+' : '-', v & UDCCR_EIM ? '+' : '-',
8202 + v & UDCCR_RESIM ? '+' : '-', v & UDCCR_UDA ? '+' : '-',
8203 + v & UDCCR_UDD ? '+' : '-', usb->udccr);
8205 + p += sprintf(p, "UDCCS0\t: 0x%02x "
8206 + "[ %cSO %cSE %cDE %cFST %cSST %cIPR %cOPR ]\n",
8208 + v & UDCCS0_SO ? '+' : '-', v & UDCCS0_SE ? '+' : '-',
8209 + v & UDCCS0_DE ? '+' : '-', v & UDCCS0_FST ? '+' : '-',
8210 + v & UDCCS0_SST ? '+' : '-', v & UDCCS0_IPR ? '+' : '-',
8211 + v & UDCCS0_OPR ? '+' : '-');
8213 + p += sprintf(p, "UDCCS1\t: 0x%02x "
8214 + "[ %cRNE %cFST %cSST %cRPE %cRPC %cRFS ]\n",
8216 + v & UDCCS1_RNE ? '+' : '-', v & UDCCS1_FST ? '+' : '-',
8217 + v & UDCCS1_SST ? '+' : '-', v & UDCCS1_RPE ? '+' : '-',
8218 + v & UDCCS1_RPC ? '+' : '-', v & UDCCS1_RFS ? '+' : '-');
8220 + p += sprintf(p, "UDCCS2\t: 0x%02x "
8221 + "[ %cFST %cSST %cTUR %cTPE %cTPC %cTFS ]\n",
8223 + v & UDCCS2_FST ? '+' : '-', v & UDCCS2_SST ? '+' : '-',
8224 + v & UDCCS2_TUR ? '+' : '-', v & UDCCS2_TPE ? '+' : '-',
8225 + v & UDCCS2_TPC ? '+' : '-', v & UDCCS2_TFS ? '+' : '-');
8227 + p += sprintf(p, "\n");
8228 + p += sprintf(p, " Bytes Packets FIFO errs Max Sz\n");
8229 + p += sprintf(p, "EP0 Rd: %10ld %10ld %10ld -\n",
8230 + usb->ep0_rd_bytes,
8231 + usb->ep0_rd_packets,
8232 + usb->ep0_rd_fifo_errs);
8233 + p += sprintf(p, "EP0 Wr: %10ld %10ld %10ld -\n",
8234 + usb->ep0_wr_bytes,
8235 + usb->ep0_wr_packets,
8236 + usb->ep0_wr_fifo_errs);
8238 + for (i = 0; i < 2; i++)
8239 + p += sprintf(p, "EP%d : %10ld %10ld %10ld %6d\n",
8242 + usb->ep[i].packets,
8243 + usb->ep[i].fifo_errs,
8244 + usb->ep[i].maxpktsize);
8246 + p += sprintf(p, "Stalls sent\t: %ld\n", usb->ep0_stall_sent);
8247 + p += sprintf(p, "Early ints\t: %ld\n", usb->ep0_early_irqs);
8251 + SAY("\nUDC Interrupt Request Register\n");
8253 + SAYC("Reset pending", (v & UDCSR_RSTIR) ? yes : no);
8254 + SAYC("Suspend pending", (v & UDCSR_SUSIR) ? yes : no);
8255 + SAYC("Resume pending", (v & UDCSR_RESIR) ? yes : no);
8256 + SAYC("ep0 pending", (v & UDCSR_EIR) ? yes : no);
8257 + SAYC("receiver pending", (v & UDCSR_RIR) ? yes : no);
8258 + SAYC("tramsitter pending", (v & UDCSR_TIR) ? yes : no);
8260 +#ifdef CONFIG_SA1100_EXTENEX1
8261 + SAYC("\nSoft connect",
8262 + (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden");
8266 + len = (p - page) - off;
8269 + *eof = (len <= cnt) ? 1 : 0;
8270 + *start = page + off;
8277 +extern struct usbctl usbctl;
8279 +static int __devinit udc_probe(struct device *dev)
8281 + struct sausb_dev *usb;
8284 + if (!request_mem_region(0x80000000, 0x10000, "sa11x0-udc"))
8287 + usb = kmalloc(sizeof(struct sausb_dev), GFP_KERNEL);
8291 + memset(usb, 0, sizeof(struct sausb_dev));
8292 + dev_set_drvdata(dev, usb);
8294 + usb_sa1100_drv.priv = usb;
8297 + usb->ctl = &usbctl;
8299 + spin_lock_init(&usb->lock);
8303 + usbctl_init(usb->ctl, &usb_sa1100_drv);
8305 +#ifdef CONFIG_PROC_FS
8306 + create_proc_read_entry("sausb", 0, NULL, udc_read_proc, usb);
8309 + /* setup rx dma */
8310 + retval = sa1100_request_dma(DMA_Ser0UDCRd, "USB receive",
8311 + NULL, NULL, &usb->ep[0].dmach);
8313 + printk("UDC: unable to register for rx dma rc=%d\n",
8318 + /* setup tx dma */
8319 + retval = sa1100_request_dma(DMA_Ser0UDCWr, "USB transmit",
8320 + NULL, NULL, &usb->ep[1].dmach);
8322 + printk("UDC: unable to register for tx dma rc=%d\n",
8327 + /* now allocate the IRQ. */
8328 + retval = request_irq(IRQ_Ser0UDC, udc_interrupt, SA_INTERRUPT,
8329 + "SA USB core", usb);
8331 + printk("UDC: couldn't request USB irq rc=%d\n", retval);
8338 + if (usb->ep[2].dmach) {
8339 + sa1100_free_dma(usb->ep[2].dmach);
8340 + usb->ep[2].dmach = NULL;
8342 + if (usb->ep[1].dmach) {
8343 + sa1100_free_dma(usb->ep[1].dmach);
8344 + usb->ep[1].dmach = NULL;
8346 +#ifdef CONFIG_PROC_FS
8347 + remove_proc_entry("sausb", NULL);
8349 + release_mem_region(0x80000000, 0x10000);
8354 + * Release DMA and interrupt resources
8356 +static int __devexit udc_remove(struct device *dev)
8358 + struct sausb_dev *usb = dev_get_drvdata(dev);
8360 + dev_set_drvdata(dev, NULL);
8362 +#ifdef CONFIG_PROC_FS
8363 + remove_proc_entry("sausb", NULL);
8368 + free_irq(IRQ_Ser0UDC, usb);
8369 + sa1100_free_dma(usb->ep[1].dmach);
8370 + sa1100_free_dma(usb->ep[0].dmach);
8372 + usbctl_exit(usb->ctl);
8374 + release_mem_region(0x80000000, 0x10000);
8379 +static struct device_driver sa11x0usb_driver = {
8380 + .name = "sa11x0-udc",
8381 + .bus = &platform_bus_type,
8382 + .probe = udc_probe,
8383 + .remove = __devexit_p(udc_remove),
8386 +static int __init udc_init(void)
8388 + return driver_register(&sa11x0usb_driver);
8391 +static void __exit udc_exit(void)
8393 + driver_unregister(&sa11x0usb_driver);
8396 +module_init(udc_init);
8397 +module_exit(udc_exit);
8399 +MODULE_LICENSE("GPL");
8400 +MODULE_DESCRIPTION("SA1100 USB Gadget driver");
8401 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
8402 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/control.c 2004-04-30 20:57:36.000000000 -0400
8407 + * This parses and handles all the control messages to/from endpoint 0.
8409 +#include <linux/module.h>
8410 +#include <linux/kernel.h>
8411 +#include <linux/errno.h>
8412 +#include <linux/usb_ch9.h>
8413 +#include <linux/gfp.h>
8414 +#include <linux/init.h>
8416 +#include "buffer.h"
8417 +#include "client.h"
8418 +#include "usbdev.h"
8420 +#include "sa1100_usb.h"
8422 +#define USB_ENDPOINT_HALT 0
8423 +#define USB_DEVICE_REMOTE_WAKEUP 1
8428 +#define DPRINTK(fmt, args...) printk(KERN_DEBUG fmt , ## args)
8430 +#define DPRINTK(fmt, args...)
8434 + * print string descriptor
8436 +static char * __attribute__((unused))
8437 +psdesc(char *str, int len, struct usb_string_descriptor *desc)
8439 + char *start = str;
8440 + int nchars = (desc->bLength - 2) / sizeof(__u16) + 2;
8443 + if (nchars >= len)
8449 + for(i = 0; i < nchars; i++)
8450 + *str++ = le16_to_cpu(desc->wData[i]);
8469 + kStateZombieSuspend = 1,
8470 + kStateDefault = 2,
8471 + kStateDefaultSuspend = 3,
8473 + kStateAddrSuspend = 5,
8475 + kStateConfigSuspend = 7
8479 +#define kSZ kStateZombie
8480 +#define kSZS kStateZombieSuspend
8481 +#define kSD kStateDefault
8482 +#define kSDS kStateDefaultSuspend
8483 +#define kSA kStateAddr
8484 +#define kSAS kStateAddrSuspend
8485 +#define kSC kStateConfig
8486 +#define kSCS kStateConfigSuspend
8490 + * Zombie == Attached | Powered
8492 +static int device_state_machine[8][6] = {
8493 +// suspend reset resume addr config deconfig
8494 +{ kSZS, kSD, kE, kE, kE, kE }, /* zombie */
8495 +{ kE, kSD, kSZ, kE, kE, kE }, /* zom sus */
8496 +{ kSDS, kError, kSD, kSA, kE, kE }, /* default */
8497 +{ kE, kSD, kSD, kE, kE, kE }, /* def sus */
8498 +{ kSAS, kSD, kE, kE, kSC, kE }, /* addr */
8499 +{ kE, kSD, kSA, kE, kE, kE }, /* addr sus */
8500 +{ kSCS, kSD, kE, kE, kE, kSA }, /* config */
8501 +{ kE, kSD, kSC, kE, kE, kE } /* cfg sus */
8505 + * "device state" is the usb device framework state, as opposed to the
8506 + * "state machine state" which is whatever the driver needs and is much
8507 + * more fine grained
8509 +static int sm_state_to_device_state[8] = {
8510 + USB_STATE_POWERED, /* zombie */
8511 + USB_STATE_SUSPENDED, /* zombie suspended */
8512 + USB_STATE_DEFAULT, /* default */
8513 + USB_STATE_SUSPENDED, /* default suspended */
8514 + USB_STATE_ADDRESS, /* address */
8515 + USB_STATE_SUSPENDED, /* address suspended */
8516 + USB_STATE_CONFIGURED, /* config */
8517 + USB_STATE_SUSPENDED /* config suspended */
8520 +static char * state_names[8] = {
8522 + "zombie suspended",
8524 + "default suspended",
8526 + "address suspended",
8528 + "config suspended"
8531 +static char * event_names[6] = {
8535 + "address assigned",
8540 +static char * device_state_names[] = {
8550 +static void usbctl_callbacks(struct usbctl *ctl, int state, int oldstate)
8552 + struct usb_client *clnt = ctl->clnt;
8555 + * Inform any clients currently attached
8556 + * that the connectivity state changed.
8558 + if (clnt && clnt->state_change)
8559 + clnt->state_change(clnt->priv, state, oldstate);
8563 + * called by the interrupt handler here and the two endpoint
8564 + * files when interesting .."events" happen
8566 +static int usbctl_next_state_on_event(struct usbctl *ctl, int event)
8568 + int next_state, next_dev_state, old_dev_state;
8570 + printk(KERN_DEBUG "usbctl: %s --[%s]--> ", state_names[ctl->sm_state],
8571 + event_names[event]);
8573 + next_state = device_state_machine[ctl->sm_state][event];
8574 + if (next_state != kError) {
8575 + next_dev_state = sm_state_to_device_state[next_state];
8577 + printk("%s. Device in %s state.\n",
8578 + state_names[next_state],
8579 + device_state_names[next_dev_state]);
8581 + old_dev_state = ctl->state;
8582 + ctl->sm_state = next_state;
8583 + ctl->state = next_dev_state;
8585 + if (old_dev_state != next_dev_state)
8586 + usbctl_callbacks(ctl, next_dev_state, old_dev_state);
8588 + printk("(error)\n");
8590 + return next_state;
8594 + * Driver detected USB HUB reset.
8596 +int usbctl_reset(struct usbctl *ctl)
8600 + ret = usbctl_next_state_on_event(ctl, kEvReset) == kError;
8608 +EXPORT_SYMBOL(usbctl_reset);
8610 +void usbctl_suspend(struct usbctl *ctl)
8612 + usbctl_next_state_on_event(ctl, kEvSuspend);
8615 +EXPORT_SYMBOL(usbctl_suspend);
8617 +void usbctl_resume(struct usbctl *ctl)
8619 + usbctl_next_state_on_event(ctl, kEvResume);
8622 +EXPORT_SYMBOL(usbctl_resume);
8624 +static struct usb_interface_descriptor *
8625 +usbctl_get_interface_descriptor(struct usbctl *ctl, unsigned int interface)
8628 + struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
8630 + return (struct usb_interface_descriptor *)&cdb->intf;
8634 +__usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req,
8635 + struct usb_buf *buf)
8637 + unsigned int reqlen = le16_to_cpu(req->wLength);
8639 + return ctl->driver->ep0_queue(ctl->driver->priv, buf, reqlen) ?
8640 + RET_ERROR : RET_QUEUED;
8644 +usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req,
8645 + void *data, unsigned int len)
8647 + struct usb_buf *buf;
8649 + buf = usbb_alloc(len, GFP_ATOMIC);
8651 + printk(KERN_ERR "usb: out of memory\n");
8656 + memcpy(usbb_push(buf, len), data, len);
8658 + return __usbctl_queue(ctl, req, buf);
8662 + * 9.4.5: Get Status (device)
8665 +usbctl_parse_dev_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
8669 + status = /* self_powered_hook() ? 1 : 0 */1;
8671 + status = cpu_to_le16(status);
8673 + return usbctl_queue(ctl, req, &status, 2);
8677 + * Send USB device description to the host.
8680 +usbctl_desc_device(struct usbctl *ctl, struct usb_ctrlrequest *req)
8682 + return __usbctl_queue(ctl, req, usbb_get(ctl->dev_desc_buf));
8686 + * Send USB configuration information to the host.
8689 +usbctl_desc_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
8692 + struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
8694 + return usbctl_queue(ctl, req, cdb, sizeof(struct cdb));
8698 + * Send a string to the host from the string table.
8701 +usbctl_desc_string(struct usbctl *ctl, struct usb_ctrlrequest *req,
8704 + struct usb_buf *buf;
8705 + unsigned int lang = le16_to_cpu(req->wIndex);
8706 + char string[32] __attribute__((unused));
8709 + DPRINTK("usbctl: desc_string (index %u, lang 0x%04x): ", idx, lang);
8711 + buf = usbc_string_find(&ctl->strings, lang, idx);
8713 + DPRINTK("%s\n", idx == 0 ? "language" :
8714 + psdesc(string, sizeof(string), usbc_string_desc(buf)));
8716 + ret = __usbctl_queue(ctl, req, buf);
8718 + DPRINTK("not found -> stall\n");
8719 + ret = RET_REQERROR;
8725 + * Send an interface description (and endpoints) to the host.
8728 +usbctl_desc_interface(struct usbctl *ctl, struct usb_ctrlrequest *req,
8731 + struct usb_interface_descriptor *desc;
8734 + DPRINTK("usbctl: desc_interface (index %d)\n", idx);
8736 + desc = usbctl_get_interface_descriptor(ctl, idx);
8739 + ret = usbctl_queue(ctl, req, desc, desc->bLength);
8741 + printk("usbctl: unknown interface %d\n", idx);
8742 + ret = RET_REQERROR;
8749 + * Send an endpoint (1 .. n) to the host.
8752 +usbctl_desc_endpoint(struct usbctl *ctl, struct usb_ctrlrequest *req,
8757 + DPRINTK("usbctl: desc_endpoint (index %d)\n", idx);
8759 + if (idx >= 1 && idx <= ctl->nr_ep) {
8760 + struct usb_endpoint_descriptor *ep = ctl->ep_desc[idx - 1];
8762 + ret = usbctl_queue(ctl, req, ep, ep->bLength);
8764 + printk("usbctl: unknown endpoint %d\n", idx);
8765 + ret = RET_REQERROR;
8772 + * 9.4.3: Parse a request for a descriptor.
8773 + * Unspecified conditions:
8775 + * Valid states: default, address, configured.
8778 +usbctl_parse_dev_descriptor(struct usbctl *ctl, struct usb_ctrlrequest *req)
8780 + unsigned int idx = le16_to_cpu(req->wValue) & 255;
8781 + unsigned int type = le16_to_cpu(req->wValue) >> 8;
8785 + case USB_DT_DEVICE: /* check if idx matters */
8786 + ret = usbctl_desc_device(ctl, req);
8789 + case USB_DT_CONFIG: /* check if idx matters */
8790 + ret = usbctl_desc_config(ctl, req);
8793 + case USB_DT_STRING:
8794 + ret = usbctl_desc_string(ctl, req, idx);
8797 + case USB_DT_INTERFACE:
8798 + ret = usbctl_desc_interface(ctl, req, idx);
8801 + case USB_DT_ENDPOINT:
8802 + ret = usbctl_desc_endpoint(ctl, req, idx);
8805 + case USB_DT_DEVICE_QUALIFIER:
8806 + case USB_DT_OTHER_SPEED_CONFIG:
8807 + case USB_DT_INTERFACE_POWER:
8809 + printk(KERN_ERR "usbctl: unknown descriptor: "
8810 + "wValue = 0x%04x wIndex = 0x%04x\n",
8811 + le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex));
8812 + ret = RET_REQERROR;
8820 + * 9.4.6: Set Address
8821 + * The USB1.1 spec says the response to SetAddress() with value 0
8822 + * is undefined. It then goes on to define the response. We
8823 + * acknowledge addresses of zero, but take no further action.
8826 +usbctl_parse_dev_set_address(struct usbctl *ctl, struct usb_ctrlrequest *req)
8828 + unsigned int address = le16_to_cpu(req->wValue) & 0x7f;
8830 + if (ctl->state == USB_STATE_CONFIGURED)
8831 + return RET_REQERROR;
8833 + if (address != 0) {
8834 + ctl->address = address;
8836 + usbctl_next_state_on_event(ctl, kEvAddress);
8838 + ctl->driver->set_address(ctl->driver->priv, address);
8845 + * 9.4.2: Get Configuration.
8846 + * Unspecified conditions:
8847 + * - non-zero wIndex, wValue or wLength (ignored)
8848 + * - default state (request error)
8849 + * Valid states: address, configured.
8852 +usbctl_parse_dev_get_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
8856 + if (ctl->state == USB_STATE_CONFIGURED)
8859 + return usbctl_queue(ctl, req, &status, 1);
8863 + * 9.4.7: Set Configuration.
8864 + * Unspecified conditions:
8865 + * - default state (request error)
8868 +usbctl_parse_dev_set_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
8870 + unsigned int cfg = le16_to_cpu(req->wValue);
8871 + int ret = RET_REQERROR;
8873 + if (ctl->state == USB_STATE_DEFAULT)
8877 + /* enter address state, or remain in address state */
8878 + usbctl_next_state_on_event(ctl, kEvDeConfig);
8880 + ctl->driver->set_config(ctl->driver->priv, NULL);
8883 + } else if (cfg == 1) {
8884 + /* enter configured state, and set configuration */
8886 + struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
8888 + usbctl_next_state_on_event(ctl, kEvConfig);
8890 + ctl->driver->set_config(ctl->driver->priv, cdb);
8898 + * Interface handling
8902 + * 9.4.5: Get Status (interface)
8905 +usbctl_parse_int_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
8907 + unsigned int interface = le16_to_cpu(req->wIndex) & 255;
8910 + switch (ctl->state) {
8911 + case USB_STATE_DEFAULT:
8912 + return RET_REQERROR;
8914 + case USB_STATE_ADDRESS:
8915 + if (interface != 0)
8916 + return RET_REQERROR;
8919 + case USB_STATE_CONFIGURED:
8920 + if (interface != 1)
8921 + return RET_REQERROR;
8925 + status = cpu_to_le16(0);
8927 + return usbctl_queue(ctl, req, &status, 2);
8931 + * 9.4.4: Get Interface
8932 + * Unspecified conditions:
8934 + * States: Default (unspecified), Address (Request Error), Configured (ok)
8937 +usbctl_parse_int_get_interface(struct usbctl *ctl, struct usb_ctrlrequest *req)
8939 + unsigned int interface = le16_to_cpu(req->wIndex) & 255;
8942 + if (ctl->state != USB_STATE_CONFIGURED)
8943 + return RET_REQERROR;
8946 + * If the interface doesn't exist, respond with request error
8948 + if (interface != 1)
8949 + return RET_REQERROR;
8951 + printk("usbctl: get interface %d not supported\n", interface);
8953 + return usbctl_queue(ctl, req, &null, 1);
8957 +usbctl_parse_int_set_interface(struct usbctl *ctl, struct usb_ctrlrequest *req)
8959 + unsigned int interface = le16_to_cpu(req->wIndex) & 255;
8961 + if (interface != 0)
8962 + printk("usbctl: set interface %d not supported (ignored)\n",
8969 + * Endpoint handling
8973 + * 9.4.5: Get Status (endpoint)
8976 +usbctl_parse_ep_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
8978 + unsigned int ep = le16_to_cpu(req->wIndex) & 15;
8981 + if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
8983 + return RET_REQERROR;
8985 + status = ctl->driver->ep_get_status(ctl->driver->priv, ep);
8986 + status = cpu_to_le16(status);
8988 + return usbctl_queue(ctl, req, &status, 2);
8992 + * 9.4.1: Clear an endpoint feature. We only support ENDPOINT_HALT.
8993 + * Unspecified conditions:
8994 + * - non-zero wLength is not specified (ignored)
8995 + * Valid states: Address, Configured.
8998 +usbctl_parse_ep_clear_feature(struct usbctl *ctl, struct usb_ctrlrequest *req)
9000 + unsigned int feature = le16_to_cpu(req->wValue);
9001 + unsigned int ep = le16_to_cpu(req->wIndex) & 15;
9004 + if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
9006 + return RET_REQERROR;
9008 + if (feature == USB_ENDPOINT_HALT) {
9009 + ctl->driver->ep_halt(ctl->driver->priv, ep, 0);
9012 + printk(KERN_ERR "usbctl: unsupported clear feature: "
9013 + "wValue = 0x%04x wIndex = 0x%04x\n",
9016 + ret = RET_REQERROR;
9022 + * 9.4.9: Set Feature (endpoint)
9025 +usbctl_parse_ep_set_feature(struct usbctl *ctl, struct usb_ctrlrequest *req)
9027 + unsigned int feature = le16_to_cpu(req->wValue);
9028 + unsigned int ep = le16_to_cpu(req->wIndex) & 15;
9031 + if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
9033 + return RET_REQERROR;
9035 + if (feature == USB_ENDPOINT_HALT) {
9036 + ctl->driver->ep_halt(ctl->driver->priv, ep, 1);
9039 + printk(KERN_ERR "usbctl: unsupported set feature "
9040 + "wValue = 0x%04x wIndex = 0x%04x\n",
9043 + ret = RET_REQERROR;
9049 + * This reflects Table 9.3 (p186) in the USB1.1 spec.
9052 + * - USB1.1 specifies remote wakeup feature, so we don't implement
9053 + * USB_RECIP_DEVICE USB_REQ_{SET,CLEAR}_FEATURE
9054 + * - USB1.1 doesn't actually specify any interface features, so we
9055 + * don't implement USB_RECIP_INTERFACE USB_REQ_{SET,CLEAR}_FEATURE
9057 +static int (*request_fns[4][16])(struct usbctl *, struct usb_ctrlrequest *) = {
9058 + [USB_RECIP_DEVICE] = {
9059 + [USB_REQ_GET_STATUS] = usbctl_parse_dev_get_status,
9060 + [USB_REQ_CLEAR_FEATURE] = NULL,
9061 + [USB_REQ_SET_FEATURE] = NULL,
9062 + [USB_REQ_SET_ADDRESS] = usbctl_parse_dev_set_address,
9063 + [USB_REQ_GET_DESCRIPTOR] = usbctl_parse_dev_descriptor,
9064 + [USB_REQ_SET_DESCRIPTOR] = NULL,
9065 + [USB_REQ_GET_CONFIGURATION] = usbctl_parse_dev_get_config,
9066 + [USB_REQ_SET_CONFIGURATION] = usbctl_parse_dev_set_config,
9069 + [USB_RECIP_INTERFACE] = {
9070 + [USB_REQ_GET_STATUS] = usbctl_parse_int_get_status,
9071 + [USB_REQ_CLEAR_FEATURE] = NULL,
9072 + [USB_REQ_SET_FEATURE] = NULL,
9073 + [USB_REQ_GET_INTERFACE] = usbctl_parse_int_get_interface,
9074 + [USB_REQ_SET_INTERFACE] = usbctl_parse_int_set_interface,
9077 + [USB_RECIP_ENDPOINT] = {
9078 + [USB_REQ_GET_STATUS] = usbctl_parse_ep_get_status,
9079 + [USB_REQ_CLEAR_FEATURE] = usbctl_parse_ep_clear_feature,
9080 + [USB_REQ_SET_FEATURE] = usbctl_parse_ep_set_feature,
9084 +static void __attribute__((unused))
9085 +usbctl_dump_request(const char *prefix, const struct usb_ctrlrequest *req)
9087 + printk("%sbRequestType=0x%02x bRequest=0x%02x "
9088 + "wValue=0x%04x wIndex=0x%04x wLength=0x%04x\n",
9089 + prefix, req->bRequestType, req->bRequest,
9090 + le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex),
9091 + le16_to_cpu(req->wLength));
9094 +int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req)
9096 + unsigned int type;
9097 + int (*fn)(struct usbctl *, struct usb_ctrlrequest *) = NULL;
9098 + int ret = RET_REQERROR;
9100 + //usbctl_dump_request("usbctl: ", req);
9102 + type = req->bRequestType & USB_TYPE_MASK;
9103 + if (type == USB_TYPE_STANDARD) {
9104 + unsigned int recip;
9106 + recip = req->bRequestType & USB_RECIP_MASK;
9107 + if (recip < ARRAY_SIZE(request_fns) &&
9108 + req->bRequest < ARRAY_SIZE(request_fns[0]))
9109 + fn = request_fns[recip][req->bRequest];
9113 + ret = fn(ctl, req);
9115 + usbctl_dump_request(KERN_ERR "usbctl: unknown request: ",
9119 + * Make sure we're doing the right thing.
9121 + if (req->bRequestType & USB_DIR_IN) {
9122 + if (ret != RET_QUEUED && ret != RET_REQERROR)
9123 + printk("Error: device to host transfer expected\n");
9125 + if (ret == RET_QUEUED)
9126 + printk("Error: no device to host transfer expected\n");
9132 +EXPORT_SYMBOL(usbctl_parse_request);
9134 +/* Start running. Must have called usb_open (above) first */
9135 +int usbctl_start(struct usb_client *client)
9137 + struct usbctl *ctl = client->ctl;
9139 + if (ctl == NULL || ctl->clnt != client) {
9140 + printk("usbctl: start: no client registered\n");
9144 + ctl->sm_state = kStateZombie;
9145 + ctl->state = USB_STATE_POWERED;
9148 + * Notify the client as to our state.
9150 + usbctl_callbacks(ctl, USB_STATE_POWERED, USB_STATE_SUSPENDED);
9152 + return ctl->driver->start(ctl->driver->priv);
9155 +EXPORT_SYMBOL(usbctl_start);
9158 + * Stop USB core from running
9160 +void usbctl_stop(struct usb_client *client)
9162 + struct usbctl *ctl = client->ctl;
9164 + if (ctl == NULL || ctl->clnt != client) {
9165 + printk("USBDEV: stop: no client/driver registered\n");
9169 + ctl->driver->stop(ctl->driver->priv);
9172 +EXPORT_SYMBOL(usbctl_stop);
9174 +struct usbctl usbctl;
9176 +EXPORT_SYMBOL(usbctl);
9178 +/* Open SA usb core on behalf of a client, but don't start running */
9180 +int usbctl_open(struct usb_client *client)
9182 + struct usbctl *ctl = &usbctl;
9184 +printk("usbctl_open: ctl %p driver %p\n", ctl, ctl->driver);
9185 + if (!ctl->driver || !try_module_get(ctl->driver->owner))
9188 + if (ctl->clnt != NULL) {
9193 + ctl->clnt = client;
9194 + ctl->state = USB_STATE_SUSPENDED;
9196 + /* start in zombie suspended state */
9197 + ctl->sm_state = kStateZombieSuspend;
9198 + ctl->state = USB_STATE_SUSPENDED;
9199 + client->ctl = ctl;
9201 + ctl->dev_desc_buf = usbb_alloc(sizeof(struct usb_device_descriptor),
9203 + if (!ctl->dev_desc_buf) {
9208 + ctl->dev_desc = usbb_push(ctl->dev_desc_buf,
9209 + sizeof(struct usb_device_descriptor));
9211 + /* create descriptors for enumeration */
9212 + initialize_descriptors(ctl);
9217 + module_put(ctl->driver->owner);
9221 +EXPORT_SYMBOL(usbctl_open);
9223 +/* Tell SA core client is through using it */
9224 +void usbctl_close(struct usb_client *client)
9226 + struct usbctl *ctl = client->ctl;
9228 + if (ctl == NULL || ctl->clnt != client) {
9229 + printk("usbctl: close: no client registered\n");
9233 + usbb_put(ctl->dev_desc_buf);
9235 + client->ctl = NULL;
9237 + ctl->dev_desc = NULL;
9238 + ctl->dev_desc_buf = NULL;
9239 + /* reset to zombie suspended state */
9240 + ctl->sm_state = kStateZombieSuspend;
9241 + ctl->state = USB_STATE_SUSPENDED;
9243 + usbc_string_free_all(&ctl->strings);
9245 + if (ctl->driver->owner)
9246 + module_put(ctl->driver->owner);
9249 +EXPORT_SYMBOL(usbctl_close);
9251 +int usbctl_proc_info(struct usbctl *ctl, char *buf)
9255 + p += sprintf(p, "USB Gadget Core:\n");
9256 + p += sprintf(p, "Driver\t: %s\n",
9257 + ctl->driver ? ctl->driver->name : "none");
9258 + p += sprintf(p, "Client\t: %s\n",
9259 + ctl->clnt ? ctl->clnt->name : "none");
9260 + p += sprintf(p, "State\t: %s (%s) %d\n",
9261 + device_state_names[sm_state_to_device_state[ctl->sm_state]],
9262 + state_names[ctl->sm_state],
9264 + p += sprintf(p, "Address\t: %d\n", ctl->address);
9269 +EXPORT_SYMBOL(usbctl_proc_info);
9272 +usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep,
9273 + char *buf, unsigned int len)
9275 + return ctl->driver->ep_queue(ctl->driver->priv, ep, buf, len);
9278 +EXPORT_SYMBOL(usbctl_ep_queue_buffer);
9280 +void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep)
9282 + return ctl->driver->ep_reset(ctl->driver->priv, ep);
9285 +EXPORT_SYMBOL(usbctl_ep_reset);
9288 +usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep,
9289 + usb_callback_t callback, void *data)
9291 + ctl->driver->ep_callback(ctl->driver->priv, ep, callback, data);
9294 +EXPORT_SYMBOL(usbctl_ep_set_callback);
9296 +int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep)
9298 + return ctl->driver->ep_idle(ctl->driver->priv, ep);
9301 +EXPORT_SYMBOL(usbctl_ep_idle);
9305 + * Module load time. Allocate dma and interrupt resources. Setup /proc fs
9306 + * entry. Leave UDC disabled.
9308 +int usbctl_init(struct usbctl *ctl, struct usbc_driver *drv)
9310 + usbc_string_init(&ctl->strings);
9311 +printk("usbctl_init: %p %p\n", ctl, drv);
9313 + * start in zombie suspended state
9315 + ctl->sm_state = kStateZombieSuspend;
9316 + ctl->state = USB_STATE_SUSPENDED;
9317 + ctl->driver = drv;
9325 +void usbctl_exit(struct usbctl *ctl)
9327 + usbc_string_free_all(&ctl->strings);
9329 + ctl->driver = NULL;
9332 +EXPORT_SYMBOL(usbctl_init);
9333 +EXPORT_SYMBOL(usbctl_exit);
9335 +MODULE_LICENSE("GPL");
9336 +MODULE_DESCRIPTION("USB gadget core");
9337 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9338 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/client.h 2004-04-30 20:57:36.000000000 -0400
9340 +#ifndef USBDEV_CLIENT_H
9341 +#define USBDEV_CLIENT_H
9343 +#include "sa1100_usb.h" /* grr */
9347 +struct usb_client {
9348 + struct usbctl *ctl;
9349 + const char *name; /* Client name */
9350 + void *priv; /* Client-private data */
9351 + void (*state_change)(void *priv, int state, int oldstate);
9352 + __u16 vendor; /* USB vendor ID */
9353 + __u16 product; /* USB product ID */
9354 + __u16 version; /* USB version ID */
9355 + __u8 class; /* USB class */
9356 + __u8 subclass; /* USB subclass */
9357 + __u8 protocol; /* USB protocol */
9360 + const char *manufacturer_str;
9361 + const char *product_str;
9362 + const char *serial_str;
9365 +int usbctl_start(struct usb_client *client);
9366 +void usbctl_stop(struct usb_client *client);
9367 +int usbctl_open(struct usb_client *client);
9368 +void usbctl_close(struct usb_client *client);
9371 +usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep,
9372 + char *buf, unsigned int len);
9373 +void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep);
9375 +usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep,
9376 + usb_callback_t callback, void *data);
9377 +int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep);
9380 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9381 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100_usb.h 2004-04-30 20:57:36.000000000 -0400
9386 + * Public interface to the sa1100 USB core. For use by client modules
9387 + * like usb-eth and usb-char.
9390 +#ifndef _SA1100_USB_H
9391 +#define _SA1100_USB_H
9393 +typedef void (*usb_callback_t)(void *data, int flag, int size);
9395 +/* in usb_send.c */
9396 +int sa1100_usb_xmitter_avail( void );
9397 +int sa1100_usb_send(char *buf, int len);
9398 +void sa1100_usb_send_set_callback(usb_callback_t callback, void *data);
9399 +void sa1100_usb_send_reset(void);
9401 +/* in usb_recev.c */
9402 +int sa1100_usb_recv(char *buf, int len);
9403 +void sa1100_usb_recv_set_callback(usb_callback_t callback, void *data);
9404 +void sa1100_usb_recv_reset(void);
9406 +//////////////////////////////////////////////////////////////////////////////
9407 +// Descriptor Management
9408 +//////////////////////////////////////////////////////////////////////////////
9411 +#define USB_POWER(x) ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
9413 +/* "config descriptor buffer" - that is, one config,
9414 + ..one interface and 2 endpoints */
9416 + struct usb_config_descriptor cfg;
9417 + struct usb_interface_descriptor intf;
9418 + struct usb_endpoint_descriptor ep1, ep2;
9419 +} __attribute__ ((packed));
9422 +/*=======================================================
9426 +/* Get the address of the statically allocated desc_t structure
9427 + in the usb core driver. Clients can modify this between
9428 + the time they call sa1100_usb_open() and sa1100_usb_start()
9430 +struct cdb *sa1100_usb_get_descriptor_ptr(void);
9432 +#endif /* _SA1100_USB_H */
9433 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9434 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100usb.h 2004-04-30 20:57:36.000000000 -0400
9437 + * Copyright (C) Compaq Computer Corporation, 1998, 1999
9438 + * Copyright (C) Extenex Corporation 2001
9442 + * PRIVATE interface used to share info among components of the SA-1100 USB
9443 + * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
9444 + * should use sa1100_usb.h.
9447 +#ifndef SA1100USB_H
9448 +#define SA1100USB_H
9453 + struct device *dev;
9454 + struct usbctl *ctl;
9460 + * EP0 write thread.
9462 + void (*wrint)(struct sausb_dev *);
9463 + struct usb_buf *wrbuf;
9464 + unsigned char *wrptr;
9465 + unsigned int wrlen;
9470 + unsigned long ep0_wr_fifo_errs;
9471 + unsigned long ep0_wr_bytes;
9472 + unsigned long ep0_wr_packets;
9473 + unsigned long ep0_rd_fifo_errs;
9474 + unsigned long ep0_rd_bytes;
9475 + unsigned long ep0_rd_packets;
9476 + unsigned long ep0_stall_sent;
9477 + unsigned long ep0_early_irqs;
9483 + dma_regs_t *dmach;
9485 + dma_addr_t bufdma;
9486 + unsigned int buflen;
9488 + dma_addr_t pktdma;
9489 + unsigned int pktlen;
9490 + unsigned int pktrem;
9493 + void (*cb_func)(void *data, int flag, int size);
9496 + unsigned int maxpktsize;
9497 + unsigned int configured;
9498 + unsigned int host_halt;
9499 + unsigned long fifo_errs;
9500 + unsigned long bytes;
9501 + unsigned long packets;
9506 +int ep1_recv(void);
9507 +void udc_ep1_init(struct sausb_dev *);
9508 +void udc_ep1_halt(struct sausb_dev *, int);
9509 +void udc_ep1_reset(struct sausb_dev *);
9510 +void udc_ep1_config(struct sausb_dev *, unsigned int);
9511 +void udc_ep1_int_hndlr(struct sausb_dev *);
9514 +void udc_ep2_init(struct sausb_dev *);
9515 +void udc_ep2_halt(struct sausb_dev *, int);
9516 +void udc_ep2_reset(struct sausb_dev *);
9517 +void udc_ep2_config(struct sausb_dev *, unsigned int);
9518 +void udc_ep2_int_hndlr(struct sausb_dev *);
9520 +#define UDC_write(reg, val) do { \
9525 + printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
9526 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9529 + } while((reg) != (val)); \
9532 +#define UDC_set(reg, val) do { \
9537 + printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
9538 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9541 + } while(!((reg) & (val))); \
9544 +#define UDC_clear(reg, val) do { \
9547 + (reg) &= ~(val); \
9549 + printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
9550 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9553 + } while((reg) & (val)); \
9556 +#define UDC_flip(reg, val) do { \
9562 + printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
9563 + __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9566 + } while(((reg) & (val))); \
9569 +#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
9572 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9573 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/strings.c 2004-04-30 20:57:36.000000000 -0400
9578 + * Copyright (C) 2002 Russell King.
9580 +#include <linux/module.h>
9581 +#include <linux/slab.h>
9582 +#include <linux/errno.h>
9583 +#include <linux/spinlock.h>
9584 +#include <linux/string.h>
9585 +#include <linux/usb_ch9.h>
9587 +#include "buffer.h"
9588 +#include "strings.h"
9590 +struct usb_buf *usbc_string_alloc(int len)
9592 + struct usb_buf *buf;
9595 + tot_len = sizeof(struct usb_descriptor_header) + sizeof(u16) * len;
9597 + buf = usbb_alloc(tot_len, GFP_KERNEL);
9600 + struct usb_string_descriptor *desc = usbb_push(buf, tot_len);
9602 + desc->bLength = tot_len;
9603 + desc->bDescriptorType = USB_DT_STRING;
9608 +void usbc_string_free(struct usb_buf *buf)
9614 +void usbc_string_from_cstr(struct usb_buf *buf, const char *str)
9616 + struct usb_string_descriptor *desc = usbc_string_desc(buf);
9619 + len = strlen(str);
9620 + BUG_ON((sizeof(__u16) * len) > desc->bLength - sizeof(struct usb_descriptor_header));
9622 + for (i = 0; i < len; i++)
9623 + desc->wData[i] = cpu_to_le16(str[i]);
9626 +int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf)
9631 + spin_lock_irq(&table->lock);
9632 + for (i = 0; i < NR_STRINGS; i++)
9633 + if (table->buf[i] == NULL) {
9634 + table->buf[i] = buf;
9638 + spin_unlock_irq(&table->lock);
9643 +void usbc_string_del(struct usbc_strs *table, int nr)
9645 + if (nr < NR_STRINGS) {
9646 + spin_lock_irq(&table->lock);
9647 + table->buf[nr] = NULL;
9648 + spin_unlock_irq(&table->lock);
9653 +usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx)
9655 + struct usb_buf *buf = NULL;
9657 + if (idx < NR_STRINGS) {
9658 + spin_lock_irq(&table->lock);
9659 + buf = usbb_get(table->buf[idx]);
9660 + spin_unlock_irq(&table->lock);
9666 +void usbc_string_free_all(struct usbc_strs *table)
9670 + spin_lock_irq(&table->lock);
9671 + for (i = 0; i < NR_STRINGS; i++) {
9672 + usbc_string_free(table->buf[i]);
9673 + table->buf[i] = NULL;
9675 + spin_unlock_irq(&table->lock);
9678 +void usbc_string_init(struct usbc_strs *table)
9680 + memset(table, 0, sizeof(struct usbc_strs));
9681 + spin_lock_init(&table->lock);
9684 +EXPORT_SYMBOL(usbc_string_from_cstr);
9685 +EXPORT_SYMBOL(usbc_string_alloc);
9686 +EXPORT_SYMBOL(usbc_string_free);
9687 +EXPORT_SYMBOL(usbc_string_add);
9688 +EXPORT_SYMBOL(usbc_string_del);
9689 +EXPORT_SYMBOL(usbc_string_find);
9690 +EXPORT_SYMBOL(usbc_string_free_all);
9691 +EXPORT_SYMBOL(usbc_string_init);
9692 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9693 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_ctl.c 2004-04-30 20:57:36.000000000 -0400
9696 + * Copyright (C) Compaq Computer Corporation, 1998, 1999
9697 + * Copyright (C) Extenex Corporation, 2001
9701 + * SA1100 USB controller core driver.
9703 + * This file provides interrupt routing and overall coordination
9704 + * of the three endpoints in usb_ep0, usb_receive (1), and usb_send (2).
9706 + * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
9709 +#include <linux/module.h>
9710 +#include <linux/errno.h>
9711 +#include <linux/usb.h>
9713 +#include "buffer.h"
9714 +#include "client.h"
9715 +#include "usbdev.h"
9716 +#include "sa1100_usb.h"
9718 +//////////////////////////////////////////////////////////////////////////////
9720 +//////////////////////////////////////////////////////////////////////////////
9722 +/* device descriptors */
9723 +static struct cdb cdb;
9725 +//////////////////////////////////////////////////////////////////////////////
9727 +//////////////////////////////////////////////////////////////////////////////
9729 +int sa1100_usb_add_string(struct usbctl *ctl, const char *str)
9734 + struct usb_buf *buf;
9737 + len = strlen(str);
9740 + buf = usbc_string_alloc(len);
9742 + usbc_string_from_cstr(buf, str);
9743 + nr = usbc_string_add(&ctl->strings, buf);
9746 + usbc_string_free(buf);
9753 +EXPORT_SYMBOL(sa1100_usb_add_string);
9755 +static int sa1100_usb_add_language(struct usbctl *ctl, unsigned int lang)
9757 + struct usb_buf *buf;
9760 + buf = usbc_string_alloc(1);
9762 + usbc_string_desc(buf)->wData[0] = cpu_to_le16(lang); /* American English */
9763 + nr = usbc_string_add(&ctl->strings, buf);
9766 + usbc_string_free(buf);
9772 +/* setup default descriptors */
9774 +void initialize_descriptors(struct usbctl *ctl)
9776 + struct usb_client *clnt = ctl->clnt;
9779 + ctl->ep_desc[0] = (struct usb_endpoint_descriptor *)&cdb.ep1;
9780 + ctl->ep_desc[1] = (struct usb_endpoint_descriptor *)&cdb.ep2;
9782 + cdb.cfg.bLength = USB_DT_CONFIG_SIZE;
9783 + cdb.cfg.bDescriptorType = USB_DT_CONFIG;
9784 + cdb.cfg.wTotalLength = cpu_to_le16(sizeof(struct cdb));
9785 + cdb.cfg.bNumInterfaces = 1;
9786 + cdb.cfg.bConfigurationValue = 1;
9787 + cdb.cfg.iConfiguration = 0;
9788 + cdb.cfg.bmAttributes = USB_CONFIG_ATT_ONE;
9789 + cdb.cfg.bMaxPower = USB_POWER( 500 );
9791 + cdb.intf.bLength = USB_DT_INTERFACE_SIZE;
9792 + cdb.intf.bDescriptorType = USB_DT_INTERFACE;
9793 + cdb.intf.bInterfaceNumber = 0; /* unique intf index*/
9794 + cdb.intf.bAlternateSetting = 0;
9795 + cdb.intf.bNumEndpoints = 2;
9796 + cdb.intf.bInterfaceClass = 0xff; /* vendor specific */
9797 + cdb.intf.bInterfaceSubClass = 0;
9798 + cdb.intf.bInterfaceProtocol = 0;
9799 + cdb.intf.iInterface = 0;
9801 + cdb.ep1.bLength = USB_DT_INTERFACE_SIZE;
9802 + cdb.ep1.bDescriptorType = USB_DT_ENDPOINT;
9803 + cdb.ep1.bEndpointAddress = USB_DIR_OUT | 1;
9804 + cdb.ep1.bmAttributes = USB_ENDPOINT_XFER_BULK;
9805 + cdb.ep1.wMaxPacketSize = cpu_to_le16(64);
9806 + cdb.ep1.bInterval = 0;
9808 + cdb.ep2.bLength = USB_DT_INTERFACE_SIZE;
9809 + cdb.ep2.bDescriptorType = USB_DT_ENDPOINT;
9810 + cdb.ep2.bEndpointAddress = USB_DIR_IN | 2;
9811 + cdb.ep2.bmAttributes = USB_ENDPOINT_XFER_BULK;
9812 + cdb.ep2.wMaxPacketSize = cpu_to_le16(64);
9813 + cdb.ep2.bInterval = 0;
9815 + ctl->dev_desc->bLength = USB_DT_DEVICE_SIZE;
9816 + ctl->dev_desc->bDescriptorType = USB_DT_DEVICE;
9817 + ctl->dev_desc->bcdUSB = cpu_to_le16(0x100); /* 1.0 */
9818 + ctl->dev_desc->bDeviceClass = clnt->class;
9819 + ctl->dev_desc->bDeviceSubClass = clnt->subclass;
9820 + ctl->dev_desc->bDeviceProtocol = clnt->protocol;
9821 + ctl->dev_desc->bMaxPacketSize0 = 8; /* ep0 max fifo size */
9822 + ctl->dev_desc->idVendor = cpu_to_le16(clnt->vendor);
9823 + ctl->dev_desc->idProduct = cpu_to_le16(clnt->product);
9824 + ctl->dev_desc->bcdDevice = cpu_to_le16(clnt->version);
9825 + ctl->dev_desc->bNumConfigurations = 1;
9827 + /* set language */
9828 + /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
9829 + r = sa1100_usb_add_language(ctl, 0x409);
9831 + printk(KERN_ERR "usbc: couldn't add language\n");
9833 + r = sa1100_usb_add_string(ctl, clnt->manufacturer_str);
9835 + printk(KERN_ERR "usbc: couldn't add manufacturer string\n");
9837 + ctl->dev_desc->iManufacturer = r > 0 ? r : 0;
9839 + r = sa1100_usb_add_string(ctl, clnt->product_str);
9841 + printk(KERN_ERR "usbc: couldn't add product string\n");
9843 + ctl->dev_desc->iProduct = r > 0 ? r : 0;
9845 + r = sa1100_usb_add_string(ctl, clnt->serial_str);
9847 + printk(KERN_ERR "usbc: couldn't add serial string\n");
9849 + ctl->dev_desc->iSerialNumber = r > 0 ? r : 0;
9853 +/*====================================================
9854 + * Descriptor Manipulation.
9855 + * Use these between open() and start() above to setup
9856 + * the descriptors for your device.
9859 +/* get pointer to static default descriptor */
9860 +struct cdb *sa1100_usb_get_descriptor_ptr(void)
9865 +EXPORT_SYMBOL(sa1100_usb_get_descriptor_ptr);
9866 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9867 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/Makefile 2004-04-30 20:57:36.000000000 -0400
9870 +# Makefile for the USB client
9873 +usbdevcore-objs := buffer.o control.o strings.o usb_ctl.o
9875 +sa1100-objs := sa1100usb.o usb_recv.o usb_send.o
9877 +obj-$(CONFIG_SA1100_USB) += usbdevcore.o sa1100.o
9878 +obj-$(CONFIG_SA1100_USB_NETLINK) += usb-eth.o
9879 +obj-$(CONFIG_SA1100_USB_CHAR) += usb-char.o
9881 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9882 +++ linux-2.6.5/arch/arm/mach-sa1100/usb/usbdev.h 2004-04-30 20:57:36.000000000 -0400
9887 +#include "strings.h"
9894 +struct usbc_driver {
9895 + struct module *owner;
9898 + int (*start)(void *);
9899 + int (*stop)(void *);
9901 + int (*ep0_queue)(void *, struct usb_buf *buf, unsigned int req_len);
9902 + void (*set_address)(void *, unsigned int addr);
9903 + void (*set_config)(void *, struct cdb *config);
9906 + * Get specified endpoint status, as defined in 9.4.5.
9908 + unsigned int (*ep_get_status)(void *, unsigned int ep);
9909 + void (*ep_halt)(void *, unsigned int ep, int halt);
9914 + int (*ep_queue)(void *, unsigned int, char *, unsigned int);
9915 + void (*ep_reset)(void *, unsigned int);
9916 + void (*ep_callback)(void *, unsigned int, void (*)(void *, int, int), void *);
9917 + int (*ep_idle)(void *, unsigned int);
9920 +struct usbc_endpoint {
9921 + struct usb_endpoint_descriptor *desc;
9924 +struct usbc_interface {
9925 + struct usb_interface_descriptor *desc;
9926 + unsigned int nr_ep;
9927 + struct usbc_endpoint *ep[0];
9930 +struct usbc_config {
9931 + struct usb_config_descriptor *desc;
9932 + unsigned int nr_interface;
9933 + struct usbc_interface *interface[0];
9937 + struct usb_client *clnt;
9938 + const struct usbc_driver *driver;
9940 + /* Internal state */
9941 + unsigned int address; /* host assigned address */
9942 + unsigned int state; /* our device state */
9943 + unsigned int sm_state; /* state machine state */
9945 + struct usbc_config *config; /* active configuration */
9946 + struct usbc_strs strings;
9949 + struct usb_device_descriptor *dev_desc; /* device descriptor */
9950 + struct usb_buf *dev_desc_buf; /* device descriptor buffer */
9954 + struct usb_endpoint_descriptor *ep_desc[2];
9958 + * Function Prototypes
9961 +#define RET_ERROR (-1)
9962 +#define RET_NOACTION (0)
9963 +#define RET_QUEUED (1)
9964 +#define RET_ACK (2)
9965 +#define RET_REQERROR (3)
9967 +int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req);
9969 +int usbctl_reset(struct usbctl *ctl);
9970 +void usbctl_suspend(struct usbctl *ctl);
9971 +void usbctl_resume(struct usbctl *ctl);
9975 --- linux-2.6.5/arch/arm/mach-sa1100/pm.c~heh 2004-04-03 22:36:27.000000000 -0500
9976 +++ linux-2.6.5/arch/arm/mach-sa1100/pm.c 2004-04-30 20:57:36.000000000 -0400
9979 static int sa11x0_pm_prepare(u32 state)
9981 + nmi_watchdog_disable();
9987 static int sa11x0_pm_finish(u32 state)
9989 + nmi_watchdog_enable();
9993 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
9994 +++ linux-2.6.5/arch/arm/mach-sa1100/nmi-oopser.c 2004-04-30 20:57:36.000000000 -0400
9996 +#include <linux/kernel.h>
9997 +#include <linux/init.h>
9998 +#include <linux/sched.h>
9999 +#include <linux/errno.h>
10000 +#include <linux/gfp.h>
10001 +#include <linux/module.h>
10002 +#include <linux/delay.h>
10004 +#include <asm/ptrace.h>
10005 +#include <asm/domain.h>
10006 +#include <asm/hardware.h>
10008 +static void *nmi_stack;
10013 + ldr r9, .Lstack \n\
10015 + sub sp, sp, #18 * 4 \n\
10016 + str r8, [sp, #16 * 4] \n\
10017 + str lr, [sp, #15 * 4] \n\
10018 + stmia sp, {r0 - r7} \n\
10019 + add r0, sp, #8 * 4 \n\
10021 + bic r1, r2, #0x1f \n\
10022 + orr r1, r1, #0x13 \n\
10023 + msr cpsr_c, r1 \n\
10025 + stmia r0, {r8 - lr} \n\
10027 + msr cpsr_c, r2 \n\
10032 + ldmia sp, {r0 - r7} \n\
10033 + ldr r8, [sp, #16 * 4] \n\
10034 + ldr lr, [sp, #15 * 4] \n\
10035 + add sp, sp, #18 * 4 \n\
10039 +.Lstack: .long nmi_stack \n\
10040 +.Lfn: .long nmi_fn \n\
10043 +extern unsigned char nmi_start, nmi_end;
10045 +static void __attribute__((unused)) nmi_fn(struct pt_regs *regs)
10047 + struct thread_info *thread;
10048 + unsigned long osmr0, osmr1, oscr, ossr, icmr, icip;
10058 + ICMR &= ~IC_OST1;
10060 + thread = (struct thread_info *)(regs->ARM_sp & ~8191);
10062 + bust_spinlocks(1);
10063 + printk("OSMR0:%08lx OSMR1:%08lx OSCR:%08lx OSSR:%08lx ICMR:%08lx ICIP:%08lx\n",
10064 + osmr0, osmr1, oscr, ossr, icmr, icip);
10065 + nmi_watchdog(thread, regs);
10066 + bust_spinlocks(0);
10069 + OSMR1 = OSSR + 36864000;
10073 +static int nmi_init(void)
10075 + unsigned char *vec_base = (unsigned char *)vectors_base();
10077 + nmi_stack = (void *)__get_free_page(GFP_KERNEL);
10081 + nmi_stack += PAGE_SIZE;
10083 + modify_domain(DOMAIN_USER, DOMAIN_MANAGER);
10084 + memcpy(vec_base + 0x1c, &nmi_start, &nmi_end - &nmi_start);
10085 + modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
10088 + * Ensure timer 1 is set to FIQ, and enabled.
10090 + OSMR1 = OSCR - 1;
10099 +__initcall(nmi_init);
10100 --- linux-2.6.5/drivers/media/Kconfig~heh 2004-04-03 22:36:51.000000000 -0500
10101 +++ linux-2.6.5/drivers/media/Kconfig 2004-04-30 20:57:36.000000000 -0400
10104 source "drivers/media/common/Kconfig"
10106 +source "drivers/media/mmc/Kconfig"
10110 default y if VIDEO_BT848=y || VIDEO_SAA7134=y || VIDEO_MXB=y || VIDEO_CX88=y
10111 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
10112 +++ linux-2.6.5/drivers/media/mmc/Kconfig 2004-04-30 20:57:36.000000000 -0400
10115 +# MMC subsystem configuration
10118 +menu "MMC/SD Card support"
10121 + tristate "MMC support"
10123 + MMC is the "multi-media card" bus protocol.
10125 + If you want MMC support, you should say Y here and also
10126 + to the specific driver for your MMC interface.
10129 + bool "MMC debugging"
10130 + depends on MMC != n
10132 + This is an option for use by developers; most people should
10133 + say N here. This enables MMC core and driver debugging.
10136 + tristate "MMC block device driver"
10140 + Say Y here to enable the MMC block device driver support.
10141 + This provides a block device driver, which you can use to
10142 + mount the filesystem. Almost everyone wishing MMC support
10143 + should say Y or M here.
10145 +config MMC_ARMMMCI
10146 + tristate "ARM AMBA Multimedia Card Interface support"
10147 + depends on ARM_AMBA && MMC
10149 + This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
10150 + Interface (PL180 and PL181) support. If you have an ARM(R)
10151 + platform with a Multimedia Card slot, say Y or M here.
10153 + If unsure, say N.
10156 + tristate "Intel PXA255 Multimedia Card Interface support"
10157 + depends on ARCH_PXA && MMC
10159 + This selects the Intel(R) PXA(R) Multimedia card Interface.
10160 + If you have a PXA(R) platform with a Multimedia Card slot,
10163 + If unsure, say N.
10166 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
10167 +++ linux-2.6.5/drivers/media/mmc/mmc_queue.c 2004-04-30 20:57:36.000000000 -0400
10170 + * linux/drivers/media/mmc/mmc_queue.c
10172 + * Copyright (C) 2003 Russell King, All Rights Reserved.
10174 + * This program is free software; you can redistribute it and/or modify
10175 + * it under the terms of the GNU General Public License version 2 as
10176 + * published by the Free Software Foundation.
10179 +#include <linux/module.h>
10180 +#include <linux/blkdev.h>
10182 +#include <linux/mmc/card.h>
10183 +#include <linux/mmc/host.h>
10184 +#include "mmc_queue.h"
10187 + * Prepare a MMC request. Essentially, this means passing the
10188 + * preparation off to the media driver. The media driver will
10189 + * create a mmc_io_request in req->special.
10191 +static int mmc_prep_request(struct request_queue *q, struct request *req)
10193 + struct mmc_queue *mq = q->queuedata;
10194 + int ret = BLKPREP_KILL;
10196 + if (req->flags & REQ_SPECIAL) {
10198 + * Special commands already have the command
10199 + * blocks already setup in req->special.
10201 + BUG_ON(!req->special);
10203 + ret = BLKPREP_OK;
10204 + } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
10206 + * Block I/O requests need translating according
10207 + * to the protocol.
10209 + ret = mq->prep_fn(mq, req);
10212 + * Everything else is invalid.
10214 + blk_dump_rq_flags(req, "MMC bad request");
10217 + if (ret == BLKPREP_OK)
10218 + req->flags |= REQ_DONTPREP;
10223 +static int mmc_queue_thread(void *d)
10225 + struct mmc_queue *mq = d;
10226 + struct request_queue *q = mq->queue;
10227 + DECLARE_WAITQUEUE(wait, current);
10231 + * Set iothread to ensure that we aren't put to sleep by
10232 + * the process freezing. We handle suspension ourselves.
10234 + current->flags |= PF_MEMALLOC|PF_IOTHREAD;
10236 + daemonize("mmcqd");
10238 + spin_lock_irq(¤t->sighand->siglock);
10239 + sigfillset(¤t->blocked);
10240 + recalc_sigpending();
10241 + spin_unlock_irq(¤t->sighand->siglock);
10243 + mq->thread = current;
10244 + complete(&mq->thread_complete);
10246 + add_wait_queue(&mq->thread_wq, &wait);
10247 + spin_lock_irq(q->queue_lock);
10249 + struct request *req = NULL;
10251 + set_current_state(TASK_INTERRUPTIBLE);
10252 + if (!blk_queue_plugged(q))
10253 + mq->req = req = elv_next_request(q);
10254 + spin_unlock(q->queue_lock);
10262 + set_current_state(TASK_RUNNING);
10264 + ret = mq->issue_fn(mq, req);
10266 + spin_lock_irq(q->queue_lock);
10267 + end_request(req, ret);
10269 + remove_wait_queue(&mq->thread_wq, &wait);
10271 + complete_and_exit(&mq->thread_complete, 0);
10276 + * Generic MMC request handler. This is called for any queue on a
10277 + * particular host. When the host is not busy, we look for a request
10278 + * on any queue on this host, and attempt to issue it. This may
10279 + * not be the queue we were asked to process.
10281 +static void mmc_request(request_queue_t *q)
10283 + struct mmc_queue *mq = q->queuedata;
10285 + if (!mq->req && !blk_queue_plugged(q))
10286 + wake_up(&mq->thread_wq);
10290 + * mmc_init_queue - initialise a queue structure.
10292 + * @card: mmc card to attach this queue
10293 + * @lock: queue lock
10295 + * Initialise a MMC card request queue.
10297 +int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
10299 + u64 limit = BLK_BOUNCE_HIGH;
10302 + if (card->host->dev->dma_mask)
10303 + limit = *card->host->dev->dma_mask;
10306 + mq->queue = blk_init_queue(mmc_request, lock);
10307 + blk_queue_prep_rq(mq->queue, mmc_prep_request);
10308 + blk_queue_bounce_limit(mq->queue, limit);
10310 + mq->queue->queuedata = mq;
10313 + init_completion(&mq->thread_complete);
10314 + init_waitqueue_head(&mq->thread_wq);
10316 + ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL);
10318 + blk_cleanup_queue(mq->queue);
10320 + wait_for_completion(&mq->thread_complete);
10321 + init_completion(&mq->thread_complete);
10327 +EXPORT_SYMBOL(mmc_init_queue);
10329 +void mmc_cleanup_queue(struct mmc_queue *mq)
10331 + mq->thread = NULL;
10332 + wake_up(&mq->thread_wq);
10333 + wait_for_completion(&mq->thread_complete);
10334 + blk_cleanup_queue(mq->queue);
10339 +EXPORT_SYMBOL(mmc_cleanup_queue);
10340 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
10341 +++ linux-2.6.5/drivers/media/mmc/pxamci.c 2004-04-30 20:57:36.000000000 -0400
10344 + * linux/drivers/media/mmc/pxa.c - PXA MMCI driver
10346 + * Copyright (C) 2003 Russell King, All Rights Reserved.
10348 + * This program is free software; you can redistribute it and/or modify
10349 + * it under the terms of the GNU General Public License version 2 as
10350 + * published by the Free Software Foundation.
10352 + * This hardware is really sick. No way to clear interrupts. Have
10353 + * to turn off the clock whenever we touch the device. Yuck!
10355 + * 1 and 3 byte data transfers not supported
10356 + * max block length up to 1023
10358 +#include <linux/config.h>
10359 +#include <linux/module.h>
10360 +#include <linux/init.h>
10361 +#include <linux/ioport.h>
10362 +#include <linux/device.h>
10363 +#include <linux/interrupt.h>
10364 +#include <linux/blkdev.h>
10365 +#include <linux/dma-mapping.h>
10366 +#include <linux/mmc/host.h>
10367 +#include <linux/mmc/protocol.h>
10369 +#include <asm/dma.h>
10370 +#include <asm/io.h>
10371 +#include <asm/irq.h>
10372 +#include <asm/sizes.h>
10374 +#include "pxamci.h"
10376 +#ifdef CONFIG_MMC_DEBUG
10377 +#define DBG(x...) printk(KERN_DEBUG x)
10379 +#define DBG(x...) do { } while (0)
10382 +struct pxamci_host {
10383 + struct mmc_host mmc;
10385 + struct resource *res;
10389 + unsigned int clkrt;
10390 + unsigned int cmdat;
10391 + unsigned int imask;
10392 + unsigned int power_mode;
10394 + struct mmc_request *req;
10395 + struct mmc_command *cmd;
10396 + struct mmc_data *data;
10398 + dma_addr_t sg_dma;
10399 + struct pxa_dma_desc *sg_cpu;
10401 + dma_addr_t dma_buf;
10402 + unsigned int dma_size;
10403 + unsigned int dma_dir;
10406 +#define to_pxamci_host(x) container_of(x, struct pxamci_host, mmc)
10409 + * The base MMC clock rate
10411 +#define CLOCKRATE 20000000
10413 +static inline unsigned int ns_to_clocks(unsigned int ns)
10415 + return (ns * (CLOCKRATE / 1000000) + 999) / 1000;
10418 +static void pxamci_stop_clock(struct pxamci_host *host)
10420 + if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
10421 + unsigned long flags;
10424 + writel(STOP_CLOCK, host->base + MMC_STRPCL);
10427 + * Wait for the "clock has stopped" interrupt.
10428 + * We need to unmask the interrupt to receive
10429 + * the notification. Sigh.
10431 + spin_lock_irqsave(&host->lock, flags);
10432 + writel(host->imask & ~CLK_IS_OFF, host->base + MMC_I_MASK);
10434 + v = readl(host->base + MMC_I_REG);
10435 + } while (!(v & CLK_IS_OFF));
10436 + writel(host->imask, host->base + MMC_I_MASK);
10437 + spin_unlock_irqrestore(&host->lock, flags);
10441 +static void pxamci_enable_irq(struct pxamci_host *host, unsigned int mask)
10443 + unsigned long flags;
10445 + spin_lock_irqsave(&host->lock, flags);
10446 + host->imask &= ~mask;
10447 + writel(host->imask, host->base + MMC_I_MASK);
10448 + spin_unlock_irqrestore(&host->lock, flags);
10451 +static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask)
10453 + unsigned long flags;
10455 + spin_lock_irqsave(&host->lock, flags);
10456 + host->imask |= mask;
10457 + writel(host->imask, host->base + MMC_I_MASK);
10458 + spin_unlock_irqrestore(&host->lock, flags);
10461 +static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
10463 + unsigned int nob = data->blocks;
10464 + unsigned int timeout, size;
10469 + host->data = data;
10471 + if (data->flags & MMC_DATA_STREAM)
10474 + writel(nob, host->base + MMC_NOB);
10475 + writel(1 << data->blksz_bits, host->base + MMC_BLKLEN);
10477 + timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks;
10478 + writel((timeout + 255) / 256, host->base + MMC_RDTO);
10480 + if (data->flags & MMC_DATA_READ) {
10481 + host->dma_dir = DMA_FROM_DEVICE;
10482 + dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG;
10484 + DRCMRRXMMC = host->dma | DRCMR_MAPVLD;
10486 + host->dma_dir = DMA_TO_DEVICE;
10487 + dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC;
10489 + DRCMRTXMMC = host->dma | DRCMR_MAPVLD;
10492 + dcmd |= DCMD_BURST32 | DCMD_WIDTH1;
10494 + host->dma_size = data->blocks << data->blksz_bits;
10495 + host->dma_buf = dma_map_single(host->mmc.dev, data->rq->buffer,
10496 + host->dma_size, host->dma_dir);
10498 + for (i = 0, size = host->dma_size, dma = host->dma_buf; size; i++) {
10501 + if (len > DCMD_LENGTH)
10504 + if (data->flags & MMC_DATA_READ) {
10505 + host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
10506 + host->sg_cpu[i].dtadr = dma;
10508 + host->sg_cpu[i].dsadr = dma;
10509 + host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
10511 + host->sg_cpu[i].dcmd = dcmd | len;
10517 + host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
10518 + sizeof(struct pxa_dma_desc);
10520 + host->sg_cpu[i].ddadr = DDADR_STOP;
10525 + DDADR(host->dma) = host->sg_dma;
10526 + DCSR(host->dma) = DCSR_RUN;
10529 +static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
10531 + WARN_ON(host->cmd != NULL);
10534 + if (cmd->flags & MMC_RSP_BUSY)
10535 + cmdat |= CMDAT_BUSY;
10537 + switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) {
10538 + case MMC_RSP_SHORT | MMC_RSP_CRC:
10539 + cmdat |= CMDAT_RESP_SHORT;
10541 + case MMC_RSP_SHORT:
10542 + cmdat |= CMDAT_RESP_R3;
10544 + case MMC_RSP_LONG | MMC_RSP_CRC:
10545 + cmdat |= CMDAT_RESP_R2;
10551 + writel(cmd->opcode, host->base + MMC_CMD);
10552 + writel(cmd->arg >> 16, host->base + MMC_ARGH);
10553 + writel(cmd->arg & 0xffff, host->base + MMC_ARGL);
10554 + writel(cmdat, host->base + MMC_CMDAT);
10555 + writel(host->clkrt, host->base + MMC_CLKRT);
10557 + writel(START_CLOCK, host->base + MMC_STRPCL);
10559 + pxamci_enable_irq(host, END_CMD_RES);
10562 +static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *req)
10564 + DBG("PXAMCI: request done\n");
10565 + host->req = NULL;
10566 + host->cmd = NULL;
10567 + host->data = NULL;
10568 + mmc_request_done(&host->mmc, req);
10571 +static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
10573 + struct mmc_command *cmd = host->cmd;
10580 + host->cmd = NULL;
10583 + * Did I mention this is Sick. We always need to
10584 + * discard the upper 8 bits of the first 16-bit word.
10586 + v = readl(host->base + MMC_RES) & 0xffff;
10587 + for (i = 0; i < 4; i++) {
10588 + u32 w1 = readl(host->base + MMC_RES) & 0xffff;
10589 + u32 w2 = readl(host->base + MMC_RES) & 0xffff;
10590 + cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8;
10594 + if (stat & STAT_TIME_OUT_RESPONSE) {
10595 + cmd->error = MMC_ERR_TIMEOUT;
10596 + } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
10597 + cmd->error = MMC_ERR_BADCRC;
10600 + pxamci_disable_irq(host, END_CMD_RES);
10601 + if (host->data && cmd->error == MMC_ERR_NONE) {
10602 + pxamci_enable_irq(host, DATA_TRAN_DONE);
10604 + pxamci_finish_request(host, host->req);
10610 +static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
10612 + struct mmc_data *data = host->data;
10617 + DCSR(host->dma) = 0;
10618 + dma_unmap_single(host->mmc.dev, host->dma_buf, host->dma_size,
10621 + if (stat & STAT_READ_TIME_OUT)
10622 + data->error = MMC_ERR_TIMEOUT;
10623 + else if (stat & (STAT_CRC_READ_ERROR|STAT_CRC_WRITE_ERROR))
10624 + data->error = MMC_ERR_BADCRC;
10626 + data->bytes_xfered = (data->blocks - readl(host->base + MMC_NOB))
10627 + << data->blksz_bits;
10629 + pxamci_disable_irq(host, DATA_TRAN_DONE);
10631 + host->data = NULL;
10632 + if (host->req->stop && data->error == MMC_ERR_NONE) {
10633 + pxamci_stop_clock(host);
10634 + pxamci_start_cmd(host, host->req->stop, 0);
10636 + pxamci_finish_request(host, host->req);
10642 +static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs)
10644 + struct pxamci_host *host = devid;
10645 + unsigned int ireg;
10648 + ireg = readl(host->base + MMC_I_REG);
10650 + DBG("PXAMCI: irq %08x\n", ireg);
10653 + unsigned stat = readl(host->base + MMC_STAT);
10655 + DBG("PXAMCI: stat %08x\n", stat);
10657 + if (ireg & END_CMD_RES)
10658 + handled |= pxamci_cmd_done(host, stat);
10659 + if (ireg & DATA_TRAN_DONE)
10660 + handled |= pxamci_data_done(host, stat);
10663 + return IRQ_RETVAL(handled);
10666 +static void pxamci_request(struct mmc_host *mmc, struct mmc_request *req)
10668 + struct pxamci_host *host = to_pxamci_host(mmc);
10669 + unsigned int cmdat;
10671 + WARN_ON(host->req != NULL);
10675 + pxamci_stop_clock(host);
10677 + cmdat = host->cmdat;
10678 + host->cmdat &= ~CMDAT_INIT;
10681 + pxamci_setup_data(host, req->data);
10683 + cmdat &= ~CMDAT_BUSY;
10684 + cmdat |= CMDAT_DATAEN | CMDAT_DMAEN;
10685 + if (req->data->flags & MMC_DATA_WRITE)
10686 + cmdat |= CMDAT_WRITE;
10688 + if (req->data->flags & MMC_DATA_STREAM)
10689 + cmdat |= CMDAT_STREAM;
10692 + pxamci_start_cmd(host, req->cmd, cmdat);
10695 +static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
10697 + struct pxamci_host *host = to_pxamci_host(mmc);
10699 + DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n",
10700 + ios->clock, ios->power_mode, ios->vdd / 100,
10703 + if (ios->clock) {
10704 + unsigned int clk = CLOCKRATE / ios->clock;
10705 + if (CLOCKRATE / clk > ios->clock)
10707 + host->clkrt = fls(clk) - 1;
10710 + * we write clkrt on the next command
10712 + } else if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
10714 + * Ensure that the clock is off.
10716 + writel(STOP_CLOCK, host->base + MMC_STRPCL);
10719 + if (host->power_mode != ios->power_mode) {
10720 + host->power_mode = ios->power_mode;
10723 + * power control? none on the lubbock.
10726 + if (ios->power_mode == MMC_POWER_ON)
10727 + host->cmdat |= CMDAT_INIT;
10730 + DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n",
10731 + host->clkrt, host->cmdat);
10734 +static struct mmc_host_ops pxamci_ops = {
10735 + .request = pxamci_request,
10736 + .set_ios = pxamci_set_ios,
10739 +static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
10743 + for (i = 0; i < dev->num_resources; i++)
10744 + if (dev->resource[i].flags == mask && nr-- == 0)
10745 + return &dev->resource[i];
10749 +static int platform_device_irq(struct platform_device *dev, int nr)
10753 + for (i = 0; i < dev->num_resources; i++)
10754 + if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0)
10755 + return dev->resource[i].start;
10759 +static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
10761 + printk(KERN_ERR "DMA%d: IRQ???\n", dma);
10762 + DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
10765 +static int pxamci_probe(struct device *dev)
10767 + struct platform_device *pdev = to_platform_device(dev);
10768 + struct pxamci_host *host;
10769 + struct resource *r;
10772 + r = platform_device_resource(pdev, IORESOURCE_MEM, 0);
10773 + irq = platform_device_irq(pdev, 0);
10774 + if (!r || irq == NO_IRQ)
10777 + r = request_mem_region(r->start, SZ_4K, "PXAMCI");
10781 + host = kmalloc(sizeof(struct pxamci_host), GFP_KERNEL);
10787 + memset(host, 0, sizeof(struct pxamci_host));
10790 + host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
10791 + if (!host->sg_cpu) {
10796 + ret = mmc_init_host(&host->mmc);
10800 + spin_lock_init(&host->lock);
10803 + host->imask = TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
10804 + END_CMD_RES|PRG_DONE|DATA_TRAN_DONE;
10805 + host->mmc.dev = dev;
10806 + host->mmc.ops = &pxamci_ops;
10807 + host->mmc.f_min = 312500;
10808 + host->mmc.f_max = 20000000;
10809 + host->mmc.ocr_avail = MMC_VDD_32_33;
10811 + host->base = ioremap(r->start, SZ_4K);
10812 + if (!host->base) {
10818 + * Ensure that the host controller is shut down, and setup
10819 + * with our defaults.
10821 + pxamci_stop_clock(host);
10822 + writel(0, host->base + MMC_SPI);
10823 + writel(64, host->base + MMC_RESTO);
10825 +#ifdef CONFIG_PREEMPT
10826 +#error Not Preempt-safe
10828 + pxa_gpio_mode(GPIO6_MMCCLK_MD);
10829 + pxa_gpio_mode(GPIO8_MMCCS0_MD);
10830 + CKEN |= CKEN12_MMC;
10832 + host->dma = pxa_request_dma("PXAMCI", DMA_PRIO_LOW, pxamci_dma_irq, host);
10833 + if (host->dma < 0)
10836 + ret = request_irq(host->irq, pxamci_irq, 0, "PXAMCI", host);
10840 + dev_set_drvdata(dev, host);
10842 + mmc_add_host(&host->mmc);
10848 + if (host->dma >= 0)
10849 + pxa_free_dma(host->dma);
10851 + iounmap(host->base);
10852 + if (host->sg_cpu)
10853 + dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
10856 + release_resource(r);
10860 +static int pxamci_remove(struct device *dev)
10862 + struct pxamci_host *host = dev_get_drvdata(dev);
10864 + dev_set_drvdata(dev, NULL);
10867 + mmc_remove_host(&host->mmc);
10869 + pxamci_stop_clock(host);
10870 + writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
10871 + END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
10872 + host->base + MMC_I_MASK);
10874 + free_irq(host->irq, host);
10875 + pxa_free_dma(host->dma);
10876 + iounmap(host->base);
10877 + dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
10879 + release_resource(host->res);
10886 +static int pxamci_suspend(struct device *dev, u32 state, u32 level)
10888 + struct pxamci_host *host = dev_get_drvdata(dev);
10891 + if (host && level == SUSPEND_DISABLE)
10892 + ret = mmc_suspend_host(&host->mmc, state);
10896 +static int pxamci_resume(struct device *dev, u32 level)
10898 + struct pxamci_host *host = dev_get_drvdata(dev);
10901 + if (host && level == RESUME_ENABLE)
10902 + ret = mmc_resume_host(&host->mmc);
10906 +static struct device_driver pxamci_driver = {
10907 + .name = "pxamci",
10908 + .bus = &platform_bus_type,
10909 + .probe = pxamci_probe,
10910 + .remove = pxamci_remove,
10911 + .suspend = pxamci_suspend,
10912 + .resume = pxamci_resume,
10915 +static int __init pxamci_init(void)
10917 + return driver_register(&pxamci_driver);
10920 +static void __exit pxamci_exit(void)
10922 + driver_unregister(&pxamci_driver);
10925 +module_init(pxamci_init);
10926 +module_exit(pxamci_exit);
10928 +MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver");
10929 +MODULE_LICENSE("GPL");
10930 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
10931 +++ linux-2.6.5/drivers/media/mmc/mmc.h 2004-04-30 20:57:36.000000000 -0400
10934 + * linux/drivers/media/mmc/mmc.h
10936 + * Copyright (C) 2003 Russell King, All Rights Reserved.
10938 + * This program is free software; you can redistribute it and/or modify
10939 + * it under the terms of the GNU General Public License version 2 as
10940 + * published by the Free Software Foundation.
10943 +/* core-internal functions */
10944 +void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
10945 +int mmc_register_card(struct mmc_card *card);
10946 +void mmc_remove_card(struct mmc_card *card);
10948 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
10949 +++ linux-2.6.5/drivers/media/mmc/mmc_sysfs.c 2004-04-30 20:57:36.000000000 -0400
10952 + * linux/drivers/media/mmc/mmc_sysfs.c
10954 + * Copyright (C) 2003 Russell King, All Rights Reserved.
10956 + * This program is free software; you can redistribute it and/or modify
10957 + * it under the terms of the GNU General Public License version 2 as
10958 + * published by the Free Software Foundation.
10960 + * MMC sysfs/driver model support.
10962 +#include <linux/module.h>
10963 +#include <linux/init.h>
10964 +#include <linux/device.h>
10966 +#include <linux/mmc/card.h>
10967 +#include <linux/mmc/host.h>
10971 +#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
10972 +#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
10974 +static void mmc_release_card(struct device *dev)
10976 + struct mmc_card *card = dev_to_mmc_card(dev);
10982 + * This currently matches any MMC driver to any MMC card - drivers
10983 + * themselves make the decision whether to drive this card in their
10986 +static int mmc_bus_match(struct device *dev, struct device_driver *drv)
10992 +mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
10995 + struct mmc_card *card = dev_to_mmc_card(dev);
10999 +#define add_env(fmt,val) \
11001 + int len, ret = -ENOMEM; \
11002 + if (i < num_envp) { \
11003 + envp[i++] = buf; \
11004 + len = snprintf(buf, buf_size, fmt, val) + 1; \
11005 + buf_size -= len; \
11007 + if (buf_size >= 0) \
11013 + for (i = 0; i < 12; i++)
11014 + ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';
11018 + add_env("MMC_CCC=%s", ccc);
11019 + add_env("MMC_MANFID=%03x", card->cid.manfid);
11020 + add_env("MMC_SLOT_NAME=%s", card->dev.bus_id);
11025 +static int mmc_bus_suspend(struct device *dev, u32 state)
11027 + struct mmc_driver *drv = to_mmc_driver(dev->driver);
11028 + struct mmc_card *card = dev_to_mmc_card(dev);
11031 + if (dev->driver && drv->suspend)
11032 + ret = drv->suspend(card, state);
11036 +static int mmc_bus_resume(struct device *dev)
11038 + struct mmc_driver *drv = to_mmc_driver(dev->driver);
11039 + struct mmc_card *card = dev_to_mmc_card(dev);
11042 + if (dev->driver && drv->resume)
11043 + ret = drv->resume(card);
11047 +static struct bus_type mmc_bus_type = {
11049 + .match = mmc_bus_match,
11050 + .hotplug = mmc_bus_hotplug,
11051 + .suspend = mmc_bus_suspend,
11052 + .resume = mmc_bus_resume,
11056 +static int mmc_drv_probe(struct device *dev)
11058 + struct mmc_driver *drv = to_mmc_driver(dev->driver);
11059 + struct mmc_card *card = dev_to_mmc_card(dev);
11061 + return drv->probe(card);
11064 +static int mmc_drv_remove(struct device *dev)
11066 + struct mmc_driver *drv = to_mmc_driver(dev->driver);
11067 + struct mmc_card *card = dev_to_mmc_card(dev);
11069 + drv->remove(card);
11076 + * mmc_register_driver - register a media driver
11077 + * @drv: MMC media driver
11079 +int mmc_register_driver(struct mmc_driver *drv)
11081 + drv->drv.bus = &mmc_bus_type;
11082 + drv->drv.probe = mmc_drv_probe;
11083 + drv->drv.remove = mmc_drv_remove;
11084 + return driver_register(&drv->drv);
11087 +EXPORT_SYMBOL(mmc_register_driver);
11090 + * mmc_unregister_driver - unregister a media driver
11091 + * @drv: MMC media driver
11093 +void mmc_unregister_driver(struct mmc_driver *drv)
11095 + drv->drv.bus = &mmc_bus_type;
11096 + driver_unregister(&drv->drv);
11099 +EXPORT_SYMBOL(mmc_unregister_driver);
11102 +#define MMC_ATTR(name, fmt, args...) \
11103 +static ssize_t mmc_dev_show_##name (struct device *dev, char *buf) \
11105 + struct mmc_card *card = dev_to_mmc_card(dev); \
11106 + return sprintf(buf, fmt, args); \
11108 +static DEVICE_ATTR(name, S_IRUGO, mmc_dev_show_##name, NULL)
11110 +MMC_ATTR(date, "%02d/%04d\n", card->cid.month, 1997 + card->cid.year);
11111 +MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
11112 +MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
11113 +MMC_ATTR(manfid, "0x%03x\n", card->cid.manfid);
11114 +MMC_ATTR(serial, "0x%06x\n", card->cid.serial);
11115 +MMC_ATTR(name, "%s\n", card->cid.prod_name);
11117 +static struct device_attribute *mmc_dev_attributes[] = {
11121 + &dev_attr_manfid,
11122 + &dev_attr_serial,
11127 + * Internal function. Initialise a MMC card structure.
11129 +void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
11131 + memset(card, 0, sizeof(struct mmc_card));
11132 + card->host = host;
11133 + device_initialize(&card->dev);
11134 + card->dev.parent = card->host->dev;
11135 + card->dev.bus = &mmc_bus_type;
11136 + card->dev.release = mmc_release_card;
11140 + * Internal function. Register a new MMC card with the driver model.
11142 +int mmc_register_card(struct mmc_card *card)
11146 + snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
11147 + "mmc%02x:%04x", card->host->host_num, card->rca);
11149 + ret = device_add(&card->dev);
11151 + for (i = 0; i < ARRAY_SIZE(mmc_dev_attributes); i++)
11152 + device_create_file(&card->dev, mmc_dev_attributes[i]);
11158 + * Internal function. Unregister a new MMC card with the
11159 + * driver model, and (eventually) free it.
11161 +void mmc_remove_card(struct mmc_card *card)
11163 + if (mmc_card_present(card))
11164 + device_del(&card->dev);
11166 + put_device(&card->dev);
11170 +static int __init mmc_init(void)
11172 + return bus_register(&mmc_bus_type);
11175 +static void __exit mmc_exit(void)
11177 + bus_unregister(&mmc_bus_type);
11180 +module_init(mmc_init);
11181 +module_exit(mmc_exit);
11182 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
11183 +++ linux-2.6.5/drivers/media/mmc/mmci.c 2004-04-30 20:57:36.000000000 -0400
11186 + * linux/drivers/media/mmc/mmci.c - ARM PrimeCell MMCI PL180/1 driver
11188 + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
11190 + * This program is free software; you can redistribute it and/or modify
11191 + * it under the terms of the GNU General Public License version 2 as
11192 + * published by the Free Software Foundation.
11194 +#include <linux/config.h>
11195 +#include <linux/module.h>
11196 +#include <linux/moduleparam.h>
11197 +#include <linux/init.h>
11198 +#include <linux/ioport.h>
11199 +#include <linux/device.h>
11200 +#include <linux/interrupt.h>
11201 +#include <linux/blkdev.h>
11202 +#include <linux/delay.h>
11203 +#include <linux/mmc/host.h>
11204 +#include <linux/mmc/protocol.h>
11206 +#include <asm/io.h>
11207 +#include <asm/irq.h>
11208 +#include <asm/hardware/amba.h>
11212 +#define DRIVER_NAME "mmci-pl18x"
11214 +#ifdef CONFIG_MMC_DEBUG
11215 +#define DBG(x...) printk(KERN_DEBUG x)
11217 +#define DBG(x...) do { } while (0)
11220 +static int fmax = 515633;
11223 +mmci_request_end(struct mmci_host *host, struct mmc_request *req)
11225 + writel(0, host->base + MMCICOMMAND);
11226 + host->req = NULL;
11227 + host->cmd = NULL;
11228 + host->data = NULL;
11231 + req->data->bytes_xfered = host->data_xfered;
11233 + mmc_request_done(&host->mmc, req);
11236 +static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
11238 + unsigned int datactrl;
11240 + DBG("MMCI: data: blksz %04x blks %04x flags %08x\n",
11241 + 1 << data->blksz_bits, data->blocks, data->flags);
11243 + datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4;
11245 + if (data->flags & MMC_DATA_READ)
11246 + datactrl |= MCI_DPSM_DIRECTION;
11248 + host->data = data;
11249 + host->buffer = data->rq->buffer;
11250 + host->size = data->blocks << data->blksz_bits;
11251 + host->data_xfered = 0;
11253 + writel(0x800000, host->base + MMCIDATATIMER);
11254 + writel(host->size, host->base + MMCIDATALENGTH);
11255 + writel(datactrl, host->base + MMCIDATACTRL);
11259 +mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
11261 + DBG("MMCI: cmd: op %02x arg %08x flags %08x\n",
11262 + cmd->opcode, cmd->arg, cmd->flags);
11264 + if (readl(host->base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
11265 + writel(0, host->base + MMCICOMMAND);
11269 + c |= cmd->opcode | MCI_CPSM_ENABLE;
11270 + switch (cmd->flags & MMC_RSP_MASK) {
11271 + case MMC_RSP_NONE:
11274 + case MMC_RSP_LONG:
11275 + c |= MCI_CPSM_LONGRSP;
11276 + case MMC_RSP_SHORT:
11277 + c |= MCI_CPSM_RESPONSE;
11280 + if (/*interrupt*/0)
11281 + c |= MCI_CPSM_INTERRUPT;
11285 + writel(cmd->arg, host->base + MMCIARGUMENT);
11286 + writel(c, host->base + MMCICOMMAND);
11290 +mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
11291 + unsigned int status)
11293 + if (status & MCI_DATABLOCKEND) {
11294 + host->data_xfered += 1 << data->blksz_bits;
11296 + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
11297 + if (status & MCI_DATACRCFAIL)
11298 + data->error = MMC_ERR_BADCRC;
11299 + else if (status & MCI_DATATIMEOUT)
11300 + data->error = MMC_ERR_TIMEOUT;
11301 + else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
11302 + data->error = MMC_ERR_FIFO;
11303 + status |= MCI_DATAEND;
11305 + if (status & MCI_DATAEND) {
11306 + host->data = NULL;
11307 + if (!data->stop) {
11308 + mmci_request_end(host, data->req);
11309 + } else /*if (readl(host->base + MMCIDATACNT) > 6)*/ {
11310 + mmci_start_command(host, data->stop, 0);
11316 +mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
11317 + unsigned int status)
11319 + host->cmd = NULL;
11321 + cmd->resp[0] = readl(host->base + MMCIRESPONSE0);
11322 + cmd->resp[1] = readl(host->base + MMCIRESPONSE1);
11323 + cmd->resp[2] = readl(host->base + MMCIRESPONSE2);
11324 + cmd->resp[3] = readl(host->base + MMCIRESPONSE3);
11326 + if (status & MCI_CMDTIMEOUT) {
11327 + cmd->error = MMC_ERR_TIMEOUT;
11328 + } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
11329 + cmd->error = MMC_ERR_BADCRC;
11332 + if (!cmd->data || cmd->error != MMC_ERR_NONE) {
11333 + mmci_request_end(host, cmd->req);
11334 + } else if (!(cmd->data->flags & MMC_DATA_READ)) {
11335 + mmci_start_data(host, cmd->data);
11339 +static irqreturn_t mmci_irq(int irq, void *dev_id, struct pt_regs *regs)
11341 + struct mmci_host *host = dev_id;
11346 + struct mmc_command *cmd;
11347 + struct mmc_data *data;
11349 + status = readl(host->base + MMCISTATUS);
11350 + writel(status, host->base + MMCICLEAR);
11352 + if (!(status & MCI_IRQMASK))
11355 + DBG("MMCI: irq %08x\n", status);
11357 + if (status & (MCI_RXDATAAVLBL|MCI_RXFIFOHALFFULL)) {
11358 + int count = host->size - (readl(host->base + MMCIFIFOCNT) << 2);
11361 + if (count && host->buffer) {
11362 + readsl(host->base + MMCIFIFO, host->buffer, count >> 2);
11363 + host->buffer += count;
11364 + host->size -= count;
11365 + if (host->size == 0)
11366 + host->buffer = NULL;
11368 + static int first = 1;
11371 + printk(KERN_ERR "MMCI: sinking excessive data\n");
11373 + readl(host->base + MMCIFIFO);
11376 + if (status & (MCI_TXFIFOEMPTY|MCI_TXFIFOHALFEMPTY)) {
11377 + int count = host->size;
11378 + if (count > MCI_FIFOHALFSIZE)
11379 + count = MCI_FIFOHALFSIZE;
11380 + if (count && host->buffer) {
11381 + writesl(host->base + MMCIFIFO, host->buffer, count >> 2);
11382 + host->buffer += count;
11383 + host->size -= count;
11384 + if (host->size == 0)
11385 + host->buffer = NULL;
11387 + static int first = 1;
11390 + printk(KERN_ERR "MMCI: ran out of source data\n");
11395 + data = host->data;
11396 + if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|
11397 + MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND))
11398 + mmci_data_irq(host, data, status);
11401 + if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd)
11402 + mmci_cmd_irq(host, cmd, status);
11405 + } while (status);
11407 + return IRQ_RETVAL(ret);
11410 +static void mmci_request(struct mmc_host *mmc, struct mmc_request *req)
11412 + struct mmci_host *host = to_mmci_host(mmc);
11414 + WARN_ON(host->req != NULL);
11418 + if (req->data && req->data->flags & MMC_DATA_READ)
11419 + mmci_start_data(host, req->data);
11421 + mmci_start_command(host, req->cmd, 0);
11424 +static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
11426 + struct mmci_host *host = to_mmci_host(mmc);
11427 + u32 clk = 0, pwr = 0;
11429 + DBG("MMCI: set_ios: clock %dHz busmode %d powermode %d Vdd %d.%02d\n",
11430 + ios->clock, ios->bus_mode, ios->power_mode,
11431 + ios->vdd / 100, ios->vdd % 100);
11433 + if (ios->clock) {
11434 + clk = host->mclk / (2 * ios->clock) - 1;
11437 + clk |= MCI_CLK_ENABLE;
11440 + switch (ios->power_mode) {
11441 + case MMC_POWER_OFF:
11443 + case MMC_POWER_UP:
11444 + pwr |= MCI_PWR_UP;
11446 + case MMC_POWER_ON:
11447 + pwr |= MCI_PWR_ON;
11451 + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
11454 + writel(clk, host->base + MMCICLOCK);
11456 + if (host->pwr != pwr) {
11458 + writel(pwr, host->base + MMCIPOWER);
11462 +static struct mmc_host_ops mmci_ops = {
11463 + .request = mmci_request,
11464 + .set_ios = mmci_set_ios,
11467 +static int mmci_probe(struct amba_device *dev, void *id)
11469 + struct mmci_host *host;
11473 + /* enable the interrupt via the VIC */
11474 +// tmp = ioremap(0xc3000000, SZ_4K);
11476 +// u32 val = readl(tmp + 0x10);
11477 +// writel(val | 0x180, tmp + 0x10);
11481 + if (!request_mem_region(dev->res.start, SZ_4K, DRIVER_NAME))
11484 + host = kmalloc(sizeof(struct mmci_host), GFP_KERNEL);
11490 + memset(host, 0, sizeof(struct mmci_host));
11492 + ret = mmc_init_host(&host->mmc);
11496 + host->base = ioremap(dev->res.start, SZ_4K);
11497 + if (!host->base) {
11502 + host->irq = dev->irq;
11503 + host->mclk = 33000000; /* impd1 */
11504 + host->mmc.dev = &dev->dev;
11505 + host->mmc.ops = &mmci_ops;
11506 + host->mmc.f_min = (host->mclk + 511) / 512;
11507 + host->mmc.f_max = host->mclk / 2;
11508 + if (host->mmc.f_max > fmax)
11509 + host->mmc.f_max = fmax;
11511 + host->mmc.ocr_avail = MMC_VDD_35_36;
11513 + writel(0, host->base + MMCIMASK0);
11514 + writel(0, host->base + MMCIMASK1);
11515 + writel(0xfff, host->base + MMCICLEAR);
11517 + ret = request_irq(host->irq, mmci_irq, SA_SHIRQ, DRIVER_NAME, host);
11521 + writel(MCI_IRQENABLE, host->base + MMCIMASK0);
11523 + amba_set_drvdata(dev, host);
11525 + mmc_add_host(&host->mmc);
11532 + iounmap(host->base);
11535 + release_mem_region(dev->res.start, SZ_4K);
11539 +static int mmci_remove(struct amba_device *dev)
11541 + struct mmci_host *host = amba_get_drvdata(dev);
11543 + amba_set_drvdata(dev, NULL);
11546 + mmc_remove_host(&host->mmc);
11548 + writel(0, host->base + MMCIMASK0);
11549 + writel(0, host->base + MMCIMASK1);
11551 + writel(0, host->base + MMCICOMMAND);
11552 + writel(0, host->base + MMCIDATACTRL);
11554 + free_irq(host->irq, host);
11556 + iounmap(host->base);
11560 + release_mem_region(dev->res.start, SZ_4K);
11567 +static int mmci_suspend(struct amba_device *dev, u32 state)
11569 + struct mmci_host *host = amba_get_drvdata(dev);
11571 + return host ? mmc_suspend_host(&host->mmc, state) : 0;
11574 +static int mmci_resume(struct amba_device *dev)
11576 + struct mmci_host *host = amba_get_drvdata(dev);
11580 + writel(MCI_IRQENABLE, host->base + MMCIMASK0);
11581 + ret = mmc_resume_host(&host->mmc);
11587 +#define mmci_suspend NULL
11588 +#define mmci_resume NULL
11591 +static struct amba_id mmci_ids[] = {
11593 + .id = 0x00041180,
11594 + .mask = 0x000fffff,
11597 + .id = 0x00041181,
11598 + .mask = 0x000fffff,
11603 +static struct amba_driver mmci_driver = {
11605 + .name = DRIVER_NAME,
11607 + .probe = mmci_probe,
11608 + .remove = mmci_remove,
11609 + .suspend = mmci_suspend,
11610 + .resume = mmci_resume,
11611 + .id_table = mmci_ids,
11614 +static int __init mmci_init(void)
11616 + return amba_driver_register(&mmci_driver);
11619 +static void __exit mmci_exit(void)
11621 + amba_driver_unregister(&mmci_driver);
11624 +module_init(mmci_init);
11625 +module_exit(mmci_exit);
11626 +module_param(fmax, int, 0444);
11628 +MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver");
11629 +MODULE_LICENSE("GPL");
11630 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
11631 +++ linux-2.6.5/drivers/media/mmc/mmc_queue.h 2004-04-30 20:57:36.000000000 -0400
11633 +#ifndef MMC_QUEUE_H
11634 +#define MMC_QUEUE_H
11637 +struct task_struct;
11639 +struct mmc_queue {
11640 + struct mmc_card *card;
11641 + struct completion thread_complete;
11642 + wait_queue_head_t thread_wq;
11643 + struct task_struct *thread;
11644 + struct request *req;
11645 + int (*prep_fn)(struct mmc_queue *, struct request *);
11646 + int (*issue_fn)(struct mmc_queue *, struct request *);
11648 + struct request_queue *queue;
11651 +struct mmc_io_request {
11652 + struct request *rq;
11654 + struct mmc_command selcmd; /* mmc_queue private */
11655 + struct mmc_command cmd[4]; /* max 4 commands */
11658 +extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
11659 +extern void mmc_cleanup_queue(struct mmc_queue *);
11662 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
11663 +++ linux-2.6.5/drivers/media/mmc/mmc_block.c 2004-04-30 20:57:36.000000000 -0400
11666 + * Block driver for media (i.e., flash cards)
11668 + * Copyright 2002 Hewlett-Packard Company
11670 + * Use consistent with the GNU GPL is permitted,
11671 + * provided that this copyright notice is
11672 + * preserved in its entirety in all copies and derived works.
11674 + * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
11675 + * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
11676 + * FITNESS FOR ANY PARTICULAR PURPOSE.
11678 + * Many thanks to Alessandro Rubini and Jonathan Corbet!
11680 + * Author: Andrew Christian
11683 +#include <linux/moduleparam.h>
11684 +#include <linux/module.h>
11685 +#include <linux/init.h>
11687 +#include <linux/sched.h>
11688 +#include <linux/kernel.h> /* printk() */
11689 +#include <linux/fs.h> /* everything... */
11690 +#include <linux/errno.h> /* error codes */
11691 +#include <linux/hdreg.h> /* HDIO_GETGEO */
11692 +#include <linux/kdev_t.h>
11693 +#include <linux/blkdev.h>
11694 +#include <linux/devfs_fs_kernel.h>
11696 +#include <linux/mmc/card.h>
11697 +#include <linux/mmc/protocol.h>
11699 +#include <asm/system.h>
11700 +#include <asm/uaccess.h>
11702 +#include "mmc_queue.h"
11704 +#define MMC_SHIFT 3 /* max 8 partitions per card */
11706 +static int mmc_major;
11707 +static int maxsectors = 8;
11710 + * There is one mmc_blk_data per slot.
11712 +struct mmc_blk_data {
11714 + struct gendisk *disk;
11715 + struct mmc_queue queue;
11717 + unsigned int usage;
11718 + unsigned int block_bits;
11719 + unsigned int suspended;
11722 +static DECLARE_MUTEX(open_lock);
11724 +static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
11726 + struct mmc_blk_data *md;
11728 + down(&open_lock);
11729 + md = disk->private_data;
11730 + if (md && md->usage == 0)
11739 +static void mmc_blk_put(struct mmc_blk_data *md)
11741 + down(&open_lock);
11743 + if (md->usage == 0) {
11744 + put_disk(md->disk);
11745 + mmc_cleanup_queue(&md->queue);
11751 +static int mmc_blk_open(struct inode *inode, struct file *filp)
11753 + struct mmc_blk_data *md;
11754 + int ret = -ENXIO;
11756 + md = mmc_blk_get(inode->i_bdev->bd_disk);
11758 + if (md->usage == 2)
11759 + check_disk_change(inode->i_bdev);
11766 +static int mmc_blk_release(struct inode *inode, struct file *filp)
11768 + struct mmc_blk_data *md = inode->i_bdev->bd_disk->private_data;
11775 +mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
11777 + struct block_device *bdev = inode->i_bdev;
11779 + if (cmd == HDIO_GETGEO) {
11780 + struct hd_geometry geo;
11782 + memset(&geo, 0, sizeof(struct hd_geometry));
11784 + geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
11786 + geo.sectors = 16;
11787 + geo.start = get_start_sect(bdev);
11789 + return copy_to_user((void *)arg, &geo, sizeof(geo))
11796 +static struct block_device_operations mmc_bdops = {
11797 + .open = mmc_blk_open,
11798 + .release = mmc_blk_release,
11799 + .ioctl = mmc_blk_ioctl,
11800 + .owner = THIS_MODULE,
11803 +struct mmc_blk_request {
11804 + struct mmc_request req;
11805 + struct mmc_command cmd;
11806 + struct mmc_command stop;
11807 + struct mmc_data data;
11810 +static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
11812 + struct mmc_blk_data *md = mq->data;
11815 + * If we have no device, we haven't finished initialising.
11817 + if (!md || !mq->card) {
11818 + printk("killing request - no device/host\n");
11822 + if (md->suspended) {
11823 + blk_plug_device(md->queue.queue);
11828 + * Check for excessive requests.
11830 + if (req->sector + req->nr_sectors > get_capacity(req->rq_disk)) {
11831 + printk("bad request size\n");
11835 + return BLKPREP_OK;
11838 + return BLKPREP_DEFER;
11840 + return BLKPREP_KILL;
11843 +static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
11845 + struct mmc_blk_data *md = mq->data;
11846 + struct mmc_card *card = md->queue.card;
11849 + err = mmc_card_claim_host(card);
11854 + struct mmc_blk_request rq;
11855 + struct mmc_command cmd;
11857 + memset(&rq, 0, sizeof(struct mmc_blk_request));
11858 + rq.req.cmd = &rq.cmd;
11859 + rq.req.data = &rq.data;
11861 + rq.cmd.arg = req->sector << 9;
11862 + rq.cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
11863 + rq.data.rq = req;
11864 + rq.data.timeout_ns = card->csd.tacc_ns * 10;
11865 + rq.data.timeout_clks = card->csd.tacc_clks * 10;
11866 + rq.data.blksz_bits = md->block_bits;
11867 + rq.data.blocks = req->current_nr_sectors >> (md->block_bits - 9);
11868 + rq.stop.opcode = MMC_STOP_TRANSMISSION;
11870 + rq.stop.flags = MMC_RSP_SHORT | MMC_RSP_CRC | MMC_RSP_BUSY;
11872 + if (rq_data_dir(req) == READ) {
11873 + rq.cmd.opcode = rq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
11874 + rq.data.flags |= MMC_DATA_READ;
11876 + rq.cmd.opcode = MMC_WRITE_BLOCK;
11877 + rq.cmd.flags |= MMC_RSP_BUSY;
11878 + rq.data.flags |= MMC_DATA_WRITE;
11879 + rq.data.blocks = 1;
11881 + rq.req.stop = rq.data.blocks > 1 ? &rq.stop : NULL;
11883 + mmc_wait_for_req(card->host, &rq.req);
11884 + if (rq.cmd.error) {
11885 + err = rq.cmd.error;
11886 + printk("error %d sending read/write command\n", err);
11890 + if (rq_data_dir(req) == READ) {
11891 + sz = rq.data.bytes_xfered;
11896 + if (rq.data.error) {
11897 + err = rq.data.error;
11898 + printk("error %d transferring data\n", err);
11902 + if (rq.stop.error) {
11903 + err = rq.stop.error;
11904 + printk("error %d sending stop command\n", err);
11909 + cmd.opcode = MMC_SEND_STATUS;
11910 + cmd.arg = card->rca << 16;
11911 + cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
11912 + err = mmc_wait_for_cmd(card->host, &cmd, 5);
11914 + printk("error %d requesting status\n", err);
11917 + } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
11920 + if (cmd.resp[0] & ~0x00000900)
11921 + printk("status = %08x\n", cmd.resp[0]);
11922 + err = mmc_decode_status(cmd.resp);
11927 + sz = rq.data.bytes_xfered;
11928 + } while (end_that_request_chunk(req, 1, sz));
11930 + mmc_card_release_host(card);
11935 + mmc_card_release_host(card);
11937 + end_that_request_chunk(req, 1, sz);
11938 + req->errors = err;
11943 +#define MMC_NUM_MINORS (256 >> MMC_SHIFT)
11945 +static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))];
11947 +static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
11949 + struct mmc_blk_data *md;
11952 + devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS);
11953 + if (devidx >= MMC_NUM_MINORS)
11955 + __set_bit(devidx, dev_use);
11957 + md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
11959 + memset(md, 0, sizeof(struct mmc_blk_data));
11961 + md->disk = alloc_disk(1 << MMC_SHIFT);
11962 + if (md->disk == NULL) {
11968 + spin_lock_init(&md->lock);
11971 + mmc_init_queue(&md->queue, card, &md->lock);
11972 + md->queue.prep_fn = mmc_blk_prep_rq;
11973 + md->queue.issue_fn = mmc_blk_issue_rq;
11974 + md->queue.data = md;
11976 + md->disk->major = mmc_major;
11977 + md->disk->first_minor = devidx << MMC_SHIFT;
11978 + md->disk->fops = &mmc_bdops;
11979 + md->disk->private_data = md;
11980 + md->disk->queue = md->queue.queue;
11981 + md->disk->driverfs_dev = &card->dev;
11983 + sprintf(md->disk->disk_name, "mmcblk%d", devidx);
11984 + sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
11986 + md->block_bits = md->queue.card->csd.read_blkbits;
11988 + blk_queue_max_sectors(md->queue.queue, maxsectors);
11989 + blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
11990 + set_capacity(md->disk, md->queue.card->csd.capacity);
11997 +mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
11999 + struct mmc_command cmd;
12002 + mmc_card_claim_host(card);
12003 + cmd.opcode = MMC_SET_BLOCKLEN;
12004 + cmd.arg = 1 << card->csd.read_blkbits;
12005 + cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
12006 + err = mmc_wait_for_cmd(card->host, &cmd, 5);
12007 + mmc_card_release_host(card);
12010 + printk(KERN_ERR "%s: unable to set block size to %d: %d\n",
12011 + md->disk->disk_name, cmd.arg, err);
12018 +static int mmc_blk_probe(struct mmc_card *card)
12020 + struct mmc_blk_data *md;
12023 + if (card->csd.cmdclass & ~0x1ff)
12026 + if (card->csd.read_blkbits < 9) {
12027 + printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
12028 + mmc_card_id(card), 1 << card->csd.read_blkbits);
12032 + md = mmc_blk_alloc(card);
12036 + err = mmc_blk_set_blksize(md, card);
12040 + printk(KERN_INFO "%s: %s %s %dKiB\n",
12041 + md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
12042 + (card->csd.capacity << card->csd.read_blkbits) / 1024);
12044 + mmc_set_drvdata(card, md);
12045 + add_disk(md->disk);
12054 +static void mmc_blk_remove(struct mmc_card *card)
12056 + struct mmc_blk_data *md = mmc_get_drvdata(card);
12061 + del_gendisk(md->disk);
12064 + * I think this is needed.
12066 + md->disk->queue = NULL;
12068 + devidx = md->disk->first_minor >> MMC_SHIFT;
12069 + __clear_bit(devidx, dev_use);
12073 + mmc_set_drvdata(card, NULL);
12077 +static int mmc_blk_suspend(struct mmc_card *card, u32 state)
12079 + struct mmc_blk_data *md = mmc_get_drvdata(card);
12082 + blk_stop_queue(md->queue.queue);
12087 +static int mmc_blk_resume(struct mmc_card *card)
12089 + struct mmc_blk_data *md = mmc_get_drvdata(card);
12092 + mmc_blk_set_blksize(md, md->queue.card);
12093 + blk_start_queue(md->queue.queue);
12098 +#define mmc_blk_suspend NULL
12099 +#define mmc_blk_resume NULL
12102 +static struct mmc_driver mmc_driver = {
12104 + .name = "mmcblk",
12106 + .probe = mmc_blk_probe,
12107 + .remove = mmc_blk_remove,
12108 + .suspend = mmc_blk_suspend,
12109 + .resume = mmc_blk_resume,
12112 +static int __init mmc_blk_init(void)
12114 + int res = -ENOMEM;
12116 + res = register_blkdev(mmc_major, "mmc");
12118 + printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n",
12122 + if (mmc_major == 0)
12125 + devfs_mk_dir("mmc");
12126 + return mmc_register_driver(&mmc_driver);
12132 +static void __exit mmc_blk_exit(void)
12134 + mmc_unregister_driver(&mmc_driver);
12135 + devfs_remove("mmc");
12136 + unregister_blkdev(mmc_major, "mmc");
12139 +module_init(mmc_blk_init);
12140 +module_exit(mmc_blk_exit);
12141 +module_param(maxsectors, int, 0444);
12143 +MODULE_PARM_DESC(maxsectors, "Maximum number of sectors for a single request");
12145 +MODULE_LICENSE("GPL");
12146 +MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
12147 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
12148 +++ linux-2.6.5/drivers/media/mmc/pxamci.h 2004-04-30 20:57:36.000000000 -0400
12161 +#undef END_CMD_RES
12163 +#undef DATA_TRAN_DONE
12172 +#define MMC_STRPCL 0x0000
12173 +#define STOP_CLOCK (1 << 0)
12174 +#define START_CLOCK (2 << 0)
12176 +#define MMC_STAT 0x0004
12177 +#define STAT_END_CMD_RES (1 << 13)
12178 +#define STAT_PRG_DONE (1 << 12)
12179 +#define STAT_DATA_TRAN_DONE (1 << 11)
12180 +#define STAT_CLK_EN (1 << 8)
12181 +#define STAT_RECV_FIFO_FULL (1 << 7)
12182 +#define STAT_XMIT_FIFO_EMPTY (1 << 6)
12183 +#define STAT_RES_CRC_ERR (1 << 5)
12184 +#define STAT_SPI_READ_ERROR_TOKEN (1 << 4)
12185 +#define STAT_CRC_READ_ERROR (1 << 3)
12186 +#define STAT_CRC_WRITE_ERROR (1 << 2)
12187 +#define STAT_TIME_OUT_RESPONSE (1 << 1)
12188 +#define STAT_READ_TIME_OUT (1 << 0)
12190 +#define MMC_CLKRT 0x0008 /* 3 bit */
12192 +#define MMC_SPI 0x000c
12193 +#define SPI_CS_ADDRESS (1 << 3)
12194 +#define SPI_CS_EN (1 << 2)
12195 +#define CRC_ON (1 << 1)
12196 +#define SPI_EN (1 << 0)
12198 +#define MMC_CMDAT 0x0010
12199 +#define CMDAT_DMAEN (1 << 7)
12200 +#define CMDAT_INIT (1 << 6)
12201 +#define CMDAT_BUSY (1 << 5)
12202 +#define CMDAT_STREAM (1 << 4) /* 1 = stream */
12203 +#define CMDAT_WRITE (1 << 3) /* 1 = write */
12204 +#define CMDAT_DATAEN (1 << 2)
12205 +#define CMDAT_RESP_NONE (0 << 0)
12206 +#define CMDAT_RESP_SHORT (1 << 0)
12207 +#define CMDAT_RESP_R2 (2 << 0)
12208 +#define CMDAT_RESP_R3 (3 << 0)
12210 +#define MMC_RESTO 0x0014 /* 7 bit */
12212 +#define MMC_RDTO 0x0018 /* 16 bit */
12214 +#define MMC_BLKLEN 0x001c /* 10 bit */
12216 +#define MMC_NOB 0x0020 /* 16 bit */
12218 +#define MMC_PRTBUF 0x0024
12219 +#define BUF_PART_FULL (1 << 0)
12221 +#define MMC_I_MASK 0x0028
12222 +#define TXFIFO_WR_REQ (1 << 6)
12223 +#define RXFIFO_RD_REQ (1 << 5)
12224 +#define CLK_IS_OFF (1 << 4)
12225 +#define STOP_CMD (1 << 3)
12226 +#define END_CMD_RES (1 << 2)
12227 +#define PRG_DONE (1 << 1)
12228 +#define DATA_TRAN_DONE (1 << 0)
12230 +#define MMC_I_REG 0x002c
12231 +/* same as MMC_I_MASK */
12233 +#define MMC_CMD 0x0030
12235 +#define MMC_ARGH 0x0034 /* 16 bit */
12237 +#define MMC_ARGL 0x0038 /* 16 bit */
12239 +#define MMC_RES 0x003c /* 16 bit */
12241 +#define MMC_RXFIFO 0x0040 /* 8 bit */
12243 +#define MMC_TXFIFO 0x0044 /* 8 bit */
12244 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
12245 +++ linux-2.6.5/drivers/media/mmc/mmci.h 2004-04-30 20:57:36.000000000 -0400
12248 + * linux/drivers/media/mmc/mmci.h - ARM PrimeCell MMCI PL180/1 driver
12250 + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
12252 + * This program is free software; you can redistribute it and/or modify
12253 + * it under the terms of the GNU General Public License version 2 as
12254 + * published by the Free Software Foundation.
12256 +#define MMCIPOWER 0x000
12257 +#define MCI_PWR_OFF 0x00
12258 +#define MCI_PWR_UP 0x02
12259 +#define MCI_PWR_ON 0x03
12260 +#define MCI_OD (1 << 6)
12261 +#define MCI_ROD (1 << 7)
12263 +#define MMCICLOCK 0x004
12264 +#define MCI_CLK_ENABLE (1 << 8)
12265 +#define MCI_PWRSAVE (1 << 9)
12266 +#define MCI_BYPASS (1 << 10)
12268 +#define MMCIARGUMENT 0x008
12269 +#define MMCICOMMAND 0x00c
12270 +#define MCI_CPSM_RESPONSE (1 << 6)
12271 +#define MCI_CPSM_LONGRSP (1 << 7)
12272 +#define MCI_CPSM_INTERRUPT (1 << 8)
12273 +#define MCI_CPSM_PENDING (1 << 9)
12274 +#define MCI_CPSM_ENABLE (1 << 10)
12276 +#define MMCIRESPCMD 0x010
12277 +#define MMCIRESPONSE0 0x014
12278 +#define MMCIRESPONSE1 0x018
12279 +#define MMCIRESPONSE2 0x01c
12280 +#define MMCIRESPONSE3 0x020
12281 +#define MMCIDATATIMER 0x024
12282 +#define MMCIDATALENGTH 0x028
12283 +#define MMCIDATACTRL 0x02c
12284 +#define MCI_DPSM_ENABLE (1 << 0)
12285 +#define MCI_DPSM_DIRECTION (1 << 1)
12286 +#define MCI_DPSM_MODE (1 << 2)
12287 +#define MCI_DPSM_DMAENABLE (1 << 3)
12289 +#define MMCIDATACNT 0x030
12290 +#define MMCISTATUS 0x034
12291 +#define MCI_CMDCRCFAIL (1 << 0)
12292 +#define MCI_DATACRCFAIL (1 << 1)
12293 +#define MCI_CMDTIMEOUT (1 << 2)
12294 +#define MCI_DATATIMEOUT (1 << 3)
12295 +#define MCI_TXUNDERRUN (1 << 4)
12296 +#define MCI_RXOVERRUN (1 << 5)
12297 +#define MCI_CMDRESPEND (1 << 6)
12298 +#define MCI_CMDSENT (1 << 7)
12299 +#define MCI_DATAEND (1 << 8)
12300 +#define MCI_DATABLOCKEND (1 << 10)
12301 +#define MCI_CMDACTIVE (1 << 11)
12302 +#define MCI_TXACTIVE (1 << 12)
12303 +#define MCI_RXACTIVE (1 << 13)
12304 +#define MCI_TXFIFOHALFEMPTY (1 << 14)
12305 +#define MCI_RXFIFOHALFFULL (1 << 15)
12306 +#define MCI_TXFIFOFULL (1 << 16)
12307 +#define MCI_RXFIFOFULL (1 << 17)
12308 +#define MCI_TXFIFOEMPTY (1 << 18)
12309 +#define MCI_RXFIFOEMPTY (1 << 19)
12310 +#define MCI_TXDATAAVLBL (1 << 20)
12311 +#define MCI_RXDATAAVLBL (1 << 21)
12313 +#define MMCICLEAR 0x038
12314 +#define MCI_CMDCRCFAILCLR (1 << 0)
12315 +#define MCI_DATACRCFAILCLR (1 << 1)
12316 +#define MCI_CMDTIMEOUTCLR (1 << 2)
12317 +#define MCI_DATATIMEOUTCLR (1 << 3)
12318 +#define MCI_TXUNDERRUNCLR (1 << 4)
12319 +#define MCI_RXOVERRUNCLR (1 << 5)
12320 +#define MCI_CMDRESPENDCLR (1 << 6)
12321 +#define MCI_CMDSENTCLR (1 << 7)
12322 +#define MCI_DATAENDCLR (1 << 8)
12323 +#define MCI_DATABLOCKENDCLR (1 << 10)
12325 +#define MMCIMASK0 0x03c
12326 +#define MCI_CMDCRCFAILMASK (1 << 0)
12327 +#define MCI_DATACRCFAILMASK (1 << 1)
12328 +#define MCI_CMDTIMEOUTMASK (1 << 2)
12329 +#define MCI_DATATIMEOUTMASK (1 << 3)
12330 +#define MCI_TXUNDERRUNMASK (1 << 4)
12331 +#define MCI_RXOVERRUNMASK (1 << 5)
12332 +#define MCI_CMDRESPENDMASK (1 << 6)
12333 +#define MCI_CMDSENTMASK (1 << 7)
12334 +#define MCI_DATAENDMASK (1 << 8)
12335 +#define MCI_DATABLOCKENDMASK (1 << 10)
12336 +#define MCI_CMDACTIVEMASK (1 << 11)
12337 +#define MCI_TXACTIVEMASK (1 << 12)
12338 +#define MCI_RXACTIVEMASK (1 << 13)
12339 +#define MCI_TXFIFOHALFEMPTYMASK (1 << 14)
12340 +#define MCI_RXFIFOHALFFULLMASK (1 << 15)
12341 +#define MCI_TXFIFOFULLMASK (1 << 16)
12342 +#define MCI_RXFIFOFULLMASK (1 << 17)
12343 +#define MCI_TXFIFOEMPTYMASK (1 << 18)
12344 +#define MCI_RXFIFOEMPTYMASK (1 << 19)
12345 +#define MCI_TXDATAAVLBLMASK (1 << 20)
12346 +#define MCI_RXDATAAVLBLMASK (1 << 21)
12348 +#define MMCIMASK1 0x040
12349 +#define MMCIFIFOCNT 0x048
12350 +#define MMCIFIFO 0x080 /* to 0x0bc */
12352 +#define MCI_IRQMASK \
12353 + (MCI_CMDCRCFAIL|MCI_DATACRCFAIL|MCI_CMDTIMEOUT|MCI_DATATIMEOUT| \
12354 + MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_CMDRESPEND|MCI_CMDSENT| \
12355 + MCI_DATAEND|MCI_DATABLOCKEND| \
12356 + MCI_TXFIFOHALFEMPTY|MCI_RXFIFOHALFFULL| \
12357 + MCI_TXFIFOEMPTY|MCI_RXDATAAVLBL)
12359 +#define MCI_IRQENABLE \
12360 + (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
12361 + MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
12362 + MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK| \
12363 + MCI_DATABLOCKENDMASK|MCI_TXFIFOHALFEMPTYMASK| \
12364 + MCI_RXFIFOHALFFULLMASK)
12366 +#define MCI_FIFOSIZE 16
12368 +#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
12370 +struct mmci_host {
12371 + struct mmc_host mmc;
12374 + unsigned int mclk;
12377 + struct mmc_request *req;
12378 + struct mmc_command *cmd;
12379 + struct mmc_data *data;
12381 + unsigned int data_xfered;
12385 + unsigned int size;
12388 +// struct scatterlist *sg_list;
12393 +#define to_mmci_host(mmc) container_of(mmc, struct mmci_host, mmc)
12394 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
12395 +++ linux-2.6.5/drivers/media/mmc/mmc.c 2004-04-30 20:57:36.000000000 -0400
12398 + * linux/drivers/media/mmc/mmc.c
12400 + * Copyright (C) 2003 Russell King, All Rights Reserved.
12402 + * This program is free software; you can redistribute it and/or modify
12403 + * it under the terms of the GNU General Public License version 2 as
12404 + * published by the Free Software Foundation.
12406 +#include <linux/config.h>
12407 +#include <linux/module.h>
12408 +#include <linux/init.h>
12409 +#include <linux/interrupt.h>
12410 +#include <linux/completion.h>
12411 +#include <linux/device.h>
12412 +#include <linux/delay.h>
12413 +#include <linux/err.h>
12415 +#include <linux/mmc/card.h>
12416 +#include <linux/mmc/host.h>
12417 +#include <linux/mmc/protocol.h>
12421 +#ifdef CONFIG_MMC_DEBUG
12422 +#define DBG(x...) printk(KERN_DEBUG x)
12424 +#define DBG(x...) do { } while (0)
12427 +#define CMD_RETRIES 3
12430 + * OCR Bit positions to 10s of Vdd mV.
12432 +static const unsigned short mmc_ocr_bit_to_vdd[] = {
12433 + 150, 155, 160, 165, 170, 180, 190, 200,
12434 + 210, 220, 230, 240, 250, 260, 270, 280,
12435 + 290, 300, 310, 320, 330, 340, 350, 360
12438 +static const unsigned int tran_exp[] = {
12439 + 10000, 100000, 1000000, 10000000,
12443 +static const unsigned char tran_mant[] = {
12444 + 0, 10, 12, 13, 15, 20, 25, 30,
12445 + 35, 40, 45, 50, 55, 60, 70, 80,
12448 +static const unsigned int tacc_exp[] = {
12449 + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
12452 +static const unsigned int tacc_mant[] = {
12453 + 0, 10, 12, 13, 15, 20, 25, 30,
12454 + 35, 40, 45, 50, 55, 60, 70, 80,
12459 + * mmc_request_done - finish processing an MMC command
12460 + * @host: MMC host which completed command
12461 + * @cmd: MMC command which completed
12462 + * @err: MMC error code
12464 + * MMC drivers should call this function when they have completed
12465 + * their processing of a command. This should be called before the
12466 + * data part of the command has completed.
12468 +void mmc_request_done(struct mmc_host *host, struct mmc_request *req)
12470 + struct mmc_command *cmd = req->cmd;
12471 + int err = req->cmd->error;
12472 + DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode,
12473 + err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
12475 + if (err && cmd->retries) {
12478 + host->ops->request(host, req);
12479 + } else if (req->done) {
12484 +EXPORT_SYMBOL(mmc_request_done);
12487 + * mmc_start_request - start a command on a host
12488 + * @host: MMC host to start command on
12489 + * @cmd: MMC command to start
12491 + * Queue a command on the specified host. We expect the
12492 + * caller to be holding the host lock with interrupts disabled.
12495 +mmc_start_request(struct mmc_host *host, struct mmc_request *req)
12497 + DBG("MMC: starting cmd %02x arg %08x flags %08x\n",
12498 + req->cmd->opcode, req->cmd->arg, req->cmd->flags);
12500 + req->cmd->error = 0;
12501 + req->cmd->req = req;
12503 + req->cmd->data = req->data;
12504 + req->data->error = 0;
12505 + req->data->req = req;
12507 + req->data->stop = req->stop;
12508 + req->stop->error = 0;
12509 + req->stop->req = req;
12512 + host->ops->request(host, req);
12515 +EXPORT_SYMBOL(mmc_start_request);
12517 +static void mmc_wait_done(struct mmc_request *req)
12519 + complete(req->done_data);
12522 +int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *req)
12524 + DECLARE_COMPLETION(complete);
12526 + req->done_data = &complete;
12527 + req->done = mmc_wait_done;
12529 + mmc_start_request(host, req);
12531 + wait_for_completion(&complete);
12536 +EXPORT_SYMBOL(mmc_wait_for_req);
12539 + * mmc_wait_for_cmd - start a command and wait for completion
12540 + * @host: MMC host to start command
12541 + * @cmd: MMC command to start
12542 + * @retries: maximum number of retries
12544 + * Start a new MMC command for a host, and wait for the command
12545 + * to complete. Return any error that occurred while the command
12546 + * was executing. Do not attempt to parse the response.
12548 +int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
12550 + struct mmc_request req;
12552 + BUG_ON(host->card_busy == NULL);
12554 + memset(&req, 0, sizeof(struct mmc_request));
12556 + memset(cmd->resp, 0, sizeof(cmd->resp));
12557 + cmd->retries = retries;
12560 + cmd->data = NULL;
12562 + mmc_wait_for_req(host, &req);
12564 + return cmd->error;
12567 +EXPORT_SYMBOL(mmc_wait_for_cmd);
12572 + * __mmc_claim_host - exclusively claim a host
12573 + * @host: mmc host to claim
12574 + * @card: mmc card to claim host for
12576 + * Claim a host for a set of operations. If a valid card
12577 + * is passed and this wasn't the last card selected, select
12578 + * the card before returning.
12580 + * Note: you should use mmc_card_claim_host or mmc_claim_host.
12582 +int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
12584 + DECLARE_WAITQUEUE(wait, current);
12585 + unsigned long flags;
12588 + add_wait_queue(&host->wq, &wait);
12589 + spin_lock_irqsave(&host->lock, flags);
12591 + set_current_state(TASK_UNINTERRUPTIBLE);
12592 + if (host->card_busy == NULL)
12594 + spin_unlock_irqrestore(&host->lock, flags);
12596 + spin_lock_irqsave(&host->lock, flags);
12598 + set_current_state(TASK_RUNNING);
12599 + host->card_busy = card;
12600 + spin_unlock_irqrestore(&host->lock, flags);
12601 + remove_wait_queue(&host->wq, &wait);
12603 + if (card != (void *)-1 && host->card_selected != card) {
12604 + struct mmc_command cmd;
12606 + host->card_selected = card;
12608 + cmd.opcode = MMC_SELECT_CARD;
12609 + cmd.arg = card->rca << 16;
12610 + cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
12612 + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12618 +EXPORT_SYMBOL(__mmc_claim_host);
12621 + * mmc_release_host - release a host
12622 + * @host: mmc host to release
12624 + * Release a MMC host, allowing others to claim the host
12625 + * for their operations.
12627 +void mmc_release_host(struct mmc_host *host)
12629 + unsigned long flags;
12631 + BUG_ON(host->card_busy == NULL);
12633 + spin_lock_irqsave(&host->lock, flags);
12634 + host->card_busy = NULL;
12635 + spin_unlock_irqrestore(&host->lock, flags);
12637 + wake_up(&host->wq);
12640 +EXPORT_SYMBOL(mmc_release_host);
12642 +static void mmc_deselect_cards(struct mmc_host *host)
12644 + struct mmc_command cmd;
12647 + * Ensure that no card is selected.
12649 + if (host->card_selected) {
12650 + host->card_selected = NULL;
12652 + cmd.opcode = MMC_SELECT_CARD;
12654 + cmd.flags = MMC_RSP_NONE;
12656 + mmc_wait_for_cmd(host, &cmd, 0);
12661 +static inline void mmc_delay(unsigned int ms)
12663 + if (ms < HZ / 1000) {
12667 + set_current_state(TASK_INTERRUPTIBLE);
12668 + schedule_timeout(ms * HZ / 1000);
12672 +static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
12677 + * Mask off any voltages we don't support
12679 + ocr &= host->ocr_avail;
12682 + * Select the lowest voltage
12690 + host->ios.vdd = mmc_ocr_bit_to_vdd[bit];
12691 + host->ops->set_ios(host, &host->ios);
12699 +static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp)
12701 + memset(cid, 0, sizeof(struct mmc_cid));
12703 + cid->manfid = resp[0] >> 8;
12704 + cid->prod_name[0] = resp[0];
12705 + cid->prod_name[1] = resp[1] >> 24;
12706 + cid->prod_name[2] = resp[1] >> 16;
12707 + cid->prod_name[3] = resp[1] >> 8;
12708 + cid->prod_name[4] = resp[1];
12709 + cid->prod_name[5] = resp[2] >> 24;
12710 + cid->prod_name[6] = resp[2] >> 16;
12711 + cid->prod_name[7] = '\0';
12712 + cid->hwrev = (resp[2] >> 12) & 15;
12713 + cid->fwrev = (resp[2] >> 8) & 15;
12714 + cid->serial = (resp[2] & 255) << 16 | (resp[3] >> 16);
12715 + cid->month = (resp[3] >> 12) & 15;
12716 + cid->year = (resp[3] >> 8) & 15;
12719 +static void mmc_decode_csd(struct mmc_csd *csd, u32 *resp)
12721 + unsigned int e, m;
12723 + csd->mmc_prot = (resp[0] >> 26) & 15;
12724 + m = (resp[0] >> 19) & 15;
12725 + e = (resp[0] >> 16) & 7;
12726 + csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
12727 + csd->tacc_clks = ((resp[0] >> 8) & 255) * 100;
12729 + m = (resp[0] >> 3) & 15;
12731 + csd->max_dtr = tran_exp[e] * tran_mant[m];
12732 + csd->cmdclass = (resp[1] >> 20) & 0xfff;
12734 + e = (resp[2] >> 15) & 7;
12735 + m = (resp[1] << 2 | resp[2] >> 30) & 0x3fff;
12736 + csd->capacity = (1 + m) << (e + 2);
12738 + csd->read_blkbits = (resp[1] >> 16) & 15;
12742 + * Locate a MMC card on this MMC host given a CID.
12744 +static struct mmc_card *
12745 +mmc_find_card(struct mmc_host *host, struct mmc_cid *cid)
12747 + struct mmc_card *card;
12749 + list_for_each_entry(card, &host->cards, node) {
12750 + if (memcmp(&card->cid, cid, sizeof(struct mmc_cid)) == 0)
12757 + * Allocate a new MMC card, and assign a unique RCA.
12759 +static struct mmc_card *
12760 +mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca)
12762 + struct mmc_card *card, *c;
12763 + unsigned int rca = *frca;
12765 + card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
12767 + return ERR_PTR(-ENOMEM);
12769 + mmc_init_card(card, host);
12770 + memcpy(&card->cid, cid, sizeof(struct mmc_cid));
12773 + list_for_each_entry(c, &host->cards, node)
12774 + if (c->rca == rca) {
12787 + * Apply power to the MMC stack.
12789 +static void mmc_power_up(struct mmc_host *host)
12791 + struct mmc_command cmd;
12792 + int bit = fls(host->ocr_avail) - 1;
12794 + host->ios.vdd = mmc_ocr_bit_to_vdd[bit];
12795 + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
12796 + host->ios.power_mode = MMC_POWER_UP;
12797 + host->ops->set_ios(host, &host->ios);
12801 + host->ios.clock = host->f_min;
12802 + host->ios.power_mode = MMC_POWER_ON;
12803 + host->ops->set_ios(host, &host->ios);
12807 + cmd.opcode = MMC_GO_IDLE_STATE;
12809 + cmd.flags = MMC_RSP_NONE;
12811 + mmc_wait_for_cmd(host, &cmd, 0);
12814 +static void mmc_power_off(struct mmc_host *host)
12816 + host->ios.clock = 0;
12817 + host->ios.vdd = 0;
12818 + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
12819 + host->ios.power_mode = MMC_POWER_OFF;
12820 + host->ops->set_ios(host, &host->ios);
12823 +static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
12825 + struct mmc_command cmd;
12828 + cmd.opcode = MMC_SEND_OP_COND;
12830 + cmd.flags = MMC_RSP_SHORT;
12832 + for (i = 100; i; i--) {
12833 + err = mmc_wait_for_cmd(host, &cmd, 0);
12834 + if (err != MMC_ERR_NONE)
12837 + if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
12840 + err = MMC_ERR_TIMEOUT;
12844 + *rocr = cmd.resp[0];
12850 + * Discover cards by requesting their CID. If this command
12851 + * times out, it is not an error; there are no further cards
12852 + * to be discovered. Add new cards to the list.
12854 + * Create a mmc_card entry for each discovered card, assigning
12855 + * it an RCA, and save the CID.
12857 +static void mmc_discover_cards(struct mmc_host *host)
12859 + struct mmc_card *card;
12860 + unsigned int first_rca = 1, err;
12863 + struct mmc_command cmd;
12864 + struct mmc_cid cid;
12869 + cmd.opcode = MMC_ALL_SEND_CID;
12871 + cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
12873 + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12874 + if (err == MMC_ERR_TIMEOUT) {
12875 + err = MMC_ERR_NONE;
12878 + if (err != MMC_ERR_NONE) {
12879 + printk(KERN_ERR "MMC: mmc%d error requesting CID: %d\n",
12880 + host->host_num, err);
12884 + mmc_decode_cid(&cid, cmd.resp);
12886 + card = mmc_find_card(host, &cid);
12888 + card = mmc_alloc_card(host, &cid, &first_rca);
12889 + if (IS_ERR(card)) {
12890 + err = PTR_ERR(card);
12893 + list_add(&card->node, &host->cards);
12896 + card->state &= ~MMC_STATE_DEAD;
12898 + cmd.opcode = MMC_SET_RELATIVE_ADDR;
12899 + cmd.arg = card->rca << 16;
12900 + cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
12902 + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12903 + if (err != MMC_ERR_NONE)
12904 + card->state |= MMC_STATE_DEAD;
12908 +static void mmc_read_csds(struct mmc_host *host)
12910 + struct mmc_card *card;
12912 + list_for_each_entry(card, &host->cards, node) {
12913 + struct mmc_command cmd;
12916 + if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
12919 + cmd.opcode = MMC_SEND_CSD;
12920 + cmd.arg = card->rca << 16;
12921 + cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
12923 + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12924 + if (err != MMC_ERR_NONE) {
12925 + card->state |= MMC_STATE_DEAD;
12929 + mmc_decode_csd(&card->csd, cmd.resp);
12933 +static unsigned int mmc_calculate_clock(struct mmc_host *host)
12935 + struct mmc_card *card;
12936 + unsigned int max_dtr = host->f_max;
12938 + list_for_each_entry(card, &host->cards, node)
12939 + if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
12940 + max_dtr = card->csd.max_dtr;
12942 + DBG("MMC: selected %d.%03dMHz transfer rate\n",
12943 + max_dtr / 1000000, (max_dtr / 1000) % 1000);
12949 + * Check whether cards we already know about are still present.
12950 + * We do this by requesting status, and checking whether a card
12953 + * A request for status does not cause a state change in data
12956 +static void mmc_check_cards(struct mmc_host *host)
12958 + struct list_head *l, *n;
12960 + mmc_deselect_cards(host);
12962 + list_for_each_safe(l, n, &host->cards) {
12963 + struct mmc_card *card = mmc_list_to_card(l);
12964 + struct mmc_command cmd;
12967 + cmd.opcode = MMC_SEND_STATUS;
12968 + cmd.arg = card->rca << 16;
12969 + cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
12971 + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12972 + if (err == MMC_ERR_NONE)
12976 + * Ok, we believe this card has been removed.
12978 + card->state |= MMC_STATE_DEAD;
12982 +static void mmc_setup(struct mmc_host *host)
12984 + if (host->ios.power_mode != MMC_POWER_ON) {
12988 + mmc_power_up(host);
12990 + err = mmc_send_op_cond(host, 0, &ocr);
12991 + if (err != MMC_ERR_NONE)
12994 + host->ocr = mmc_select_voltage(host, ocr);
12996 + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
12997 + host->ios.clock = host->f_min;
12998 + host->ops->set_ios(host, &host->ios);
13001 + * We should remember the OCR mask from the existing
13002 + * cards, and detect the new cards OCR mask, combine
13003 + * the two and re-select the VDD. However, if we do
13004 + * change VDD, we should do an idle, and then do a
13005 + * full re-initialisation. We would need to notify
13006 + * drivers so that they can re-setup the cards as
13007 + * well, while keeping their queues at bay.
13009 + * For the moment, we take the easy way out - if the
13010 + * new cards don't like our currently selected VDD,
13011 + * they drop off the bus.
13015 + if (host->ocr == 0)
13019 + * Send the selected OCR multiple times... until the cards
13020 + * all get the idea that they should be ready for CMD2.
13021 + * (My SanDisk card seems to need this.)
13023 + mmc_send_op_cond(host, host->ocr, NULL);
13025 + mmc_discover_cards(host);
13028 + * Ok, now switch to push-pull mode.
13030 + host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
13031 + host->ops->set_ios(host, &host->ios);
13033 + mmc_read_csds(host);
13038 + * mmc_detect_change - process change of state on a MMC socket
13039 + * @host: host which changed state.
13041 + * All we know is that card(s) have been inserted or removed
13042 + * from the socket(s). We don't know which socket or cards.
13044 +void mmc_detect_change(struct mmc_host *host)
13046 + struct list_head *l, *n;
13048 + mmc_claim_host(host);
13050 + if (host->ios.power_mode == MMC_POWER_ON)
13051 + mmc_check_cards(host);
13055 + if (!list_empty(&host->cards)) {
13057 + * (Re-)calculate the fastest clock rate which the
13058 + * attached cards and the host support.
13060 + host->ios.clock = mmc_calculate_clock(host);
13061 + host->ops->set_ios(host, &host->ios);
13064 + mmc_release_host(host);
13066 + list_for_each_safe(l, n, &host->cards) {
13067 + struct mmc_card *card = mmc_list_to_card(l);
13070 + * If this is a new and good card, register it.
13072 + if (!mmc_card_present(card) && !mmc_card_dead(card)) {
13073 + if (mmc_register_card(card))
13074 + card->state |= MMC_STATE_DEAD;
13076 + card->state |= MMC_STATE_PRESENT;
13080 + * If this card is dead, destroy it.
13082 + if (mmc_card_dead(card)) {
13083 + list_del(&card->node);
13084 + mmc_remove_card(card);
13089 + * If we discover that there are no cards on the
13090 + * bus, turn off the clock and power down.
13092 + if (list_empty(&host->cards))
13093 + mmc_power_off(host);
13096 +EXPORT_SYMBOL(mmc_detect_change);
13100 + * mmc_init_host - initialise the per-host structure.
13101 + * @host: mmc host
13103 + * Initialise the per-host structure.
13105 +int mmc_init_host(struct mmc_host *host)
13107 + static unsigned int host_num;
13109 + memset(host, 0, sizeof(struct mmc_host));
13111 + host->host_num = host_num++;
13113 + spin_lock_init(&host->lock);
13114 + init_waitqueue_head(&host->wq);
13115 + INIT_LIST_HEAD(&host->cards);
13120 +EXPORT_SYMBOL(mmc_init_host);
13123 + * mmc_add_host - initialise host hardware
13124 + * @host: mmc host
13126 +int mmc_add_host(struct mmc_host *host)
13128 + mmc_power_off(host);
13129 + mmc_detect_change(host);
13134 +EXPORT_SYMBOL(mmc_add_host);
13137 + * mmc_remove_host - remove host hardware
13138 + * @host: mmc host
13140 + * Unregister and remove all cards associated with this host,
13141 + * and power down the MMC bus.
13143 +void mmc_remove_host(struct mmc_host *host)
13145 + struct list_head *l, *n;
13147 + list_for_each_safe(l, n, &host->cards) {
13148 + struct mmc_card *card = mmc_list_to_card(l);
13150 + mmc_remove_card(card);
13153 + mmc_power_off(host);
13156 +EXPORT_SYMBOL(mmc_remove_host);
13161 + * mmc_suspend_host - suspend a host
13162 + * @host: mmc host
13163 + * @state: suspend mode (PM_SUSPEND_xxx)
13165 +int mmc_suspend_host(struct mmc_host *host, u32 state)
13167 + mmc_claim_host(host);
13168 + mmc_deselect_cards(host);
13169 + mmc_power_off(host);
13170 + mmc_release_host(host);
13176 + * mmc_resume_host - resume a previously suspended host
13177 + * @host: mmc host
13179 +int mmc_resume_host(struct mmc_host *host)
13181 + mmc_detect_change(host);
13187 +#else /* CONFIG_PM is not set */
13189 +int mmc_suspend_host(struct mmc_host *host, u32 state) { return 0; }
13190 +int mmc_resume_host(struct mmc_host *host) { return 0; }
13194 +EXPORT_SYMBOL(mmc_suspend_host);
13195 +EXPORT_SYMBOL(mmc_resume_host);
13197 +MODULE_LICENSE("GPL");
13198 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
13199 +++ linux-2.6.5/drivers/media/mmc/Makefile 2004-04-30 20:57:36.000000000 -0400
13202 +# Makefile for the kernel mmc device drivers.
13208 +obj-$(CONFIG_MMC) += mmc_core.o
13213 +obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
13218 +obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
13219 +obj-$(CONFIG_MMC_PXA) += pxamci.o
13221 +mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
13222 --- linux-2.6.5/drivers/media/Makefile~heh 2004-04-03 22:38:15.000000000 -0500
13223 +++ linux-2.6.5/drivers/media/Makefile 2004-04-30 20:57:36.000000000 -0400
13227 obj-y := video/ radio/ dvb/ common/
13229 +obj-$(CONFIG_MMC) += mmc/
13231 --- linux-2.6.5/drivers/serial/Kconfig~heh 2004-04-03 22:38:15.000000000 -0500
13232 +++ linux-2.6.5/drivers/serial/Kconfig 2004-04-30 20:57:36.000000000 -0400
13233 @@ -315,6 +315,29 @@
13234 your boot loader (lilo or loadlin) about how to pass options to the
13235 kernel at boot time.)
13238 + bool "PXA serial port support"
13239 + depends on ARM && ARCH_PXA
13240 + select SERIAL_CORE
13242 + If you have a machine based on an Intel XScale PXA2xx CPU you
13243 + can enable its onboard serial ports by enabling this option.
13245 +config SERIAL_PXA_CONSOLE
13246 + bool "Console on PXA serial port"
13247 + depends on SERIAL_PXA
13248 + select SERIAL_CORE_CONSOLE
13250 + If you have enabled the serial port on the Intel XScale PXA
13251 + CPU you can make it the console by answering Y to this option.
13253 + Even if you say Y here, the currently visible virtual console
13254 + (/dev/tty0) will still be used as the system console by default, but
13255 + you can alter that using a kernel command line option such as
13256 + "console=ttySA0". (Try "man bootparam" or see the documentation of
13257 + your boot loader (lilo or loadlin) about how to pass options to the
13258 + kernel at boot time.)
13260 config SERIAL_SA1100
13261 bool "SA1100 serial port support"
13262 depends on ARM && ARCH_SA1100
13263 --- linux-2.6.5/drivers/serial/pxa.c~heh 2004-04-03 22:38:16.000000000 -0500
13264 +++ linux-2.6.5/drivers/serial/pxa.c 2004-04-30 20:57:36.000000000 -0400
13265 @@ -294,7 +294,6 @@
13266 unsigned char status;
13269 -return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
13270 spin_lock_irqsave(&up->port.lock, flags);
13271 status = serial_in(up, UART_MSR);
13272 spin_unlock_irqrestore(&up->port.lock, flags);
13273 @@ -800,6 +799,21 @@
13274 .ops = &serial_pxa_pops,
13277 + }, { /* HWUART */
13278 + .name = "HWUART",
13279 + .cken = CKEN4_HWUART,
13281 + .type = PORT_PXA,
13282 + .iotype = SERIAL_IO_MEM,
13283 + .membase = (void *)&HWUART,
13284 + .mapbase = __PREG(HWUART),
13285 + .irq = IRQ_HWUART,
13286 + .uartclk = 921600 * 16,
13288 + .flags = ASYNC_SKIP_TEST,
13289 + .ops = &serial_pxa_pops,
13295 --- linux-2.6.5/drivers/serial/sa1100.c~heh 2004-04-03 22:36:24.000000000 -0500
13296 +++ linux-2.6.5/drivers/serial/sa1100.c 2004-04-30 20:57:36.000000000 -0400
13297 @@ -448,6 +448,15 @@
13298 unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
13301 + * If we don't support modem control lines, don't allow
13302 + * these to be set.
13305 + termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR);
13306 + termios->c_cflag |= CLOCAL;
13310 * We only support CS7 and CS8.
13312 while ((termios->c_cflag & CSIZE) != CS7 &&
13313 @@ -894,6 +903,7 @@
13314 if (sa1100_ports[i].port.mapbase != res->start)
13317 + sa1100_ports[i].port.dev = _dev;
13318 uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
13319 dev_set_drvdata(_dev, &sa1100_ports[i]);
13321 --- linux-2.6.5/drivers/mtd/mtd_blkdevs.c~heh 2004-04-03 22:36:14.000000000 -0500
13322 +++ linux-2.6.5/drivers/mtd/mtd_blkdevs.c 2004-04-30 20:57:36.000000000 -0400
13324 struct request_queue *rq = tr->blkcore_priv->rq;
13326 /* we might get involved when memory gets low, so use PF_MEMALLOC */
13327 - current->flags |= PF_MEMALLOC;
13328 + current->flags |= PF_MEMALLOC|PF_IOTHREAD;
13330 daemonize("%sd", tr->name);
13332 --- linux-2.6.5/drivers/mtd/devices/doc1000.c~heh 2004-04-03 22:37:36.000000000 -0500
13333 +++ linux-2.6.5/drivers/mtd/devices/doc1000.c 2004-04-30 20:57:36.000000000 -0400
13335 /*======================================================================
13337 - $Id: doc1000.c,v 1.15 2001/10/02 15:05:13 dwmw2 Exp $
13338 + $Id: doc1000.c,v 1.16 2001/12/28 22:45:17 dwmw2 Exp $
13340 ======================================================================*/
13343 #include <linux/ioctl.h>
13344 #include <asm/io.h>
13345 #include <asm/system.h>
13346 +#include <asm/segment.h>
13347 #include <stdarg.h>
13348 #include <linux/delay.h>
13349 #include <linux/init.h>
13350 @@ -482,7 +483,7 @@
13352 priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
13354 - else if (erase->time + erase_timeout < jiffies)
13355 + else if (time_after(jiffies, erase->time + erase_timeout))
13357 printk("Flash erase timed out. The world is broken.\n");
13359 --- linux-2.6.5/drivers/mtd/mtdconcat.c~heh 2004-04-03 22:37:37.000000000 -0500
13360 +++ linux-2.6.5/drivers/mtd/mtdconcat.c 2004-04-30 20:57:36.000000000 -0400
13365 - * $Id: mtdconcat.c,v 1.4 2003/03/07 17:44:59 rkaiser Exp $
13366 + * $Id: mtdconcat.c,v 1.7 2003/06/29 21:26:34 dwmw2 Exp $
13369 #include <linux/module.h>
13372 struct mtd_concat {
13373 struct mtd_info mtd;
13376 struct mtd_info **subdev;
13379 @@ -37,21 +37,20 @@
13380 #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \
13381 ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *)))
13385 * Given a pointer to the MTD object in the mtd_concat structure,
13386 * we can retrieve the pointer to that structure with this macro.
13388 #define CONCAT(x) ((struct mtd_concat *)(x))
13392 * MTD methods which look up the relevant subdevice, translate the
13393 * effective address and pass through to the subdevice.
13396 -static int concat_read (struct mtd_info *mtd, loff_t from, size_t len,
13397 - size_t *retlen, u_char *buf)
13399 +concat_read(struct mtd_info *mtd, loff_t from, size_t len,
13400 + size_t * retlen, u_char * buf)
13402 struct mtd_concat *concat = CONCAT(mtd);
13404 @@ -59,43 +58,43 @@
13408 - for(i = 0; i < concat->num_subdev; i++)
13410 + for (i = 0; i < concat->num_subdev; i++) {
13411 struct mtd_info *subdev = concat->subdev[i];
13412 size_t size, retsize;
13414 - if (from >= subdev->size)
13415 - { /* Not destined for this subdev */
13417 + if (from >= subdev->size) {
13418 + /* Not destined for this subdev */
13420 from -= subdev->size;
13423 + if (from + len > subdev->size)
13424 + /* First part goes into this subdev */
13425 + size = subdev->size - from;
13428 - if (from + len > subdev->size)
13429 - size = subdev->size - from; /* First part goes into this subdev */
13431 - size = len; /* Entire transaction goes into this subdev */
13432 + /* Entire transaction goes into this subdev */
13435 - err = subdev->read(subdev, from, size, &retsize, buf);
13436 + err = subdev->read(subdev, from, size, &retsize, buf);
13443 - *retlen += retsize;
13447 + *retlen += retsize;
13463 -static int concat_write (struct mtd_info *mtd, loff_t to, size_t len,
13464 - size_t *retlen, const u_char *buf)
13466 +concat_write(struct mtd_info *mtd, loff_t to, size_t len,
13467 + size_t * retlen, const u_char * buf)
13469 struct mtd_concat *concat = CONCAT(mtd);
13471 @@ -106,46 +105,44 @@
13475 - for(i = 0; i < concat->num_subdev; i++)
13477 + for (i = 0; i < concat->num_subdev; i++) {
13478 struct mtd_info *subdev = concat->subdev[i];
13479 size_t size, retsize;
13481 - if (to >= subdev->size)
13484 + if (to >= subdev->size) {
13486 to -= subdev->size;
13489 + if (to + len > subdev->size)
13490 + size = subdev->size - to;
13493 - if (to + len > subdev->size)
13494 - size = subdev->size - to;
13499 - if (!(subdev->flags & MTD_WRITEABLE))
13502 - err = subdev->write(subdev, to, size, &retsize, buf);
13503 + if (!(subdev->flags & MTD_WRITEABLE))
13506 + err = subdev->write(subdev, to, size, &retsize, buf);
13513 - *retlen += retsize;
13517 + *retlen += retsize;
13533 -static int concat_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
13534 - size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
13536 +concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
13537 + size_t * retlen, u_char * buf, u_char * eccbuf,
13538 + struct nand_oobinfo *oobsel)
13540 struct mtd_concat *concat = CONCAT(mtd);
13542 @@ -153,53 +150,56 @@
13546 - for(i = 0; i < concat->num_subdev; i++)
13548 + for (i = 0; i < concat->num_subdev; i++) {
13549 struct mtd_info *subdev = concat->subdev[i];
13550 size_t size, retsize;
13552 - if (from >= subdev->size)
13553 - { /* Not destined for this subdev */
13556 + if (from >= subdev->size) {
13557 + /* Not destined for this subdev */
13559 from -= subdev->size;
13563 + if (from + len > subdev->size)
13564 + /* First part goes into this subdev */
13565 + size = subdev->size - from;
13568 - if (from + len > subdev->size)
13569 - size = subdev->size - from; /* First part goes into this subdev */
13571 - size = len; /* Entire transaction goes into this subdev */
13573 - if (subdev->read_ecc)
13574 - err = subdev->read_ecc(subdev, from, size, &retsize, buf, eccbuf, oobsel);
13577 + /* Entire transaction goes into this subdev */
13582 + if (subdev->read_ecc)
13583 + err = subdev->read_ecc(subdev, from, size,
13584 + &retsize, buf, eccbuf, oobsel);
13588 - *retlen += retsize;
13599 - eccbuf += subdev->oobsize;
13600 - /* in nand.c at least, eccbufs are tagged with 2 (int)eccstatus',
13601 - we must account for these */
13602 - eccbuf += 2 * (sizeof(int));
13605 + *retlen += retsize;
13613 + eccbuf += subdev->oobsize;
13614 + /* in nand.c at least, eccbufs are
13615 + tagged with 2 (int)eccstatus'; we
13616 + must account for these */
13617 + eccbuf += 2 * (sizeof (int));
13624 -static int concat_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
13625 - size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
13627 +concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
13628 + size_t * retlen, const u_char * buf, u_char * eccbuf,
13629 + struct nand_oobinfo *oobsel)
13631 struct mtd_concat *concat = CONCAT(mtd);
13633 @@ -210,50 +210,48 @@
13637 - for(i = 0; i < concat->num_subdev; i++)
13639 + for (i = 0; i < concat->num_subdev; i++) {
13640 struct mtd_info *subdev = concat->subdev[i];
13641 size_t size, retsize;
13643 - if (to >= subdev->size)
13647 + if (to >= subdev->size) {
13649 to -= subdev->size;
13652 + if (to + len > subdev->size)
13653 + size = subdev->size - to;
13656 - if (to + len > subdev->size)
13657 - size = subdev->size - to;
13662 - if (!(subdev->flags & MTD_WRITEABLE))
13664 - else if (subdev->write_ecc)
13665 - err = subdev->write_ecc(subdev, to, size, &retsize, buf, eccbuf, oobsel);
13668 + if (!(subdev->flags & MTD_WRITEABLE))
13670 + else if (subdev->write_ecc)
13671 + err = subdev->write_ecc(subdev, to, size,
13672 + &retsize, buf, eccbuf, oobsel);
13681 - *retlen += retsize;
13685 + *retlen += retsize;
13693 - eccbuf += subdev->oobsize;
13699 + eccbuf += subdev->oobsize;
13705 -static int concat_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
13706 - size_t *retlen, u_char *buf)
13708 +concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
13709 + size_t * retlen, u_char * buf)
13711 struct mtd_concat *concat = CONCAT(mtd);
13713 @@ -261,46 +259,47 @@
13717 - for(i = 0; i < concat->num_subdev; i++)
13719 + for (i = 0; i < concat->num_subdev; i++) {
13720 struct mtd_info *subdev = concat->subdev[i];
13721 size_t size, retsize;
13723 - if (from >= subdev->size)
13724 - { /* Not destined for this subdev */
13727 + if (from >= subdev->size) {
13728 + /* Not destined for this subdev */
13730 from -= subdev->size;
13733 + if (from + len > subdev->size)
13734 + /* First part goes into this subdev */
13735 + size = subdev->size - from;
13738 - if (from + len > subdev->size)
13739 - size = subdev->size - from; /* First part goes into this subdev */
13741 - size = len; /* Entire transaction goes into this subdev */
13743 - if (subdev->read_oob)
13744 - err = subdev->read_oob(subdev, from, size, &retsize, buf);
13747 + /* Entire transaction goes into this subdev */
13752 + if (subdev->read_oob)
13753 + err = subdev->read_oob(subdev, from, size,
13758 - *retlen += retsize;
13769 + *retlen += retsize;
13781 -static int concat_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
13782 - size_t *retlen, const u_char *buf)
13784 +concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
13785 + size_t * retlen, const u_char * buf)
13787 struct mtd_concat *concat = CONCAT(mtd);
13789 @@ -311,50 +310,46 @@
13793 - for(i = 0; i < concat->num_subdev; i++)
13795 + for (i = 0; i < concat->num_subdev; i++) {
13796 struct mtd_info *subdev = concat->subdev[i];
13797 size_t size, retsize;
13799 - if (to >= subdev->size)
13803 + if (to >= subdev->size) {
13805 to -= subdev->size;
13808 + if (to + len > subdev->size)
13809 + size = subdev->size - to;
13812 - if (to + len > subdev->size)
13813 - size = subdev->size - to;
13818 - if (!(subdev->flags & MTD_WRITEABLE))
13820 - else if (subdev->write_oob)
13821 - err = subdev->write_oob(subdev, to, size, &retsize, buf);
13824 + if (!(subdev->flags & MTD_WRITEABLE))
13826 + else if (subdev->write_oob)
13827 + err = subdev->write_oob(subdev, to, size, &retsize,
13837 - *retlen += retsize;
13841 + *retlen += retsize;
13858 -static void concat_erase_callback (struct erase_info *instr)
13859 +static void concat_erase_callback(struct erase_info *instr)
13861 - wake_up((wait_queue_head_t *)instr->priv);
13862 + wake_up((wait_queue_head_t *) instr->priv);
13865 static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
13866 @@ -370,18 +365,18 @@
13869 erase->callback = concat_erase_callback;
13870 - erase->priv = (unsigned long)&waitq;
13872 + erase->priv = (unsigned long) &waitq;
13875 * FIXME: Allow INTERRUPTIBLE. Which means
13876 * not having the wait_queue head on the stack.
13878 err = mtd->erase(mtd, erase);
13882 set_current_state(TASK_UNINTERRUPTIBLE);
13883 add_wait_queue(&waitq, &wait);
13884 - if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED)
13885 + if (erase->state != MTD_ERASE_DONE
13886 + && erase->state != MTD_ERASE_FAILED)
13888 remove_wait_queue(&waitq, &wait);
13889 set_current_state(TASK_RUNNING);
13890 @@ -391,7 +386,7 @@
13894 -static int concat_erase (struct mtd_info *mtd, struct erase_info *instr)
13895 +static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
13897 struct mtd_concat *concat = CONCAT(mtd);
13898 struct mtd_info *subdev;
13899 @@ -402,10 +397,10 @@
13900 if (!(mtd->flags & MTD_WRITEABLE))
13903 - if(instr->addr > concat->mtd.size)
13904 + if (instr->addr > concat->mtd.size)
13907 - if(instr->len + instr->addr > concat->mtd.size)
13908 + if (instr->len + instr->addr > concat->mtd.size)
13912 @@ -414,23 +409,22 @@
13913 * region info rather than looking at each particular sub-device
13916 - if (!concat->mtd.numeraseregions)
13917 - { /* the easy case: device has uniform erase block size */
13918 - if(instr->addr & (concat->mtd.erasesize - 1))
13919 + if (!concat->mtd.numeraseregions) {
13920 + /* the easy case: device has uniform erase block size */
13921 + if (instr->addr & (concat->mtd.erasesize - 1))
13923 - if(instr->len & (concat->mtd.erasesize - 1))
13924 + if (instr->len & (concat->mtd.erasesize - 1))
13928 - { /* device has variable erase size */
13929 - struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions;
13931 + /* device has variable erase size */
13932 + struct mtd_erase_region_info *erase_regions =
13933 + concat->mtd.eraseregions;
13936 * Find the erase region where the to-be-erased area begins:
13938 - for(i = 0; i < concat->mtd.numeraseregions &&
13939 - instr->addr >= erase_regions[i].offset; i++)
13941 + for (i = 0; i < concat->mtd.numeraseregions &&
13942 + instr->addr >= erase_regions[i].offset; i++) ;
13946 @@ -438,25 +432,26 @@
13947 * to-be-erased area begins. Verify that the starting
13948 * offset is aligned to this region's erase size:
13950 - if (instr->addr & (erase_regions[i].erasesize-1))
13951 + if (instr->addr & (erase_regions[i].erasesize - 1))
13955 * now find the erase region where the to-be-erased area ends:
13957 - for(; i < concat->mtd.numeraseregions &&
13958 - (instr->addr + instr->len) >= erase_regions[i].offset ; ++i)
13960 + for (; i < concat->mtd.numeraseregions &&
13961 + (instr->addr + instr->len) >= erase_regions[i].offset;
13965 * check if the ending offset is aligned to this region's erase size
13967 - if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1))
13968 + if ((instr->addr + instr->len) & (erase_regions[i].erasesize -
13973 /* make a local copy of instr to avoid modifying the caller's struct */
13974 - erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL);
13975 + erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
13979 @@ -468,39 +463,40 @@
13980 * find the subdevice where the to-be-erased area begins, adjust
13981 * starting offset to be relative to the subdevice start
13983 - for(i = 0; i < concat->num_subdev; i++)
13985 + for (i = 0; i < concat->num_subdev; i++) {
13986 subdev = concat->subdev[i];
13987 - if(subdev->size <= erase->addr)
13988 + if (subdev->size <= erase->addr)
13989 erase->addr -= subdev->size;
13993 - if(i >= concat->num_subdev) /* must never happen since size */
13994 - BUG(); /* limit has been verified above */
13997 + /* must never happen since size limit has been verified above */
13998 + if (i >= concat->num_subdev)
14001 /* now do the erase: */
14003 - for(;length > 0; i++) /* loop for all subevices affected by this request */
14005 - subdev = concat->subdev[i]; /* get current subdevice */
14006 + for (; length > 0; i++) {
14007 + /* loop for all subdevices affected by this request */
14008 + subdev = concat->subdev[i]; /* get current subdevice */
14010 /* limit length to subdevice's size: */
14011 - if(erase->addr + length > subdev->size)
14012 + if (erase->addr + length > subdev->size)
14013 erase->len = subdev->size - erase->addr;
14015 erase->len = length;
14017 - if (!(subdev->flags & MTD_WRITEABLE))
14019 + if (!(subdev->flags & MTD_WRITEABLE)) {
14023 length -= erase->len;
14024 - if ((err = concat_dev_erase(subdev, erase)))
14026 - if(err == -EINVAL) /* sanity check: must never happen since */
14027 - BUG(); /* block alignment has been checked above */
14028 + if ((err = concat_dev_erase(subdev, erase))) {
14029 + /* sanity check: should never happen since
14030 + * block alignment has been checked above */
14031 + if (err == -EINVAL)
14036 @@ -523,85 +519,79 @@
14040 -static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
14041 +static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
14043 struct mtd_concat *concat = CONCAT(mtd);
14044 int i, err = -EINVAL;
14046 - if ((len + ofs) > mtd->size)
14047 + if ((len + ofs) > mtd->size)
14050 - for(i = 0; i < concat->num_subdev; i++)
14052 + for (i = 0; i < concat->num_subdev; i++) {
14053 struct mtd_info *subdev = concat->subdev[i];
14056 - if (ofs >= subdev->size)
14059 + if (ofs >= subdev->size) {
14061 ofs -= subdev->size;
14064 + if (ofs + len > subdev->size)
14065 + size = subdev->size - ofs;
14068 - if (ofs + len > subdev->size)
14069 - size = subdev->size - ofs;
14074 - err = subdev->lock(subdev, ofs, size);
14075 + err = subdev->lock(subdev, ofs, size);
14099 -static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
14100 +static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
14102 struct mtd_concat *concat = CONCAT(mtd);
14105 - if ((len + ofs) > mtd->size)
14106 + if ((len + ofs) > mtd->size)
14109 - for(i = 0; i < concat->num_subdev; i++)
14111 + for (i = 0; i < concat->num_subdev; i++) {
14112 struct mtd_info *subdev = concat->subdev[i];
14115 - if (ofs >= subdev->size)
14118 + if (ofs >= subdev->size) {
14120 ofs -= subdev->size;
14123 + if (ofs + len > subdev->size)
14124 + size = subdev->size - ofs;
14127 - if (ofs + len > subdev->size)
14128 - size = subdev->size - ofs;
14133 - err = subdev->unlock(subdev, ofs, size);
14134 + err = subdev->unlock(subdev, ofs, size);
14158 @@ -610,8 +600,7 @@
14159 struct mtd_concat *concat = CONCAT(mtd);
14162 - for(i = 0; i < concat->num_subdev; i++)
14164 + for (i = 0; i < concat->num_subdev; i++) {
14165 struct mtd_info *subdev = concat->subdev[i];
14166 subdev->sync(subdev);
14168 @@ -622,10 +611,9 @@
14169 struct mtd_concat *concat = CONCAT(mtd);
14172 - for(i = 0; i < concat->num_subdev; i++)
14174 + for (i = 0; i < concat->num_subdev; i++) {
14175 struct mtd_info *subdev = concat->subdev[i];
14176 - if((rc = subdev->suspend(subdev)) < 0)
14177 + if ((rc = subdev->suspend(subdev)) < 0)
14181 @@ -636,8 +624,7 @@
14182 struct mtd_concat *concat = CONCAT(mtd);
14185 - for(i = 0; i < concat->num_subdev; i++)
14187 + for (i = 0; i < concat->num_subdev; i++) {
14188 struct mtd_info *subdev = concat->subdev[i];
14189 subdev->resume(subdev);
14191 @@ -649,11 +636,10 @@
14192 * stored to *new_dev upon success. This function does _not_
14193 * register any devices: this is the caller's responsibility.
14195 -struct mtd_info *mtd_concat_create(
14196 - struct mtd_info *subdev[], /* subdevices to concatenate */
14197 - int num_devs, /* number of subdevices */
14198 - char *name) /* name for the new device */
14200 +struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */
14201 + int num_devs, /* number of subdevices */
14203 +{ /* name for the new device */
14206 struct mtd_concat *concat;
14207 @@ -661,94 +647,103 @@
14208 int num_erase_region;
14210 printk(KERN_NOTICE "Concatenating MTD devices:\n");
14211 - for(i = 0; i < num_devs; i++)
14212 + for (i = 0; i < num_devs; i++)
14213 printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name);
14214 printk(KERN_NOTICE "into device \"%s\"\n", name);
14216 /* allocate the device structure */
14217 size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
14218 - concat = kmalloc (size, GFP_KERNEL);
14221 - printk ("memory allocation error while creating concatenated device \"%s\"\n",
14224 + concat = kmalloc(size, GFP_KERNEL);
14227 + ("memory allocation error while creating concatenated device \"%s\"\n",
14231 memset(concat, 0, size);
14232 - concat->subdev = (struct mtd_info **)(concat + 1);
14233 + concat->subdev = (struct mtd_info **) (concat + 1);
14236 * Set up the new "super" device's MTD object structure, check for
14237 * incompatibilites between the subdevices.
14239 - concat->mtd.type = subdev[0]->type;
14240 - concat->mtd.flags = subdev[0]->flags;
14241 - concat->mtd.size = subdev[0]->size;
14242 + concat->mtd.type = subdev[0]->type;
14243 + concat->mtd.flags = subdev[0]->flags;
14244 + concat->mtd.size = subdev[0]->size;
14245 concat->mtd.erasesize = subdev[0]->erasesize;
14246 - concat->mtd.oobblock = subdev[0]->oobblock;
14247 - concat->mtd.oobsize = subdev[0]->oobsize;
14248 - concat->mtd.ecctype = subdev[0]->ecctype;
14249 - concat->mtd.eccsize = subdev[0]->eccsize;
14250 + concat->mtd.oobblock = subdev[0]->oobblock;
14251 + concat->mtd.oobsize = subdev[0]->oobsize;
14252 + concat->mtd.ecctype = subdev[0]->ecctype;
14253 + concat->mtd.eccsize = subdev[0]->eccsize;
14254 + if (subdev[0]->read_ecc)
14255 + concat->mtd.read_ecc = concat_read_ecc;
14256 + if (subdev[0]->write_ecc)
14257 + concat->mtd.write_ecc = concat_write_ecc;
14258 + if (subdev[0]->read_oob)
14259 + concat->mtd.read_oob = concat_read_oob;
14260 + if (subdev[0]->write_oob)
14261 + concat->mtd.write_oob = concat_write_oob;
14263 - concat->subdev[0] = subdev[0];
14264 + concat->subdev[0] = subdev[0];
14266 - for(i = 1; i < num_devs; i++)
14268 - if(concat->mtd.type != subdev[i]->type)
14270 + for (i = 1; i < num_devs; i++) {
14271 + if (concat->mtd.type != subdev[i]->type) {
14273 - printk ("Incompatible device type on \"%s\"\n", subdev[i]->name);
14274 + printk("Incompatible device type on \"%s\"\n",
14275 + subdev[i]->name);
14278 - if(concat->mtd.flags != subdev[i]->flags)
14280 - * Expect all flags except MTD_WRITEABLE to be equal on
14281 - * all subdevices.
14282 + if (concat->mtd.flags != subdev[i]->flags) {
14284 + * Expect all flags except MTD_WRITEABLE to be
14285 + * equal on all subdevices.
14287 - if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE)
14289 + if ((concat->mtd.flags ^ subdev[i]->
14290 + flags) & ~MTD_WRITEABLE) {
14292 - printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name);
14293 + printk("Incompatible device flags on \"%s\"\n",
14294 + subdev[i]->name);
14297 - else /* if writeable attribute differs, make super device writeable */
14298 - concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE;
14300 + /* if writeable attribute differs,
14301 + make super device writeable */
14302 + concat->mtd.flags |=
14303 + subdev[i]->flags & MTD_WRITEABLE;
14305 concat->mtd.size += subdev[i]->size;
14306 - if(concat->mtd.oobblock != subdev[i]->oobblock ||
14307 - concat->mtd.oobsize != subdev[i]->oobsize ||
14308 - concat->mtd.ecctype != subdev[i]->ecctype ||
14309 - concat->mtd.eccsize != subdev[i]->eccsize)
14311 + if (concat->mtd.oobblock != subdev[i]->oobblock ||
14312 + concat->mtd.oobsize != subdev[i]->oobsize ||
14313 + concat->mtd.ecctype != subdev[i]->ecctype ||
14314 + concat->mtd.eccsize != subdev[i]->eccsize ||
14315 + !concat->mtd.read_ecc != !subdev[i]->read_ecc ||
14316 + !concat->mtd.write_ecc != !subdev[i]->write_ecc ||
14317 + !concat->mtd.read_oob != !subdev[i]->read_oob ||
14318 + !concat->mtd.write_oob != !subdev[i]->write_oob) {
14320 - printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name);
14321 + printk("Incompatible OOB or ECC data on \"%s\"\n",
14322 + subdev[i]->name);
14325 concat->subdev[i] = subdev[i];
14330 - concat->num_subdev = num_devs;
14331 - concat->mtd.name = name;
14332 + concat->num_subdev = num_devs;
14333 + concat->mtd.name = name;
14336 * NOTE: for now, we do not provide any readv()/writev() methods
14337 * because they are messy to implement and they are not
14338 * used to a great extent anyway.
14340 - concat->mtd.erase = concat_erase;
14341 - concat->mtd.read = concat_read;
14342 - concat->mtd.write = concat_write;
14343 - concat->mtd.read_ecc = concat_read_ecc;
14344 - concat->mtd.write_ecc = concat_write_ecc;
14345 - concat->mtd.read_oob = concat_read_oob;
14346 - concat->mtd.write_oob = concat_write_oob;
14347 - concat->mtd.sync = concat_sync;
14348 - concat->mtd.lock = concat_lock;
14349 - concat->mtd.unlock = concat_unlock;
14350 - concat->mtd.suspend = concat_suspend;
14351 - concat->mtd.resume = concat_resume;
14353 + concat->mtd.erase = concat_erase;
14354 + concat->mtd.read = concat_read;
14355 + concat->mtd.write = concat_write;
14356 + concat->mtd.sync = concat_sync;
14357 + concat->mtd.lock = concat_lock;
14358 + concat->mtd.unlock = concat_unlock;
14359 + concat->mtd.suspend = concat_suspend;
14360 + concat->mtd.resume = concat_resume;
14363 * Combine the erase block size info of the subdevices:
14364 @@ -758,44 +753,44 @@
14366 max_erasesize = curr_erasesize = subdev[0]->erasesize;
14367 num_erase_region = 1;
14368 - for(i = 0; i < num_devs; i++)
14370 - if(subdev[i]->numeraseregions == 0)
14371 - { /* current subdevice has uniform erase size */
14372 - if(subdev[i]->erasesize != curr_erasesize)
14373 - { /* if it differs from the last subdevice's erase size, count it */
14374 + for (i = 0; i < num_devs; i++) {
14375 + if (subdev[i]->numeraseregions == 0) {
14376 + /* current subdevice has uniform erase size */
14377 + if (subdev[i]->erasesize != curr_erasesize) {
14378 + /* if it differs from the last subdevice's erase size, count it */
14379 ++num_erase_region;
14380 curr_erasesize = subdev[i]->erasesize;
14381 - if(curr_erasesize > max_erasesize)
14382 + if (curr_erasesize > max_erasesize)
14383 max_erasesize = curr_erasesize;
14387 - { /* current subdevice has variable erase size */
14389 + /* current subdevice has variable erase size */
14391 - for(j = 0; j < subdev[i]->numeraseregions; j++)
14392 - { /* walk the list of erase regions, count any changes */
14393 - if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
14395 + for (j = 0; j < subdev[i]->numeraseregions; j++) {
14397 + /* walk the list of erase regions, count any changes */
14398 + if (subdev[i]->eraseregions[j].erasesize !=
14399 + curr_erasesize) {
14400 ++num_erase_region;
14401 - curr_erasesize = subdev[i]->eraseregions[j].erasesize;
14402 - if(curr_erasesize > max_erasesize)
14404 + subdev[i]->eraseregions[j].
14406 + if (curr_erasesize > max_erasesize)
14407 max_erasesize = curr_erasesize;
14413 - if(num_erase_region == 1)
14415 + if (num_erase_region == 1) {
14417 * All subdevices have the same uniform erase size.
14420 concat->mtd.erasesize = curr_erasesize;
14421 concat->mtd.numeraseregions = 0;
14427 * erase block size varies across the subdevices: allocate
14428 * space to store the data describing the variable erase regions
14430 @@ -804,13 +799,14 @@
14432 concat->mtd.erasesize = max_erasesize;
14433 concat->mtd.numeraseregions = num_erase_region;
14434 - concat->mtd.eraseregions = erase_region_p = kmalloc (
14435 - num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
14436 - if(!erase_region_p)
14438 + concat->mtd.eraseregions = erase_region_p =
14439 + kmalloc(num_erase_region *
14440 + sizeof (struct mtd_erase_region_info), GFP_KERNEL);
14441 + if (!erase_region_p) {
14443 - printk ("memory allocation error while creating erase region list"
14444 - " for device \"%s\"\n", name);
14446 + ("memory allocation error while creating erase region list"
14447 + " for device \"%s\"\n", name);
14451 @@ -820,46 +816,53 @@
14453 curr_erasesize = subdev[0]->erasesize;
14454 begin = position = 0;
14455 - for(i = 0; i < num_devs; i++)
14457 - if(subdev[i]->numeraseregions == 0)
14458 - { /* current subdevice has uniform erase size */
14459 - if(subdev[i]->erasesize != curr_erasesize)
14461 + for (i = 0; i < num_devs; i++) {
14462 + if (subdev[i]->numeraseregions == 0) {
14463 + /* current subdevice has uniform erase size */
14464 + if (subdev[i]->erasesize != curr_erasesize) {
14466 * fill in an mtd_erase_region_info structure for the area
14467 * we have walked so far:
14469 - erase_region_p->offset = begin;
14470 - erase_region_p->erasesize = curr_erasesize;
14471 - erase_region_p->numblocks = (position - begin) / curr_erasesize;
14472 + erase_region_p->offset = begin;
14473 + erase_region_p->erasesize =
14475 + erase_region_p->numblocks =
14476 + (position - begin) / curr_erasesize;
14479 curr_erasesize = subdev[i]->erasesize;
14482 position += subdev[i]->size;
14485 - { /* current subdevice has variable erase size */
14487 + /* current subdevice has variable erase size */
14489 - for(j = 0; j < subdev[i]->numeraseregions; j++)
14490 - { /* walk the list of erase regions, count any changes */
14491 - if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
14493 - erase_region_p->offset = begin;
14494 - erase_region_p->erasesize = curr_erasesize;
14495 - erase_region_p->numblocks = (position - begin) / curr_erasesize;
14496 + for (j = 0; j < subdev[i]->numeraseregions; j++) {
14497 + /* walk the list of erase regions, count any changes */
14498 + if (subdev[i]->eraseregions[j].
14499 + erasesize != curr_erasesize) {
14500 + erase_region_p->offset = begin;
14501 + erase_region_p->erasesize =
14503 + erase_region_p->numblocks =
14505 + begin) / curr_erasesize;
14508 - curr_erasesize = subdev[i]->eraseregions[j].erasesize;
14510 + subdev[i]->eraseregions[j].
14514 - position += subdev[i]->eraseregions[j].numblocks * curr_erasesize;
14516 + subdev[i]->eraseregions[j].
14517 + numblocks * curr_erasesize;
14521 /* Now write the final entry */
14522 - erase_region_p->offset = begin;
14523 + erase_region_p->offset = begin;
14524 erase_region_p->erasesize = curr_erasesize;
14525 erase_region_p->numblocks = (position - begin) / curr_erasesize;
14527 @@ -874,16 +877,14 @@
14528 void mtd_concat_destroy(struct mtd_info *mtd)
14530 struct mtd_concat *concat = CONCAT(mtd);
14531 - if(concat->mtd.numeraseregions)
14532 + if (concat->mtd.numeraseregions)
14533 kfree(concat->mtd.eraseregions);
14538 EXPORT_SYMBOL(mtd_concat_create);
14539 EXPORT_SYMBOL(mtd_concat_destroy);
14542 MODULE_LICENSE("GPL");
14543 MODULE_AUTHOR("Robert Kaiser <rkaiser@sysgo.de>");
14544 MODULE_DESCRIPTION("Generic support for concatenating of MTD devices");
14545 --- linux-2.6.5/drivers/mtd/maps/Makefile~heh 2004-04-03 22:36:12.000000000 -0500
14546 +++ linux-2.6.5/drivers/mtd/maps/Makefile 2004-04-30 20:57:36.000000000 -0400
14547 @@ -17,12 +17,14 @@
14548 obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o
14549 obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o
14550 obj-$(CONFIG_MTD_IQ80310) += iq80310.o
14551 +obj-$(CONFIG_MTD_IQ80321) += iq80321.o
14552 obj-$(CONFIG_MTD_L440GX) += l440gx.o
14553 obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
14554 obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o
14555 obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
14556 obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
14557 obj-$(CONFIG_MTD_MBX860) += mbx860.o
14558 +obj-$(CONFIG_MTD_NORA) += nora.o
14559 obj-$(CONFIG_MTD_CEIVA) += ceiva.o
14560 obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
14561 obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
14562 --- linux-2.6.5/drivers/mtd/maps/sa1100-flash.c~heh 2004-04-03 22:36:51.000000000 -0500
14563 +++ linux-2.6.5/drivers/mtd/maps/sa1100-flash.c 2004-04-30 20:57:36.000000000 -0400
14565 #include <linux/init.h>
14566 #include <linux/errno.h>
14567 #include <linux/slab.h>
14568 +#include <linux/device.h>
14570 #include <linux/mtd/mtd.h>
14571 #include <linux/mtd/map.h>
14572 @@ -887,6 +888,7 @@
14575 void (*set_vpp)(struct map_info *, int);
14577 struct map_info *map;
14578 struct mtd_info *mtd;
14579 struct resource *res;
14580 @@ -925,6 +927,8 @@
14583 sa[i].map = maps + i;
14584 + sa[i].map->name = sa[i].name;
14585 + sprintf(sa[i].name, "sa1100-%d", i);
14587 sa[i].vbase = ioremap(sa[i].base, sa[i].size);
14588 if (!sa[i].vbase) {
14589 @@ -986,7 +990,7 @@
14591 #ifdef CONFIG_MTD_CONCAT
14592 *rmtd = mtd_concat_create(subdev, found,
14598 @@ -1044,13 +1048,9 @@
14599 * - Is the MSC setup for flash (no -> failure)
14600 * - Probe for flash
14603 -static struct map_info sa1100_probe_map __initdata = {
14604 - .name = "SA1100-flash",
14607 -static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
14608 +static void sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
14610 + struct map_info map;
14611 struct mtd_info *mtd;
14613 printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
14614 @@ -1066,19 +1066,23 @@
14618 - sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4;
14619 - sa1100_probe_map.size = SZ_1M;
14620 - sa1100_probe_map.phys = phys;
14621 - sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M);
14622 - if (sa1100_probe_map.virt == 0)
14623 + memset(&map, 0, sizeof(map));
14625 + map.name = "Probe";
14626 + map.buswidth = msc & MSC_RBW ? 2 : 4;
14627 + map.size = SZ_1M;
14628 + map.phys = NO_XIP;
14629 + map.virt = (unsigned long)ioremap(phys, SZ_1M);
14630 + if (map.virt == 0)
14632 - simple_map_init(&sa1100_probe_map);
14634 + simple_map_init(&map);
14636 /* Shame cfi_probe blurts out kernel messages... */
14637 - mtd = do_map_probe("cfi_probe", &sa1100_probe_map);
14638 + mtd = do_map_probe("cfi_probe", &map);
14641 - iounmap((void *)sa1100_probe_map.virt);
14642 + iounmap((void *)map.virt);
14646 @@ -1090,7 +1094,7 @@
14647 printk("failed\n");
14650 -static void __init sa1100_probe_flash(void)
14651 +static void sa1100_probe_flash(void)
14653 printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n");
14654 sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS);
14655 @@ -1321,10 +1325,9 @@
14656 kfree(parsed_parts);
14659 -static struct mtd_info *mymtd;
14661 -static int __init sa1100_mtd_init(void)
14662 +static int __init sa1100_mtd_probe(struct device *dev)
14664 + struct mtd_info *mtd;
14668 @@ -1332,21 +1335,74 @@
14672 - ret = sa1100_setup_mtd(info, nr, &mymtd);
14674 - sa1100_locate_partitions(mymtd);
14675 + ret = sa1100_setup_mtd(info, nr, &mtd);
14677 + sa1100_locate_partitions(mtd);
14678 + dev_set_drvdata(dev, mtd);
14684 -static void __exit sa1100_mtd_cleanup(void)
14685 +static int __exit sa1100_mtd_remove(struct device *dev)
14687 - sa1100_destroy_mtd(info, mymtd);
14688 + struct mtd_info *mtd = dev_get_drvdata(dev);
14689 + sa1100_destroy_mtd(info, mtd);
14690 sa1100_destroy_partitions();
14694 +static int sa1100_mtd_suspend(struct device *dev, u32 level, u32 state)
14696 + struct mtd_info *mtd = dev_get_drvdata(dev);
14697 + if (level == SUSPEND_SAVE_STATE)
14698 + mtd->suspend(mtd);
14702 +static int sa1100_mtd_resume(struct device *dev, u32 level)
14704 + struct mtd_info *mtd = dev_get_drvdata(dev);
14705 + if (level == RESUME_RESTORE_STATE)
14706 + mtd->resume(mtd);
14710 +static struct platform_device sa1100_mtd_device = {
14715 +static struct device_driver sa1100_mtd_driver = {
14717 + .bus = &platform_bus_type,
14718 + .probe = sa1100_mtd_probe,
14720 + .remove = sa1100_mtd_remove,
14722 + .suspend = sa1100_mtd_suspend,
14723 + .resume = sa1100_mtd_resume,
14726 +static int __init sa1100_mtd_init(void)
14728 + int ret = driver_register(&sa1100_mtd_driver);
14730 + ret = platform_device_register(&sa1100_mtd_device);
14732 + driver_unregister(&sa1100_mtd_driver);
14737 +static void __exit sa1100_mtd_exit(void)
14739 + platform_device_unregister(&sa1100_mtd_device);
14740 + driver_unregister(&sa1100_mtd_driver);
14743 module_init(sa1100_mtd_init);
14744 -module_exit(sa1100_mtd_cleanup);
14745 +module_exit(sa1100_mtd_exit);
14747 MODULE_AUTHOR("Nicolas Pitre");
14748 MODULE_DESCRIPTION("SA1100 CFI map driver");
14749 --- linux-2.6.5/drivers/mtd/maps/pcmciamtd.c~heh 2004-04-03 22:36:19.000000000 -0500
14750 +++ linux-2.6.5/drivers/mtd/maps/pcmciamtd.c 2004-04-30 20:57:36.000000000 -0400
14752 #include <pcmcia/ds.h>
14754 #include <linux/mtd/map.h>
14755 -#include <linux/mtd/mtd.h>
14757 -#ifdef CONFIG_MTD_DEBUG
14758 -static int debug = CONFIG_MTD_DEBUG_VERBOSE;
14759 +#if 1 //def CONFIG_MTD_DEBUG
14760 +static int debug = 5; //CONFIG_MTD_DEBUG_VERBOSE;
14761 MODULE_PARM(debug, "i");
14762 MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
14767 /* Force card to be treated as FLASH, ROM or RAM */
14768 -static int mem_type;
14769 +static int mem_type = 1;
14771 MODULE_LICENSE("GPL");
14772 MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
14773 --- linux-2.6.5/drivers/mtd/maps/pci.c~heh 2004-04-03 22:36:56.000000000 -0500
14774 +++ linux-2.6.5/drivers/mtd/maps/pci.c 2004-04-30 20:57:36.000000000 -0400
14776 #include <linux/mtd/map.h>
14777 #include <linux/mtd/partitions.h>
14779 +#include <asm/io.h>
14781 struct map_pci_info;
14783 struct mtd_pci_info {
14784 --- linux-2.6.5/drivers/input/Kconfig~heh 2004-04-03 22:36:18.000000000 -0500
14785 +++ linux-2.6.5/drivers/input/Kconfig 2004-04-30 20:57:36.000000000 -0400
14787 module will be called joydev.
14790 - tristate "Touchscreen interface"
14791 + tristate "Compaq Touchscreen interface"
14794 Say Y here if you have an application that only can understand the
14795 @@ -102,6 +102,10 @@
14796 depends on INPUT_TSDEV
14799 +config INPUT_TSLIBDEV
14800 + tristate "TSLIB Touchscreen interface"
14804 tristate "Event interface"
14806 --- linux-2.6.5/drivers/input/serio/Kconfig~heh 2004-04-03 22:37:07.000000000 -0500
14807 +++ linux-2.6.5/drivers/input/serio/Kconfig 2004-04-30 20:57:36.000000000 -0400
14810 config SERIO_RPCKBD
14811 tristate "Acorn RiscPC keyboard controller"
14812 - depends on ARCH_ACORN && SERIO
14813 + depends on (ARCH_ACORN || ARCH_CLPS7500) && SERIO
14816 Say Y here if you have the Acorn RiscPC and want to use an AT
14818 To compile this driver as a module, choose M here: the
14819 module will be called rpckbd.
14821 +config SERIO_CLPS7500
14822 + tristate "CLPS7500 PS/2 mouse port controller"
14823 + depends on ARCH_CLPS7500 && SERIO
14825 + Say Y here if you have CLPS7500 based hardware and want to use
14828 + This driver is also available as a module ( = code which can be
14829 + inserted in and removed from the running kernel whenever you want).
14830 + The module will be called clps7500ps2. If you want to compile it
14831 + as a module, say M here and read <file:Documentation/modules.txt>.
14833 config SERIO_AMBAKMI
14834 tristate "AMBA KMI keyboard controller"
14835 depends on ARCH_INTEGRATOR && SERIO
14836 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
14837 +++ linux-2.6.5/drivers/input/serio/sa1100ir.c 2004-04-30 20:57:36.000000000 -0400
14840 + * linux/drivers/input/serio/sa1100ir.c
14842 + * This program is free software; you can redistribute it and/or modify
14843 + * it under the terms of the GNU General Public License as published by
14844 + * the Free Software Foundation; either version 2.
14846 +#include <linux/module.h>
14847 +#include <linux/init.h>
14848 +#include <linux/serio.h>
14850 +#include <asm/io.h>
14851 +#include <asm/irq.h>
14852 +#include <asm/hardware.h>
14856 +struct sa1100_kbd {
14862 +static void sa1100ir_int(int irq, void *dev_id, struct pt_regs *regs)
14864 + struct sa1100_kbd *kbd = dev_id;
14865 + unsigned int status;
14868 + unsigned int flag, data;
14870 + status = readl(kbd->base + UTSR1);
14871 + if (!(status & UTSR1_RNE))
14874 + flag = (status & UTSR1_FRE ? SERIO_FRAME : 0) |
14875 + (status & UTSR1_PRE ? SERIO_PARITY : 0);
14877 + data = readl(kbd->base + UTDR);
14879 + serio_interrupt(&kbd->io, data, flag);
14882 + status = readl(kbd->base + UTSR0) & UTSR0_RID | UTSR0_RBB | UTSR0_REB;
14884 + writel(status, kbd->base + UTSR0);
14887 +static int sa1100ir_kbd_open(struct serio *io)
14889 + struct sa1100_kbd *kbd = io->driver;
14892 + ret = request_irq(kbd->irq, sa1100ir_int, 0, kbd->io.phys, kbd);
14899 +static void sa1100ir_kbd_close(struct serio *io)
14901 + struct sa1100_kbd *kbd = io->driver;
14903 + free_irq(kbd->irq, kbd);
14906 +static struct sa1100_kbd sa1100_kbd = {
14909 + .open = sa1100ir_kbd_open,
14910 + .close = sa1100ir_kbd_close,
14911 + .name = "SA11x0 IR port",
14912 + .phys = "sa11x0/ir",
14913 + .driver = &sa1100_kbd,
14917 +static int __init sa1100_kbd_init(void)
14919 + serio_register_port(&sa1100_kbd.io);
14922 +static void __exit sa1100_kbd_exit(void)
14924 + serio_unregister_port(&sa1100_kbd.io);
14927 +module_init(sa1100_kbd_init);
14928 +module_exit(sa1100_kbd_exit);
14929 --- linux-2.6.5/drivers/input/serio/Makefile~heh 2004-04-03 22:36:16.000000000 -0500
14930 +++ linux-2.6.5/drivers/input/serio/Makefile 2004-04-30 20:57:36.000000000 -0400
14932 obj-$(CONFIG_SERIO_SERPORT) += serport.o
14933 obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o
14934 obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o
14935 +obj-$(CONFIG_SERIO_CLPS7500) += clps7500ps2.o
14936 obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o
14937 obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o
14938 obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
14939 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
14940 +++ linux-2.6.5/drivers/input/tslibdev.c 2004-04-30 20:57:36.000000000 -0400
14943 + * linux/drivers/input/tslibdev.c
14945 + * Copyright (C) 2002 Russell King
14949 + * Copyright (c) 2001 "Crazy" james Simmons
14951 + * Input driver to Touchscreen device driver module.
14953 + * Sponsored by Transvirtual Technology
14957 + * This program is free software; you can redistribute it and/or modify
14958 + * it under the terms of the GNU General Public License as published by
14959 + * the Free Software Foundation; either version 2 of the License, or
14960 + * (at your option) any later version.
14962 + * This program is distributed in the hope that it will be useful,
14963 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14964 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14965 + * GNU General Public License for more details.
14967 + * You should have received a copy of the GNU General Public License
14968 + * along with this program; if not, write to the Free Software
14969 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14971 + * Should you need to contact me, the author, you can do so either by
14972 + * e-mail - mail your message to <jsimmons@transvirtual.com>.
14975 +#include <linux/slab.h>
14976 +#include <linux/poll.h>
14977 +#include <linux/module.h>
14978 +#include <linux/init.h>
14979 +#include <linux/input.h>
14980 +#include <linux/config.h>
14981 +#include <linux/smp_lock.h>
14982 +#include <linux/random.h>
14983 +#include <linux/time.h>
14984 +#include <linux/list.h>
14985 +#include <linux/miscdevice.h>
14987 +struct ucb1x00_dev {
14990 + wait_queue_head_t wait;
14991 + struct list_head list;
14992 + struct input_handle handle;
15003 + struct timeval stamp;
15006 +#define TSDEV_BUFFER_SIZE 64
15008 +struct ucb1x00_list {
15009 + struct list_head list;
15010 + struct fasync_struct *fasync;
15011 + struct ucb1x00_dev *tsdev;
15012 + unsigned int head;
15013 + unsigned int tail;
15014 + struct ts_event event[TSDEV_BUFFER_SIZE];
15017 +static struct input_handler ucb1x00_handler;
15018 +static struct ucb1x00_dev *ucb1x00_dev;
15020 +static void ucb1x00_remove(struct ucb1x00_dev *tsdev);
15023 +static int ucb1x00_fasync(int fd, struct file *file, int on)
15025 + struct ucb1x00_list *list = file->private_data;
15028 + retval = fasync_helper(fd, file, on, &list->fasync);
15029 + return retval < 0 ? retval : 0;
15032 +static int ucb1x00_open(struct inode *inode, struct file *file)
15034 + struct ucb1x00_list *list;
15037 + if (!ucb1x00_dev || !ucb1x00_dev->exist)
15040 + printk(KERN_WARNING
15041 + "tslibdev: process %s (%d) uses obsolete tslib device\n",
15042 + current->comm, current->pid);
15044 + list = kmalloc(sizeof(struct ucb1x00_list), GFP_KERNEL);
15048 + memset(list, 0, sizeof(struct ucb1x00_list));
15050 + empty = list_empty(&ucb1x00_dev->list);
15052 + list->tsdev = ucb1x00_dev;
15053 + list_add(&list->list, &list->tsdev->list);
15055 + file->private_data = list;
15057 + if (empty && list->tsdev->exist)
15058 + input_open_device(&list->tsdev->handle);
15063 +static int ucb1x00_release(struct inode *inode, struct file *file)
15065 + struct ucb1x00_list *list = file->private_data;
15067 + ucb1x00_fasync(-1, file, 0);
15069 + list_del(&list->list);
15071 + ucb1x00_remove(list->tsdev);
15079 +ucb1x00_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
15081 + DECLARE_WAITQUEUE(wait, current);
15082 + struct ucb1x00_list *list = file->private_data;
15085 + if (list->head == list->tail) {
15086 + add_wait_queue(&list->tsdev->wait, &wait);
15088 + while (list->head == list->tail) {
15089 + set_current_state(TASK_INTERRUPTIBLE);
15091 + if (!list->tsdev->exist) {
15092 + retval = -ENODEV;
15095 + if (file->f_flags & O_NONBLOCK) {
15096 + retval = -EAGAIN;
15099 + if (signal_pending(current)) {
15100 + retval = -ERESTARTSYS;
15105 + set_current_state(TASK_RUNNING);
15106 + remove_wait_queue(&list->tsdev->wait, &wait);
15112 + while (list->head != list->tail && count >= sizeof(struct ts_event)) {
15113 + if (copy_to_user(buffer, list->event + list->tail,
15114 + sizeof(struct ts_event)))
15115 + return retval ? retval : -EFAULT;
15116 + list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1);
15117 + retval += sizeof(struct ts_event);
15118 + buffer += sizeof(struct ts_event);
15119 + count -= sizeof(struct ts_event);
15124 +/* No kernel lock - fine */
15125 +static unsigned int ucb1x00_poll(struct file *file, poll_table * wait)
15127 + struct ucb1x00_list *list = file->private_data;
15129 + poll_wait(file, &list->tsdev->wait, wait);
15130 + if (list->head != list->tail || !list->tsdev->exist)
15131 + return POLLIN | POLLRDNORM;
15136 +ucb1x00_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
15137 + unsigned long arg)
15142 +struct file_operations ucb1x00_fops = {
15143 + .owner = THIS_MODULE,
15144 + .open = ucb1x00_open,
15145 + .release = ucb1x00_release,
15146 + .read = ucb1x00_read,
15147 + .poll = ucb1x00_poll,
15148 + .fasync = ucb1x00_fasync,
15149 + .ioctl = ucb1x00_ioctl,
15153 + * The official UCB1x00 touchscreen is a miscdevice:
15154 + * 10 char Non-serial mice, misc features
15155 + * 14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen
15157 +static struct miscdevice ucb1x00_ts_dev = {
15159 + .name = "touchscreen/ucb1x00",
15160 + .fops = &ucb1x00_fops,
15161 + .devfs_name = "touchscreen/ucb1x00",
15164 +static void ucb1x00_remove(struct ucb1x00_dev *tsdev)
15166 + if (list_empty(&tsdev->list)) {
15167 + if (tsdev->exist) {
15168 + input_close_device(&tsdev->handle);
15169 + wake_up_interruptible(&tsdev->wait);
15171 + misc_deregister(&ucb1x00_ts_dev);
15172 + ucb1x00_dev = NULL;
15180 +ucb1x00_event(struct input_handle *handle, unsigned int type, unsigned int code,
15183 + struct ucb1x00_dev *tsdev = handle->private;
15184 + struct list_head *l;
15186 + /* sorry, we only handle absolute stuff */
15187 + if (type == EV_ABS) {
15190 + tsdev->x = value;
15193 + tsdev->y = value;
15195 + case ABS_PRESSURE:
15196 + tsdev->pressure = value;
15202 + if (type != EV_SYN || code != SYN_REPORT)
15205 + list_for_each(l, &tsdev->list) {
15206 + struct ucb1x00_list *list = list_entry(l, struct ucb1x00_list, list);
15207 + list->event[list->head].pressure = tsdev->pressure;
15208 + if (tsdev->pressure) {
15209 + list->event[list->head].x = tsdev->x;
15210 + list->event[list->head].y = tsdev->y;
15212 + list->event[list->head].x = 0;
15213 + list->event[list->head].y = 0;
15215 + do_gettimeofday(&list->event[list->head].stamp);
15216 + list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1);
15217 + kill_fasync(&list->fasync, SIGIO, POLL_IN);
15219 + wake_up_interruptible(&tsdev->wait);
15222 +static struct input_handle *
15223 +ucb1x00_connect(struct input_handler *handler, struct input_dev *dev,
15224 + struct input_device_id *id)
15226 + struct ucb1x00_dev *tsdev;
15231 + tsdev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL);
15235 + memset(tsdev, 0, sizeof(struct ucb1x00_dev));
15236 + init_waitqueue_head(&tsdev->wait);
15237 + INIT_LIST_HEAD(&tsdev->list);
15239 + ucb1x00_dev = tsdev;
15241 + strcpy(tsdev->name, ucb1x00_ts_dev.name);
15243 + tsdev->handle.dev = dev;
15244 + tsdev->handle.name = tsdev->name;
15245 + tsdev->handle.handler = handler;
15246 + tsdev->handle.private = tsdev;
15248 + misc_register(&ucb1x00_ts_dev);
15250 + tsdev->exist = 1;
15252 + return &tsdev->handle;
15255 +static void ucb1x00_disconnect(struct input_handle *handle)
15257 + struct ucb1x00_dev *tsdev = handle->private;
15259 + tsdev->exist = 0;
15260 + ucb1x00_remove(tsdev);
15263 +static struct input_device_id ucb1x00_ids[] = {
15265 + .flags = INPUT_DEVICE_ID_MATCH_ABSBIT,
15266 + .evbit = { BIT(EV_ABS) },
15267 + .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
15270 + {},/* Terminating entry */
15273 +MODULE_DEVICE_TABLE(input, ucb1x00_ids);
15275 +static struct input_handler ucb1x00_handler = {
15276 + .event = ucb1x00_event,
15277 + .connect = ucb1x00_connect,
15278 + .disconnect = ucb1x00_disconnect,
15279 + .name = "touchscreen/ucb1x00",
15280 + .id_table = ucb1x00_ids,
15283 +static int __init ucb1x00_init(void)
15285 + input_register_handler(&ucb1x00_handler);
15286 + printk(KERN_INFO "ts: UCB1x00 touchscreen protocol output\n");
15290 +static void __exit ucb1x00_exit(void)
15292 + input_unregister_handler(&ucb1x00_handler);
15295 +module_init(ucb1x00_init);
15296 +module_exit(ucb1x00_exit);
15298 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
15299 +MODULE_DESCRIPTION("Input driver to UCB1x00 touchscreen converter");
15300 --- linux-2.6.5/drivers/input/Makefile~heh 2004-04-03 22:38:17.000000000 -0500
15301 +++ linux-2.6.5/drivers/input/Makefile 2004-04-30 20:57:36.000000000 -0400
15303 obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
15304 obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
15305 obj-$(CONFIG_INPUT_EVDEV) += evdev.o
15306 +obj-$(CONFIG_INPUT_TSLIBDEV) += tslibdev.o
15307 obj-$(CONFIG_INPUT_TSDEV) += tsdev.o
15308 obj-$(CONFIG_INPUT_POWER) += power.o
15309 obj-$(CONFIG_INPUT_EVBUG) += evbug.o
15310 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
15311 +++ linux-2.6.5/drivers/char/sa1100-rtc.c 2004-04-30 20:57:36.000000000 -0400
15314 + * Real Time Clock interface for Linux on Intel SA11x0/PXA2xx
15316 + * Copyright (c) 2000 Nils Faerber
15318 + * Based on rtc.c by Paul Gortmaker
15319 + * Date/time conversion routines taken from arch/arm/kernel/time.c
15320 + * by Linus Torvalds and Russel King
15321 + * and the GNU C Library
15322 + * ( ... I love the GPL ... just take what you need! ;)
15324 + * This program is free software; you can redistribute it and/or
15325 + * modify it under the terms of the GNU General Public License
15326 + * as published by the Free Software Foundation; either version
15327 + * 2 of the License, or (at your option) any later version.
15329 + * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org>
15330 + * - added periodic timer capability using OSMR1
15331 + * - flag compatibility with other RTC chips
15332 + * - permission checks for ioctls
15333 + * - major cleanup, partial rewrite
15335 + * 0.03 2001-03-07 CIH <cih@coventive.com>
15336 + * - Modify the bug setups RTC clock.
15338 + * 0.02 2001-02-27 Nils Faerber <nils@@kernelconcepts.de>
15339 + * - removed mktime(), added alarm irq clear
15341 + * 0.01 2000-10-01 Nils Faerber <nils@@kernelconcepts.de>
15342 + * - initial release
15345 +#include <linux/module.h>
15346 +#include <linux/fs.h>
15347 +#include <linux/miscdevice.h>
15348 +#include <linux/string.h>
15349 +#include <linux/init.h>
15350 +#include <linux/poll.h>
15351 +#include <linux/proc_fs.h>
15352 +#include <linux/interrupt.h>
15353 +#include <linux/rtc.h>
15355 +#include <asm/bitops.h>
15356 +#include <asm/hardware.h>
15357 +#include <asm/irq.h>
15358 +#include <asm/rtc.h>
15360 +#define TIMER_FREQ 3686400
15362 +#define RTC_DEF_DIVIDER 32768 - 1
15363 +#define RTC_DEF_TRIM 0
15365 +/* Those are the bits from a classic RTC we want to mimic */
15366 +#define RTC_IRQF 0x80 /* any of the following 3 is active */
15367 +#define RTC_PF 0x40
15368 +#define RTC_AF 0x20
15369 +#define RTC_UF 0x10
15371 +static unsigned long rtc_freq = 1024;
15372 +static struct rtc_time rtc_alarm = {
15381 +extern spinlock_t rtc_lock;
15383 +static int rtc_update_alarm(struct rtc_time *alrm)
15385 + struct rtc_time alarm_tm, now_tm;
15386 + unsigned long now, time;
15391 + rtc_time_to_tm(now, &now_tm);
15392 + rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
15393 + ret = rtc_tm_to_time(&alarm_tm, &time);
15397 + RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
15399 + } while (now != RCNR);
15404 +static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15406 + unsigned int rtsr;
15407 + unsigned long events = 0;
15409 + spin_lock(&rtc_lock);
15412 + /* clear interrupt sources */
15414 + RTSR = (RTSR_AL|RTSR_HZ) & (rtsr >> 2);
15416 + /* clear alarm interrupt if it has occurred */
15417 + if (rtsr & RTSR_AL)
15418 + rtsr &= ~RTSR_ALE;
15419 + RTSR = rtsr & (RTSR_ALE|RTSR_HZE);
15421 + /* update irq data & counter */
15422 + if (rtsr & RTSR_AL)
15423 + events |= (RTC_AF|RTC_IRQF);
15424 + if (rtsr & RTSR_HZ)
15425 + events |= (RTC_UF|RTC_IRQF);
15427 + rtc_update(1, events);
15429 + if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
15430 + rtc_update_alarm(&rtc_alarm);
15432 + spin_unlock(&rtc_lock);
15434 + return IRQ_HANDLED;
15438 +static unsigned long rtc_irq_data;
15440 +static irqreturn_t timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15443 + * If we match for the first time, the periodic interrupt flag won't
15444 + * be set. If it is, then we did wrap around (very unlikely but
15445 + * still possible) and compute the amount of missed periods.
15446 + * The match reg is updated only when the data is actually retrieved
15447 + * to avoid unnecessary interrupts.
15449 + OSSR = OSSR_M1; /* clear match on timer1 */
15450 + if (rtc_irq_data & RTC_PF) {
15451 + rtc_irq_data += (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))) << 8;
15453 + rtc_update(1, RTC_PF | RTC_IRQF);
15456 + wake_up_interruptible(&rtc_wait);
15457 + kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
15459 + return IRQ_HANDLED;
15463 +static int sa1100_rtc_open(void)
15467 + ret = request_irq(IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
15469 + printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
15472 + ret = request_irq(IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
15474 + printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
15478 + ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL);
15480 + printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1);
15483 + rtc_irq_data = 0;
15488 + free_irq(IRQ_RTCAlrm, NULL);
15490 + free_irq(IRQ_RTC1Hz, NULL);
15495 +static void sa1100_rtc_release(void)
15497 + spin_lock_irq (&rtc_lock);
15499 + OIER &= ~OIER_E1;
15501 + spin_unlock_irq (&rtc_lock);
15503 +// free_irq(IRQ_OST1, NULL);
15504 + free_irq(IRQ_RTCAlrm, NULL);
15505 + free_irq(IRQ_RTC1Hz, NULL);
15509 +ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
15511 + DECLARE_WAITQUEUE(wait, current);
15512 + unsigned long data;
15515 + if (count < sizeof(unsigned long))
15518 + add_wait_queue(&rtc_wait, &wait);
15519 + set_current_state(TASK_INTERRUPTIBLE);
15521 + spin_lock_irq (&rtc_lock);
15522 + data = rtc_irq_data;
15524 + rtc_irq_data = 0;
15527 + spin_unlock_irq (&rtc_lock);
15529 + if (file->f_flags & O_NONBLOCK) {
15530 + retval = -EAGAIN;
15534 + if (signal_pending(current)) {
15535 + retval = -ERESTARTSYS;
15542 + if (data & RTC_PF) {
15543 + /* interpolate missed periods and set match for the next one */
15544 + unsigned long period = TIMER_FREQ/rtc_freq;
15545 + unsigned long oscr = OSCR;
15546 + unsigned long osmr1 = OSMR1;
15547 + unsigned long missed = (oscr - osmr1)/period;
15548 + data += missed << 8;
15549 + OSSR = OSSR_M1; /* clear match on timer 1 */
15550 + OSMR1 = osmr1 + (missed + 1)*period;
15551 + /* ensure we didn't miss another match in the mean time */
15552 + while( (signed long)((osmr1 = OSMR1) - OSCR) <= 0 ) {
15554 + OSSR = OSSR_M1; /* clear match on timer 1 */
15555 + OSMR1 = osmr1 + period;
15558 + spin_unlock_irq (&rtc_lock);
15560 + data -= 0x100; /* the first IRQ wasn't actually missed */
15562 + retval = put_user(data, (unsigned long *)buf);
15564 + retval = sizeof(unsigned long);
15567 + set_current_state(TASK_RUNNING);
15568 + remove_wait_queue(&rtc_wait, &wait);
15573 +static int sa1100_rtc_ioctl(unsigned int cmd, unsigned long arg)
15576 + case RTC_AIE_OFF:
15577 + spin_lock_irq(&rtc_lock);
15578 + RTSR &= ~RTSR_ALE;
15579 +// rtc_irq_data = 0;
15580 + spin_unlock_irq(&rtc_lock);
15583 + spin_lock_irq(&rtc_lock);
15584 + RTSR |= RTSR_ALE;
15585 +// rtc_irq_data = 0;
15586 + spin_unlock_irq(&rtc_lock);
15588 + case RTC_UIE_OFF:
15589 + spin_lock_irq(&rtc_lock);
15590 + RTSR &= ~RTSR_HZE;
15591 +// rtc_irq_data = 0;
15592 + spin_unlock_irq(&rtc_lock);
15595 + spin_lock_irq(&rtc_lock);
15596 + RTSR |= RTSR_HZE;
15597 +// rtc_irq_data = 0;
15598 + spin_unlock_irq(&rtc_lock);
15601 + case RTC_PIE_OFF:
15602 + spin_lock_irq(&rtc_lock);
15603 + OIER &= ~OIER_E1;
15604 +// rtc_irq_data = 0;
15605 + spin_unlock_irq(&rtc_lock);
15608 + if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
15610 + spin_lock_irq(&rtc_lock);
15611 + OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
15613 +// rtc_irq_data = 0;
15614 + spin_unlock_irq(&rtc_lock);
15616 + case RTC_IRQP_READ:
15617 + return put_user(rtc_freq, (unsigned long *)arg);
15618 + case RTC_IRQP_SET:
15619 + if (arg < 1 || arg > TIMER_FREQ)
15621 + if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
15630 +static void sa1100_rtc_read_time(struct rtc_time *tm)
15632 + rtc_time_to_tm(RCNR, tm);
15635 +static int sa1100_rtc_set_time(struct rtc_time *tm)
15637 + unsigned long time;
15640 + ret = rtc_tm_to_time(tm, &time);
15646 +static void sa1100_rtc_read_alarm(struct rtc_wkalrm *alrm)
15648 + memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
15649 + alrm->pending = RTSR & RTSR_AL ? 1 : 0;
15652 +static int sa1100_rtc_set_alarm(struct rtc_wkalrm *alrm)
15656 + spin_lock_irq(&rtc_lock);
15657 + ret = rtc_update_alarm(&alrm->time);
15659 + memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time));
15661 + if (alrm->enabled)
15662 + enable_irq_wake(IRQ_RTCAlrm);
15664 + disable_irq_wake(IRQ_RTCAlrm);
15666 + spin_unlock_irq(&rtc_lock);
15671 +static int sa1100_rtc_proc(char *buf)
15675 + p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR);
15676 + p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" );
15677 + p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no");
15678 + p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no");
15679 + p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq);
15684 +static struct rtc_ops sa1100_rtc_ops = {
15685 + .owner = THIS_MODULE,
15686 + .open = sa1100_rtc_open,
15687 + .release = sa1100_rtc_release,
15688 + .ioctl = sa1100_rtc_ioctl,
15690 + .read_time = sa1100_rtc_read_time,
15691 + .set_time = sa1100_rtc_set_time,
15692 + .read_alarm = sa1100_rtc_read_alarm,
15693 + .set_alarm = sa1100_rtc_set_alarm,
15694 + .proc = sa1100_rtc_proc,
15697 +static int __init rtc_init(void)
15700 + * According to the manual we should be able to let RTTR be zero
15701 + * and then a default diviser for a 32.768KHz clock is used.
15702 + * Apparently this doesn't work, at least for my SA1110 rev 5.
15703 + * If the clock divider is uninitialized then reset it to the
15704 + * default value to get the 1Hz clock.
15707 + RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
15708 + printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
15709 + /* The current RTC value probably doesn't make sense either */
15713 + register_rtc(&sa1100_rtc_ops);
15718 +static void __exit rtc_exit(void)
15720 + unregister_rtc(&sa1100_rtc_ops);
15723 +module_init(rtc_init);
15724 +module_exit(rtc_exit);
15726 +MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>");
15727 +MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
15728 +MODULE_LICENSE("GPL"); /* so says the header */
15729 --- linux-2.6.5/drivers/char/Kconfig~heh 2004-04-03 22:36:15.000000000 -0500
15730 +++ linux-2.6.5/drivers/char/Kconfig 2004-04-30 20:57:36.000000000 -0400
15731 @@ -814,6 +814,10 @@
15736 + tristate "SA1100 or PXA Real Time Clock"
15737 + depends on ARCH_SA1100 || ARCH_PXA
15740 tristate "Double Talk PC internal speech card support"
15742 --- linux-2.6.5/drivers/char/tty_io.c~heh 2004-04-03 22:37:23.000000000 -0500
15743 +++ linux-2.6.5/drivers/char/tty_io.c 2004-04-30 20:57:36.000000000 -0400
15744 @@ -1535,10 +1535,17 @@
15749 + * In the case of pty's, "tty" is the master side
15750 + * and "real_tty" is the slave side.
15752 static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
15753 struct winsize * arg)
15755 struct winsize tmp_ws;
15756 + struct task_struct *p;
15757 + struct list_head *l;
15760 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
15762 @@ -1558,8 +1565,21 @@
15765 kill_pg(tty->pgrp, SIGWINCH, 1);
15766 - if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
15767 - kill_pg(real_tty->pgrp, SIGWINCH, 1);
15770 + * Send SIGWINCH to the whole session on the slave tty.
15771 + * However, in the case of non-master pty's, be careful
15772 + * not to send two SIGWINCH to the same procress group.
15774 + if (real_tty->session > 0) {
15775 + read_lock(&tasklist_lock);
15776 + for_each_task_pid(real_tty->session, PIDTYPE_SID, p, l, pid) {
15777 + if (process_group(p) != tty->pgrp)
15778 + group_send_sig_info(SIGWINCH, (void *)1L, p);
15780 + read_unlock(&tasklist_lock);
15783 tty->winsize = tmp_ws;
15784 real_tty->winsize = tmp_ws;
15786 --- linux-2.6.5/drivers/Makefile~heh 2004-04-03 22:37:43.000000000 -0500
15787 +++ linux-2.6.5/drivers/Makefile 2004-04-30 20:57:36.000000000 -0400
15789 # PnP must come after ACPI since it will eventually need to check if acpi
15790 # was used and do nothing if so
15791 obj-$(CONFIG_PNP) += pnp/
15792 +obj-$(CONFIG_I2C) += i2c/
15793 +obj-$(CONFIG_L3) += l3/
15795 # char/ comes before serial/ etc so that the VT console is the boot-time
15798 obj-$(CONFIG_GAMEPORT) += input/gameport/
15799 obj-$(CONFIG_SERIO) += input/serio/
15800 obj-$(CONFIG_I2O) += message/
15801 -obj-$(CONFIG_I2C) += i2c/
15802 obj-$(CONFIG_PHONE) += telephony/
15803 obj-$(CONFIG_MD) += md/
15804 obj-$(CONFIG_BT) += bluetooth/
15805 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
15806 +++ linux-2.6.5/drivers/l3/Kconfig 2004-04-30 20:57:36.000000000 -0400
15809 +# L3 bus configuration
15812 +menu "L3 serial bus support"
15815 + tristate "L3 support"
15818 + bool "L3 bit-banging interfaces"
15821 +config L3_BIT_SA1100_GPIO
15822 + bool "SA11x0 GPIO adapter"
15823 + depends on L3_ALGOBIT && ARCH_SA1100
15825 +# i2c must come before this
15826 +config BIT_SA1100_GPIO
15828 + depends on L3_BIT_SA1100_GPIO || I2C_BIT_SA1100_GPIO=y
15832 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
15833 +++ linux-2.6.5/drivers/l3/l3-core.c 2004-04-30 20:57:36.000000000 -0400
15836 + * linux/drivers/l3/l3-core.c
15838 + * Copyright (C) 2001 Russell King
15840 + * General structure taken from i2c-core.c by Simon G. Vogl
15842 + * This program is free software; you can redistribute it and/or modify
15843 + * it under the terms of the GNU General Public License as published by
15844 + * the Free Software Foundation; either version 2 of the License.
15846 + * See linux/Documentation/l3 for further documentation.
15848 +#include <linux/module.h>
15849 +#include <linux/kernel.h>
15850 +#include <linux/errno.h>
15851 +#include <linux/slab.h>
15852 +#include <linux/proc_fs.h>
15853 +#include <linux/kmod.h>
15854 +#include <linux/init.h>
15855 +#include <linux/l3/l3.h>
15857 +static DECLARE_MUTEX(adapter_lock);
15858 +static LIST_HEAD(adapter_list);
15860 +static DECLARE_MUTEX(driver_lock);
15861 +static LIST_HEAD(driver_list);
15864 + * l3_add_adapter - register a new L3 bus adapter
15865 + * @adap: l3_adapter structure for the registering adapter
15867 + * Make the adapter available for use by clients using name adap->name.
15868 + * The adap->adapters list is initialised by this function.
15872 +int l3_add_adapter(struct l3_adapter *adap)
15874 + down(&adapter_lock);
15875 + list_add(&adap->adapters, &adapter_list);
15876 + up(&adapter_lock);
15881 + * l3_del_adapter - unregister a L3 bus adapter
15882 + * @adap: l3_adapter structure to unregister
15884 + * Remove an adapter from the list of available L3 Bus adapters.
15888 +int l3_del_adapter(struct l3_adapter *adap)
15890 + down(&adapter_lock);
15891 + list_del(&adap->adapters);
15892 + up(&adapter_lock);
15896 +static struct l3_adapter *__l3_get_adapter(const char *name)
15898 + struct list_head *l;
15900 + list_for_each(l, &adapter_list) {
15901 + struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters);
15903 + if (strcmp(adap->name, name) == 0)
15911 + * l3_get_adapter - get a reference to an adapter
15912 + * @name: driver name
15914 + * Obtain a l3_adapter structure for the specified adapter. If the adapter
15915 + * is not currently load, then load it. The adapter will be locked in core
15916 + * until all references are released via l3_put_adapter.
15918 +struct l3_adapter *l3_get_adapter(const char *name)
15920 + struct l3_adapter *adap;
15923 + for (try = 0; try < 2; try ++) {
15924 + down(&adapter_lock);
15925 + adap = __l3_get_adapter(name);
15926 + if (adap && !try_module_get(adap->owner))
15928 + up(&adapter_lock);
15934 + request_module(name);
15941 + * l3_put_adapter - release a reference to an adapter
15942 + * @adap: driver to release reference
15944 + * Indicate to the L3 core that you no longer require the adapter reference.
15945 + * The adapter module may be unloaded when there are no references to its
15946 + * data structure.
15948 + * You must not use the reference after calling this function.
15950 +void l3_put_adapter(struct l3_adapter *adap)
15952 + if (adap && adap->owner)
15953 + module_put(adap->owner);
15957 + * l3_transfer - transfer information on an L3 bus
15958 + * @adap: adapter structure to perform transfer on
15959 + * @msgs: array of l3_msg structures describing transfer
15960 + * @num: number of l3_msg structures
15962 + * Transfer the specified messages to/from a device on the L3 bus.
15964 + * Returns number of messages successfully transferred, otherwise negative
15967 +int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
15969 + int ret = -ENOSYS;
15971 + if (adap->algo->xfer) {
15972 + down(adap->lock);
15973 + ret = adap->algo->xfer(adap, msgs, num);
15980 + * l3_write - send data to a device on an L3 bus
15981 + * @adap: L3 bus adapter
15982 + * @addr: L3 bus address
15983 + * @buf: buffer for bytes to send
15984 + * @len: number of bytes to send
15986 + * Send len bytes pointed to by buf to device address addr on the L3 bus
15987 + * described by client.
15989 + * Returns the number of bytes transferred, or negative error code.
15991 +int l3_write(struct l3_adapter *adap, int addr, const char *buf, int len)
15993 + struct l3_msg msg;
15998 + msg.buf = (char *)buf;
16001 + ret = l3_transfer(adap, &msg, 1);
16002 + return ret == 1 ? len : ret;
16006 + * l3_read - receive data from a device on an L3 bus
16007 + * @adap: L3 bus adapter
16008 + * @addr: L3 bus address
16009 + * @buf: buffer for bytes to receive
16010 + * @len: number of bytes to receive
16012 + * Receive len bytes from device address addr on the L3 bus described by
16013 + * client to a buffer pointed to by buf.
16015 + * Returns the number of bytes transferred, or negative error code.
16017 +int l3_read(struct l3_adapter *adap, int addr, char *buf, int len)
16019 + struct l3_msg msg;
16023 + msg.flags = L3_M_RD;
16027 + ret = l3_transfer(adap, &msg, 1);
16028 + return ret == 1 ? len : ret;
16031 +EXPORT_SYMBOL(l3_add_adapter);
16032 +EXPORT_SYMBOL(l3_del_adapter);
16033 +EXPORT_SYMBOL(l3_get_adapter);
16034 +EXPORT_SYMBOL(l3_put_adapter);
16035 +EXPORT_SYMBOL(l3_transfer);
16036 +EXPORT_SYMBOL(l3_write);
16037 +EXPORT_SYMBOL(l3_read);
16038 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16039 +++ linux-2.6.5/drivers/l3/l3-algo-bit.c 2004-04-30 20:57:36.000000000 -0400
16042 + * L3 bus algorithm module.
16044 + * Copyright (C) 2001 Russell King, All Rights Reserved.
16046 + * This program is free software; you can redistribute it and/or modify
16047 + * it under the terms of the GNU General Public License version 2 as
16048 + * published by the Free Software Foundation.
16050 + * Note that L3 buses can share the same pins as I2C buses, so we must
16051 + * _not_ generate an I2C start condition. An I2C start condition is
16052 + * defined as a high-to-low transition of the data line while the clock
16053 + * is high. Therefore, we must only change the data line while the
16056 +#include <linux/module.h>
16057 +#include <linux/kernel.h>
16058 +#include <linux/delay.h>
16059 +#include <linux/slab.h>
16060 +#include <linux/init.h>
16061 +#include <linux/errno.h>
16062 +#include <linux/sched.h>
16063 +#include <linux/l3/l3.h>
16064 +#include <linux/l3/algo-bit.h>
16066 +#define setdat(adap,val) adap->setdat(adap->data, val)
16067 +#define setclk(adap,val) adap->setclk(adap->data, val)
16068 +#define setmode(adap,val) adap->setmode(adap->data, val)
16069 +#define setdatin(adap) adap->setdir(adap->data, 1)
16070 +#define setdatout(adap) adap->setdir(adap->data, 0)
16071 +#define getdat(adap) adap->getdat(adap->data)
16074 + * Send one byte of data to the chip. Data is latched into the chip on
16075 + * the rising edge of the clock.
16077 +static void sendbyte(struct l3_algo_bit_data *adap, unsigned int byte)
16081 + for (i = 0; i < 8; i++) {
16083 + udelay(adap->data_hold);
16084 + setdat(adap, byte & 1);
16085 + udelay(adap->data_setup);
16087 + udelay(adap->clock_high);
16093 + * Send a set of bytes to the chip. We need to pulse the MODE line
16094 + * between each byte, but never at the start nor at the end of the
16097 +static void sendbytes(struct l3_algo_bit_data *adap, const char *buf, int len)
16101 + for (i = 0; i < len; i++) {
16103 + udelay(adap->mode_hold);
16104 + setmode(adap, 0);
16105 + udelay(adap->mode);
16107 + setmode(adap, 1);
16108 + udelay(adap->mode_setup);
16109 + sendbyte(adap, buf[i]);
16114 + * Read one byte of data from the chip. Data is latched into the chip on
16115 + * the rising edge of the clock.
16117 +static unsigned int readbyte(struct l3_algo_bit_data *adap)
16119 + unsigned int byte = 0;
16122 + for (i = 0; i < 8; i++) {
16124 + udelay(adap->data_hold + adap->data_setup);
16126 + if (getdat(adap))
16128 + udelay(adap->clock_high);
16135 + * Read a set of bytes from the chip. We need to pulse the MODE line
16136 + * between each byte, but never at the start nor at the end of the
16139 +static void readbytes(struct l3_algo_bit_data *adap, char *buf, int len)
16143 + for (i = 0; i < len; i++) {
16145 + udelay(adap->mode_hold);
16146 + setmode(adap, 0);
16148 + setmode(adap, 1);
16149 + udelay(adap->mode_setup);
16150 + buf[i] = readbyte(adap);
16154 +static int l3_xfer(struct l3_adapter *l3_adap, struct l3_msg msgs[], int num)
16156 + struct l3_algo_bit_data *adap = l3_adap->algo_data;
16160 + * If we share an I2C bus, ensure that it is in STOP mode
16164 + setmode(adap, 1);
16166 + udelay(adap->mode);
16168 + for (i = 0; i < num; i++) {
16169 + struct l3_msg *pmsg = &msgs[i];
16171 + if (!(pmsg->flags & L3_M_NOADDR)) {
16172 + setmode(adap, 0);
16173 + udelay(adap->mode_setup);
16174 + sendbyte(adap, pmsg->addr);
16175 + udelay(adap->mode_hold);
16178 + if (pmsg->flags & L3_M_RD) {
16180 + readbytes(adap, pmsg->buf, pmsg->len);
16183 + sendbytes(adap, pmsg->buf, pmsg->len);
16188 + * Ensure that we leave the bus in I2C stop mode.
16192 + setmode(adap, 0);
16198 +static struct l3_algorithm l3_bit_algo = {
16199 + name: "L3 bit-shift algorithm",
16203 +int l3_bit_add_bus(struct l3_adapter *adap)
16205 + adap->algo = &l3_bit_algo;
16206 + return l3_add_adapter(adap);
16209 +int l3_bit_del_bus(struct l3_adapter *adap)
16211 + return l3_del_adapter(adap);
16214 +EXPORT_SYMBOL(l3_bit_add_bus);
16215 +EXPORT_SYMBOL(l3_bit_del_bus);
16216 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16217 +++ linux-2.6.5/drivers/l3/Makefile 2004-04-30 20:57:36.000000000 -0400
16220 +# Makefile for the L3 bus driver.
16224 +# (core, adapters, algorithms, drivers) then clients
16226 +l3-$(CONFIG_L3_ALGOBIT) += l3-algo-bit.o
16227 +l3-$(CONFIG_BIT_SA1100_GPIO) += l3-bit-sa1100.o
16229 +obj-$(CONFIG_L3) += l3-core.o $(l3-y) $(l3-drv-y)
16230 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16231 +++ linux-2.6.5/drivers/l3/l3-bit-sa1100.c 2004-04-30 20:57:36.000000000 -0400
16234 + * linux/drivers/l3/l3-bit-sa1100.c
16236 + * Copyright (C) 2001 Russell King
16238 + * This program is free software; you can redistribute it and/or modify
16239 + * it under the terms of the GNU General Public License version 2 as
16240 + * published by the Free Software Foundation.
16242 + * This is a combined I2C and L3 bus driver.
16244 +#include <linux/config.h>
16245 +#include <linux/module.h>
16246 +#include <linux/kernel.h>
16247 +#include <linux/ioport.h>
16248 +#include <linux/delay.h>
16249 +#include <linux/slab.h>
16250 +#include <linux/init.h>
16251 +#include <linux/i2c.h>
16252 +#include <linux/i2c-algo-bit.h>
16253 +#include <linux/l3/algo-bit.h>
16255 +#include <asm/system.h>
16256 +#include <asm/hardware.h>
16257 +#include <asm/mach-types.h>
16258 +#include <asm/arch/assabet.h>
16260 +#define NAME "l3-bit-sa1100-gpio"
16263 + unsigned int sda;
16264 + unsigned int scl;
16265 + unsigned int l3_mode;
16268 +static int getsda(void *data)
16270 + struct bit_data *bits = data;
16272 + return GPLR & bits->sda;
16275 +#ifdef CONFIG_I2C_BIT_SA1100_GPIO
16276 +static void i2c_setsda(void *data, int state)
16278 + struct bit_data *bits = data;
16279 + unsigned long flags;
16281 + local_irq_save(flags);
16283 + GPDR &= ~bits->sda;
16285 + GPCR = bits->sda;
16286 + GPDR |= bits->sda;
16288 + local_irq_restore(flags);
16291 +static void i2c_setscl(void *data, int state)
16293 + struct bit_data *bits = data;
16294 + unsigned long flags;
16296 + local_irq_save(flags);
16298 + GPDR &= ~bits->scl;
16300 + GPCR = bits->scl;
16301 + GPDR |= bits->scl;
16303 + local_irq_restore(flags);
16306 +static int i2c_getscl(void *data)
16308 + struct bit_data *bits = data;
16310 + return GPLR & bits->scl;
16313 +static struct i2c_algo_bit_data i2c_bit_data = {
16314 + .setsda = i2c_setsda,
16315 + .setscl = i2c_setscl,
16316 + .getsda = getsda,
16317 + .getscl = i2c_getscl,
16323 +static struct i2c_adapter i2c_adapter = {
16324 + .algo_data = &i2c_bit_data,
16327 +#define LOCK &i2c_adapter.bus_lock
16329 +static int __init i2c_init(struct bit_data *bits)
16331 + i2c_bit_data.data = bits;
16332 + return i2c_bit_add_bus(&i2c_adapter);
16335 +static void i2c_exit(void)
16337 + i2c_bit_del_bus(&i2c_adapter);
16341 +static DECLARE_MUTEX(l3_lock);
16342 +#define LOCK &l3_lock
16343 +#define i2c_init(bits) (0)
16344 +#define i2c_exit() do { } while (0)
16347 +#ifdef CONFIG_L3_BIT_SA1100_GPIO
16349 + * iPAQs need the clock line driven hard high and low.
16351 +static void l3_setscl(void *data, int state)
16353 + struct bit_data *bits = data;
16354 + unsigned long flags;
16356 + local_irq_save(flags);
16358 + GPSR = bits->scl;
16360 + GPCR = bits->scl;
16361 + GPDR |= bits->scl;
16362 + local_irq_restore(flags);
16365 +static void l3_setsda(void *data, int state)
16367 + struct bit_data *bits = data;
16370 + GPSR = bits->sda;
16372 + GPCR = bits->sda;
16375 +static void l3_setdir(void *data, int in)
16377 + struct bit_data *bits = data;
16378 + unsigned long flags;
16380 + local_irq_save(flags);
16382 + GPDR &= ~bits->sda;
16384 + GPDR |= bits->sda;
16385 + local_irq_restore(flags);
16388 +static void l3_setmode(void *data, int state)
16390 + struct bit_data *bits = data;
16393 + GPSR = bits->l3_mode;
16395 + GPCR = bits->l3_mode;
16398 +static struct l3_algo_bit_data l3_bit_data = {
16400 + .setdat = l3_setsda,
16401 + .setclk = l3_setscl,
16402 + .setmode = l3_setmode,
16403 + .setdir = l3_setdir,
16404 + .getdat = getsda,
16412 +static struct l3_adapter l3_adapter = {
16413 + .owner = THIS_MODULE,
16415 + .algo_data = &l3_bit_data,
16419 +static int __init l3_init(struct bit_data *bits)
16421 + l3_bit_data.data = bits;
16422 + return l3_bit_add_bus(&l3_adapter);
16425 +static void __exit l3_exit(void)
16427 + l3_bit_del_bus(&l3_adapter);
16430 +#define l3_init(bits) (0)
16431 +#define l3_exit() do { } while (0)
16434 +static struct bit_data bit_data;
16436 +static int __init bus_init(void)
16438 + struct bit_data *bit = &bit_data;
16439 + unsigned long flags;
16442 + if (machine_is_assabet() || machine_is_pangolin()) {
16443 + bit->sda = GPIO_GPIO15;
16444 + bit->scl = GPIO_GPIO18;
16445 + bit->l3_mode = GPIO_GPIO17;
16448 + if (machine_is_h3600() || machine_is_h3100()) {
16449 + bit->sda = GPIO_GPIO14;
16450 + bit->scl = GPIO_GPIO16;
16451 + bit->l3_mode = GPIO_GPIO15;
16454 + if (machine_is_stork()) {
16455 + bit->sda = GPIO_GPIO15;
16456 + bit->scl = GPIO_GPIO18;
16457 + bit->l3_mode = GPIO_GPIO17;
16464 + * Default level for L3 mode is low.
16465 + * We set SCL and SDA high (i2c idle state).
16467 + local_irq_save(flags);
16468 + GPDR &= ~(bit->scl | bit->sda);
16469 + GPCR = bit->l3_mode | bit->scl | bit->sda;
16470 + GPDR |= bit->l3_mode;
16471 + local_irq_restore(flags);
16473 + if (machine_is_assabet()) {
16475 + * Release reset on UCB1300, ADI7171 and UDA1341. We
16476 + * need to do this here so that we can communicate on
16477 + * the I2C/L3 buses.
16479 + ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
16481 + ASSABET_BCR_clear(ASSABET_BCR_CODEC_RST);
16483 + ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
16486 + ret = i2c_init(bit);
16487 + if (ret == 0 && bit->l3_mode) {
16488 + ret = l3_init(bit);
16496 +static void __exit bus_exit(void)
16502 +module_init(bus_init);
16503 +module_exit(bus_exit);
16504 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16505 +++ linux-2.6.5/drivers/misc/switches.h 2004-04-30 20:57:36.000000000 -0400
16508 + * linux/drivers/misc/switches.h
16510 + * Copyright (C) 2001 John Dorsey
16512 + * This program is free software; you can redistribute it and/or modify
16513 + * it under the terms of the GNU General Public License version 2 as
16514 + * published by the Free Software Foundation.
16516 + * 19 December 2001 - created.
16519 +#if !defined(_SWITCHES_H)
16520 +# define _SWITCHES_H
16522 +#include <linux/switches.h>
16524 +#define SWITCHES_NAME "switches"
16526 +extern int switches_event(switches_mask_t *mask);
16528 +#endif /* !defined(_SWITCHES_H) */
16529 --- linux-2.6.5/drivers/misc/Kconfig~heh 2004-04-03 22:36:26.000000000 -0500
16530 +++ linux-2.6.5/drivers/misc/Kconfig 2004-04-30 20:57:36.000000000 -0400
16535 +menu "Multimedia Capabilities Port drivers"
16538 + tristate "Multimedia drivers"
16540 +# Interface drivers
16542 + tristate "Support SA1100 MCP interface"
16543 + depends on MCP && ARCH_SA1100
16546 +config MCP_UCB1200
16547 + tristate "Support for UCB1200 / UCB1300"
16550 +config MCP_UCB1200_AUDIO
16551 + tristate "Audio / Telephony interface support"
16552 + depends on MCP_UCB1200 && SOUND
16554 +config MCP_UCB1200_TS
16555 + tristate "Touchscreen interface support"
16556 + depends on MCP_UCB1200 && INPUT
16561 +menu "Console Switches"
16564 + tristate "Console Switch Support"
16566 + Say Y here to include support for simple console momentary switches.
16567 + This driver implements a miscellaneous character device (named
16568 + `switches' in /proc/misc) which can be read by userland programs
16569 + to respond to switch press events. This mechanism is efficient for
16570 + systems which may not implement a traditional heavyweight console
16573 + It is also possible to say M to build this driver as a module (named
16576 +config SWITCHES_SA1100
16577 + tristate "SA-1100 switches"
16578 + depends on SWITCHES && ARCH_SA1100
16580 + Say Y here to include support for switches routed directly to
16581 + interruptable signals on StrongARM SA-1100 systems.
16583 +config SWITCHES_UCB1X00
16584 + tristate "UCB1x00 switches"
16585 + depends on SWITCHES && MCP_UCB1200
16587 + Say Y here to include support for switches routed through a
16588 + UCB1x00 modem/audio analog front-end device.
16594 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16595 +++ linux-2.6.5/drivers/misc/ucb1x00-assabet.c 2004-04-30 20:57:36.000000000 -0400
16598 + * linux/drivers/misc/ucb1x00-assabet.c
16600 + * Copyright (C) 2001-2003 Russell King, All Rights Reserved.
16602 + * This program is free software; you can redistribute it and/or modify
16603 + * it under the terms of the GNU General Public License as published by
16604 + * the Free Software Foundation; either version 2 of the License.
16606 + * We handle the machine-specific bits of the UCB1x00 driver here.
16608 +#include <linux/module.h>
16609 +#include <linux/init.h>
16610 +#include <linux/fs.h>
16611 +#include <linux/proc_fs.h>
16612 +#include <linux/device.h>
16614 +#include <asm/dma.h>
16616 +#include "ucb1x00.h"
16618 +#define UCB1X00_ATTR(name,input)\
16619 +static ssize_t name##_show(struct class_device *dev, char *buf) \
16621 + struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
16623 + ucb1x00_adc_enable(ucb); \
16624 + val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
16625 + ucb1x00_adc_disable(ucb); \
16626 + return sprintf(buf, "%d\n", val); \
16628 +static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL)
16630 +UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1);
16631 +UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0);
16632 +UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
16634 +static int ucb1x00_assabet_add(struct class_device *dev)
16636 + class_device_create_file(dev, &class_device_attr_vbatt);
16637 + class_device_create_file(dev, &class_device_attr_vcharger);
16638 + class_device_create_file(dev, &class_device_attr_batt_temp);
16642 +static void ucb1x00_assabet_remove(struct class_device *dev)
16644 + class_device_remove_file(dev, &class_device_attr_batt_temp);
16645 + class_device_remove_file(dev, &class_device_attr_vcharger);
16646 + class_device_remove_file(dev, &class_device_attr_vbatt);
16649 +static struct class_interface ucb1x00_assabet_interface = {
16650 + .add = ucb1x00_assabet_add,
16651 + .remove = ucb1x00_assabet_remove,
16654 +static int __init ucb1x00_assabet_init(void)
16656 + return ucb1x00_register_interface(&ucb1x00_assabet_interface);
16659 +static void __exit ucb1x00_assabet_exit(void)
16661 + ucb1x00_unregister_interface(&ucb1x00_assabet_interface);
16664 +module_init(ucb1x00_assabet_init);
16665 +module_exit(ucb1x00_assabet_exit);
16667 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
16668 +MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver");
16669 +MODULE_LICENSE("GPL");
16670 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16671 +++ linux-2.6.5/drivers/misc/mcp-pxa.c 2004-04-30 20:57:36.000000000 -0400
16674 + * linux/drivers/misc/mcp-pxa.c
16676 + * 2002-01-10 Jeff Sutherland <jeffs@accelent.com>
16678 + * This program is free software; you can redistribute it and/or modify
16679 + * it under the terms of the GNU General Public License as published by
16680 + * the Free Software Foundation; either version 2 of the License.
16682 + * NOTE: This is a quick hack to gain access to the aclink codec's
16683 + * touch screen facility. Its audio is handled by a separate
16684 + * (non-mcp) driver at the present time.
16687 +#include <linux/module.h>
16688 +#include <linux/types.h>
16689 +#include <linux/ac97_codec.h>
16694 +extern int pxa_ac97_get(struct ac97_codec **codec);
16695 +extern void pxa_ac97_put(void);
16698 +struct mcp *mcp_get(void)
16700 + struct ac97_codec *codec;
16701 + if (pxa_ac97_get(&codec) < 0)
16703 + return (struct mcp *)codec;
16706 +void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
16708 + struct ac97_codec *codec = (struct ac97_codec *)mcp;
16709 + codec->codec_write(codec, reg, val);
16712 +unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
16714 + struct ac97_codec *codec = (struct ac97_codec *)mcp;
16715 + return codec->codec_read(codec, reg);
16718 +void mcp_enable(struct mcp *mcp)
16721 + * Should we do something here to make sure the aclink
16722 + * codec is alive???
16723 + * A: not for now --NP
16727 +void mcp_disable(struct mcp *mcp)
16730 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16731 +++ linux-2.6.5/drivers/misc/mcp-core.c 2004-04-30 20:57:36.000000000 -0400
16734 + * linux/drivers/misc/mcp-core.c
16736 + * Copyright (C) 2001 Russell King
16738 + * This program is free software; you can redistribute it and/or modify
16739 + * it under the terms of the GNU General Public License as published by
16740 + * the Free Software Foundation; either version 2 of the License.
16742 + * Generic MCP (Multimedia Communications Port) layer. All MCP locking
16743 + * is solely held within this file.
16745 +#include <linux/module.h>
16746 +#include <linux/init.h>
16747 +#include <linux/errno.h>
16748 +#include <linux/smp.h>
16749 +#include <linux/device.h>
16751 +#include <asm/dma.h>
16752 +#include <asm/system.h>
16756 +#define to_mcp(d) container_of(d, struct mcp, attached_device)
16757 +#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
16759 +static int mcp_bus_match(struct device *dev, struct device_driver *drv)
16764 +static int mcp_bus_probe(struct device *dev)
16766 + struct mcp *mcp = to_mcp(dev);
16767 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
16769 + return drv->probe(mcp);
16772 +static int mcp_bus_remove(struct device *dev)
16774 + struct mcp *mcp = to_mcp(dev);
16775 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
16777 + drv->remove(mcp);
16781 +static int mcp_bus_suspend(struct device *dev, u32 state)
16783 + struct mcp *mcp = to_mcp(dev);
16786 + if (dev->driver) {
16787 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
16789 + ret = drv->suspend(mcp, state);
16794 +static int mcp_bus_resume(struct device *dev)
16796 + struct mcp *mcp = to_mcp(dev);
16799 + if (dev->driver) {
16800 + struct mcp_driver *drv = to_mcp_driver(dev->driver);
16802 + ret = drv->resume(mcp);
16807 +static struct bus_type mcp_bus_type = {
16809 + .match = mcp_bus_match,
16810 + .suspend = mcp_bus_suspend,
16811 + .resume = mcp_bus_resume,
16815 + * mcp_set_telecom_divisor - set the telecom divisor
16816 + * @mcp: MCP interface structure
16817 + * @div: SIB clock divisor
16819 + * Set the telecom divisor on the MCP interface. The resulting
16820 + * sample rate is SIBCLOCK/div.
16822 +void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
16824 + spin_lock_irq(&mcp->lock);
16825 + mcp->set_telecom_divisor(mcp, div);
16826 + spin_unlock_irq(&mcp->lock);
16830 + * mcp_set_audio_divisor - set the audio divisor
16831 + * @mcp: MCP interface structure
16832 + * @div: SIB clock divisor
16834 + * Set the audio divisor on the MCP interface.
16836 +void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
16838 + spin_lock_irq(&mcp->lock);
16839 + mcp->set_audio_divisor(mcp, div);
16840 + spin_unlock_irq(&mcp->lock);
16844 + * mcp_reg_write - write a device register
16845 + * @mcp: MCP interface structure
16846 + * @reg: 4-bit register index
16847 + * @val: 16-bit data value
16849 + * Write a device register. The MCP interface must be enabled
16850 + * to prevent this function hanging.
16852 +void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
16854 + unsigned long flags;
16856 + spin_lock_irqsave(&mcp->lock, flags);
16857 + mcp->reg_write(mcp, reg, val);
16858 + spin_unlock_irqrestore(&mcp->lock, flags);
16862 + * mcp_reg_read - read a device register
16863 + * @mcp: MCP interface structure
16864 + * @reg: 4-bit register index
16866 + * Read a device register and return its value. The MCP interface
16867 + * must be enabled to prevent this function hanging.
16869 +unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
16871 + unsigned long flags;
16872 + unsigned int val;
16874 + spin_lock_irqsave(&mcp->lock, flags);
16875 + val = mcp->reg_read(mcp, reg);
16876 + spin_unlock_irqrestore(&mcp->lock, flags);
16882 + * mcp_enable - enable the MCP interface
16883 + * @mcp: MCP interface to enable
16885 + * Enable the MCP interface. Each call to mcp_enable will need
16886 + * a corresponding call to mcp_disable to disable the interface.
16888 +void mcp_enable(struct mcp *mcp)
16890 + spin_lock_irq(&mcp->lock);
16891 + if (mcp->use_count++ == 0)
16892 + mcp->enable(mcp);
16893 + spin_unlock_irq(&mcp->lock);
16897 + * mcp_disable - disable the MCP interface
16898 + * @mcp: MCP interface to disable
16900 + * Disable the MCP interface. The MCP interface will only be
16901 + * disabled once the number of calls to mcp_enable matches the
16902 + * number of calls to mcp_disable.
16904 +void mcp_disable(struct mcp *mcp)
16906 + unsigned long flags;
16908 + spin_lock_irqsave(&mcp->lock, flags);
16909 + if (--mcp->use_count == 0)
16910 + mcp->disable(mcp);
16911 + spin_unlock_irqrestore(&mcp->lock, flags);
16914 +int mcp_host_register(struct mcp *mcp, struct device *parent)
16916 + mcp->attached_device.parent = parent;
16917 + mcp->attached_device.bus = &mcp_bus_type;
16918 + mcp->attached_device.dma_mask = parent->dma_mask;
16919 + strcpy(mcp->attached_device.bus_id, "mcp0");
16920 + return device_register(&mcp->attached_device);
16923 +void mcp_host_unregister(struct mcp *mcp)
16925 + device_unregister_wait(&mcp->attached_device);
16928 +int mcp_driver_register(struct mcp_driver *mcpdrv)
16930 + mcpdrv->drv.bus = &mcp_bus_type;
16931 + mcpdrv->drv.probe = mcp_bus_probe;
16932 + mcpdrv->drv.remove = mcp_bus_remove;
16933 + return driver_register(&mcpdrv->drv);
16936 +void mcp_driver_unregister(struct mcp_driver *mcpdrv)
16938 + driver_unregister(&mcpdrv->drv);
16941 +static int __init mcp_init(void)
16943 + return bus_register(&mcp_bus_type);
16946 +static void __exit mcp_exit(void)
16948 + bus_unregister(&mcp_bus_type);
16951 +module_init(mcp_init);
16952 +module_exit(mcp_exit);
16954 +EXPORT_SYMBOL(mcp_set_telecom_divisor);
16955 +EXPORT_SYMBOL(mcp_set_audio_divisor);
16956 +EXPORT_SYMBOL(mcp_reg_write);
16957 +EXPORT_SYMBOL(mcp_reg_read);
16958 +EXPORT_SYMBOL(mcp_enable);
16959 +EXPORT_SYMBOL(mcp_disable);
16960 +EXPORT_SYMBOL(mcp_host_register);
16961 +EXPORT_SYMBOL(mcp_host_unregister);
16962 +EXPORT_SYMBOL(mcp_driver_register);
16963 +EXPORT_SYMBOL(mcp_driver_unregister);
16965 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
16966 +MODULE_DESCRIPTION("Core multimedia communications port driver");
16967 +MODULE_LICENSE("GPL");
16968 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
16969 +++ linux-2.6.5/drivers/misc/ucb1x00-ts.c 2004-04-30 20:57:36.000000000 -0400
16972 + * linux/drivers/misc/ucb1x00-ts.c
16974 + * Copyright (C) 2001 Russell King, All Rights Reserved.
16976 + * This program is free software; you can redistribute it and/or modify
16977 + * it under the terms of the GNU General Public License version 2 as
16978 + * published by the Free Software Foundation.
16980 + * 21-Jan-2002 <jco@ict.es> :
16982 + * Added support for synchronous A/D mode. This mode is useful to
16983 + * avoid noise induced in the touchpanel by the LCD, provided that
16984 + * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
16985 + * It is important to note that the signal connected to the ADCSYNC
16986 + * pin should provide pulses even when the LCD is blanked, otherwise
16987 + * a pen touch needed to unblank the LCD will never be read.
16989 +#include <linux/config.h>
16990 +#include <linux/module.h>
16991 +#include <linux/init.h>
16992 +#include <linux/smp.h>
16993 +#include <linux/smp_lock.h>
16994 +#include <linux/sched.h>
16995 +#include <linux/completion.h>
16996 +#include <linux/delay.h>
16997 +#include <linux/string.h>
16998 +#include <linux/input.h>
16999 +#include <linux/device.h>
17000 +#include <linux/slab.h>
17002 +#include <asm/dma.h>
17003 +#include <asm/semaphore.h>
17005 +#include "ucb1x00.h"
17008 +struct ucb1x00_ts {
17009 + struct input_dev idev;
17010 + struct ucb1x00 *ucb;
17012 + struct semaphore irq_wait;
17013 + struct semaphore sem;
17014 + struct completion init_exit;
17015 + struct task_struct *rtask;
17024 +static int adcsync = UCB_NOSYNC;
17026 +static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
17028 + input_report_abs(&ts->idev, ABS_X, x);
17029 + input_report_abs(&ts->idev, ABS_Y, y);
17030 + input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
17031 + input_sync(&ts->idev);
17034 +static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
17036 + input_report_abs(&ts->idev, ABS_PRESSURE, 0);
17037 + input_sync(&ts->idev);
17041 + * Switch to interrupt mode.
17043 +static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
17045 + if (ts->ucb->id == UCB_ID_1400_BUGGY)
17046 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17047 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
17048 + UCB_TS_CR_MODE_INT);
17050 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17051 + UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
17052 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
17053 + UCB_TS_CR_MODE_INT);
17057 + * Switch to pressure mode, and read pressure. We don't need to wait
17058 + * here, since both plates are being driven.
17060 +static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
17062 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17063 + UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
17064 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
17065 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17067 + return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
17071 + * Switch to X position mode and measure Y plate. We switch the plate
17072 + * configuration in pressure mode, then switch to position mode. This
17073 + * gives a faster response time. Even so, we need to wait about 55us
17074 + * for things to stabilise.
17076 +static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
17078 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17079 + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
17080 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17081 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17082 + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
17083 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17084 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17085 + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
17086 + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
17090 + return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
17094 + * Switch to Y position mode and measure X plate. We switch the plate
17095 + * configuration in pressure mode, then switch to position mode. This
17096 + * gives a faster response time. Even so, we need to wait about 55us
17097 + * for things to stabilise.
17099 +static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
17101 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17102 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
17103 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17104 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17105 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
17106 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17107 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17108 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
17109 + UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
17113 + return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
17117 + * Switch to X plate resistance mode. Set MX to ground, PX to
17118 + * supply. Measure current.
17120 +static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
17122 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17123 + UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
17124 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17125 + return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
17129 + * Switch to Y plate resistance mode. Set MY to ground, PY to
17130 + * supply. Measure current.
17132 +static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
17134 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
17135 + UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
17136 + UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
17137 + return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
17141 + * This is a RT kernel thread that handles the ADC accesses
17142 + * (mainly so we can use semaphores in the UCB1200 core code
17143 + * to serialise accesses to the ADC, and in the UCB1400 case where
17144 + * any register access may sleep).
17146 +static int ucb1x00_thread(void *_ts)
17148 + struct ucb1x00_ts *ts = _ts;
17149 + struct task_struct *tsk = current;
17154 + daemonize("ktsd");
17155 + /* only want to receive SIGKILL */
17156 + allow_signal(SIGKILL);
17159 + * We could run as a real-time thread. However, thus far
17160 + * this doesn't seem to be necessary.
17162 +// tsk->policy = SCHED_FIFO;
17163 +// tsk->rt_priority = 1;
17165 + complete(&ts->init_exit);
17170 + unsigned int x, y, p, val;
17174 + ucb1x00_adc_enable(ts->ucb);
17176 + x = ucb1x00_ts_read_xpos(ts);
17177 + y = ucb1x00_ts_read_ypos(ts);
17178 + p = ucb1x00_ts_read_pressure(ts);
17181 + * Switch back to interrupt mode.
17183 + ucb1x00_ts_mode_int(ts);
17184 + ucb1x00_adc_disable(ts->ucb);
17186 + set_task_state(tsk, TASK_UNINTERRUPTIBLE);
17187 + schedule_timeout(HZ / 100);
17188 + if (signal_pending(tsk))
17191 + ucb1x00_enable(ts->ucb);
17192 + val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
17194 + if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
17195 + ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
17196 + ucb1x00_disable(ts->ucb);
17199 + * If we spat out a valid sample set last time,
17200 + * spit out a "pen off" sample here.
17203 + ucb1x00_ts_event_release(ts);
17208 + * Since ucb1x00_enable_irq() might sleep due
17209 + * to the way the UCB1400 regs are accessed, we
17210 + * can't use set_task_state() before that call,
17211 + * and not changing state before enabling the
17212 + * interrupt is racy. A semaphore solves all
17213 + * those issues quite nicely.
17215 + down_interruptible(&ts->irq_wait);
17217 + ucb1x00_disable(ts->ucb);
17220 + * Filtering is policy. Policy belongs in user
17221 + * space. We therefore leave it to user space
17222 + * to do any filtering they please.
17224 + if (!ts->restart) {
17225 + ucb1x00_ts_evt_add(ts, p, x, y);
17229 + set_task_state(tsk, TASK_INTERRUPTIBLE);
17232 + schedule_timeout(HZ / 100);
17233 + if (signal_pending(tsk))
17237 + ts->rtask = NULL;
17238 + complete_and_exit(&ts->init_exit, 0);
17242 + * We only detect touch screen _touches_ with this interrupt
17243 + * handler, and even then we just schedule our task.
17245 +static void ucb1x00_ts_irq(int idx, void *id)
17247 + struct ucb1x00_ts *ts = id;
17248 + ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
17249 + up(&ts->irq_wait);
17252 +static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
17254 + input_report_abs(&ts->idev, ABS_PRESSURE, 0);
17257 +static int ucb1x00_ts_open(struct input_dev *idev)
17259 + struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
17262 + if (down_interruptible(&ts->sem))
17265 + if (ts->use_count++ != 0)
17269 + panic("ucb1x00: rtask running?");
17271 + sema_init(&ts->irq_wait, 0);
17272 + ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
17277 + * If we do this at all, we should allow the user to
17278 + * measure and read the X and Y resistance at any time.
17280 + ucb1x00_adc_enable(ts->ucb);
17281 + ts->x_res = ucb1x00_ts_read_xres(ts);
17282 + ts->y_res = ucb1x00_ts_read_yres(ts);
17283 + ucb1x00_adc_disable(ts->ucb);
17285 + init_completion(&ts->init_exit);
17286 + ret = kernel_thread(ucb1x00_thread, ts, CLONE_KERNEL);
17288 + wait_for_completion(&ts->init_exit);
17291 + ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
17302 + * Release touchscreen resources. Disable IRQs.
17304 +static void ucb1x00_ts_close(struct input_dev *idev)
17306 + struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
17309 + if (--ts->use_count == 0) {
17311 + send_sig(SIGKILL, ts->rtask, 1);
17312 + wait_for_completion(&ts->init_exit);
17315 + ucb1x00_enable(ts->ucb);
17316 + ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
17317 + ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
17318 + ucb1x00_disable(ts->ucb);
17324 +static int ucb1x00_ts_resume(struct device *_dev, u32 level)
17326 + struct ucb1x00_device *dev = ucb1x00_dev(_dev);
17327 + struct ucb1x00_ts *ts = ucb1x00_get_drvdata(dev);
17329 + if (level == RESUME_ENABLE && ts->rtask != NULL) {
17331 + * Restart the TS thread to ensure the
17332 + * TS interrupt mode is set up again
17336 + up(&ts->irq_wait);
17344 + * Initialisation.
17346 +static int ucb1x00_ts_add(struct class_device *dev)
17348 + struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
17349 + struct ucb1x00_ts *ts;
17351 + ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
17355 + memset(ts, 0, sizeof(struct ucb1x00_ts));
17358 + ts->adcsync = adcsync;
17359 + init_MUTEX(&ts->sem);
17361 + ts->idev.name = "Touchscreen panel";
17362 + ts->idev.id.product = ts->ucb->id;
17363 + ts->idev.open = ucb1x00_ts_open;
17364 + ts->idev.close = ucb1x00_ts_close;
17366 + __set_bit(EV_ABS, ts->idev.evbit);
17367 + __set_bit(ABS_X, ts->idev.absbit);
17368 + __set_bit(ABS_Y, ts->idev.absbit);
17369 + __set_bit(ABS_PRESSURE, ts->idev.absbit);
17371 + input_register_device(&ts->idev);
17373 + ucb->ts_data = ts;
17378 +static void ucb1x00_ts_remove(struct class_device *dev)
17380 + struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
17381 + struct ucb1x00_ts *ts = ucb->ts_data;
17383 + input_unregister_device(&ts->idev);
17387 +static struct class_interface ucb1x00_ts_interface = {
17388 + .add = ucb1x00_ts_add,
17389 + .remove = ucb1x00_ts_remove,
17392 +static int __init ucb1x00_ts_init(void)
17394 + return ucb1x00_register_interface(&ucb1x00_ts_interface);
17397 +static void __exit ucb1x00_ts_exit(void)
17399 + ucb1x00_unregister_interface(&ucb1x00_ts_interface);
17405 + * Parse kernel command-line options.
17407 + * syntax : ucbts=[sync|nosync],...
17409 +static int __init ucb1x00_ts_setup(char *str)
17413 + while ((p = strsep(&str, ",")) != NULL) {
17414 + if (strcmp(p, "sync") == 0)
17415 + adcsync = UCB_SYNC;
17421 +__setup("ucbts=", ucb1x00_ts_setup);
17425 +MODULE_PARM(adcsync, "i");
17426 +MODULE_PARM_DESC(adcsync, "Enable use of ADCSYNC signal");
17430 +module_init(ucb1x00_ts_init);
17431 +module_exit(ucb1x00_ts_exit);
17433 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
17434 +MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
17435 +MODULE_LICENSE("GPL");
17436 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
17437 +++ linux-2.6.5/drivers/misc/ucb1x00-core.c 2004-04-30 20:57:36.000000000 -0400
17440 + * linux/drivers/misc/ucb1x00-core.c
17442 + * Copyright (C) 2001 Russell King, All Rights Reserved.
17444 + * This program is free software; you can redistribute it and/or modify
17445 + * it under the terms of the GNU General Public License as published by
17446 + * the Free Software Foundation; either version 2 of the License.
17448 + * The UCB1x00 core driver provides basic services for handling IO,
17449 + * the ADC, interrupts, and accessing registers. It is designed
17450 + * such that everything goes through this layer, thereby providing
17451 + * a consistent locking methodology, as well as allowing the drivers
17452 + * to be used on other non-MCP-enabled hardware platforms.
17454 + * Note that all locks are private to this file. Nothing else may
17457 +#include <linux/config.h>
17458 +#include <linux/module.h>
17459 +#include <linux/kernel.h>
17460 +#include <linux/slab.h>
17461 +#include <linux/init.h>
17462 +#include <linux/errno.h>
17463 +#include <linux/interrupt.h>
17464 +#include <linux/device.h>
17466 +#include <asm/dma.h>
17467 +#include <asm/hardware.h>
17468 +#include <asm/irq.h>
17470 +#include "ucb1x00.h"
17473 + * ucb1x00_io_set_dir - set IO direction
17474 + * @ucb: UCB1x00 structure describing chip
17475 + * @in: bitfield of IO pins to be set as inputs
17476 + * @out: bitfield of IO pins to be set as outputs
17478 + * Set the IO direction of the ten general purpose IO pins on
17479 + * the UCB1x00 chip. The @in bitfield has priority over the
17480 + * @out bitfield, in that if you specify a pin as both input
17481 + * and output, it will end up as an input.
17483 + * ucb1x00_enable must have been called to enable the comms
17484 + * before using this function.
17486 + * This function takes a spinlock, disabling interrupts.
17488 +void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out)
17490 + unsigned long flags;
17492 + spin_lock_irqsave(&ucb->io_lock, flags);
17493 + ucb->io_dir |= out;
17494 + ucb->io_dir &= ~in;
17496 + ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
17497 + spin_unlock_irqrestore(&ucb->io_lock, flags);
17501 + * ucb1x00_io_write - set or clear IO outputs
17502 + * @ucb: UCB1x00 structure describing chip
17503 + * @set: bitfield of IO pins to set to logic '1'
17504 + * @clear: bitfield of IO pins to set to logic '0'
17506 + * Set the IO output state of the specified IO pins. The value
17507 + * is retained if the pins are subsequently configured as inputs.
17508 + * The @clear bitfield has priority over the @set bitfield -
17509 + * outputs will be cleared.
17511 + * ucb1x00_enable must have been called to enable the comms
17512 + * before using this function.
17514 + * This function takes a spinlock, disabling interrupts.
17516 +void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
17518 + unsigned long flags;
17520 + spin_lock_irqsave(&ucb->io_lock, flags);
17521 + ucb->io_out |= set;
17522 + ucb->io_out &= ~clear;
17524 + ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
17525 + spin_unlock_irqrestore(&ucb->io_lock, flags);
17529 + * ucb1x00_io_read - read the current state of the IO pins
17530 + * @ucb: UCB1x00 structure describing chip
17532 + * Return a bitfield describing the logic state of the ten
17533 + * general purpose IO pins.
17535 + * ucb1x00_enable must have been called to enable the comms
17536 + * before using this function.
17538 + * This function does not take any semaphores or spinlocks.
17540 +unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
17542 + return ucb1x00_reg_read(ucb, UCB_IO_DATA);
17546 + * UCB1300 data sheet says we must:
17547 + * 1. enable ADC => 5us (including reference startup time)
17548 + * 2. select input => 51*tsibclk => 4.3us
17549 + * 3. start conversion => 102*tsibclk => 8.5us
17550 + * (tsibclk = 1/11981000)
17551 + * Period between SIB 128-bit frames = 10.7us
17555 + * ucb1x00_adc_enable - enable the ADC converter
17556 + * @ucb: UCB1x00 structure describing chip
17558 + * Enable the ucb1x00 and ADC converter on the UCB1x00 for use.
17559 + * Any code wishing to use the ADC converter must call this
17560 + * function prior to using it.
17562 + * This function takes the ADC semaphore to prevent two or more
17563 + * concurrent uses, and therefore may sleep. As a result, it
17564 + * can only be called from process context, not interrupt
17567 + * You should release the ADC as soon as possible using
17568 + * ucb1x00_adc_disable.
17570 +void ucb1x00_adc_enable(struct ucb1x00 *ucb)
17572 + down(&ucb->adc_sem);
17574 + ucb->adc_cr |= UCB_ADC_ENA;
17576 + ucb1x00_enable(ucb);
17577 + ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
17581 + * ucb1x00_adc_read - read the specified ADC channel
17582 + * @ucb: UCB1x00 structure describing chip
17583 + * @adc_channel: ADC channel mask
17584 + * @sync: wait for syncronisation pulse.
17586 + * Start an ADC conversion and wait for the result. Note that
17587 + * synchronised ADC conversions (via the ADCSYNC pin) must wait
17588 + * until the trigger is asserted and the conversion is finished.
17590 + * This function currently spins waiting for the conversion to
17591 + * complete (2 frames max without sync).
17593 + * If called for a synchronised ADC conversion, it may sleep
17594 + * with the ADC semaphore held.
17596 + * See ucb1x00.h for definition of the UCB_ADC_DAT macro. It
17597 + * addresses a bug in the ucb1200/1300 which, of course, Philips
17598 + * decided to finally fix in the ucb1400 ;-) -jws
17600 +unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
17602 + unsigned int val;
17605 + adc_channel |= UCB_ADC_SYNC_ENA;
17607 + ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel);
17608 + ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START);
17611 + val = ucb1x00_reg_read(ucb, UCB_ADC_DATA);
17612 + if (val & UCB_ADC_DAT_VAL)
17614 + /* yield to other processes */
17615 + set_current_state(TASK_INTERRUPTIBLE);
17616 + schedule_timeout(1);
17619 + return UCB_ADC_DAT(val);
17623 + * ucb1x00_adc_disable - disable the ADC converter
17624 + * @ucb: UCB1x00 structure describing chip
17626 + * Disable the ADC converter and release the ADC semaphore.
17628 +void ucb1x00_adc_disable(struct ucb1x00 *ucb)
17630 + ucb->adc_cr &= ~UCB_ADC_ENA;
17631 + ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
17632 + ucb1x00_disable(ucb);
17634 + up(&ucb->adc_sem);
17638 + * UCB1x00 Interrupt handling.
17640 + * The UCB1x00 can generate interrupts when the SIBCLK is stopped.
17641 + * Since we need to read an internal register, we must re-enable
17642 + * SIBCLK to talk to the chip. We leave the clock running until
17643 + * we have finished processing all interrupts from the chip.
17645 + * A restriction with interrupts exists when using the ucb1400, as
17646 + * the codec read/write routines may sleep while waiting for codec
17647 + * access completion and uses semaphores for access control to the
17648 + * AC97 bus. A complete codec read cycle could take anywhere from
17649 + * 60 to 100uSec so we *definitely* don't want to spin inside the
17650 + * interrupt handler waiting for codec access. So, we handle the
17651 + * interrupt by scheduling a RT kernel thread to run in process
17652 + * context instead of interrupt context.
17655 +static int ucb1x00_thread(void *_ucb)
17657 + struct task_struct *tsk = current;
17658 + DECLARE_WAITQUEUE(wait, tsk);
17659 + struct ucb1x00 *ucb = _ucb;
17660 + struct ucb1x00_irq *irq;
17661 + unsigned int isr, i;
17663 + ucb->rtask = tsk;
17666 + reparent_to_init();
17668 + tsk->policy = SCHED_FIFO;
17669 + tsk->rt_priority = 1;
17670 + strcpy(tsk->comm, "kUCB1x00d");
17672 + /* only want to receive SIGKILL */
17673 + spin_lock_irq(&tsk->sigmask_lock);
17674 + siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
17675 + recalc_sigpending();
17676 + spin_unlock_irq(&tsk->sigmask_lock);
17678 + add_wait_queue(&ucb->irq_wait, &wait);
17679 + set_task_state(tsk, TASK_INTERRUPTIBLE);
17680 + complete(&ucb->complete);
17683 + if (signal_pending(tsk))
17685 + enable_irq(ucb->irq);
17688 + ucb1x00_enable(ucb);
17689 + isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
17690 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
17691 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
17693 + for (i = 0, irq = ucb->irq_handler;
17695 + i++, isr >>= 1, irq++)
17696 + if (isr & 1 && irq->fn)
17697 + irq->fn(i, irq->devid);
17698 + ucb1x00_disable(ucb);
17700 + set_task_state(tsk, TASK_INTERRUPTIBLE);
17703 + remove_wait_queue(&ucb->irq_wait, &wait);
17704 + ucb->rtask = NULL;
17705 + complete_and_exit(&ucb->complete, 0);
17708 +static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
17710 + struct ucb1x00 *ucb = devid;
17711 + disable_irq(irqnr);
17712 + wake_up(&ucb->irq_wait);
17713 + return IRQ_HANDLED;
17717 + * ucb1x00_hook_irq - hook a UCB1x00 interrupt
17718 + * @ucb: UCB1x00 structure describing chip
17719 + * @idx: interrupt index
17720 + * @fn: function to call when interrupt is triggered
17721 + * @devid: device id to pass to interrupt handler
17723 + * Hook the specified interrupt. You can only register one handler
17724 + * for each interrupt source. The interrupt source is not enabled
17725 + * by this function; use ucb1x00_enable_irq instead.
17727 + * Interrupt handlers will be called with other interrupts enabled.
17729 + * Returns zero on success, or one of the following errors:
17730 + * -EINVAL if the interrupt index is invalid
17731 + * -EBUSY if the interrupt has already been hooked
17733 +int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
17735 + struct ucb1x00_irq *irq;
17736 + int ret = -EINVAL;
17739 + irq = ucb->irq_handler + idx;
17742 + spin_lock_irq(&ucb->lock);
17743 + if (irq->fn == NULL) {
17744 + irq->devid = devid;
17748 + spin_unlock_irq(&ucb->lock);
17754 + * ucb1x00_enable_irq - enable an UCB1x00 interrupt source
17755 + * @ucb: UCB1x00 structure describing chip
17756 + * @idx: interrupt index
17757 + * @edges: interrupt edges to enable
17759 + * Enable the specified interrupt to trigger on %UCB_RISING,
17760 + * %UCB_FALLING or both edges. The interrupt should have been
17761 + * hooked by ucb1x00_hook_irq.
17763 +void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
17765 + unsigned long flags;
17768 + spin_lock_irqsave(&ucb->lock, flags);
17770 + ucb1x00_enable(ucb);
17772 + /* This prevents spurious interrupts on the UCB1400 */
17773 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx);
17774 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
17776 + if (edges & UCB_RISING) {
17777 + ucb->irq_ris_enbl |= 1 << idx;
17778 + ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
17780 + if (edges & UCB_FALLING) {
17781 + ucb->irq_fal_enbl |= 1 << idx;
17782 + ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
17784 + ucb1x00_disable(ucb);
17785 + spin_unlock_irqrestore(&ucb->lock, flags);
17790 + * ucb1x00_disable_irq - disable an UCB1x00 interrupt source
17791 + * @ucb: UCB1x00 structure describing chip
17792 + * @edges: interrupt edges to disable
17794 + * Disable the specified interrupt triggering on the specified
17795 + * (%UCB_RISING, %UCB_FALLING or both) edges.
17797 +void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
17799 + unsigned long flags;
17802 + spin_lock_irqsave(&ucb->lock, flags);
17804 + ucb1x00_enable(ucb);
17805 + if (edges & UCB_RISING) {
17806 + ucb->irq_ris_enbl &= ~(1 << idx);
17807 + ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
17809 + if (edges & UCB_FALLING) {
17810 + ucb->irq_fal_enbl &= ~(1 << idx);
17811 + ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
17813 + ucb1x00_disable(ucb);
17814 + spin_unlock_irqrestore(&ucb->lock, flags);
17819 + * ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
17820 + * @ucb: UCB1x00 structure describing chip
17821 + * @idx: interrupt index
17822 + * @devid: device id.
17824 + * Disable the interrupt source and remove the handler. devid must
17825 + * match the devid passed when hooking the interrupt.
17827 + * Returns zero on success, or one of the following errors:
17828 + * -EINVAL if the interrupt index is invalid
17829 + * -ENOENT if devid does not match
17831 +int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
17833 + struct ucb1x00_irq *irq;
17839 + irq = ucb->irq_handler + idx;
17842 + spin_lock_irq(&ucb->lock);
17843 + if (irq->devid == devid) {
17844 + ucb->irq_ris_enbl &= ~(1 << idx);
17845 + ucb->irq_fal_enbl &= ~(1 << idx);
17847 + ucb1x00_enable(ucb);
17848 + ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
17849 + ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
17850 + ucb1x00_disable(ucb);
17853 + irq->devid = NULL;
17856 + spin_unlock_irq(&ucb->lock);
17860 + printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx);
17865 + * Try to probe our interrupt, rather than relying on lots of
17866 + * hard-coded machine dependencies. For reference, the expected
17867 + * IRQ mappings are:
17869 + * Machine Default IRQ
17870 + * adsbitsy IRQ_GPCIN4
17871 + * cerf IRQ_GPIO_UCB1200_IRQ
17872 + * flexanet IRQ_GPIO_GUI
17873 + * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ
17874 + * graphicsclient ADS_EXT_IRQ(8)
17875 + * graphicsmaster ADS_EXT_IRQ(8)
17876 + * lart LART_IRQ_UCB1200
17877 + * omnimeter IRQ_GPIO23
17878 + * pfs168 IRQ_GPIO_UCB1300_IRQ
17879 + * simpad IRQ_GPIO_UCB1300_IRQ
17880 + * shannon SHANNON_IRQ_GPIO_IRQ_CODEC
17881 + * yopy IRQ_GPIO_UCB1200_IRQ
17883 +static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
17885 + unsigned long mask;
17887 + mask = probe_irq_on();
17892 + * Enable the ADC interrupt.
17894 + ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
17895 + ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
17896 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
17897 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
17900 + * Cause an ADC interrupt.
17902 + ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
17903 + ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
17906 + * Wait for the conversion to complete.
17908 + while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0);
17909 + ucb1x00_reg_write(ucb, UCB_ADC_CR, 0);
17912 + * Disable and clear interrupt.
17914 + ucb1x00_reg_write(ucb, UCB_IE_RIS, 0);
17915 + ucb1x00_reg_write(ucb, UCB_IE_FAL, 0);
17916 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
17917 + ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
17920 + * Read triggered interrupt.
17922 + return probe_irq_off(mask);
17925 +static int ucb1x00_probe(struct mcp *mcp)
17927 + struct ucb1x00 *ucb;
17929 + int ret = -ENODEV;
17932 + id = mcp_reg_read(mcp, UCB_ID);
17934 + if (id != UCB_ID_1200 && id != UCB_ID_1300) {
17935 + printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
17936 + goto err_disable;
17939 + ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
17942 + goto err_disable;
17944 + memset(ucb, 0, sizeof(struct ucb1x00));
17946 + ucb->cdev.class = &ucb1x00_class;
17947 + ucb->cdev.dev = &mcp->attached_device;
17948 + strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id));
17950 + spin_lock_init(&ucb->lock);
17951 + spin_lock_init(&ucb->io_lock);
17952 + sema_init(&ucb->adc_sem, 1);
17956 + ucb->irq = ucb1x00_detect_irq(ucb);
17957 + if (ucb->irq == NO_IRQ) {
17958 + printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
17963 + ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb);
17965 + printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
17970 + set_irq_type(ucb->irq, IRQT_RISING);
17971 + mcp_set_drvdata(mcp, ucb);
17973 + ret = class_device_register(&ucb->cdev);
17975 + free_irq(ucb->irq, ucb);
17980 + mcp_disable(mcp);
17984 +static void ucb1x00_remove(struct mcp *mcp)
17986 + struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
17988 + class_device_unregister(&ucb->cdev);
17989 + free_irq(ucb->irq, ucb);
17992 +static void ucb1x00_release(struct class_device *dev)
17994 + struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
17998 +static struct class ucb1x00_class = {
17999 + .name = "ucb1x00",
18000 + .release = ucb1x00_release,
18003 +int ucb1x00_register_interface(struct class_interface *intf)
18005 + intf->class = &ucb1x00_class;
18006 + return class_interface_register(intf);
18009 +void ucb1x00_unregister_interface(struct class_interface *intf)
18011 + class_interface_unregister(intf);
18014 +static struct mcp_driver ucb1x00_driver = {
18016 + .name = "ucb1x00",
18018 + .probe = ucb1x00_probe,
18019 + .remove = ucb1x00_remove,
18022 +static int __init ucb1x00_init(void)
18024 + int ret = class_register(&ucb1x00_class);
18026 + ret = mcp_driver_register(&ucb1x00_driver);
18028 + class_unregister(&ucb1x00_class);
18033 +static void __exit ucb1x00_exit(void)
18035 + mcp_driver_unregister(&ucb1x00_driver);
18036 + class_unregister(&ucb1x00_class);
18039 +module_init(ucb1x00_init);
18040 +module_exit(ucb1x00_exit);
18042 +EXPORT_SYMBOL(ucb1x00_class);
18044 +EXPORT_SYMBOL(ucb1x00_io_set_dir);
18045 +EXPORT_SYMBOL(ucb1x00_io_write);
18046 +EXPORT_SYMBOL(ucb1x00_io_read);
18048 +EXPORT_SYMBOL(ucb1x00_adc_enable);
18049 +EXPORT_SYMBOL(ucb1x00_adc_read);
18050 +EXPORT_SYMBOL(ucb1x00_adc_disable);
18052 +EXPORT_SYMBOL(ucb1x00_hook_irq);
18053 +EXPORT_SYMBOL(ucb1x00_free_irq);
18054 +EXPORT_SYMBOL(ucb1x00_enable_irq);
18055 +EXPORT_SYMBOL(ucb1x00_disable_irq);
18057 +EXPORT_SYMBOL(ucb1x00_register_interface);
18058 +EXPORT_SYMBOL(ucb1x00_unregister_interface);
18060 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
18061 +MODULE_DESCRIPTION("UCB1x00 core driver");
18062 +MODULE_LICENSE("GPL");
18063 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
18064 +++ linux-2.6.5/drivers/misc/switches-ucb1x00.c 2004-04-30 20:57:36.000000000 -0400
18067 + * linux/drivers/misc/switches-ucb1x00.c
18069 + * Copyright (C) 2001 John Dorsey
18071 + * This program is free software; you can redistribute it and/or modify
18072 + * it under the terms of the GNU General Public License version 2 as
18073 + * published by the Free Software Foundation.
18075 + * 19 December 2001 - created from sa1100_switches.c.
18078 +#include <linux/config.h>
18079 +#include <linux/module.h>
18080 +#include <linux/init.h>
18081 +#include <linux/kernel.h>
18082 +#include <linux/sched.h>
18083 +#include <linux/errno.h>
18084 +#include <linux/device.h>
18086 +#include <asm/dma.h>
18087 +#include <asm/hardware.h>
18088 +#include <asm/irq.h>
18089 +#include <asm/mach-types.h>
18091 +#ifdef CONFIG_SA1100_ASSABET
18092 +#include <asm/arch/assabet.h>
18095 +#include "switches.h"
18096 +#include "ucb1x00.h"
18099 +static void switches_ucb1x00_handler(int irq, void *devid);
18102 +#ifdef CONFIG_SA1100_ASSABET
18106 + * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
18107 + * This code sets bits in the range [3, 8] in the mask that we
18108 + * return to userland. Note that we transpose signals SW7 and SW8;
18109 + * see assabet_switches_ucb1x00_handler().
18112 +static int assabet_switches_ucb1x00_init(struct ucb1x00 *ucb)
18116 + ucb1x00_enable(ucb);
18118 + ucb1x00_io_set_dir(ucb,
18119 + UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
18120 + UCB_IO_3 | UCB_IO_4 | UCB_IO_5, 0);
18122 + for (i = 0; i < 6; ++i) {
18123 + ucb1x00_enable_irq(ucb, i, UCB_RISING | UCB_FALLING);
18125 + if (ucb1x00_hook_irq(ucb, i,
18126 + switches_ucb1x00_handler, ucb) < 0) {
18127 + printk(KERN_ERR "%s: unable to hook IRQ for "
18128 + "UCB1300 IO_%d\n", SWITCHES_NAME, i);
18130 + /* FIXME: BUGGY ERROR HANDLING */
18136 + ucb1x00_disable(ucb);
18142 +static void assabet_switches_ucb1x00_shutdown(struct ucb1x00 *ucb)
18146 + ucb1x00_enable(ucb);
18148 + for (i = 5; i >= 0; --i) {
18149 + ucb1x00_disable_irq(ucb, i, UCB_RISING | UCB_FALLING);
18151 + /* Only error conditions are ENOENT and EINVAL; silently
18154 + ucb1x00_free_irq(ucb, i, ucb);
18157 + ucb1x00_disable(ucb);
18160 +static void assabet_switches_ucb1x00_handler(struct ucb1x00 *ucb, int irq, switches_mask_t *mask)
18162 + unsigned int last, this;
18163 + static unsigned int states = 0;
18165 + last = ((states & (1 << irq)) != 0);
18166 + this = ((ucb1x00_io_read(ucb) & (1 << irq)) != 0);
18168 + if (last == this) /* debounce */
18171 + /* Intel StrongARM SA-1110 Development Board
18172 + * Schematics Figure 5, Sheet 5 of 12
18174 + * See switches S8 and S7. Notice their
18175 + * relationship to signals SW7 and SW8. Hmmm.
18182 + SWITCHES_SET(mask, 8, this);
18187 + SWITCHES_SET(mask, 7, this);
18192 + SWITCHES_SET(mask, irq + 3, this);
18196 + states = this ? (states | (1 << irq)) : (states & ~(1 << irq));
18199 +#endif /* CONFIG_SA1100_ASSABET */
18202 +/* switches_ucb1x00_handler()
18203 + * ^^^^^^^^^^^^^^^^^^^^^^^^^^
18204 + * This routine is a generalized handler for UCB1x00 GPIO switches
18205 + * which calls a board-specific service routine and passes an event
18206 + * mask to the core event handler. This routine is appropriate for
18207 + * systems which use the ucb1x00 framework, and can be registered
18208 + * using ucb1x00_hook_irq().
18210 +static void switches_ucb1x00_handler(int irq, void *devid)
18212 + struct ucb1x00 *ucb = devid;
18213 + switches_mask_t mask;
18215 + SWITCHES_ZERO(&mask);
18217 + /* Porting note: call a board-specific UCB1x00 switch handler here.
18218 + * The handler can assume that sufficient storage for `mask' has
18219 + * been allocated, and that the corresponding switches_mask_t
18220 + * structure has been zeroed.
18223 +#ifdef CONFIG_SA1100_ASSABET
18224 + if (machine_is_assabet()) {
18225 + assabet_switches_ucb1x00_handler(ucb, irq, &mask);
18229 + switches_event(&mask);
18232 +static int switches_add(struct class_device *dev)
18234 + struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
18235 + int ret = -ENODEV;
18237 +#ifdef CONFIG_SA1100_ASSABET
18238 + if (machine_is_assabet()) {
18239 + ret = assabet_switches_ucb1x00_init(ucb);
18242 + /* Porting note: call a board-specific init routine here. */
18247 +static void switches_remove(struct class_device *dev)
18249 + struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
18251 + /* Porting note: call a board-specific shutdown routine here. */
18253 +#ifdef CONFIG_SA1100_ASSABET
18254 + if (machine_is_assabet()) {
18255 + assabet_switches_ucb1x00_shutdown(ucb);
18260 +static struct class_interface ucb1x00_switches_interface = {
18261 + .add = switches_add,
18262 + .remove = switches_remove,
18265 +static int __init switches_ucb1x00_init(void)
18267 + return ucb1x00_register_interface(&ucb1x00_switches_interface);
18270 +static void __exit switches_ucb1x00_exit(void)
18272 + ucb1x00_unregister_interface(&ucb1x00_switches_interface);
18275 +module_init(switches_ucb1x00_init);
18276 +module_exit(switches_ucb1x00_exit);
18278 +MODULE_DESCRIPTION("ucb1x00 switches driver");
18279 +MODULE_LICENSE("GPL");
18280 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
18281 +++ linux-2.6.5/drivers/misc/switches-core.c 2004-04-30 20:57:36.000000000 -0400
18284 + * linux/drivers/misc/switches-core.c
18286 + * Copyright (C) 2000-2001 John Dorsey
18288 + * This program is free software; you can redistribute it and/or modify
18289 + * it under the terms of the GNU General Public License version 2 as
18290 + * published by the Free Software Foundation.
18292 + * 5 October 2000 - created.
18294 + * 25 October 2000 - userland file interface added.
18296 + * 13 January 2001 - added support for Spot.
18298 + * 11 September 2001 - UCB1200 driver framework support added.
18300 + * 19 December 2001 - separated out SA-1100 and UCB1x00 code.
18303 +#include <linux/config.h>
18304 +#include <linux/init.h>
18305 +#include <linux/fs.h>
18306 +#include <linux/kernel.h>
18307 +#include <linux/miscdevice.h>
18308 +#include <linux/module.h>
18309 +#include <linux/mm.h>
18310 +#include <linux/poll.h>
18311 +#include <linux/sched.h>
18312 +#include <linux/slab.h>
18313 +#include <linux/wait.h>
18315 +#include <asm/uaccess.h>
18317 +#include "switches.h"
18320 +MODULE_AUTHOR("John Dorsey");
18321 +MODULE_DESCRIPTION("Console switch support");
18322 +MODULE_LICENSE("GPL");
18325 +struct switches_action {
18326 + struct list_head list;
18327 + switches_mask_t mask;
18331 +static int switches_users = 0;
18333 +static spinlock_t switches_lock = SPIN_LOCK_UNLOCKED;
18335 +DECLARE_WAIT_QUEUE_HEAD(switches_wait);
18336 +LIST_HEAD(switches_event_queue);
18339 +static ssize_t switches_read(struct file *file, char *buffer,
18340 + size_t count, loff_t *pos)
18342 + unsigned long flags;
18343 + struct list_head *event;
18344 + struct switches_action *action;
18346 + if (count < sizeof(struct switches_mask_t))
18349 + while (list_empty(&switches_event_queue)) {
18351 + if (file->f_flags & O_NDELAY)
18354 + interruptible_sleep_on(&switches_wait);
18356 + if (signal_pending(current))
18357 + return -ERESTARTSYS;
18361 + if (verify_area(VERIFY_WRITE, buffer, sizeof(struct switches_mask_t)))
18364 + spin_lock_irqsave(&switches_lock, flags);
18366 + event = switches_event_queue.next;
18367 + action = list_entry(event, struct switches_action, list);
18368 + copy_to_user(buffer, &(action->mask), sizeof(struct switches_mask_t));
18372 + spin_unlock_irqrestore(&switches_lock, flags);
18378 +static ssize_t switches_write(struct file *file, const char *buffer,
18379 + size_t count, loff_t *ppos)
18384 +static unsigned int switches_poll(struct file *file, poll_table *wait)
18387 + poll_wait(file, &switches_wait, wait);
18389 + if (!list_empty(&switches_event_queue))
18390 + return POLLIN | POLLRDNORM;
18396 +static int switches_open(struct inode *inode, struct file *file)
18399 + if (switches_users > 0)
18402 + ++switches_users;
18407 +static int switches_release(struct inode *inode, struct file *file)
18410 + --switches_users;
18415 +static struct file_operations switches_ops = {
18416 + .owner = THIS_MODULE,
18417 + .read = switches_read,
18418 + .write = switches_write,
18419 + .poll = switches_poll,
18420 + .open = switches_open,
18421 + .release = switches_release,
18424 +static struct miscdevice switches_misc = {
18425 + .minor = MISC_DYNAMIC_MINOR,
18426 + .name = SWITCHES_NAME,
18427 + .fops = &switches_ops,
18430 +int switches_event(switches_mask_t *mask)
18432 + struct switches_action *action;
18434 + if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) {
18436 + if ((action = (struct switches_action *)
18437 + kmalloc(sizeof(struct switches_action),
18438 + GFP_KERNEL)) == NULL) {
18439 + printk(KERN_ERR "%s: unable to allocate action "
18440 + "descriptor\n", SWITCHES_NAME);
18444 + action->mask = *mask;
18446 + spin_lock(&switches_lock);
18447 + list_add_tail(&action->list, &switches_event_queue);
18448 + spin_unlock(&switches_lock);
18450 + wake_up_interruptible(&switches_wait);
18458 +EXPORT_SYMBOL(switches_event);
18461 +static int __init switches_init(void)
18463 + if (misc_register(&switches_misc) < 0) {
18464 + printk(KERN_ERR "%s: unable to register misc device\n",
18469 + printk(KERN_INFO "Console switches initialized\n");
18474 +static void __exit switches_exit(void)
18476 + if (misc_deregister(&switches_misc) < 0)
18477 + printk(KERN_ERR "%s: unable to deregister misc device\n",
18481 +module_init(switches_init);
18482 +module_exit(switches_exit);
18483 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
18484 +++ linux-2.6.5/drivers/misc/ucb1x00-audio.c 2004-04-30 20:57:36.000000000 -0400
18487 + * linux/drivers/misc/ucb1x00-audio.c
18489 + * Copyright (C) 2001 Russell King, All Rights Reserved.
18491 + * This program is free software; you can redistribute it and/or modify
18492 + * it under the terms of the GNU General Public License version 2 as
18493 + * published by the Free Software Foundation.
18495 +#include <linux/module.h>
18496 +#include <linux/init.h>
18497 +#include <linux/fs.h>
18498 +#include <linux/errno.h>
18499 +#include <linux/slab.h>
18500 +#include <linux/sound.h>
18501 +#include <linux/soundcard.h>
18502 +#include <linux/list.h>
18503 +#include <linux/device.h>
18505 +#include <asm/dma.h>
18506 +#include <asm/hardware.h>
18507 +#include <asm/semaphore.h>
18508 +#include <asm/uaccess.h>
18510 +#include "ucb1x00.h"
18512 +#include "../sound/oss/sa1100-audio.h"
18514 +#define MAGIC 0x41544154
18516 +struct ucb1x00_audio {
18517 + struct file_operations fops;
18518 + struct file_operations mops;
18519 + struct ucb1x00 *ucb;
18520 + audio_stream_t output_stream;
18521 + audio_stream_t input_stream;
18522 + audio_state_t state;
18523 + unsigned int rate;
18526 + unsigned int daa_oh_bit;
18527 + unsigned int telecom;
18528 + unsigned int magic;
18529 + unsigned int ctrl_a;
18530 + unsigned int ctrl_b;
18533 + unsigned int mod_cnt;
18534 + unsigned short output_level;
18535 + unsigned short input_level;
18538 +#define REC_MASK (SOUND_MASK_VOLUME | SOUND_MASK_MIC)
18539 +#define DEV_MASK REC_MASK
18542 +ucb1x00_mixer_ioctl(struct inode *ino, struct file *filp, uint cmd, ulong arg)
18544 + struct ucb1x00_audio *ucba;
18545 + unsigned int val, gain;
18548 + ucba = list_entry(filp->f_op, struct ucb1x00_audio, mops);
18550 + if (_IOC_TYPE(cmd) != 'M')
18553 + if (cmd == SOUND_MIXER_INFO) {
18554 + struct mixer_info mi;
18556 + strncpy(mi.id, "UCB1x00", sizeof(mi.id));
18557 + strncpy(mi.name, "Philips UCB1x00", sizeof(mi.name));
18558 + mi.modify_counter = ucba->mod_cnt;
18559 + return copy_to_user((void *)arg, &mi, sizeof(mi)) ? -EFAULT : 0;
18562 + if (_IOC_DIR(cmd) & _IOC_WRITE) {
18563 + unsigned int left, right;
18565 + ret = get_user(val, (unsigned int *)arg);
18569 + left = val & 255;
18570 + right = val >> 8;
18577 + gain = (left + right) / 2;
18580 + if (!ucba->telecom) {
18581 + switch(_IOC_NR(cmd)) {
18582 + case SOUND_MIXER_VOLUME:
18583 + ucba->output_level = gain | gain << 8;
18585 + ucba->ctrl_b = (ucba->ctrl_b & 0xff00) |
18586 + ((gain * 31) / 100);
18587 + ucb1x00_reg_write(ucba->ucb, UCB_AC_B,
18592 + case SOUND_MIXER_MIC:
18593 + ucba->input_level = gain | gain << 8;
18595 + ucba->ctrl_a = (ucba->ctrl_a & 0x7f) |
18596 + (((gain * 31) / 100) << 7);
18597 + ucb1x00_reg_write(ucba->ucb, UCB_AC_A,
18605 + if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
18606 + switch (_IOC_NR(cmd)) {
18607 + case SOUND_MIXER_VOLUME:
18608 + val = ucba->output_level;
18611 + case SOUND_MIXER_MIC:
18612 + val = ucba->input_level;
18615 + case SOUND_MIXER_RECSRC:
18616 + case SOUND_MIXER_RECMASK:
18617 + val = ucba->telecom ? 0 : REC_MASK;
18620 + case SOUND_MIXER_DEVMASK:
18621 + val = ucba->telecom ? 0 : DEV_MASK;
18624 + case SOUND_MIXER_CAPS:
18625 + case SOUND_MIXER_STEREODEVS:
18636 + ret = put_user(val, (int *)arg);
18642 +static int ucb1x00_audio_setrate(struct ucb1x00_audio *ucba, int rate)
18644 + unsigned int div_rate = ucb1x00_clkrate(ucba->ucb) / 32;
18645 + unsigned int div;
18647 + div = (div_rate + (rate / 2)) / rate;
18653 + ucba->ctrl_a = (ucba->ctrl_a & ~0x7f) | div;
18655 + if (ucba->telecom) {
18656 + ucb1x00_reg_write(ucba->ucb, UCB_TC_B, 0);
18657 + ucb1x00_set_telecom_divisor(ucba->ucb, div * 32);
18658 + ucb1x00_reg_write(ucba->ucb, UCB_TC_A, ucba->ctrl_a);
18659 + ucb1x00_reg_write(ucba->ucb, UCB_TC_B, ucba->ctrl_b);
18661 + ucb1x00_reg_write(ucba->ucb, UCB_AC_B, 0);
18662 + ucb1x00_set_audio_divisor(ucba->ucb, div * 32);
18663 + ucb1x00_reg_write(ucba->ucb, UCB_AC_A, ucba->ctrl_a);
18664 + ucb1x00_reg_write(ucba->ucb, UCB_AC_B, ucba->ctrl_b);
18667 + ucba->rate = div_rate / div;
18669 + return ucba->rate;
18672 +static int ucb1x00_audio_getrate(struct ucb1x00_audio *ucba)
18674 + return ucba->rate;
18677 +static void ucb1x00_audio_startup(void *data)
18679 + struct ucb1x00_audio *ucba = data;
18681 + ucb1x00_enable(ucba->ucb);
18682 + ucb1x00_audio_setrate(ucba, ucba->rate);
18684 + ucb1x00_reg_write(ucba->ucb, UCB_MODE, UCB_MODE_DYN_VFLAG_ENA);
18689 + if (ucba->daa_oh_bit)
18690 + ucb1x00_io_write(ucba->ucb, 0, ucba->daa_oh_bit);
18693 +static void ucb1x00_audio_shutdown(void *data)
18695 + struct ucb1x00_audio *ucba = data;
18700 + if (ucba->daa_oh_bit)
18701 + ucb1x00_io_write(ucba->ucb, ucba->daa_oh_bit, 0);
18703 + ucb1x00_reg_write(ucba->ucb, ucba->telecom ? UCB_TC_B : UCB_AC_B, 0);
18704 + ucb1x00_disable(ucba->ucb);
18708 +ucb1x00_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
18710 + struct ucb1x00_audio *ucba;
18711 + int val, ret = 0;
18713 + ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
18716 + * Make sure we have our magic number
18718 + if (ucba->magic != MAGIC)
18722 + case SNDCTL_DSP_STEREO:
18723 + ret = get_user(val, (int *)arg);
18731 + case SNDCTL_DSP_CHANNELS:
18732 + case SOUND_PCM_READ_CHANNELS:
18736 + case SNDCTL_DSP_SPEED:
18737 + ret = get_user(val, (int *)arg);
18740 + val = ucb1x00_audio_setrate(ucba, val);
18743 + case SOUND_PCM_READ_RATE:
18744 + val = ucb1x00_audio_getrate(ucba);
18747 + case SNDCTL_DSP_SETFMT:
18748 + case SNDCTL_DSP_GETFMTS:
18749 + val = AFMT_S16_LE;
18753 + return ucb1x00_mixer_ioctl(inode, file, cmd, arg);
18756 + return put_user(val, (int *)arg);
18759 +static int ucb1x00_audio_open(struct inode *inode, struct file *file)
18761 + struct ucb1x00_audio *ucba;
18763 + ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
18765 + return sa1100_audio_attach(inode, file, &ucba->state);
18768 +static struct ucb1x00_audio *ucb1x00_audio_alloc(struct ucb1x00 *ucb)
18770 + struct ucb1x00_audio *ucba;
18772 + ucba = kmalloc(sizeof(*ucba), GFP_KERNEL);
18774 + memset(ucba, 0, sizeof(*ucba));
18776 + ucba->magic = MAGIC;
18778 + ucba->fops.owner = THIS_MODULE;
18779 + ucba->fops.open = ucb1x00_audio_open;
18780 + ucba->mops.owner = THIS_MODULE;
18781 + ucba->mops.ioctl = ucb1x00_mixer_ioctl;
18782 + ucba->state.output_stream = &ucba->output_stream;
18783 + ucba->state.input_stream = &ucba->input_stream;
18784 + ucba->state.data = ucba;
18785 + ucba->state.hw_init = ucb1x00_audio_startup;
18786 + ucba->state.hw_shutdown = ucb1x00_audio_shutdown;
18787 + ucba->state.client_ioctl = ucb1x00_audio_ioctl;
18789 + /* There is a bug in the StrongARM causes corrupt MCP data to be sent to
18790 + * the codec when the FIFOs are empty and writes are made to the OS timer
18791 + * match register 0. To avoid this we must make sure that data is always
18792 + * sent to the codec.
18794 + ucba->state.need_tx_for_rx = 1;
18796 + init_MUTEX(&ucba->state.sem);
18797 + ucba->rate = 8000;
18802 +static struct ucb1x00_audio *ucb1x00_audio_add_one(struct ucb1x00 *ucb, int telecom)
18804 + struct ucb1x00_audio *a;
18806 + a = ucb1x00_audio_alloc(ucb);
18808 + a->telecom = telecom;
18810 + a->input_stream.dev = ucb->cdev.dev;
18811 + a->output_stream.dev = ucb->cdev.dev;
18814 + if (a->telecom) {
18815 + a->input_stream.dma_dev = ucb->mcp->dma_telco_rd;
18816 + a->input_stream.id = "UCB1x00 telco in";
18817 + a->output_stream.dma_dev = ucb->mcp->dma_telco_wr;
18818 + a->output_stream.id = "UCB1x00 telco out";
18819 + a->ctrl_b = UCB_TC_B_IN_ENA|UCB_TC_B_OUT_ENA;
18821 + a->daa_oh_bit = UCB_IO_8;
18823 + ucb1x00_enable(ucb);
18824 + ucb1x00_io_write(ucb, a->daa_oh_bit, 0);
18825 + ucb1x00_io_set_dir(ucb, UCB_IO_7 | UCB_IO_6, a->daa_oh_bit);
18826 + ucb1x00_disable(ucb);
18829 + a->input_stream.dma_dev = ucb->mcp->dma_audio_rd;
18830 + a->input_stream.id = "UCB1x00 audio in";
18831 + a->output_stream.dma_dev = ucb->mcp->dma_audio_wr;
18832 + a->output_stream.id = "UCB1x00 audio out";
18833 + a->ctrl_b = UCB_AC_B_IN_ENA|UCB_AC_B_OUT_ENA;
18836 + a->dev_id = register_sound_dsp(&a->fops, -1);
18837 + a->mix_id = register_sound_mixer(&a->mops, -1);
18839 + printk("Sound: UCB1x00 %s: dsp id %d mixer id %d\n",
18840 + a->telecom ? "telecom" : "audio",
18841 + a->dev_id, a->mix_id);
18847 +static void ucb1x00_audio_remove_one(struct ucb1x00_audio *a)
18849 + unregister_sound_dsp(a->dev_id);
18850 + unregister_sound_mixer(a->mix_id);
18854 +static int ucb1x00_audio_add(struct class_device *cdev)
18856 + struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev);
18858 + if (ucb->cdev.dev == NULL || ucb->cdev.dev->dma_mask == NULL)
18861 + ucb->audio_data = ucb1x00_audio_add_one(ucb, 0);
18862 + ucb->telecom_data = ucb1x00_audio_add_one(ucb, 1);
18867 +static void ucb1x00_audio_remove(struct class_device *cdev)
18869 + struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev);
18871 + ucb1x00_audio_remove_one(ucb->audio_data);
18872 + ucb1x00_audio_remove_one(ucb->telecom_data);
18875 +#if 0 //def CONFIG_PM
18876 +static int ucb1x00_audio_suspend(struct ucb1x00 *ucb, u32 state)
18878 + struct ucb1x00_audio *a;
18880 + a = ucb->audio_data;
18881 + sa1100_audio_suspend(&a->state, state);
18882 + a = ucb->telecom_data;
18883 + sa1100_audio_suspend(&a->state, state);
18888 +static int ucb1x00_audio_resume(struct ucb1x00 *ucb)
18890 + struct ucb1x00_audio *a;
18892 + a = ucb->audio_data;
18893 + sa1100_audio_resume(&a->state);
18894 + a = ucb->telecom_data;
18895 + sa1100_audio_resume(&a->state);
18900 +#define ucb1x00_audio_suspend NULL
18901 +#define ucb1x00_audio_resume NULL
18904 +static struct class_interface ucb1x00_audio_interface = {
18905 + .add = ucb1x00_audio_add,
18906 + .remove = ucb1x00_audio_remove,
18909 +static int __init ucb1x00_audio_init(void)
18911 + return ucb1x00_register_interface(&ucb1x00_audio_interface);
18914 +static void __exit ucb1x00_audio_exit(void)
18916 + ucb1x00_unregister_interface(&ucb1x00_audio_interface);
18919 +module_init(ucb1x00_audio_init);
18920 +module_exit(ucb1x00_audio_exit);
18922 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
18923 +MODULE_DESCRIPTION("UCB1x00 telecom/audio driver");
18924 +MODULE_LICENSE("GPL");
18925 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
18926 +++ linux-2.6.5/drivers/misc/mcp-sa1100.c 2004-04-30 20:57:36.000000000 -0400
18929 + * linux/drivers/misc/mcp-sa1100.c
18931 + * Copyright (C) 2001 Russell King
18933 + * This program is free software; you can redistribute it and/or modify
18934 + * it under the terms of the GNU General Public License as published by
18935 + * the Free Software Foundation; either version 2 of the License.
18937 + * SA1100 MCP (Multimedia Communications Port) driver.
18939 + * MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
18941 +#include <linux/module.h>
18942 +#include <linux/init.h>
18943 +#include <linux/errno.h>
18944 +#include <linux/kernel.h>
18945 +#include <linux/delay.h>
18946 +#include <linux/spinlock.h>
18947 +#include <linux/slab.h>
18948 +#include <linux/device.h>
18950 +#include <asm/dma.h>
18951 +#include <asm/hardware.h>
18952 +#include <asm/mach-types.h>
18953 +#include <asm/system.h>
18955 +#include <asm/arch/assabet.h>
18960 +mcp_sa1100_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
18962 + unsigned int mccr0;
18966 + mccr0 = Ser4MCCR0 & ~0x00007f00;
18967 + mccr0 |= divisor << 8;
18968 + Ser4MCCR0 = mccr0;
18972 +mcp_sa1100_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
18974 + unsigned int mccr0;
18978 + mccr0 = Ser4MCCR0 & ~0x0000007f;
18979 + mccr0 |= divisor;
18980 + Ser4MCCR0 = mccr0;
18984 + * Write data to the device. The bit should be set after 3 subframe
18985 + * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
18986 + * We really should try doing something more productive while we
18990 +mcp_sa1100_write(struct mcp *mcp, unsigned int reg, unsigned int val)
18992 + int ret = -ETIME;
18995 + Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
18997 + for (i = 0; i < 2; i++) {
18998 + udelay(mcp->rw_timeout);
18999 + if (Ser4MCSR & MCSR_CWC) {
19006 + printk(KERN_WARNING "mcp: write timed out\n");
19010 + * Read data from the device. The bit should be set after 3 subframe
19011 + * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
19012 + * We really should try doing something more productive while we
19015 +static unsigned int
19016 +mcp_sa1100_read(struct mcp *mcp, unsigned int reg)
19018 + int ret = -ETIME;
19021 + Ser4MCDR2 = reg << 17 | MCDR2_Rd;
19023 + for (i = 0; i < 2; i++) {
19024 + udelay(mcp->rw_timeout);
19025 + if (Ser4MCSR & MCSR_CRC) {
19026 + ret = Ser4MCDR2 & 0xffff;
19032 + printk(KERN_WARNING "mcp: read timed out\n");
19037 +static void mcp_sa1100_enable(struct mcp *mcp)
19040 + Ser4MCCR0 |= MCCR0_MCE;
19043 +static void mcp_sa1100_disable(struct mcp *mcp)
19045 + Ser4MCCR0 &= ~MCCR0_MCE;
19051 +static struct mcp mcp_sa1100 = {
19052 + .owner = THIS_MODULE,
19053 + .lock = SPIN_LOCK_UNLOCKED,
19054 + .sclk_rate = 11981000,
19055 + .dma_audio_rd = DMA_Ser4MCP0Rd,
19056 + .dma_audio_wr = DMA_Ser4MCP0Wr,
19057 + .dma_telco_rd = DMA_Ser4MCP1Rd,
19058 + .dma_telco_wr = DMA_Ser4MCP1Wr,
19059 + .set_telecom_divisor = mcp_sa1100_set_telecom_divisor,
19060 + .set_audio_divisor = mcp_sa1100_set_audio_divisor,
19061 + .reg_write = mcp_sa1100_write,
19062 + .reg_read = mcp_sa1100_read,
19063 + .enable = mcp_sa1100_enable,
19064 + .disable = mcp_sa1100_disable,
19067 +static int mcp_sa1100_probe(struct device *dev)
19069 + struct platform_device *pdev = to_platform_device(dev);
19070 + struct mcp *mcp = &mcp_sa1100;
19073 + if (!machine_is_adsbitsy() && !machine_is_assabet() &&
19074 + !machine_is_cerf() && !machine_is_flexanet() &&
19075 + !machine_is_freebird() && !machine_is_graphicsclient() &&
19076 + !machine_is_graphicsmaster() && !machine_is_lart() &&
19077 + !machine_is_omnimeter() && !machine_is_pfs168() &&
19078 + !machine_is_shannon() && !machine_is_simpad() &&
19079 + !machine_is_yopy())
19082 + if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
19086 + dev_set_drvdata(dev, mcp);
19088 + if (machine_is_assabet()) {
19089 + ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
19093 + * Setup the PPC unit correctly.
19095 + PPDR &= ~PPC_RXD4;
19096 + PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
19097 + PSDR |= PPC_RXD4;
19098 + PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
19099 + PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
19103 + Ser4MCCR0 = 0x00007f7f | MCCR0_ADM;
19106 + * Calculate the read/write timeout (us) from the bit clock
19107 + * rate. This is the period for 3 64-bit frames. Always
19108 + * round this time up.
19110 + mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
19113 + ret = mcp_host_register(mcp, &pdev->dev);
19115 + release_mem_region(0x80060000, 0x60);
19116 + dev_set_drvdata(dev, NULL);
19122 +static int mcp_sa1100_remove(struct device *dev)
19124 + struct mcp *mcp = dev_get_drvdata(dev);
19126 + dev_set_drvdata(dev, NULL);
19128 + mcp_host_unregister(mcp);
19129 + release_mem_region(0x80060000, 0x60);
19134 +struct mcp_sa1100_state {
19139 +static int mcp_sa1100_suspend(struct device *dev, u32 state, u32 level)
19141 + struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state;
19144 + s = kmalloc(sizeof(struct mcp_sa1100_state), GFP_KERNEL);
19145 + dev->saved_state = (unsigned char *)s;
19149 + s->mccr0 = Ser4MCCR0;
19150 + s->mccr1 = Ser4MCCR1;
19153 + if (level == SUSPEND_DISABLE)
19154 + Ser4MCCR0 &= ~MCCR0_MCE;
19158 +static int mcp_sa1100_resume(struct device *dev, u32 level)
19160 + struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state;
19162 + if (s && level == RESUME_RESTORE_STATE) {
19163 + Ser4MCCR1 = s->mccr1;
19164 + Ser4MCCR0 = s->mccr0;
19166 + dev->saved_state = NULL;
19173 + * The driver for the SA11x0 MCP port.
19175 +static struct device_driver mcp_sa1100_driver = {
19176 + .name = "sa11x0-mcp",
19177 + .bus = &platform_bus_type,
19178 + .probe = mcp_sa1100_probe,
19179 + .remove = mcp_sa1100_remove,
19180 + .suspend = mcp_sa1100_suspend,
19181 + .resume = mcp_sa1100_resume,
19185 + * This needs re-working
19187 +static int __init mcp_sa1100_init(void)
19189 + return driver_register(&mcp_sa1100_driver);
19192 +static void __exit mcp_sa1100_exit(void)
19194 + driver_unregister(&mcp_sa1100_driver);
19197 +module_init(mcp_sa1100_init);
19198 +module_exit(mcp_sa1100_exit);
19200 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
19201 +MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
19202 +MODULE_LICENSE("GPL");
19203 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
19204 +++ linux-2.6.5/drivers/misc/mcp.h 2004-04-30 20:57:36.000000000 -0400
19207 + * linux/drivers/misc/mcp.h
19209 + * Copyright (C) 2001 Russell King, All Rights Reserved.
19211 + * This program is free software; you can redistribute it and/or modify
19212 + * it under the terms of the GNU General Public License as published by
19213 + * the Free Software Foundation; either version 2 of the License.
19219 + struct module *owner;
19220 + struct device *me;
19223 + unsigned int sclk_rate;
19224 + unsigned int rw_timeout;
19225 + dma_device_t dma_audio_rd;
19226 + dma_device_t dma_audio_wr;
19227 + dma_device_t dma_telco_rd;
19228 + dma_device_t dma_telco_wr;
19229 + void (*set_telecom_divisor)(struct mcp *, unsigned int);
19230 + void (*set_audio_divisor)(struct mcp *, unsigned int);
19231 + void (*reg_write)(struct mcp *, unsigned int, unsigned int);
19232 + unsigned int (*reg_read)(struct mcp *, unsigned int);
19233 + void (*enable)(struct mcp *);
19234 + void (*disable)(struct mcp *);
19235 + struct device attached_device;
19238 +void mcp_set_telecom_divisor(struct mcp *, unsigned int);
19239 +void mcp_set_audio_divisor(struct mcp *, unsigned int);
19240 +void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
19241 +unsigned int mcp_reg_read(struct mcp *, unsigned int);
19242 +void mcp_enable(struct mcp *);
19243 +void mcp_disable(struct mcp *);
19244 +#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
19246 +int mcp_host_register(struct mcp *, struct device *);
19247 +void mcp_host_unregister(struct mcp *);
19249 +struct mcp_driver {
19250 + struct device_driver drv;
19251 + int (*probe)(struct mcp *);
19252 + void (*remove)(struct mcp *);
19253 + int (*suspend)(struct mcp *, u32);
19254 + int (*resume)(struct mcp *);
19257 +int mcp_driver_register(struct mcp_driver *);
19258 +void mcp_driver_unregister(struct mcp_driver *);
19260 +#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
19261 +#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
19264 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
19265 +++ linux-2.6.5/drivers/misc/ucb1x00-input.h 2004-04-30 20:57:36.000000000 -0400
19268 + * linux/drivers/misc/ucb1x00.h
19270 + * Copyright (C) 2001 Russell King, All Rights Reserved.
19272 + * This program is free software; you can redistribute it and/or modify
19273 + * it under the terms of the GNU General Public License as published by
19274 + * the Free Software Foundation; either version 2 of the License.
19279 +#define UCB_IO_DATA 0x00
19280 +#define UCB_IO_DIR 0x01
19282 +#define UCB_IO_0 (1 << 0)
19283 +#define UCB_IO_1 (1 << 1)
19284 +#define UCB_IO_2 (1 << 2)
19285 +#define UCB_IO_3 (1 << 3)
19286 +#define UCB_IO_4 (1 << 4)
19287 +#define UCB_IO_5 (1 << 5)
19288 +#define UCB_IO_6 (1 << 6)
19289 +#define UCB_IO_7 (1 << 7)
19290 +#define UCB_IO_8 (1 << 8)
19291 +#define UCB_IO_9 (1 << 9)
19293 +#define UCB_IE_RIS 0x02
19294 +#define UCB_IE_FAL 0x03
19295 +#define UCB_IE_STATUS 0x04
19296 +#define UCB_IE_CLEAR 0x04
19297 +#define UCB_IE_ADC (1 << 11)
19298 +#define UCB_IE_TSPX (1 << 12)
19299 +#define UCB_IE_TSMX (1 << 13)
19300 +#define UCB_IE_TCLIP (1 << 14)
19301 +#define UCB_IE_ACLIP (1 << 15)
19303 +#define UCB_IRQ_TSPX 12
19305 +#define UCB_TC_A 0x05
19306 +#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
19307 +#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
19309 +#define UCB_TC_B 0x06
19310 +#define UCB_TC_B_VOICE_ENA (1 << 3)
19311 +#define UCB_TC_B_CLIP (1 << 4)
19312 +#define UCB_TC_B_ATT (1 << 6)
19313 +#define UCB_TC_B_SIDE_ENA (1 << 11)
19314 +#define UCB_TC_B_MUTE (1 << 13)
19315 +#define UCB_TC_B_IN_ENA (1 << 14)
19316 +#define UCB_TC_B_OUT_ENA (1 << 15)
19318 +#define UCB_AC_A 0x07
19319 +#define UCB_AC_B 0x08
19320 +#define UCB_AC_B_LOOP (1 << 8)
19321 +#define UCB_AC_B_MUTE (1 << 13)
19322 +#define UCB_AC_B_IN_ENA (1 << 14)
19323 +#define UCB_AC_B_OUT_ENA (1 << 15)
19325 +#define UCB_TS_CR 0x09
19326 +#define UCB_TS_CR_TSMX_POW (1 << 0)
19327 +#define UCB_TS_CR_TSPX_POW (1 << 1)
19328 +#define UCB_TS_CR_TSMY_POW (1 << 2)
19329 +#define UCB_TS_CR_TSPY_POW (1 << 3)
19330 +#define UCB_TS_CR_TSMX_GND (1 << 4)
19331 +#define UCB_TS_CR_TSPX_GND (1 << 5)
19332 +#define UCB_TS_CR_TSMY_GND (1 << 6)
19333 +#define UCB_TS_CR_TSPY_GND (1 << 7)
19334 +#define UCB_TS_CR_MODE_INT (0 << 8)
19335 +#define UCB_TS_CR_MODE_PRES (1 << 8)
19336 +#define UCB_TS_CR_MODE_POS (2 << 8)
19337 +#define UCB_TS_CR_BIAS_ENA (1 << 11)
19338 +#define UCB_TS_CR_TSPX_LOW (1 << 12)
19339 +#define UCB_TS_CR_TSMX_LOW (1 << 13)
19341 +#define UCB_ADC_CR 0x0a
19342 +#define UCB_ADC_SYNC_ENA (1 << 0)
19343 +#define UCB_ADC_VREFBYP_CON (1 << 1)
19344 +#define UCB_ADC_INP_TSPX (0 << 2)
19345 +#define UCB_ADC_INP_TSMX (1 << 2)
19346 +#define UCB_ADC_INP_TSPY (2 << 2)
19347 +#define UCB_ADC_INP_TSMY (3 << 2)
19348 +#define UCB_ADC_INP_AD0 (4 << 2)
19349 +#define UCB_ADC_INP_AD1 (5 << 2)
19350 +#define UCB_ADC_INP_AD2 (6 << 2)
19351 +#define UCB_ADC_INP_AD3 (7 << 2)
19352 +#define UCB_ADC_EXT_REF (1 << 5)
19353 +#define UCB_ADC_START (1 << 7)
19354 +#define UCB_ADC_ENA (1 << 15)
19356 +#define UCB_ADC_DATA 0x0b
19357 +#define UCB_ADC_DAT_VAL (1 << 15)
19358 +#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
19360 +#define UCB_ID 0x0c
19361 +#define UCB_ID_1200 0x1004
19362 +#define UCB_ID_1300 0x1005
19363 +#define UCB_ID_1400 0x4304
19364 +#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */
19366 +#define UCB_MODE 0x0d
19367 +#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
19368 +#define UCB_MODE_AUD_OFF_CAN (1 << 13)
19374 +struct ucb1x00_irq {
19376 + void (*fn)(int, void *);
19382 + unsigned int irq;
19383 + struct semaphore adc_sem;
19384 + spinlock_t io_lock;
19389 + u16 irq_fal_enbl;
19390 + u16 irq_ris_enbl;
19391 + struct ucb1x00_irq irq_handler[16];
19395 + * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
19396 + * @ucb: UCB1x00 structure describing chip
19398 + * Return the SIB clock rate in Hz.
19400 +static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
19402 + return mcp_get_sclk_rate(ucb->mcp);
19406 + * ucb1x00_enable - enable the UCB1x00 SIB clock
19407 + * @ucb: UCB1x00 structure describing chip
19409 + * Enable the SIB clock. This can be called multiple times.
19411 +static inline void ucb1x00_enable(struct ucb1x00 *ucb)
19413 + mcp_enable(ucb->mcp);
19417 + * ucb1x00_disable - disable the UCB1x00 SIB clock
19418 + * @ucb: UCB1x00 structure describing chip
19420 + * Disable the SIB clock. The SIB clock will only be disabled
19421 + * when the number of ucb1x00_enable calls match the number of
19422 + * ucb1x00_disable calls.
19424 +static inline void ucb1x00_disable(struct ucb1x00 *ucb)
19426 + mcp_disable(ucb->mcp);
19430 + * ucb1x00_reg_write - write a UCB1x00 register
19431 + * @ucb: UCB1x00 structure describing chip
19432 + * @reg: UCB1x00 4-bit register index to write
19433 + * @val: UCB1x00 16-bit value to write
19435 + * Write the UCB1x00 register @reg with value @val. The SIB
19436 + * clock must be running for this function to return.
19438 +static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
19440 + mcp_reg_write(ucb->mcp, reg, val);
19444 + * ucb1x00_reg_read - read a UCB1x00 register
19445 + * @ucb: UCB1x00 structure describing chip
19446 + * @reg: UCB1x00 4-bit register index to write
19448 + * Read the UCB1x00 register @reg and return its value. The SIB
19449 + * clock must be running for this function to return.
19451 +static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
19453 + return mcp_reg_read(ucb->mcp, reg);
19456 + * ucb1x00_set_audio_divisor -
19457 + * @ucb: UCB1x00 structure describing chip
19458 + * @div: SIB clock divisor
19460 +static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
19462 + mcp_set_audio_divisor(ucb->mcp, div);
19466 + * ucb1x00_set_telecom_divisor -
19467 + * @ucb: UCB1x00 structure describing chip
19468 + * @div: SIB clock divisor
19470 +static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
19472 + mcp_set_telecom_divisor(ucb->mcp, div);
19475 +struct ucb1x00 *ucb1x00_get(void);
19477 +void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
19478 +void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
19479 +unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
19481 +#define UCB_NOSYNC (0)
19482 +#define UCB_SYNC (1)
19484 +unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
19485 +void ucb1x00_adc_enable(struct ucb1x00 *ucb);
19486 +void ucb1x00_adc_disable(struct ucb1x00 *ucb);
19489 + * Which edges of the IRQ do you want to control today?
19491 +#define UCB_RISING (1 << 0)
19492 +#define UCB_FALLING (1 << 1)
19494 +int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
19495 +void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
19496 +void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
19497 +int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
19500 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
19501 +++ linux-2.6.5/drivers/misc/ucb1x00.h 2004-04-30 20:57:36.000000000 -0400
19504 + * linux/drivers/misc/ucb1x00.h
19506 + * Copyright (C) 2001 Russell King, All Rights Reserved.
19508 + * This program is free software; you can redistribute it and/or modify
19509 + * it under the terms of the GNU General Public License as published by
19510 + * the Free Software Foundation; either version 2 of the License.
19515 +#ifdef CONFIG_ARCH_PXA
19517 +/* ucb1400 aclink register mappings: */
19519 +#define UCB_IO_DATA 0x5a
19520 +#define UCB_IO_DIR 0x5c
19521 +#define UCB_IE_RIS 0x5e
19522 +#define UCB_IE_FAL 0x60
19523 +#define UCB_IE_STATUS 0x62
19524 +#define UCB_IE_CLEAR 0x62
19525 +#define UCB_TS_CR 0x64
19526 +#define UCB_ADC_CR 0x66
19527 +#define UCB_ADC_DATA 0x68
19528 +#define UCB_ID 0x7e /* 7c is mfr id, 7e part id (from aclink spec) */
19530 +#define UCB_ADC_DAT(x) ((x) & 0x3ff)
19534 +/* ucb1x00 SIB register mappings: */
19536 +#define UCB_IO_DATA 0x00
19537 +#define UCB_IO_DIR 0x01
19538 +#define UCB_IE_RIS 0x02
19539 +#define UCB_IE_FAL 0x03
19540 +#define UCB_IE_STATUS 0x04
19541 +#define UCB_IE_CLEAR 0x04
19542 +#define UCB_TC_A 0x05
19543 +#define UCB_TC_B 0x06
19544 +#define UCB_AC_A 0x07
19545 +#define UCB_AC_B 0x08
19546 +#define UCB_TS_CR 0x09
19547 +#define UCB_ADC_CR 0x0a
19548 +#define UCB_ADC_DATA 0x0b
19549 +#define UCB_ID 0x0c
19550 +#define UCB_MODE 0x0d
19552 +#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
19557 +#define UCB_IO_0 (1 << 0)
19558 +#define UCB_IO_1 (1 << 1)
19559 +#define UCB_IO_2 (1 << 2)
19560 +#define UCB_IO_3 (1 << 3)
19561 +#define UCB_IO_4 (1 << 4)
19562 +#define UCB_IO_5 (1 << 5)
19563 +#define UCB_IO_6 (1 << 6)
19564 +#define UCB_IO_7 (1 << 7)
19565 +#define UCB_IO_8 (1 << 8)
19566 +#define UCB_IO_9 (1 << 9)
19568 +#define UCB_IE_ADC (1 << 11)
19569 +#define UCB_IE_TSPX (1 << 12)
19570 +#define UCB_IE_TSMX (1 << 13)
19571 +#define UCB_IE_TCLIP (1 << 14)
19572 +#define UCB_IE_ACLIP (1 << 15)
19574 +#define UCB_IRQ_TSPX 12
19576 +#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
19577 +#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
19579 +#define UCB_TC_B_VOICE_ENA (1 << 3)
19580 +#define UCB_TC_B_CLIP (1 << 4)
19581 +#define UCB_TC_B_ATT (1 << 6)
19582 +#define UCB_TC_B_SIDE_ENA (1 << 11)
19583 +#define UCB_TC_B_MUTE (1 << 13)
19584 +#define UCB_TC_B_IN_ENA (1 << 14)
19585 +#define UCB_TC_B_OUT_ENA (1 << 15)
19587 +#define UCB_AC_B_LOOP (1 << 8)
19588 +#define UCB_AC_B_MUTE (1 << 13)
19589 +#define UCB_AC_B_IN_ENA (1 << 14)
19590 +#define UCB_AC_B_OUT_ENA (1 << 15)
19592 +#define UCB_TS_CR_TSMX_POW (1 << 0)
19593 +#define UCB_TS_CR_TSPX_POW (1 << 1)
19594 +#define UCB_TS_CR_TSMY_POW (1 << 2)
19595 +#define UCB_TS_CR_TSPY_POW (1 << 3)
19596 +#define UCB_TS_CR_TSMX_GND (1 << 4)
19597 +#define UCB_TS_CR_TSPX_GND (1 << 5)
19598 +#define UCB_TS_CR_TSMY_GND (1 << 6)
19599 +#define UCB_TS_CR_TSPY_GND (1 << 7)
19600 +#define UCB_TS_CR_MODE_INT (0 << 8)
19601 +#define UCB_TS_CR_MODE_PRES (1 << 8)
19602 +#define UCB_TS_CR_MODE_POS (2 << 8)
19603 +#define UCB_TS_CR_BIAS_ENA (1 << 11)
19604 +#define UCB_TS_CR_TSPX_LOW (1 << 12)
19605 +#define UCB_TS_CR_TSMX_LOW (1 << 13)
19607 +#define UCB_ADC_SYNC_ENA (1 << 0)
19608 +#define UCB_ADC_VREFBYP_CON (1 << 1)
19609 +#define UCB_ADC_INP_TSPX (0 << 2)
19610 +#define UCB_ADC_INP_TSMX (1 << 2)
19611 +#define UCB_ADC_INP_TSPY (2 << 2)
19612 +#define UCB_ADC_INP_TSMY (3 << 2)
19613 +#define UCB_ADC_INP_AD0 (4 << 2)
19614 +#define UCB_ADC_INP_AD1 (5 << 2)
19615 +#define UCB_ADC_INP_AD2 (6 << 2)
19616 +#define UCB_ADC_INP_AD3 (7 << 2)
19617 +#define UCB_ADC_EXT_REF (1 << 5)
19618 +#define UCB_ADC_START (1 << 7)
19619 +#define UCB_ADC_ENA (1 << 15)
19621 +#define UCB_ADC_DAT_VAL (1 << 15)
19623 +#define UCB_ID_1200 0x1004
19624 +#define UCB_ID_1300 0x1005
19625 +#define UCB_ID_1400 0x4304
19626 +#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */
19628 +#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
19629 +#define UCB_MODE_AUD_OFF_CAN (1 << 13)
19631 +#include <linux/completion.h>
19634 +struct ucb1x00_irq {
19636 + void (*fn)(int, void *);
19639 +extern struct class ucb1x00_class;
19644 + unsigned int irq;
19645 + struct semaphore adc_sem;
19646 + spinlock_t io_lock;
19647 + wait_queue_head_t irq_wait;
19648 + struct completion complete;
19649 + struct task_struct *rtask;
19654 + u16 irq_fal_enbl;
19655 + u16 irq_ris_enbl;
19656 + struct ucb1x00_irq irq_handler[16];
19657 + struct class_device cdev;
19658 + void *audio_data;
19659 + void *telecom_data;
19663 +#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev)
19665 +int ucb1x00_register_interface(struct class_interface *intf);
19666 +void ucb1x00_unregister_interface(struct class_interface *intf);
19669 + * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
19670 + * @ucb: UCB1x00 structure describing chip
19672 + * Return the SIB clock rate in Hz.
19674 +static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
19676 + return mcp_get_sclk_rate(ucb->mcp);
19680 + * ucb1x00_enable - enable the UCB1x00 SIB clock
19681 + * @ucb: UCB1x00 structure describing chip
19683 + * Enable the SIB clock. This can be called multiple times.
19685 +static inline void ucb1x00_enable(struct ucb1x00 *ucb)
19687 + mcp_enable(ucb->mcp);
19691 + * ucb1x00_disable - disable the UCB1x00 SIB clock
19692 + * @ucb: UCB1x00 structure describing chip
19694 + * Disable the SIB clock. The SIB clock will only be disabled
19695 + * when the number of ucb1x00_enable calls match the number of
19696 + * ucb1x00_disable calls.
19698 +static inline void ucb1x00_disable(struct ucb1x00 *ucb)
19700 + mcp_disable(ucb->mcp);
19704 + * ucb1x00_reg_write - write a UCB1x00 register
19705 + * @ucb: UCB1x00 structure describing chip
19706 + * @reg: UCB1x00 4-bit register index to write
19707 + * @val: UCB1x00 16-bit value to write
19709 + * Write the UCB1x00 register @reg with value @val. The SIB
19710 + * clock must be running for this function to return.
19712 +static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
19714 + mcp_reg_write(ucb->mcp, reg, val);
19718 + * ucb1x00_reg_read - read a UCB1x00 register
19719 + * @ucb: UCB1x00 structure describing chip
19720 + * @reg: UCB1x00 4-bit register index to write
19722 + * Read the UCB1x00 register @reg and return its value. The SIB
19723 + * clock must be running for this function to return.
19725 +static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
19727 + return mcp_reg_read(ucb->mcp, reg);
19730 + * ucb1x00_set_audio_divisor -
19731 + * @ucb: UCB1x00 structure describing chip
19732 + * @div: SIB clock divisor
19734 +static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
19736 + mcp_set_audio_divisor(ucb->mcp, div);
19740 + * ucb1x00_set_telecom_divisor -
19741 + * @ucb: UCB1x00 structure describing chip
19742 + * @div: SIB clock divisor
19744 +static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
19746 + mcp_set_telecom_divisor(ucb->mcp, div);
19749 +#define ucb1x00_get() NULL
19751 +void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
19752 +void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
19753 +unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
19755 +#define UCB_NOSYNC (0)
19756 +#define UCB_SYNC (1)
19758 +unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
19759 +void ucb1x00_adc_enable(struct ucb1x00 *ucb);
19760 +void ucb1x00_adc_disable(struct ucb1x00 *ucb);
19763 + * Which edges of the IRQ do you want to control today?
19765 +#define UCB_RISING (1 << 0)
19766 +#define UCB_FALLING (1 << 1)
19768 +int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
19769 +void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
19770 +void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
19771 +int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
19774 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
19775 +++ linux-2.6.5/drivers/misc/switches-sa1100.c 2004-04-30 20:57:36.000000000 -0400
19778 + * linux/drivers/misc/switches-sa1100.c
19780 + * Copyright (C) 2001 John Dorsey
19782 + * This program is free software; you can redistribute it and/or modify
19783 + * it under the terms of the GNU General Public License version 2 as
19784 + * published by the Free Software Foundation.
19786 + * 19 December 2001 - created from sa1100_switches.c.
19789 +#include <linux/config.h>
19790 +#include <linux/init.h>
19791 +#include <linux/module.h>
19792 +#include <linux/kernel.h>
19793 +#include <linux/sched.h>
19794 +#include <linux/errno.h>
19795 +#include <linux/interrupt.h>
19797 +#include <asm/hardware.h>
19798 +#include <asm/mach-types.h>
19799 +#include <asm/irq.h>
19801 +#include <asm/arch/assabet.h>
19802 +#include <asm/arch/neponset.h>
19803 +#include <asm/arch/badge4.h>
19805 +#include "switches.h"
19808 +static irqreturn_t switches_sa1100_handler(int irq, void *dev_id,
19809 + struct pt_regs *regs);
19812 +#ifdef CONFIG_SA1100_ASSABET
19816 + * We have two general-purpose switches, S1 and S2, available via GPIO
19817 + * on Assabet. This code sets bits in the range [1, 2] in the mask that
19818 + * we return to userland.
19821 +static int assabet_switches_sa1100_init(void)
19824 + if (machine_has_neponset())
19825 + NCR_0 |= NCR_GP01_OFF;
19827 + if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT,
19828 + SWITCHES_NAME, NULL) < 0) {
19829 + printk(KERN_ERR "%s: unable to register IRQ for GPIO 0\n",
19834 + if (request_irq(IRQ_GPIO1, switches_sa1100_handler, SA_INTERRUPT,
19835 + SWITCHES_NAME, NULL) < 0) {
19836 + printk(KERN_ERR "%s: unable to register IRQ for GPIO 1\n",
19838 + free_irq(IRQ_GPIO0, NULL);
19842 + set_irq_type(IRQ_GPIO0, IRQT_BOTHEDGE);
19843 + set_irq_type(IRQ_GPIO1, IRQT_BOTHEDGE);
19849 +static void assabet_switches_sa1100_shutdown(void)
19852 + free_irq(IRQ_GPIO1, NULL);
19853 + free_irq(IRQ_GPIO0, NULL);
19857 +static irqreturn_t assabet_switches_sa1100_handler(int irq, switches_mask_t *mask)
19859 + unsigned int s, last, this;
19860 + static unsigned int states = 0;
19864 + case IRQ_GPIO0: s = 0; break;
19866 + case IRQ_GPIO1: s = 1; break;
19868 + default: return IRQ_NONE;
19872 + last = ((states & (1 << s)) != 0);
19873 + this = ((GPLR & GPIO_GPIO(s)) != 0);
19875 + if (last == this) /* debounce */
19876 + return IRQ_HANDLED;
19878 + SWITCHES_SET(mask, s + 1, this);
19880 + states = this ? (states | (1 << s)) : (states & ~(1 << s));
19882 + return IRQ_HANDLED;
19884 +#endif /* CONFIG_SA1100_ASSABET */
19886 +#ifdef CONFIG_SA1100_BADGE4
19891 + * Here we use test point J6 (BADGE4_GPIO_TESTPT_J6 aka GPIO 23) as a
19892 + * general purpose switch input. We map this to switch #0.
19895 +#define BADGE4_SW0_GPIO GPIO_GPIO23 /* aka BADGE4_GPIO_TESTPT_J6 */
19896 +#define BADGE4_SW0_IRQ IRQ_GPIO23
19898 +static int badge4_switches_sa1100_init(void)
19900 + if (request_irq(BADGE4_SW0_IRQ, switches_sa1100_handler, SA_INTERRUPT,
19901 + SWITCHES_NAME, NULL) < 0) {
19902 + printk(KERN_ERR "%s: unable to register IRQ for SW0\n",
19907 + set_irq_type(BADGE4_SW0_IRQ, IRQT_BOTHEDGE);
19912 +static void badge4_switches_sa1100_shutdown(void)
19914 + free_irq(BADGE4_SW0_IRQ, NULL);
19917 +static irqreturn_t badge4_switches_sa1100_handler(int irq, switches_mask_t *mask)
19919 + unsigned int swno, last, this, gpio;
19920 + static unsigned int states = 0;
19923 + case BADGE4_SW0_IRQ:
19925 + gpio = BADGE4_SW0_GPIO;
19931 + last = ((states & gpio) != 0);
19932 + this = ((GPLR & gpio) != 0);
19934 + if (last == this) /* debounce */
19935 + return IRQ_HANDLED;
19937 + SWITCHES_SET(mask, swno, this);
19939 + states = this ? (states | gpio) : (states & ~gpio);
19941 + return IRQ_HANDLED;
19943 +#endif /* CONFIG_SA1100_BADGE4 */
19946 +#ifdef CONFIG_SA1100_SPOT
19950 + * Spot (R2, R3) has a single general-purpose switch (S1), which is
19951 + * also the power-on switch. We set bit [1] in the mask we return to
19955 +static int spot_switches_sa1100_init(void)
19958 + set_GPIO_IRQ_edge(GPIO_SW1, GPIO_BOTH_EDGES);
19960 + if (request_irq(IRQ_GPIO_SW1, switches_sa1100_handler, SA_INTERRUPT,
19961 + SWITCHES_NAME, NULL) < 0) {
19962 + printk(KERN_ERR "%s: unable to register IRQ for SW1\n",
19971 +static void spot_switches_sa1100_shutdown(void)
19974 + free_irq(IRQ_GPIO_SW1, NULL);
19978 +static irqreturn_t spot_switches_sa1100_handler(int irq, switches_mask_t *mask)
19980 + unsigned int s, last, this;
19981 + static unsigned int states = 0;
19985 + case IRQ_GPIO_SW1: s = 0; break;
19987 + default: return IRQ_NONE;
19991 + last = ((states & (1 << s)) != 0);
19992 + this = ((GPLR & GPIO_GPIO(s)) != 0);
19994 + if (last == this) /* debounce */
19995 + return IRQ_HANDLED;
19997 + SWITCHES_SET(mask, s + 1, this);
19999 + states = this ? (states | (1 << s)) : (states & ~(1 << s));
20001 + return IRQ_HANDLED;
20004 +#endif /* CONFIG_SA1100_SPOT */
20007 +/* switches_sa1100_handler()
20008 + * ^^^^^^^^^^^^^^^^^^^^^^^^^
20009 + * This routine is a generalized handler for SA-1100 switches
20010 + * which manages action descriptors and calls a board-specific
20011 + * service routine. This routine is appropriate for GPIO switches
20012 + * or other primary interrupt sources, and can be registered as a
20013 + * first-class IRQ handler using request_irq().
20015 +static irqreturn_t switches_sa1100_handler(int irq, void *dev_id,
20016 + struct pt_regs *regs)
20018 + switches_mask_t mask;
20019 + irqreturn_t ret = IRQ_NONE;
20021 + SWITCHES_ZERO(&mask);
20023 + /* Porting note: call a board-specific switch interrupt handler
20024 + * here. The handler can assume that sufficient storage for
20025 + * `mask' has been allocated, and that the corresponding
20026 + * switches_mask_t structure has been zeroed.
20029 + if (machine_is_assabet()) {
20030 +#ifdef CONFIG_SA1100_ASSABET
20031 + ret = assabet_switches_sa1100_handler(irq, &mask);
20033 + } else if (machine_is_badge4()) {
20034 +#ifdef CONFIG_SA1100_BADGE4
20035 + ret = badge4_switches_sa1100_handler(irq, &mask);
20037 + } else if (machine_is_spot()) {
20038 +#ifdef CONFIG_SA1100_SPOT
20039 + ret = spot_switches_sa1100_handler(irq, &mask);
20043 + switches_event(&mask);
20048 +int __init switches_sa1100_init(void)
20051 + /* Porting note: call a board-specific init routine here. */
20053 + if (machine_is_assabet()) {
20054 +#ifdef CONFIG_SA1100_ASSABET
20055 + if (assabet_switches_sa1100_init() < 0)
20058 + } else if (machine_is_badge4()) {
20059 +#ifdef CONFIG_SA1100_BADGE4
20060 + if (badge4_switches_sa1100_init() < 0)
20063 + } else if (machine_is_spot()) {
20064 +#ifdef CONFIG_SA1100_SPOT
20065 + if (spot_switches_sa1100_init() < 0)
20074 +void __exit switches_sa1100_exit(void)
20077 + /* Porting note: call a board-specific shutdown routine here. */
20079 + if (machine_is_assabet()) {
20080 +#ifdef CONFIG_SA1100_ASSABET
20081 + assabet_switches_sa1100_shutdown();
20083 + } else if (machine_is_badge4()) {
20084 +#ifdef CONFIG_SA1100_BADGE4
20085 + badge4_switches_sa1100_shutdown();
20087 + } else if (machine_is_spot()) {
20088 +#ifdef CONFIG_SA1100_SPOT
20089 + spot_switches_sa1100_shutdown();
20095 +module_init(switches_sa1100_init);
20096 +module_exit(switches_sa1100_exit);
20098 +MODULE_DESCRIPTION("SA-1100 switches driver");
20099 +MODULE_LICENSE("GPL");
20100 --- linux-2.6.5/drivers/misc/Makefile~heh 2004-04-03 22:38:17.000000000 -0500
20101 +++ linux-2.6.5/drivers/misc/Makefile 2004-04-30 20:57:36.000000000 -0400
20103 obj- := misc.o # Dummy rule to force built-in.o to be made
20105 obj-$(CONFIG_IBM_ASM) += ibmasm/
20107 +obj-$(CONFIG_MCP) += mcp-core.o
20108 +obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
20109 +obj-$(CONFIG_MCP_UCB1200_AUDIO) += ucb1x00-audio.o
20110 +obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
20112 +ifeq ($(CONFIG_SA1100_ASSABET),y)
20113 +obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
20116 +obj-$(CONFIG_SWITCHES) += switches-core.o
20117 +obj-$(CONFIG_SWITCHES_SA1100) += switches-sa1100.o
20118 +obj-$(CONFIG_SWITCHES_UCB1X00) += switches-ucb1x00.o
20120 +obj-$(CONFIG_MCP_SA1100) += mcp-sa1100.o
20122 +obj-$(CONFIG_UCB1400_TS) += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o
20124 --- linux-2.6.5/drivers/i2c/busses/Kconfig~heh 2004-04-03 22:38:10.000000000 -0500
20125 +++ linux-2.6.5/drivers/i2c/busses/Kconfig 2004-04-30 20:57:36.000000000 -0400
20127 This support is also available as a module. If so, the module
20128 will be called i2c-hydra.
20130 +config I2C_BIT_SA1100_GPIO
20131 + bool "SA1100 I2C GPIO adapter"
20132 + depends on ARCH_SA1100 && I2C_ALGOBIT
20134 + This supports I2C on the SA11x0 processor GPIO pins. This
20135 + shares support with the L3 driver.
20137 + This support is also available as a module. If so, the module
20138 + will be called l3-bit-sa1100.
20141 tristate "Intel 801"
20142 depends on I2C && PCI && EXPERIMENTAL
20143 @@ -241,6 +251,18 @@
20144 This support is also available as a module. If so, the module
20145 will be called i2c-prosavage.
20148 + tristate "PXA I2C Interface"
20149 + depends on I2C && ARCH_PXA
20150 + select I2C_ALGOPXA
20152 + This supports the use of the PXA I2C interface found on the Intel
20153 + PXA 25x and PXA 26x systems. Say Y if you have one of these.
20155 + This support is also available as a module. If you want to compile
20156 + it as a module, say M here and read Documentation/modules.txt.
20157 + The module will be called i2c-adap-pxa.
20160 tristate "Embedded Planet RPX Lite/Classic support"
20161 depends on (RPXLITE || RPXCLASSIC) && I2C
20162 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
20163 +++ linux-2.6.5/drivers/i2c/busses/pxa2xx_i2c.c 2004-04-30 20:57:36.000000000 -0400
20168 + * I2C adapter for the PXA I2C bus access.
20170 + * Copyright (C) 2002 Intrinsyc Software Inc.
20172 + * This program is free software; you can redistribute it and/or modify
20173 + * it under the terms of the GNU General Public License version 2 as
20174 + * published by the Free Software Foundation.
20177 + * Apr 2002: Initial version [CS]
20178 + * Jun 2002: Properly seperated algo/adap [FB]
20179 + * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
20180 + * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
20181 + * Jun 2003: updated for 2.5 [Dustin McIntire]
20184 +#include <linux/kernel.h>
20185 +#include <linux/module.h>
20187 +#include <linux/i2c.h>
20188 +#include <linux/i2c-id.h>
20189 +#include <linux/init.h>
20190 +#include <linux/time.h>
20191 +#include <linux/sched.h>
20192 +#include <linux/delay.h>
20193 +#include <linux/errno.h>
20194 +#include <linux/interrupt.h>
20196 +#include <asm/hardware.h>
20197 +#include <asm/irq.h>
20198 +#include <asm/arch/irqs.h> /* for IRQ_I2C */
20200 +#include <linux/i2c-pxa.h>
20203 + * Set this to zero to remove all debug statements via dead code elimination.
20208 +static unsigned int i2c_debug = DEBUG;
20210 +#define i2c_debug 0
20213 +static int irq = 0;
20214 +static volatile int i2c_pending = 0; /* interrupt pending when 1 */
20215 +static volatile int bus_error = 0;
20216 +static volatile int tx_finished = 0;
20217 +static volatile int rx_finished = 0;
20219 +static wait_queue_head_t i2c_wait;
20220 +static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte);
20222 +/* place a byte in the transmit register */
20223 +static void i2c_pxa_write_byte(u8 value)
20228 +/* read byte in the receive register */
20229 +static u8 i2c_pxa_read_byte(void)
20231 + return (u8) (0xff & IDBR);
20234 +static void i2c_pxa_start(void)
20236 + unsigned long icr = ICR;
20237 + icr |= ICR_START;
20238 + icr &= ~(ICR_STOP | ICR_ALDIE | ICR_ACKNAK);
20241 + bus_error=0; /* clear any bus_error from previous txfers */
20242 + tx_finished=0; /* clear rx and tx interrupts from previous txfers */
20247 +static void i2c_pxa_repeat_start(void)
20249 + unsigned long icr = ICR;
20250 + icr |= ICR_START;
20251 + icr &= ~(ICR_STOP | ICR_ALDIE);
20254 + bus_error=0; /* clear any bus_error from previous txfers */
20255 + tx_finished=0; /* clear rx and tx interrupts from previous txfers */
20260 +static void i2c_pxa_stop(void)
20262 + unsigned long icr = ICR;
20264 + icr &= ~(ICR_START);
20268 +static void i2c_pxa_midbyte(void)
20270 + unsigned long icr = ICR;
20271 + icr &= ~(ICR_START | ICR_STOP);
20275 +static void i2c_pxa_abort(void)
20277 + unsigned long timeout = jiffies + HZ/4;
20279 +#ifdef PXA_ABORT_MA
20280 + while ((long)(timeout - jiffies) > 0 && (ICR & ICR_TB)) {
20281 + set_current_state(TASK_INTERRUPTIBLE);
20282 + schedule_timeout(1);
20288 + while ((long)(timeout - jiffies) > 0 && (IBMR & 0x1) == 0) {
20289 + i2c_pxa_transfer( 1, I2C_RECEIVE, 1);
20290 + set_current_state(TASK_INTERRUPTIBLE);
20291 + schedule_timeout(1);
20294 + ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
20297 +static int i2c_pxa_wait_bus_not_busy( void)
20299 + int timeout = DEF_TIMEOUT;
20301 + while (timeout-- && (ISR & ISR_IBB)) {
20302 + udelay(100); /* wait for 100 us */
20305 + return (timeout<=0);
20308 +spinlock_t i2c_pxa_irqlock = SPIN_LOCK_UNLOCKED;
20310 +static void i2c_pxa_wait_for_ite(void){
20311 + unsigned long flags;
20313 + spin_lock_irqsave(&i2c_pxa_irqlock, flags);
20314 + if (i2c_pending == 0) {
20315 + interruptible_sleep_on_timeout(&i2c_wait, I2C_SLEEP_TIMEOUT );
20318 + spin_unlock_irqrestore(&i2c_pxa_irqlock, flags);
20324 +static int i2c_pxa_wait_for_int( int wait_type)
20326 + int timeout = DEF_TIMEOUT;
20329 + printk(KERN_INFO"i2c_pxa_wait_for_int: Bus error on enter\n");
20331 + printk(KERN_INFO"i2c_pxa_wait_for_int: Receive interrupt on enter\n");
20333 + printk(KERN_INFO"i2c_pxa_wait_for_int: Transmit interrupt on enter\n");
20336 + if (wait_type == I2C_RECEIVE){ /* wait on receive */
20339 + i2c_pxa_wait_for_ite();
20340 + } while (!(rx_finished) && timeout-- && !signal_pending(current));
20345 + printk("Error: i2c-algo-pxa.o: received a tx"
20346 + " interrupt while waiting on a rx in wait_for_int");
20349 + } else { /* wait on transmit */
20352 + i2c_pxa_wait_for_ite();
20353 + } while (!(tx_finished) && timeout-- && !signal_pending(current));
20358 + printk("Error: i2c-algo-pxa.o: received a rx"
20359 + " interrupt while waiting on a tx in wait_for_int");
20364 + udelay(ACK_DELAY); /* this is needed for the bus error */
20371 + if( i2c_debug > 2)printk("wait_for_int: error - no ack.\n");
20372 + return BUS_ERROR;
20375 + if (signal_pending(current)) {
20376 + return (-ERESTARTSYS);
20377 + } else if (timeout < 0) {
20378 + if( i2c_debug > 2)printk("wait_for_int: timeout.\n");
20384 +static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte)
20388 + if( receive==I2C_RECEIVE) ICR |= ICR_ACKNAK;
20391 + else if( midbyte)
20393 + i2c_pxa_midbyte();
20398 +static void i2c_pxa_reset( void)
20401 + printk("Resetting I2C Controller Unit\n");
20404 + /* abort any transfer currently under way */
20407 + /* reset according to 9.8 */
20409 + ISR = I2C_ISR_INIT;
20412 + /* set the global I2C clock on */
20413 + CKEN |= CKEN14_I2C;
20415 + /* set our slave address */
20416 + ISAR = I2C_PXA_SLAVE_ADDR;
20418 + /* set control register values */
20419 + ICR = I2C_ICR_INIT;
20421 + /* clear any leftover states from prior transmissions */
20422 + i2c_pending = rx_finished = tx_finished = bus_error = 0;
20424 + /* enable unit */
20429 +static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
20431 + unsigned long flags;
20432 + int status, wakeup = 0;
20435 + if (status & ISR_BED){
20436 + (ISR) |= ISR_BED;
20437 + bus_error=ISR_BED;
20440 + if (status & ISR_ITE){
20441 + (ISR) |= ISR_ITE;
20442 + tx_finished=ISR_ITE;
20445 + if (status & ISR_IRF){
20446 + (ISR) |= ISR_IRF;
20447 + rx_finished=ISR_IRF;
20451 + spin_lock_irqsave(&i2c_pxa_irqlock, flags);
20453 + spin_unlock_irqrestore(&i2c_pxa_irqlock, flags);
20454 + wake_up_interruptible(&i2c_wait);
20456 + return IRQ_HANDLED;
20459 +static int i2c_pxa_resource_init( void)
20461 + init_waitqueue_head(&i2c_wait);
20463 + if (request_irq(IRQ_I2C, &i2c_pxa_handler, SA_INTERRUPT, "I2C", 0) < 0) {
20466 + printk(KERN_INFO "I2C: Failed to register I2C irq %i\n", IRQ_I2C);
20472 +static void i2c_pxa_resource_release( void)
20476 + disable_irq(irq);
20482 +static int i2c_pxa_client_register(struct i2c_client *client)
20487 +static int i2c_pxa_client_unregister(struct i2c_client *client)
20492 +static struct i2c_algo_pxa_data i2c_pxa_data = {
20493 + write_byte: i2c_pxa_write_byte,
20494 + read_byte: i2c_pxa_read_byte,
20496 + start: i2c_pxa_start,
20497 + repeat_start: i2c_pxa_repeat_start,
20498 + stop: i2c_pxa_stop,
20499 + abort: i2c_pxa_abort,
20501 + wait_bus_not_busy: i2c_pxa_wait_bus_not_busy,
20502 + wait_for_interrupt: i2c_pxa_wait_for_int,
20503 + transfer: i2c_pxa_transfer,
20504 + reset: i2c_pxa_reset,
20507 + timeout: DEF_TIMEOUT,
20510 +static struct i2c_adapter i2c_pxa_ops = {
20511 + .owner = THIS_MODULE,
20512 + .id = I2C_ALGO_PXA,
20513 + .algo_data = &i2c_pxa_data,
20515 + .name = "PXA I2C Adapter",
20517 + .client_register = i2c_pxa_client_register,
20518 + .client_unregister = i2c_pxa_client_unregister,
20522 +extern int i2c_pxa_add_bus(struct i2c_adapter *);
20523 +extern int i2c_pxa_del_bus(struct i2c_adapter *);
20525 +static int __init i2c_adap_pxa_init(void)
20527 + if( i2c_pxa_resource_init() == 0) {
20529 + if (i2c_pxa_add_bus(&i2c_pxa_ops) < 0) {
20530 + i2c_pxa_resource_release();
20531 + printk(KERN_INFO "I2C: Failed to add bus\n");
20538 + printk(KERN_INFO "I2C: Successfully added bus\n");
20543 +static void i2c_adap_pxa_exit(void)
20545 + i2c_pxa_del_bus( &i2c_pxa_ops);
20546 + i2c_pxa_resource_release();
20548 + printk(KERN_INFO "I2C: Successfully removed bus\n");
20551 +module_init(i2c_adap_pxa_init);
20552 +module_exit(i2c_adap_pxa_exit);
20553 --- linux-2.6.5/drivers/i2c/busses/Makefile~heh 2004-04-03 22:36:17.000000000 -0500
20554 +++ linux-2.6.5/drivers/i2c/busses/Makefile 2004-04-30 20:57:36.000000000 -0400
20556 obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
20557 obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
20558 obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
20559 +obj-$(CONFIG_I2C_PXA) += pxa2xx_i2c.o
20560 obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
20561 obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
20562 obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
20563 --- linux-2.6.5/drivers/i2c/algos/Kconfig~heh 2004-04-03 22:37:59.000000000 -0500
20564 +++ linux-2.6.5/drivers/i2c/algos/Kconfig 2004-04-30 20:57:36.000000000 -0400
20566 This support is also available as a module. If so, the module
20567 will be called i2c-algo-ite.
20569 +config I2C_ALGOPXA
20570 + tristate "PXA I2C Algorithm"
20571 + depends on ARCH_PXA && I2C
20573 + This supports the use of the PXA I2C interface found on the Intel
20574 + PXA 25x and PXA 26x systems. Say Y if you have one of these.
20575 + You should also say Y for the PXA I2C peripheral driver support below.
20577 + This support is also available as a module. If you want to compile
20578 + it as a module, say M here and read Documentation/modules.txt.
20579 + The module will be called i2c-algo-pxa.
20582 tristate "MPC8xx CPM I2C interface"
20583 depends on 8xx && I2C
20584 --- /dev/null 2003-09-23 18:19:32.000000000 -0400
20585 +++ linux-2.6.5/drivers/i2c/algos/i2c-algo-pxa.c 2004-04-30 20:57:36.000000000 -0400
20590 + * I2C algorithm for the PXA I2C bus access.
20591 + * Byte driven algorithm similar to pcf.
20593 + * Copyright (C) 2002 Intrinsyc Software Inc.
20595 + * This program is free software; you can redistribute it and/or modify
20596 + * it under the terms of the GNU General Public License version 2 as
20597 + * published by the Free Software Foundation.
20600 + * Apr 2002: Initial version [CS]
20601 + * Jun 2002: Properly seperated algo/adap [FB]
20602 + * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
20603 + * Jan 2003: allow SMBUS_QUICK as valid msg [FB]
20604 + * Jun 2003: updated for 2.5 [Dustin McIntire]
20607 +#include <linux/kernel.h>
20608 +#include <linux/module.h>
20610 +#include <linux/init.h>
20611 +#include <linux/delay.h>
20612 +#include <linux/errno.h>
20613 +#include <linux/i2c.h> /* struct i2c_msg and others */
20614 +#include <linux/i2c-id.h>
20616 +#include <linux/i2c-pxa.h>
20619 + * Set this to zero to remove all the debug statements via dead code elimination.
20624 +static unsigned int i2c_debug = DEBUG;
20626 +#define i2c_debug 0
20629 +static int pxa_scan = 1;
20631 +static int i2c_pxa_valid_messages( struct i2c_msg msgs[], int num)
20634 + if (num < 1 || num > MAX_MESSAGES){
20636 + printk(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n",
20637 + MAX_MESSAGES, num);
20641 + /* check consistency of our messages */
20642 + for (i=0;i<num;i++){
20643 + if (&msgs[i]==NULL){
20644 + if( i2c_debug) printk(KERN_INFO "Msgs is NULL\n");
20647 + if (msgs[i].buf == NULL){
20648 + if( i2c_debug)printk(KERN_INFO "Length is less than zero");
20657 +static int i2c_pxa_readbytes(struct i2c_adapter *i2c_adap, char *buf,
20658 + int count, int last)
20661 + int i, timeout=0;
20662 + struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
20664 + /* increment number of bytes to read by one -- read dummy byte */
20665 + for (i = 0; i <= count; i++) {
20667 + /* set ACK to NAK for last received byte ICR[ACKNAK] = 1
20668 + only if not a repeated start */
20670 + if ((i == count) && last) {
20671 + adap->transfer( last, I2C_RECEIVE, 0);
20673 + adap->transfer( 0, I2C_RECEIVE, 1);
20676 + timeout = adap->wait_for_interrupt(I2C_RECEIVE);
20679 + if (timeout==BUS_ERROR){
20680 + printk(KERN_INFO "i2c_pxa_readbytes: bus error -> forcing reset\n");
20682 + return I2C_RETRY;
20685 + if (timeout == -ERESTARTSYS) {
20691 + printk(KERN_INFO "i2c_pxa_readbytes: timeout -> forcing reset\n");
20694 + return I2C_RETRY;
20700 + buf[i - 1] = adap->read_byte();
20702 + adap->read_byte(); /* dummy read */
20708 +static int i2c_pxa_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
20709 + int count, int last)
20712 + struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
20713 + int wrcount, timeout;
20715 + for (wrcount=0; wrcount<count; ++wrcount) {
20717 + adap->write_byte(buf[wrcount]);
20718 + if ((wrcount==(count-1)) && last) {
20719 + adap->transfer( last, I2C_TRANSMIT, 0);
20721 + adap->transfer( 0, I2C_TRANSMIT, 1);
20724 + timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
20727 + if (timeout==BUS_ERROR) {
20728 + printk(KERN_INFO "i2c_pxa_sendbytes: bus error -> forcing reset.\n");
20730 + return I2C_RETRY;
20733 + if (timeout == -ERESTARTSYS) {
20739 + printk(KERN_INFO "i2c_pxa_sendbytes: timeout -> forcing reset\n");
20742 + return I2C_RETRY;
20745 + return (wrcount);
20749 +static inline int i2c_pxa_set_ctrl_byte(struct i2c_algo_pxa_data * adap, struct i2c_msg *msg)
20751 + u16 flags = msg->flags;
20753 + addr = (u8) ( (0x7f & msg->addr) << 1 );
20754 + if (flags & I2C_M_RD )
20756 + if (flags & I2C_M_REV_DIR_ADDR )
20758 + adap->write_byte(addr);
20762 +static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
20764 + struct i2c_algo_pxa_data * adap;
20765 + struct i2c_msg *pmsg=NULL;
20767 + int ret=0, timeout;
20769 + adap = i2c_adap->algo_data;
20771 + timeout = adap->wait_bus_not_busy();
20774 + return I2C_RETRY;
20777 + for (i = 0;ret >= 0 && i < num; i++) {
20778 + int last = i + 1 == num;
20781 + ret = i2c_pxa_set_ctrl_byte(adap,pmsg);
20787 + adap->repeat_start();
20790 + adap->transfer(0, I2C_TRANSMIT, 0);
20792 + /* Wait for ITE (transmit empty) */
20793 + timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
20796 + /* Check for ACK (bus error) */
20797 + if (timeout==BUS_ERROR){
20798 + printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n");
20800 + return I2C_RETRY;
20803 + if (timeout == -ERESTARTSYS) {
20809 + printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n");
20812 + return I2C_RETRY;
20814 +/* FIXME: handle arbitration... */
20816 + /* Check for bus arbitration loss */
20817 + if (adap->arbitration_loss()){
20818 + printk("Arbitration loss detected \n");
20820 + return I2C_RETRY;
20825 + if (pmsg->flags & I2C_M_RD) {
20826 + /* read bytes into buffer*/
20827 + ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last);
20829 + if (ret != pmsg->len) {
20830 + printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n",
20833 + printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret);
20836 + } else { /* Write */
20837 + ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last);
20839 + if (ret != pmsg->len) {
20840 + printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n",
20843 + printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret);
20856 +static int i2c_pxa_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
20858 + int retval = i2c_pxa_valid_messages( msgs, num);
20862 + for (i=i2c_adap->retries; i>=0; i--){
20863 + int retval = i2c_pxa_do_xfer(i2c_adap,msgs,num);
20864 + if (retval!=I2C_RETRY){
20867 + if( i2c_debug)printk(KERN_INFO"Retrying transmission \n");
20870 + if( i2c_debug)printk(KERN_INFO"Retried %i times\n",i2c_adap->retries);
20871 + return -EREMOTEIO;
20877 +static u32 i2c_pxa_functionality(struct i2c_adapter * adapter)
20879 + /* Emulate the SMBUS functions */
20880 + return I2C_FUNC_SMBUS_EMUL;
20883 +struct i2c_algorithm i2c_pxa_algorithm = {
20884 + name: "PXA I2C Algorithm",
20885 + id: I2C_ALGO_PXA,
20886 + master_xfer: i2c_pxa_xfer,
20887 + smbus_xfer: NULL,
20888 + slave_send: NULL,
20889 + slave_recv: NULL,
20890 + algo_control: NULL,
20891 + functionality: i2c_pxa_functionality,
20895 + * registering functions to load algorithms at runtime
20897 +int i2c_pxa_add_bus(struct i2c_adapter *i2c_adap)
20899 + struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
20901 + printk(KERN_INFO"I2C: Adding %s.\n", i2c_adap->dev.name);
20903 + i2c_adap->algo = &i2c_pxa_algorithm;
20905 + MOD_INC_USE_COUNT;
20907 + /* register new adapter to i2c module... */
20908 + i2c_add_adapter(i2c_adap);
20915 + printk(KERN_INFO "I2C: Scanning bus ");
20916 + for (i = 0x02; i < 0xff; i+=2) {
20917 + if( i==(I2C_PXA_SLAVE_ADDR<<1)) continue;
20919 + if (adap->wait_bus_not_busy()) {
20920 + printk(KERN_INFO "I2C: scanning bus %s - TIMEOUT.\n",
20921 + i2c_adap->dev.name);
20924 + adap->write_byte(i);
20926 + adap->transfer(0, I2C_TRANSMIT, 0);
20928 + if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) {
20929 + printk("(%02x)",i>>1);
20935 + udelay(adap->udelay);
20942 +int i2c_pxa_del_bus(struct i2c_adapter *i2c_adap)
20945 + if ((res = i2c_del_adapter(i2c_adap)) < 0)
20948 + MOD_DEC_USE_COUNT;
20950 + printk(KERN_INFO "I2C: Removing %s.\n", i2c_adap->dev.name);
20955 +static int __init i2c_algo_pxa_init (void)
20957 + printk(KERN_INFO "I2C: PXA algorithm module loaded.\n");
20961 +EXPORT_SYMBOL(i2c_pxa_add_bus);
20962 +EXPORT_SYMBOL(i2c_pxa_del_bus);
20964 +MODULE_PARM(pxa_scan, "i");
20965 +MODULE_PARM_DESC(pxa_scan, "Scan for active chips on the bus");
20967 +MODULE_AUTHOR("Intrinsyc Software Inc.");
20968 +MODULE_LICENSE("GPL");
20970 +module_init(i2c_algo_pxa_init);
20971 --- linux-2.6.5/drivers/i2c/algos/Makefile~heh 2004-04-03 22:37:37.000000000 -0500
20972 +++ linux-2.6.5/drivers/i2c/algos/Makefile 2004-04-30 20:57:36.000000000 -0400
20975 obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
20976 obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
20977 +obj-$(CONFIG_I2C_ALGOPXA) += i2c-algo-pxa.o
20978 obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o
20980 ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
20981 --- linux-2.6.5/Makefile~heh 2004-04-03 22:37:36.000000000 -0500
20982 +++ linux-2.6.5/Makefile 2004-04-30 20:57:58.000000000 -0400
20988 +EXTRAVERSION = -gnalm1