]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / linux / gumstix-2.6.5-gnalm1-gum0 / linux-2.6.5-gnalm1.patch
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
3 @@ -832,3 +832,25 @@
4                                 printk_ratelimit_burst);
5  }
6  EXPORT_SYMBOL(printk_ratelimit);
7 +
8 +#include <linux/sysrq.h>
9 +
10 +static void
11 +show_msg_info(int key, struct pt_regs *regs, struct tty_struct *tty)
12 +{
13 +       call_console_drivers(log_end - logged_chars, log_end);
14 +}
15 +
16 +static struct sysrq_key_op msg_info_op = {
17 +       .handler        = show_msg_info,
18 +       .help_msg       = "Dumpmsgs",
19 +       .action_msg     = "Kernel Messages",
20 +};
21 +
22 +static int __init dbg_init(void)
23 +{
24 +       register_sysrq_key('d', &msg_info_op);
25 +       return 0;
26 +}
27 +
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
31 @@ -179,6 +179,8 @@
32  {
33         struct resource *tmp, **p;
34  
35 +       BUG_ON(old->child);
36 +
37         p = &old->parent->child;
38         for (;;) {
39                 tmp = *p;
40 @@ -409,6 +411,47 @@
41  EXPORT_SYMBOL(adjust_resource);
42  
43  /*
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.
47 + */
48 +int reallocate_resource(struct resource *res, unsigned long start, unsigned long size)
49 +{
50 +       struct resource *tmp, *parent = res->parent;
51 +       unsigned long end = start + size - 1;
52 +       int result = -EBUSY;
53 +
54 +       write_lock(&resource_lock);
55 +
56 +       if ((start < parent->start) || (end > parent->end))
57 +               goto out;
58 +
59 +       for (tmp = res->child; tmp; tmp = tmp->sibling) {
60 +               if ((tmp->start < start) || (tmp->end > end))
61 +                       goto out;
62 +       }
63 +
64 +       if (res->sibling && (res->sibling->start <= end))
65 +               goto out;
66 +
67 +       tmp = parent->child;
68 +       if (tmp != res) {
69 +               while (tmp->sibling != res)
70 +                       tmp = tmp->sibling;
71 +               if (start <= tmp->end)
72 +                       goto out;
73 +       }
74 +
75 +       res->start = start;
76 +       res->end = end;
77 +       result = 0;
78 +
79 + out:
80 +       write_unlock(&resource_lock);
81 +       return result;
82 +}
83 +
84 +/*
85   * This is compatibility stuff for IO resources.
86   *
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
90 @@ -14,6 +14,19 @@
91  struct pt_regs;
92  struct seq_file;
93  
94 +/*
95 + * Architectures are expected to define NR_IRQ_DEVICES and
96 + * NR_IRQ_DEVICE_SHIFT if they wish to use dynamic IRQs.
97 + */
98 +#ifndef NR_IRQ_DEVICES
99 +#define NR_IRQ_DEVICES         1
100 +#endif
101 +#define NR_IRQ_PER_DEVICE      (1 << (NR_IRQ_DEVICE_SHIFT - 1))
102 +
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))
106 +
107  typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
108  typedef void (*irq_control_t)(unsigned int);
109  
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
112 @@ -12,6 +12,7 @@
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)
117  
118  #define UART           FFUART
119  
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
122 @@ -22,11 +22,11 @@
123   * Note: this structure must always be aligned to a 16-byte boundary.
124   */
125  
126 -typedef struct {
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 */
136  } pxa_dma_desc;
137  
138  /*
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
141 @@ -43,6 +43,15 @@
142                 io_type:                SERIAL_IO_MEM,  \
143                 irq:                    IRQ_BTUART,     \
144                 flags:                  STD_COM_FLAGS,  \
145 +       }, {    \
146 +               type:                   PORT_PXA,       \
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,  \
152 +               irq:                    IRQ_HWUART,     \
153 +               flags:                  STD_COM_FLAGS,  \
154         }
155  
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
206  
207  #define DRCMR_MAPVLD   (1 << 7)        /* Map Valid (read / write) */
208  #define DRCMR_CHLNUM   0x0f            /* mask for Channel Number (read / write) */
209 @@ -303,6 +307,22 @@
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) */
212  
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) */
228 +
229  /* Standard UART (STUART) */
230  #define STUART         STRBR
231  #define STRBR          __REG(0x40700000)  /* Receive Buffer Register (read only) */
232 @@ -1078,6 +1098,111 @@
233  
234  
235  /*
236 + * NSSP Serial Port Registers (Network SSP)
237 + */
238 +
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*/
246 +
247 +
248 +/*
249 + * ASSP Serial Port Registers (Audio SSP)
250 + */
251 +
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*/
259 +
260 +
261 +/* 
262 + * Bit definitions for SSP, NSSP and ASSP registers 
263 + *  - note that some bits are only available on the NSSP and ASSP
264 + */
265 +
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)
278 +
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 */
301 +
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)
316 +
317 +#define SSTO_TIMEOUT_MASK      0x00ffffff  /* [23:0] timeout */
318 +#define SSTO_TIMEOUT(x)                ((x) & XSSTO_TIMEOUT_MASK)
319 +
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 */
323 +
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 */
338 +
339 +
340 +/*
341   * MultiMediaCard (MMC) controller
342   */
343  
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
354 @@ -92,6 +92,14 @@
355  # endif
356  #endif
357  
358 +#ifdef CONFIG_CPU_COPY_V6
359 +# ifdef _USER
360 +#  define MULTI_USER 1
361 +# else
362 +#  define _USER v6
363 +# endif
364 +#endif
365 +
366  #ifndef _USER
367  #error Unknown user operations model
368  #endif
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
371 @@ -108,8 +108,8 @@
372  #define TI_CPU         20
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)
379  
380  #endif
381  
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
384 @@ -0,0 +1,45 @@
385 +/*
386 + *  linux/include/asm-arm/rtc.h
387 + *
388 + *  Copyright (C) 2003 Deep Blue Solutions Ltd.
389 + *
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.
393 + */
394 +#ifndef ASMARM_RTC_H
395 +#define ASMARM_RTC_H
396 +
397 +struct module;
398 +
399 +struct rtc_ops {
400 +       struct module   *owner;
401 +       int             (*open)(void);
402 +       void            (*release)(void);
403 +       int             (*ioctl)(unsigned int, unsigned long);
404 +
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);
410 +};
411 +
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 *);
418 +
419 +static inline int rtc_periodic_alarm(struct rtc_time *tm)
420 +{
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);
427 +}
428 +
429 +#endif
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
432 @@ -81,17 +81,6 @@
433  #define SERIAL_IO_HUB6 1
434  #define SERIAL_IO_MEM  2
435  
436 -struct serial_uart_config {
437 -       char    *name;
438 -       int     dfl_xmit_fifo_size;
439 -       int     flags;
440 -};
441 -
442 -#define UART_CLEAR_FIFO                0x01
443 -#define UART_USE_FIFO          0x02
444 -#define UART_STARTECH          0x04
445 -#define UART_NATSEMI           0x08
446 -
447  /*
448   * Definitions for async_struct (and serial_struct) flags field
449   */
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
452 @@ -0,0 +1,76 @@
453 +/*
454 + *  i2c_pxa.h
455 + *
456 + *  Copyright (C) 2002 Intrinsyc Software Inc.
457 + * 
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.
461 + *
462 + */
463 +#ifndef _I2C_PXA_H_
464 +#define _I2C_PXA_H_
465 +
466 +struct i2c_algo_pxa_data
467 +{
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);
478 +
479 +       int udelay;
480 +       int timeout;
481 +};
482 +
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 */
487 +
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 
495 +*                       
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 
501 +*                                       in master mode)
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)
514 +*
515 +*/
516 +
517 +#define I2C_ISR_INIT            0x7FF  /* status register init */
518 +/* I2C status register init values 
519 + *
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)
526 + */
527 +
528 +#endif
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
531 @@ -99,6 +99,7 @@
532                              void (*alignf)(void *, struct resource *,
533                                             unsigned long, unsigned long),
534                              void *alignf_data);
535 +extern int reallocate_resource(struct resource *res, unsigned long start, unsigned long size);
536  int adjust_resource(struct resource *res, unsigned long start,
537                     unsigned long size);
538  
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
541 @@ -0,0 +1,74 @@
542 +/*
543 + *  linux/include/linux/switches.h
544 + *
545 + *  Copyright (C) 2000 John Dorsey
546 + *
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.
550 + *
551 + *  23 October 2000 - created.
552 + */
553 +
554 +#if !defined(_LINUX_SWITCHES_H)
555 +#define _LINUX_SWITCHES_H
556 +
557 +#define SWITCHES_MASK_SIZE  (128)
558 +
559 +typedef unsigned long switches_bitfield;
560 +
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) % \
565 +                                  SWITCHES_BITS))
566 +
567 +typedef struct switches_mask_t {
568 +       unsigned int count;
569 +       switches_bitfield events[SWITCHES_NUM_FIELDS];
570 +       switches_bitfield states[SWITCHES_NUM_FIELDS];
571 +} switches_mask_t;
572 +
573 +#define SWITCHES_ZERO(m) \
574 +do { \
575 +       unsigned int sz_i; \
576 +       (m)->count = 0; \
577 +       for(sz_i = 0; sz_i < SWITCHES_NUM_FIELDS; ++sz_i) \
578 +               (m)->events[sz_i] = (m)->states[sz_i] = 0; \
579 +} while (0)
580 +
581 +/* `s' is the state of the switch, either 0 or non-zero: */
582 +#define SWITCHES_SET(m, i, s) \
583 +do { \
584 +       ((m)->events[SWITCHES_FIELD_SELECT((i))] |= \
585 +         SWITCHES_FIELD_MASK((i))); \
586 +       if(s) \
587 +               ((m)->states[SWITCHES_FIELD_SELECT((i))] |= \
588 +                 SWITCHES_FIELD_MASK((i))); \
589 +       else \
590 +               ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
591 +                 ~SWITCHES_FIELD_MASK((i))); \
592 +       ++((m)->count); \
593 +} while (0)
594 +
595 +/* Should only use to clear an event set by SWITCHES_SET(): */
596 +#define SWITCHES_CLEAR(m, i) \
597 +do { \
598 +       ((m)->events[SWITCHES_FIELD_SELECT((i))] &= \
599 +         ~SWITCHES_FIELD_MASK((i))); \
600 +       ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
601 +         ~SWITCHES_FIELD_MASK((i))); \
602 +       --((m)->count); \
603 +}
604 +
605 +#define SWITCHES_COUNT(m) ((m)->count)
606 +
607 +/* Returns 0 or non-zero: */
608 +#define SWITCHES_EVENT(m, i) \
609 +((m)->events[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
610 +
611 +/* Returns 0 or non-zero: */
612 +#define SWITCHES_STATE(m, i) \
613 +((m)->states[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
614 +
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
618 @@ -121,6 +121,7 @@
619  /*
620   * These are the definitions for the Modem Control Register
621   */
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 */
626 @@ -156,6 +157,21 @@
627  #define UART_FCR_PXAR32        0xc0    /* receive FIFO treshold = 32 */
628  
629  /*
630 + * The Intel PXA2xx chip defines those bits
631 + */
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 */
636 +
637 +#define UART_IIR_TOD   0x08    /* Character Timeout Indication Detected */
638 +
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 */
643 +
644 +/*
645   * These are the definitions for the Extended Features Register
646   * (StarTech 16C660 only, when DLAB=1)
647   */
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
650 @@ -0,0 +1,83 @@
651 +/*
652 + *  linux/include/linux/mmc/card.h
653 + *
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.
657 + *
658 + *  Card driver specific definitions.
659 + */
660 +#ifndef LINUX_MMC_CARD_H
661 +#define LINUX_MMC_CARD_H
662 +
663 +#include <linux/mmc/mmc.h>
664 +
665 +struct mmc_cid {
666 +       unsigned int            manfid;
667 +       unsigned int            serial;
668 +       char                    prod_name[8];
669 +       unsigned char           hwrev;
670 +       unsigned char           fwrev;
671 +       unsigned char           month;
672 +       unsigned char           year;
673 +};
674 +
675 +struct mmc_csd {
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;
683 +};
684 +
685 +struct mmc_host;
686 +
687 +/*
688 + * MMC device
689 + */
690 +struct mmc_card {
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 */
700 +};
701 +
702 +#define mmc_card_dead(c)       ((c)->state & MMC_STATE_DEAD)
703 +#define mmc_card_present(c)    ((c)->state & MMC_STATE_PRESENT)
704 +
705 +#define mmc_card_name(c)       ((c)->cid.prod_name)
706 +#define mmc_card_id(c)         ((c)->dev.bus_id)
707 +
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)
711 +
712 +/*
713 + * MMC device driver (e.g., Flash card, I/O card...)
714 + */
715 +struct mmc_driver {
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 *);
721 +};
722 +
723 +extern int mmc_register_driver(struct mmc_driver *);
724 +extern void mmc_unregister_driver(struct mmc_driver *);
725 +
726 +static inline int mmc_card_claim_host(struct mmc_card *card)
727 +{
728 +       return __mmc_claim_host(card->host, card);
729 +}
730 +
731 +#define mmc_card_release_host(c)       mmc_release_host((c)->host)
732 +
733 +#endif
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
736 @@ -0,0 +1,88 @@
737 +/*
738 + *  linux/include/linux/mmc/mmc.h
739 + *
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.
743 + */
744 +#ifndef MMC_H
745 +#define MMC_H
746 +
747 +#include <linux/list.h>
748 +#include <linux/interrupt.h>
749 +#include <linux/device.h>
750 +
751 +struct request;
752 +struct mmc_data;
753 +struct mmc_request;
754 +
755 +struct mmc_command {
756 +       u32                     opcode;
757 +       u32                     arg;
758 +       u32                     resp[4];
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 */
766 +
767 +       unsigned int            retries;        /* max number of retries */
768 +       unsigned int            error;          /* command error */
769 +
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
776 +
777 +       struct mmc_data         *data;          /* data segment associated with cmd */
778 +       struct mmc_request      *req;           /* assoicated request */
779 +};
780 +
781 +struct mmc_data {
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;
789 +
790 +#define MMC_DATA_WRITE (1 << 8)
791 +#define MMC_DATA_READ  (1 << 9)
792 +#define MMC_DATA_STREAM        (1 << 10)
793 +
794 +       unsigned int            bytes_xfered;
795 +
796 +       struct mmc_command      *stop;          /* stop command */
797 +       struct mmc_request      *req;           /* assoicated request */
798 +};
799 +
800 +struct mmc_request {
801 +       struct mmc_command      *cmd;
802 +       struct mmc_data         *data;
803 +       struct mmc_command      *stop;
804 +
805 +       void                    *done_data;     /* completion data */
806 +       void                    (*done)(struct mmc_request *);/* completion function */
807 +};
808 +
809 +struct mmc_host;
810 +struct mmc_card;
811 +
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);
814 +
815 +extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card);
816 +
817 +static inline void mmc_claim_host(struct mmc_host *host)
818 +{
819 +       __mmc_claim_host(host, (struct mmc_card *)-1);
820 +}
821 +
822 +extern void mmc_release_host(struct mmc_host *host);
823 +
824 +#endif
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
827 @@ -0,0 +1,67 @@
828 +/*
829 + *  linux/include/linux/mmc/host.h
830 + *
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.
834 + *
835 + *  Host driver specific definitions.
836 + */
837 +#ifndef LINUX_MMC_HOST_H
838 +#define LINUX_MMC_HOST_H
839 +
840 +#include <linux/mmc/mmc.h>
841 +
842 +struct mmc_ios {
843 +       unsigned int    clock;                  /* clock rate */
844 +       unsigned short  vdd;                    /* supply (units of 10mV) */
845 +       unsigned char   bus_mode;               /* command output mode */
846 +
847 +#define MMC_BUSMODE_OPENDRAIN  1
848 +#define MMC_BUSMODE_PUSHPULL   2
849 +
850 +       unsigned char   power_mode;             /* power supply mode */
851 +
852 +#define MMC_POWER_OFF          0
853 +#define MMC_POWER_UP           1
854 +#define MMC_POWER_ON           2
855 +};
856 +
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);
860 +};
861 +
862 +struct mmc_card;
863 +
864 +struct mmc_host {
865 +       struct device           *dev;
866 +       struct mmc_host_ops     *ops;
867 +       unsigned int            f_min;
868 +       unsigned int            f_max;
869 +       u32                     ocr_avail;
870 +
871 +       /* private data */
872 +       unsigned int            host_num;       /* host number */
873 +       struct mmc_ios          ios;            /* current io bus settings */
874 +       u32                     ocr;            /* the current OCR setting */
875 +
876 +       struct list_head        cards;          /* devices attached to this host */
877 +
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 */
882 +};
883 +
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 *);
889 +
890 +extern void mmc_detect_change(struct mmc_host *);
891 +extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
892 +
893 +#endif
894 +
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
897 @@ -0,0 +1,203 @@
898 +/*
899 + * Header for MultiMediaCard (MMC)
900 + *
901 + * Copyright 2002 Hewlett-Packard Company
902 + *
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.
906 + *
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.
910 + *
911 + * Many thanks to Alessandro Rubini and Jonathan Corbet!
912 + *
913 + * Based strongly on code by:
914 + *
915 + * Author: Yong-iL Joh <tolkien@mizi.com>
916 + * Date  : $Date: 2002/06/18 12:37:30 $
917 + *
918 + * Author:  Andrew Christian
919 + *          15 May 2002
920 + */
921 +
922 +#ifndef MMC_MMC_PROTOCOL_H
923 +#define MMC_MMC_PROTOCOL_H
924 +
925 +/* Standard MMC commands (3.1)           type  argument     response */
926 +   /* class 1 */
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            */
939 +
940 +  /* class 2 */
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  */
944 +
945 +  /* class 3 */
946 +#define MMC_WRITE_DAT_UNTIL_STOP 20   /* adtc [31:0] data addr   R1  */
947 +
948 +  /* class 4 */
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  */
954 +
955 +  /* class 6 */
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  */
959 +
960 +  /* class 5 */
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 */
964 +
965 +  /* class 9 */
966 +#define MMC_FAST_IO              39   /* ac   <Complex>          R4  */
967 +#define MMC_GO_IRQ_STATE         40   /* bcr                     R5  */
968 +
969 +  /* class 7 */
970 +#define MMC_LOCK_UNLOCK          42   /* adtc                    R1b */
971 +
972 +  /* class 8 */
973 +#define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */
974 +#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1b */
975 +
976 +/*
977 +  MMC status in R1
978 +  Type
979 +       e : error bit
980 +       s : status bit
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.
984 +  Clear condition
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)
988 +       c : clear by read
989 + */
990 +
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 */
1014 +
1015 +/* These are unpacked versions of the actual responses */
1016 +
1017 +struct _mmc_csd {
1018 +       u8  csd_structure;
1019 +       u8  spec_vers;
1020 +       u8  taac;
1021 +       u8  nsac;
1022 +       u8  tran_speed;
1023 +       u16 ccc;
1024 +       u8  read_bl_len;
1025 +       u8  read_bl_partial;
1026 +       u8  write_blk_misalign;
1027 +       u8  read_blk_misalign;
1028 +       u8  dsr_imp;
1029 +       u16 c_size;
1030 +       u8  vdd_r_curr_min;
1031 +       u8  vdd_r_curr_max;
1032 +       u8  vdd_w_curr_min;
1033 +       u8  vdd_w_curr_max;
1034 +       u8  c_size_mult;
1035 +       union {
1036 +               struct { /* MMC system specification version 3.1 */
1037 +                       u8  erase_grp_size;
1038 +                       u8  erase_grp_mult;
1039 +               } v31;
1040 +               struct { /* MMC system specification version 2.2 */
1041 +                       u8  sector_size;
1042 +                       u8  erase_grp_size;
1043 +               } v22;
1044 +       } erase;
1045 +       u8  wp_grp_size;
1046 +       u8  wp_grp_enable;
1047 +       u8  default_ecc;
1048 +       u8  r2w_factor;
1049 +       u8  write_bl_len;
1050 +       u8  write_bl_partial;
1051 +       u8  file_format_grp;
1052 +       u8  copy;
1053 +       u8  perm_write_protect;
1054 +       u8  tmp_write_protect;
1055 +       u8  file_format;
1056 +       u8  ecc;
1057 +};
1058 +
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 */
1084 +
1085 +
1086 +/*
1087 + * CSD field definitions
1088 + */
1089 +
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       */
1093 +
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 */
1098 +
1099 +#endif  /* MMC_MMC_PROTOCOL_H */
1100 +
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
1103 @@ -0,0 +1,39 @@
1104 +/*
1105 + *  linux/include/linux/l3/algo-bit.h
1106 + *
1107 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
1108 + *
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.
1112 + *
1113 + * L3 Bus bit-banging algorithm.  Derived from i2c-algo-bit.h by
1114 + * Simon G. Vogl.
1115 + */
1116 +#ifndef L3_ALGO_BIT_H
1117 +#define L3_ALGO_BIT_H 1
1118 +
1119 +#include <linux/l3/l3.h>
1120 +
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);
1127 +
1128 +       void *data;
1129 +
1130 +       /* bus timings (us) */
1131 +       int     data_hold;
1132 +       int     data_setup;
1133 +       int     clock_high;
1134 +       int     mode_hold;
1135 +       int     mode_setup;
1136 +       int     mode;
1137 +};
1138 +
1139 +int l3_bit_add_bus(struct l3_adapter *);
1140 +int l3_bit_del_bus(struct l3_adapter *);
1141 +
1142 +#endif
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
1145 @@ -0,0 +1,95 @@
1146 +/*
1147 + *  linux/include/linux/l3/l3.h
1148 + *
1149 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
1150 + *
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.
1154 + *
1155 + * Derived from i2c.h by Simon G. Vogl
1156 + */
1157 +#ifndef L3_H
1158 +#define L3_H
1159 +
1160 +struct l3_msg {
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  */
1167 +};
1168 +
1169 +#ifdef __KERNEL__
1170 +
1171 +#include <linux/types.h>
1172 +#include <linux/list.h>
1173 +
1174 +struct l3_adapter;
1175 +
1176 +struct l3_algorithm {
1177 +       /* textual description */
1178 +       char name[32];
1179 +
1180 +       /* perform bus transactions */
1181 +       int (*xfer)(struct l3_adapter *, struct l3_msg msgs[], int num);
1182 +};
1183 +
1184 +struct semaphore;
1185 +
1186 +/*
1187 + * l3_adapter is the structure used to identify a physical L3 bus along
1188 + * with the access algorithms necessary to access it.
1189 + */
1190 +struct l3_adapter {
1191 +       /*
1192 +        * This name is used to uniquely identify the adapter.
1193 +        * It should be the same as the module name.
1194 +        */
1195 +       char                    name[32];
1196 +
1197 +       /*
1198 +        * the algorithm to access the bus
1199 +        */
1200 +       struct l3_algorithm     *algo;
1201 +
1202 +       /*
1203 +        * Algorithm specific data
1204 +        */
1205 +       void                    *algo_data;
1206 +
1207 +       /*
1208 +        * This may be NULL, or should point to the module struct
1209 +        */
1210 +       struct module           *owner;
1211 +
1212 +       /*
1213 +        * private data for the adapter
1214 +        */
1215 +       void                    *data;
1216 +
1217 +       /*
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.
1221 +        */
1222 +       struct semaphore        *lock;
1223 +
1224 +       /*
1225 +        * List of all adapters.
1226 +        */
1227 +       struct list_head        adapters;
1228 +};
1229 +
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);
1234 +
1235 +extern int l3_write(struct l3_adapter *, int, const char *, int);
1236 +extern int l3_read(struct l3_adapter *, int, char *, int);
1237 +
1238 +#endif
1239 +
1240 +#endif /* L3_H */
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
1243 @@ -0,0 +1,61 @@
1244 +/*
1245 + *  linux/include/linux/l3/uda1341.h
1246 + *
1247 + * Philips UDA1341 mixer device driver
1248 + *
1249 + * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
1250 + *
1251 + * This program is free software; you can redistribute it and/or
1252 + * modify it under the terms of the GNU General Public License.
1253 + */
1254 +
1255 +#define UDA1341_NAME "uda1341"
1256 +
1257 +struct uda1341_cfg {
1258 +       unsigned int fs:16;
1259 +       unsigned int format:3;
1260 +};
1261 +
1262 +#define FMT_I2S                0
1263 +#define FMT_LSB16      1
1264 +#define FMT_LSB18      2
1265 +#define FMT_LSB20      3
1266 +#define FMT_MSB                4
1267 +#define FMT_LSB16MSB   5
1268 +#define FMT_LSB18MSB   6
1269 +#define FMT_LSB20MSB   7
1270 +
1271 +#define L3_UDA1341_CONFIGURE   0x13410001
1272 +
1273 +struct l3_gain {
1274 +       unsigned int    left:8;
1275 +       unsigned int    right:8;
1276 +       unsigned int    unused:8;
1277 +       unsigned int    channel:8;
1278 +};
1279 +
1280 +#define L3_SET_VOLUME          0x13410002
1281 +#define L3_SET_TREBLE          0x13410003
1282 +#define L3_SET_BASS            0x13410004
1283 +#define L3_SET_GAIN            0x13410005
1284 +
1285 +struct l3_agc {
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;
1291 +};
1292 +
1293 +#define L3_INPUT_AGC           0x13410006
1294 +
1295 +struct uda1341;
1296 +
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);
1301 +
1302 +struct uda1341 *uda1341_attach(const char *adapter);
1303 +void uda1341_detach(struct uda1341 *uda);
1304 +
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
1307 @@ -187,6 +187,7 @@
1308  #define I2C_ALGO_BITHS 0x130000        /* enhanced bit style adapters  */
1309  #define I2C_ALGO_OCP_IOP3XX  0x140000  /* XSCALE IOP3XX On-chip I2C alg */
1310  
1311 +#define I2C_ALGO_PXA   0x200000        /* Intel PXA I2C algorithm  */
1312  #define I2C_ALGO_EXP   0x800000        /* experimental                 */
1313  
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
1317 @@ -17,7 +17,7 @@
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
1320   *
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 $
1323   */
1324  
1325  /*
1326 @@ -159,8 +159,6 @@
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 */
1335 @@ -172,6 +170,7 @@
1336  
1337         unsigned int            read_status_mask;       /* driver specific */
1338         unsigned int            ignore_status_mask;     /* driver specific */
1339 +
1340         struct uart_info        *info;                  /* pointer to parent info */
1341         struct uart_icount      icount;                 /* statistics */
1342  
1343 @@ -182,7 +181,6 @@
1344  
1345         unsigned int            flags;
1346  
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];
1363  };
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
1366 @@ -35,6 +35,8 @@
1367   *     Lowlevel-APIs (not for driver use!)
1368   */
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);
1379  #endif
1380  
1381 +#ifndef __arm__
1382 +#define memc_update_addr(x,y,z)
1383 +#define memc_update_mm(x)
1384 +#define memc_clear(x,y)
1385 +#endif
1386 +
1387  #endif /* __KERNEL__ */
1388  #endif /* _LINUX_MM_H */
1389 +
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
1392 @@ -391,7 +391,7 @@
1393                         root_device_name += 5;
1394         }
1395  
1396 -       is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
1397 +       is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR || MAJOR(ROOT_DEV) == 31;
1398  
1399         if (initrd_load())
1400                 goto out;
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 @@
1404                 else
1405                         send_sig(SIGTRAP, current, 0);
1406         }
1407 +#ifndef __arm__
1408         return 0;
1409 +#else
1410 +       return regs->ARM_r0;
1411 +#endif
1412  }
1413  
1414  static int load_aout_library(struct file *file)
1415 @@ -462,8 +466,11 @@
1416  
1417         /* For  QMAGIC, the starting address is 0x20 into the page.  We mask
1418            this off to get the starting address for the page */
1419 -
1420 -       start_addr =  ex.a_entry & 0xfffff000;
1421 +#ifndef __arm__
1422 +       start_addr = ex.a_entry & 0xfffff000;
1423 +#else
1424 +       start_addr = ex.a_entry & 0xffff8000;
1425 +#endif
1426  
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 @@
1432   *
1433   * Called with disabled ints.
1434   */
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)
1437  {
1438         struct array_cache *ac = ac_data(cachep);
1439  
1440         check_irq_off();
1441 -       objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
1442 +       objp = cache_free_debugcheck(cachep, objp, caller /*__builtin_return_address(0)*/);
1443  
1444         if (likely(ac->avail < ac->limit)) {
1445                 STATS_INC_FREEHIT(cachep);
1446 @@ -2289,7 +2289,7 @@
1447         unsigned long flags;
1448  
1449         local_irq_save(flags);
1450 -       __cache_free(cachep, objp);
1451 +       __cache_free(cachep, objp, __builtin_return_address(0));
1452         local_irq_restore(flags);
1453  }
1454  
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);
1462  }
1463  
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
1466 @@ -0,0 +1,36 @@
1467 +L3 Bus Driver
1468 +-------------
1469 +
1470 +The structure of the driver is as follows:
1471 +
1472 +       +----------+    +----------+    +----------+
1473 +       | client 1 |    | client 2 |    | client 3 |
1474 +       +-----^----+    +----^-----+    +----^-----+
1475 +             |              |               |
1476 +       +-----v--------------v---------------v-----+
1477 +       |                                          |
1478 +       +-----^-------+              +-------^-----+
1479 +             |       |     core     |       |
1480 +       +-----v----+  |              |  +----v-----+
1481 +       | device   |  |              |  | device   |
1482 +       | driver 1 |  |              |  | driver 2 |
1483 +       +-----^----+  |              |  +----^-----+
1484 +             |       |   services   |       |
1485 +       +-----v-------+              +-------v-----+
1486 +       |                                          |
1487 +       +-----------------^----^-------------------+
1488 +                         |    |
1489 +                         |  +-v---------+
1490 +                         |  | algorithm |
1491 +                         |  |  driver   |
1492 +                         |  +-v---------+
1493 +                         |    |
1494 +                       +-v----v-+
1495 +                       |  bus   |
1496 +                       | driver |
1497 +                       +--------+
1498 +
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 @@
1506  
1507                 @ if all ports are inactive, then there is nothing we can do
1508                 moveq   pc, lr
1509 +               ldr     r1, [\rx, #UTCR2]
1510 +               teq     r1, #5
1511 +               movne   r1, #0
1512 +               strne   r1, [\rx, #UTCR3]
1513 +               movne   r1, #8
1514 +               strne   r1, [\rx, #UTCR0]
1515 +               movne   r1, #5
1516 +               strne   r1, [\rx, #UTCR2]
1517 +               movne   r1, #0
1518 +               strne   r1, [\rx, #UTCR1]
1519 +               movne   r1, #3
1520 +               strne   r1, [\rx, #UTCR3]
1521 +               movne   r1, #255
1522 +               strne   r1, [\rx, #UTSR0]
1523                 .endm
1524  
1525                 .macro  senduart,rd,rx
1526 @@ -287,7 +301,7 @@
1527  
1528  #elif defined(CONFIG_ARCH_INTEGRATOR)
1529  
1530 -#include <asm/hardware/serial_amba.h>
1531 +#include <asm/hardware/amba_serial.h>
1532  
1533                 .macro  addruart,rx
1534                 mrc     p15, 0, \rx, c1, c0
1535 @@ -298,7 +312,7 @@
1536                 .endm
1537  
1538                 .macro  senduart,rd,rx
1539 -               strb    \rd, [\rx, #AMBA_UARTDR]
1540 +               strb    \rd, [\rx, #UART01x_DR]
1541                 .endm
1542  
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.
1548   */
1549  vector_FIQ:    disable_fiq
1550 +               mrs     r13, spsr
1551 +               orr     r13, r13, #PSR_F_BIT
1552 +               msr     spsr, r13
1553                 subs    pc, lr, #4
1554  
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
1558 @@ -47,12 +47,36 @@
1559  #define MAX_IRQ_CNT    100000
1560  
1561  static volatile unsigned long irq_err_count;
1562 -static spinlock_t irq_controller_lock;
1563  static LIST_HEAD(irq_pending);
1564  
1565  struct irqdesc irq_desc[NR_IRQS];
1566  void (*init_arch_irq)(void) __initdata = NULL;
1567  
1568 +#if NR_IRQ_DEVICES > 1
1569 +struct irq_device {
1570 +       spinlock_t      lock;
1571 +       int             nr_irqs;
1572 +       struct irq_desc *irqs;
1573 +};
1574 +
1575 +static struct irq_device irq_devices[NR_IRQ_DEVICES] = {
1576 +       [0] = {
1577 +               .lock           = SPIN_LOCK_UNLOCKED,
1578 +               .nr_irqs        = NR_IRQS,
1579 +               .irqs           = irq_desc,
1580 +       },
1581 +};
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)
1586 +#else
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)
1591 +#endif
1592 +
1593  /*
1594   * Dummy mask/unmask handler
1595   */
1596 @@ -95,13 +119,13 @@
1597   */
1598  void disable_irq(unsigned int irq)
1599  {
1600 -       struct irqdesc *desc = irq_desc + irq;
1601 +       struct irqdesc *desc = IRQ_DESC(irq);
1602         unsigned long flags;
1603  
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);
1610  }
1611  
1612  /**
1613 @@ -116,10 +140,10 @@
1614   */
1615  void enable_irq(unsigned int irq)
1616  {
1617 -       struct irqdesc *desc = irq_desc + irq;
1618 +       struct irqdesc *desc = IRQ_DESC(irq);
1619         unsigned long flags;
1620  
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));
1626 @@ -140,7 +164,7 @@
1627                                 list_add(&desc->pend, &irq_pending);
1628                 }
1629         }
1630 -       spin_unlock_irqrestore(&irq_controller_lock, flags);
1631 +       spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1632  }
1633  
1634  /*
1635 @@ -148,24 +172,24 @@
1636   */
1637  void enable_irq_wake(unsigned int irq)
1638  {
1639 -       struct irqdesc *desc = irq_desc + irq;
1640 +       struct irqdesc *desc = IRQ_DESC(irq);
1641         unsigned long flags;
1642  
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);
1649  }
1650  
1651  void disable_irq_wake(unsigned int irq)
1652  {
1653 -       struct irqdesc *desc = irq_desc + irq;
1654 +       struct irqdesc *desc = IRQ_DESC(irq);
1655         unsigned long flags;
1656  
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);
1663  }
1664  
1665  int show_interrupts(struct seq_file *p, void *v)
1666 @@ -175,8 +199,8 @@
1667         unsigned long flags;
1668  
1669         if (i < NR_IRQS) {
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;
1674                 if (!action)
1675                         goto unlock;
1676  
1677 @@ -187,7 +211,7 @@
1678  
1679                 seq_putc(p, '\n');
1680  unlock:
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);
1686 @@ -259,7 +283,7 @@
1687         unsigned int status;
1688         int retval = 0;
1689  
1690 -       spin_unlock(&irq_controller_lock);
1691 +       spin_unlock(IRQ_LOCK(irq));
1692  
1693         if (!(action->flags & SA_INTERRUPT))
1694                 local_irq_enable();
1695 @@ -274,7 +298,7 @@
1696         if (status & SA_SAMPLE_RANDOM)
1697                 add_interrupt_randomness(irq);
1698  
1699 -       spin_lock_irq(&irq_controller_lock);
1700 +       spin_lock_irq(IRQ_LOCK(irq));
1701  
1702         return retval;
1703  }
1704 @@ -455,7 +479,7 @@
1705                 desc = &bad_irq_desc;
1706  
1707         irq_enter();
1708 -       spin_lock(&irq_controller_lock);
1709 +       spin_lock(IRQ_LOCK(irq));
1710         desc->handle(irq, desc, regs);
1711  
1712         /*
1713 @@ -464,7 +488,7 @@
1714         if (!list_empty(&irq_pending))
1715                 do_pending_irqs(regs);
1716  
1717 -       spin_unlock(&irq_controller_lock);
1718 +       spin_unlock(IRQ_LOCK(irq));
1719         irq_exit();
1720  }
1721  
1722 @@ -473,7 +497,7 @@
1723         struct irqdesc *desc;
1724         unsigned long flags;
1725  
1726 -       if (irq >= NR_IRQS) {
1727 +       if (!IRQ_VALID(irq)) {
1728                 printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
1729                 return;
1730         }
1731 @@ -481,12 +505,12 @@
1732         if (handle == NULL)
1733                 handle = do_bad_IRQ;
1734  
1735 -       desc = irq_desc + irq;
1736 +       desc = IRQ_DESC(irq);
1737  
1738         if (is_chained && desc->chip == &bad_chip)
1739                 printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
1740  
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);
1746 @@ -499,7 +523,7 @@
1747                 desc->disable_depth = 0;
1748                 desc->chip->unmask(irq);
1749         }
1750 -       spin_unlock_irqrestore(&irq_controller_lock, flags);
1751 +       spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1752  }
1753  
1754  void set_irq_chip(unsigned int irq, struct irqchip *chip)
1755 @@ -507,7 +531,7 @@
1756         struct irqdesc *desc;
1757         unsigned long flags;
1758  
1759 -       if (irq >= NR_IRQS) {
1760 +       if (!IRQ_VALID(irq)) {
1761                 printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
1762                 return;
1763         }
1764 @@ -515,10 +539,10 @@
1765         if (chip == NULL)
1766                 chip = &bad_chip;
1767  
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);
1772         desc->chip = chip;
1773 -       spin_unlock_irqrestore(&irq_controller_lock, flags);
1774 +       spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1775  }
1776  
1777  int set_irq_type(unsigned int irq, unsigned int type)
1778 @@ -527,16 +551,21 @@
1779         unsigned long flags;
1780         int ret = -ENXIO;
1781  
1782 -       if (irq >= NR_IRQS) {
1783 +       if (!IRQ_VALID(irq)) {
1784                 printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
1785                 return -ENODEV;
1786         }
1787  
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));
1793 +       }
1794 +
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);
1801         }
1802  
1803         return ret;
1804 @@ -547,17 +576,17 @@
1805         struct irqdesc *desc;
1806         unsigned long flags;
1807  
1808 -       if (irq >= NR_IRQS) {
1809 +       if (!IRQ_VALID(irq)) {
1810                 printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
1811                 return;
1812         }
1813  
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);
1823  }
1824  
1825  int setup_irq(unsigned int irq, struct irqaction *new)
1826 @@ -587,13 +616,13 @@
1827         /*
1828          * The following block of code has to be executed atomically
1829          */
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);
1834         p = &desc->action;
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);
1840                         return -EBUSY;
1841                 }
1842  
1843 @@ -618,7 +647,7 @@
1844                 }
1845         }
1846  
1847 -       spin_unlock_irqrestore(&irq_controller_lock, flags);
1848 +       spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1849         return 0;
1850  }
1851  
1852 @@ -659,7 +688,7 @@
1853         unsigned long retval;
1854         struct irqaction *action;
1855  
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))
1859                 return -EINVAL;
1860  
1861 @@ -700,14 +729,14 @@
1862         struct irqaction * action, **p;
1863         unsigned long flags;
1864  
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);
1868                 dump_stack();
1869                 return;
1870         }
1871  
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)
1877                         continue;
1878  
1879 @@ -715,7 +744,7 @@
1880                 *p = action->next;
1881                 break;
1882         }
1883 -       spin_unlock_irqrestore(&irq_controller_lock, flags);
1884 +       spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
1885  
1886         if (!action) {
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
1891          */
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)
1895 -                       continue;
1896 -
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);
1902 -               irqs += 1;
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);
1910 +                       irqs += 1;
1911 +               }
1912 +               spin_unlock_irq(IRQ_LOCK(i));
1913         }
1914 -       spin_unlock_irq(&irq_controller_lock);
1915  
1916         /*
1917          * wait for spurious interrupts to mask themselves out again
1918 @@ -770,14 +798,14 @@
1919         /*
1920          * now filter out any obviously spurious interrupts
1921          */
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;
1927                         irqs -= 1;
1928                 }
1929 +               spin_unlock_irq(IRQ_LOCK(i));
1930         }
1931 -       spin_unlock_irq(&irq_controller_lock);
1932  
1933         return irqs;
1934  }
1935 @@ -788,11 +816,13 @@
1936  {
1937         unsigned int mask = 0, i;
1938  
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)
1946                         mask |= 1 << i;
1947 -       spin_unlock_irq(&irq_controller_lock);
1948 +               spin_unlock_irq(IRQ_LOCK(i));
1949 +       }
1950  
1951         up(&probe_sem);
1952  
1953 @@ -813,23 +843,21 @@
1954          * look at the interrupts, and find exactly one
1955          * that we were probing has been triggered
1956          */
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);
1962 +
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));
1967                                 irq_found = NO_IRQ;
1968 -                               goto out;
1969 +                               break;
1970                         }
1971                         irq_found = i;
1972                 }
1973 +               spin_unlock_irq(IRQ_LOCK(i));
1974         }
1975  
1976 -       if (irq_found == -1)
1977 -               irq_found = NO_IRQ;
1978 -out:
1979 -       spin_unlock_irq(&irq_controller_lock);
1980 -
1981         up(&probe_sem);
1982  
1983         return irq_found;
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
1986 @@ -565,8 +565,6 @@
1987         if (hw->postinit)
1988                 hw->postinit();
1989  
1990 -       pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
1991 -
1992         list_for_each_entry(sys, &hw->buses, node) {
1993                 struct pci_bus *bus = sys->bus;
1994  
1995 @@ -581,6 +579,11 @@
1996                 pci_bus_assign_resources(bus);
1997  
1998                 /*
1999 +                * Fixup IRQs.
2000 +                */
2001 +               pci_bus_fixup_irqs(bus, pcibios_swizzle, pcibios_map_irq);
2002 +
2003 +               /*
2004                  * Tell drivers about devices found.
2005                  */
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);
2011  }
2012  
2013 -spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
2014 -
2015 -/*
2016 - * This function is protected against re-entrancy.
2017 - */
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)
2020  {
2021 -       struct task_struct *tsk = current;
2022 +       struct task_struct *tsk = thread->task;
2023         static int die_counter;
2024  
2025 -       console_verbose();
2026 -       spin_lock_irq(&die_lock);
2027 -       bust_spinlocks(1);
2028 -
2029         printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
2030         print_modules();
2031         printk("CPU: %d\n", smp_processor_id());
2032         show_regs(regs);
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);
2036  
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);
2040                 dump_instr(regs);
2041         }
2042 +}
2043 +
2044 +void nmi_watchdog(struct thread_info *thread, struct pt_regs *regs)
2045 +{
2046 +       __die("NMI watchdog", 0, thread, regs);
2047 +}
2048  
2049 +spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
2050 +
2051 +/*
2052 + * This function is protected against re-entrancy.
2053 + */
2054 +NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
2055 +{
2056 +       struct thread_info *thread = current_thread_info();
2057 +
2058 +       console_verbose();
2059 +       spin_lock_irq(&die_lock);
2060 +       bust_spinlocks(1);
2061 +       __die(str, err, thread, regs);
2062         bust_spinlocks(0);
2063         spin_unlock_irq(&die_lock);
2064         do_exit(SIGSEGV);
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
2067 @@ -297,7 +297,7 @@
2068  
2069  config CPU_FREQ
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
2073         help
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
2078 @@ -0,0 +1,294 @@
2079 +/*
2080 +At entry the registers contain the following information:
2081 +
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)
2087
2088 +*/
2089 +
2090 +/*---------------------------------------------------------------------------*/
2091 +
2092 +       .data
2093 +fp_const:
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
2102 +fp_undef:
2103 +       .word   0
2104 +fp_cond:
2105 +       .word   0xf0f0  @ eq
2106 +       .word   0x0f0f  @ ne
2107 +       .word   0xcccc  @ cs
2108 +       .word   0x3333  @ cc
2109 +       .word   0xff00  @ mi
2110 +       .word   0x00ff  @ pl
2111 +       .word   0xaaaa  @ vs
2112 +       .word   0x5555  @ vc
2113 +       .word   0x0c0c  @ hi
2114 +       .word   0xf3f3  @ ls
2115 +       .word   0xaa55  @ ge
2116 +       .word   0x55aa  @ lt
2117 +       .word   0x0a05  @ gt
2118 +       .word   0xf5fa  @ le
2119 +       .word   0xffff  @ al
2120 +       .word   0x0000  @ nv
2121 +       
2122 +/*---------------------------------------------------------------------------*/
2123 +       
2124 +       .text
2125 +       .globl  fastfpe_enter
2126 +fastfpe_enter:
2127 +       ldr     r4,=fp_undef
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
2132 +next_enter:
2133 +       cmp     r1,#1<<8                @ copro 1 ?
2134 +       beq     copro_1
2135 +       cmp     r1,#2<<8
2136 +       movne   pc,r14
2137 +
2138 +copro_2:
2139 +       and     r1,r4,#0x0f000000
2140 +       cmp     r1,#0x0c000000          @ CPDT with post indexing
2141 +        cmpne   r1,#0x0d000000          @ CPDT with pre indexing
2142 +        beq     CPDT_M_enter
2143 +       mov     pc,r14
2144 +
2145 +copro_1:
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
2151 +       beq     CPDT_1_enter
2152 +       mov     pc,r14
2153 +
2154 +/*---------------------------------------------------------------------------*/
2155 +
2156 +       .globl  fastfpe_next
2157 +fastfpe_next:
2158 +       ldr     r5,[r13,#60]
2159 +next_after_cond:
2160 +__x1:
2161 +       ldrt    r4,[r5],#4
2162 +       
2163 +       ldr     r0,=fp_cond             @ check condition of next instruction
2164 +       ldr     r1,[r13,#64]            @ psr containing flags
2165 +       mov     r2,r4,lsr#28
2166 +       mov     r1,r1,lsr#28
2167 +       ldr     r0,[r0,r2,lsl#2]
2168 +       mov     r0,r0,lsr r1
2169 +       tst     r0,#1
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
2176 +       
2177 +       ands    r1,r4,#0x00000f00       @ r1 = coprocessor << 8
2178 +       cmpne   r1,#3<<8
2179 +       movge   pc,r9                   @ copro = 0 or >=3, return
2180 +               
2181 +       str     r5,[r13,#60]            @ save updated pc
2182 +       b       next_enter
2183 +
2184 +/*---------------------------------------------------------------------------*/
2185 +
2186 +undefined:
2187 +       ldr     r4,=fp_undef
2188 +       ldr     pc,[r4] 
2189 +
2190 +/*---------------------------------------------------------------------------*/
2191 +
2192 +CPDT_1_enter:
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 ?
2196 +       addeq   r6,r6,#4
2197 +       and     r7,r4,#0x000000ff       @ r7=offset value
2198 +
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 ?
2203 +       movne   r6,r7
2204 +       tst     r4,#0x00200000          @ write back ?
2205 +       cmpne   r5,#0x000f0000          @ base register = pc ?
2206 +       strne   r7,[r13,r5,lsr#14]
2207 +
2208 +       and     r0,r4,#0x00007000       @ r0=fp register number << 12
2209 +       add     r0,r10,r0,lsr#8         @ r0=address of fp register
2210 +       mov     r1,#0
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
2217 +
2218 +       add     pc,pc,r1,lsl#2
2219 +       mov     r0,r0
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
2228 +
2229 +/*---------------------------------------------------------------------------*/
2230 +
2231 +CPDT_M_enter:
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 ?
2235 +       addeq   r6,r6,#4
2236 +       and     r7,r4,#0x000000ff       @ r7=offset value
2237 +
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 ?
2242 +       movne   r6,r7
2243 +       tst     r4,#0x00200000          @ write back ?
2244 +       cmpne   r5,#0x000f0000          @ base register = pc ?
2245 +       strne   r7,[r13,r5,lsr#14]
2246 +
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
2253 +
2254 +       tst     r4,#0x00100000          @ load/store
2255 +       beq     CPDT_sfm
2256 +       b       CPDT_lfm
2257 +
2258 +/*---------------------------------------------------------------------------*/
2259 +
2260 +CPDO_CPRT_enter:
2261 +       tst     r4,#0x00000010
2262 +       bne     CPRT_enter
2263 +       
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
2269 +       bne     CPDO_const
2270 +       and     r2,r4,#0x00000007
2271 +       add     r2,r10,r2,lsl#4         @ r2=address of Fm
2272 +       
2273 +CPDO_constback:
2274 +       and     r3,r4,#0x00f00000
2275 +       tst     r4,#0x00008000
2276 +       orrne   r3,r3,#0x01000000
2277 +               
2278 +       add     pc,pc,r3,lsr#18
2279 +       mov     r0,r0
2280 +       b       CPDO_adf
2281 +       b       CPDO_muf
2282 +       b       CPDO_suf
2283 +       b       CPDO_rsf
2284 +       b       CPDO_dvf
2285 +       b       CPDO_rdf
2286 +       b       undefined
2287 +       b       undefined
2288 +       b       undefined               @ CPDO_rmf
2289 +       b       CPDO_muf
2290 +       b       CPDO_dvf
2291 +       b       CPDO_rdf
2292 +       b       undefined
2293 +       b       undefined
2294 +       b       undefined
2295 +       b       undefined
2296 +       b       CPDO_mvf
2297 +       b       CPDO_mnf
2298 +       b       CPDO_abs
2299 +       b       CPDO_rnd
2300 +       b       CPDO_sqt
2301 +       b       undefined
2302 +       b       undefined
2303 +       b       undefined
2304 +       b       undefined
2305 +       b       undefined
2306 +       b       undefined
2307 +       b       undefined
2308 +       b       undefined
2309 +       b       undefined
2310 +       b       CPDO_rnd
2311 +       b       fastfpe_next
2312 +
2313 +CPDO_const:
2314 +       ldr     r2,=fp_const
2315 +       and     r3,r4,#0x00000007
2316 +       add     r2,r2,r3,lsl#4  
2317 +       b       CPDO_constback
2318 +       
2319 +/*---------------------------------------------------------------------------*/
2320 +
2321 +CPRT_enter:
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
2326 +       bne     CPRT_const
2327 +       and     r2,r4,#0x00000007
2328 +       add     r2,r10,r2,lsl#4         @ r2=address of Fm
2329 +       
2330 +CPRT_constback:
2331 +       and     r3,r4,#0x00f00000
2332 +               
2333 +       add     pc,pc,r3,lsr#18
2334 +       mov     r0,r0
2335 +       b       CPRT_flt
2336 +       b       CPRT_fix
2337 +       b       CPRT_wfs
2338 +       b       CPRT_rfs
2339 +       b       undefined
2340 +       b       undefined
2341 +       b       undefined
2342 +       b       undefined
2343 +       b       undefined
2344 +       b       CPRT_cmf
2345 +       b       undefined
2346 +       b       CPRT_cnf
2347 +       b       undefined
2348 +       b       CPRT_cmf
2349 +       b       undefined
2350 +       b       CPRT_cnf
2351 +
2352 +CPRT_const:
2353 +       ldr     r2,=fp_const
2354 +       and     r3,r4,#0x00000007
2355 +       add     r2,r2,r3,lsl#4  
2356 +       b       CPRT_constback
2357 +       
2358 +/*---------------------------------------------------------------------------*/
2359 +
2360 +       @ The fetch of the next instruction to emulate could fault
2361 +
2362 +       .section .fixup,"ax"
2363 +       .align
2364 +__f1:
2365 +       mov     pc,r9
2366 +       .previous
2367 +       .section __ex_table,"a"
2368 +       .align 3
2369 +       .long   __x1,__f1
2370 +       .previous
2371 +       
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
2375 @@ -0,0 +1,62 @@
2376 +/*
2377 +    Fast Floating Point Emulator
2378 +    (c) Peter Teichmann <mail@peter-teichmann.de>
2379 +
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.
2384 +
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.
2389 +
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.
2393 +*/
2394 +
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>
2402 +
2403 +#ifndef MODULE
2404 +#define kern_fp_enter  fp_enter
2405 +
2406 +extern char fpe_type[];
2407 +#endif
2408 +
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 */
2412 +
2413 +static int __init fpe_init(void)
2414 +{
2415 +  if (fpe_type[0] && strcmp(fpe_type, "fastfpe"))
2416 +    return 0;
2417 +
2418 +  printk("Fast Floating Point Emulator V0.9 (c) Peter Teichmann.\n");
2419 +
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;
2423 +
2424 +  return 0;
2425 +}
2426 +
2427 +static void __exit fpe_exit(void)
2428 +{
2429 +  /* Restore the values we saved earlier. */
2430 +  kern_fp_enter = orig_fp_enter;
2431 +}
2432 +
2433 +module_init(fpe_init);
2434 +module_exit(fpe_exit);
2435 +
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
2440 @@ -0,0 +1,682 @@
2441 +/*
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.
2446 +
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.
2449 +
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.
2453 +
2454 +Decimal and packed decimal numbers are not supported yet.
2455 +
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.
2459 +*/
2460 +
2461 +/*---------------------------------------------------------------------------*/
2462 +
2463 +       .globl  CPDO_adf
2464 +CPDO_adf:
2465 +       ldmia   r1,{r1,r3,r5,r7}
2466 +       ldmia   r2,{r2,r4,r6,r8}
2467 +
2468 +       cmp     r7,#0x7fffffff
2469 +       cmpne   r8,#0x7fffffff
2470 +       beq     CPDO_adf_extra
2471 +
2472 +       cmp     r1,r2
2473 +       bne     CPDO_suf_s
2474 +
2475 +CPDO_adf_s:
2476 +       subs    r2,r7,r8
2477 +       bge     CPDO_adf_2nd
2478 +       
2479 +       mov     r7,r8
2480 +       rsb     r2,r2,#0
2481 +       cmp     r2,#32
2482 +       ble     CPDO_adf_1st2
2483 +
2484 +       sub     r2,r2,#32
2485 +       cmp     r2,#32
2486 +       movgt   r2,#32
2487 +       mov     r5,r3,lsr r2
2488 +       mov     r3,#0
2489 +       b       CPDO_adf_add
2490 +
2491 +CPDO_adf_1st2:
2492 +       rsb     r8,r2,#32
2493 +       mov     r5,r5,lsr r2
2494 +       orr     r5,r5,r3,lsl r8
2495 +       mov     r3,r3,lsr r2    @ 1. op normalized
2496 +       b       CPDO_adf_add
2497 +
2498 +CPDO_adf_2nd:
2499 +       cmp     r2,#32
2500 +       ble     CPDO_adf_2nd2
2501 +
2502 +       sub     r2,r2,#32
2503 +       cmp     r2,#32
2504 +       movgt   r2,#32
2505 +       mov     r6,r4,lsr r2
2506 +       mov     r4,#0
2507 +       b       CPDO_adf_add
2508 +
2509 +CPDO_adf_2nd2:
2510 +       rsb     r8,r2,#32
2511 +       mov     r6,r6,lsr r2
2512 +       orr     r6,r6,r4,lsl r8
2513 +       mov     r4,r4,lsr r2    @ 2. op normalized
2514 +
2515 +CPDO_adf_add:
2516 +       adds    r5,r5,r6
2517 +       adcs    r3,r3,r4        @ do addition
2518 +       bcc     CPDO_adf_end
2519 +
2520 +       add     r7,r7,#1
2521 +       movs    r3,r3,rrx
2522 +       mov     r5,r5,rrx       @ correct for overflow
2523 +
2524 +CPDO_adf_end:
2525 +       cmp     r7,#0x20000000
2526 +       bge     CPDO_inf
2527 +
2528 +       stmia   r0,{r1,r3,r5,r7}
2529 +       b       fastfpe_next
2530 +
2531 +CPDO_adf_extra:
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
2536 +       cmp     r3,#0
2537 +       cmpeq   r4,#0
2538 +       bne     CPDO_nan_12
2539 +       b       CPDO_inf
2540 +
2541 +/*---------------------------------------------------------------------------*/
2542 +
2543 +CPDO_infnan_1:
2544 +       stmia   r0,{r1,r3,r5,r7}
2545 +       b       fastfpe_next
2546 +
2547 +CPDO_infnan_2:
2548 +       stmia   r0,{r2,r4,r6,r8}
2549 +       b       fastfpe_next
2550 +       
2551 +CPDO_nan_12:
2552 +       orr     r2,r3,r4
2553 +       b       CPDO_inf_1
2554 +
2555 +CPDO_nan:
2556 +       mov     r2,#0x40000000          @ create non signalling NaN
2557 +       b       CPDO_inf_1
2558 +
2559 +CPDO_inf:
2560 +       mov     r2,#0
2561 +CPDO_inf_1:
2562 +       mov     r3,#0
2563 +       mov     r4,#0x7fffffff
2564 +CPDO_store_1234:
2565 +       stmia   r0,{r1,r2,r3,r4}
2566 +       b       fastfpe_next
2567 +
2568 +CPDO_zero:
2569 +       mov     r1,#0
2570 +CPDO_zero_1:
2571 +       mov     r2,#0
2572 +       mov     r3,#0
2573 +       mov     r4,#0x80000000
2574 +       stmia   r0,{r1,r2,r3,r4}
2575 +       b       fastfpe_next
2576 +
2577 +/*---------------------------------------------------------------------------*/
2578 +
2579 +       .globl  CPDO_suf
2580 +CPDO_suf:
2581 +       ldmia   r1,{r1,r3,r5,r7}
2582 +       ldmia   r2,{r2,r4,r6,r8}
2583 +
2584 +CPDO_suf_l:
2585 +       cmp     r7,#0x7fffffff
2586 +       cmpne   r8,#0x7fffffff
2587 +       beq     CPDO_suf_extra
2588 +
2589 +       cmp     r1,r2
2590 +       bne     CPDO_adf_s
2591 +
2592 +CPDO_suf_s:
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
2597 +       cmpeq   r5,r6
2598 +       bhi     CPDO_suf_2nd            @ first number is greater
2599 +       beq     CPDO_zero
2600 +
2601 +CPDO_suf_1st:
2602 +       eor     r1,r1,#0x80000000       @ second number is greater, invert sign
2603 +       mov     r7,r8
2604 +       rsb     r2,r2,#0
2605 +       cmp     r2,#32
2606 +       ble     CPDO_suf_1st2
2607 +
2608 +       sub     r2,r2,#32
2609 +       cmp     r2,#32
2610 +       movgt   r2,#32
2611 +       mov     r5,r3,lsr r2
2612 +       mov     r3,#0
2613 +       b       CPDO_suf_1st_sub
2614 +
2615 +CPDO_suf_1st2:
2616 +       rsb     r8,r2,#32
2617 +       mov     r5,r5,lsr r2
2618 +       orr     r5,r5,r3,lsl r8
2619 +       mov     r3,r3,lsr r2    @ 1. op normalized
2620 +
2621 +CPDO_suf_1st_sub:
2622 +       subs    r5,r6,r5        @ do subtraction
2623 +       sbc     r3,r4,r3
2624 +       b       CPDO_suf_norm
2625 +
2626 +CPDO_suf_2nd:
2627 +       cmp     r2,#32
2628 +       ble     CPDO_suf_2nd2
2629 +
2630 +       sub     r2,r2,#32
2631 +       cmp     r2,#32
2632 +       movgt   r2,#32
2633 +       mov     r6,r4,lsr r2
2634 +       mov     r4,#0
2635 +       b       CPDO_suf_2nd_sub
2636 +
2637 +CPDO_suf_2nd2:
2638 +       rsb     r8,r2,#32
2639 +       mov     r6,r6,lsr r2
2640 +       orr     r6,r6,r4,lsl r8
2641 +       mov     r4,r4,lsr r2    @ 2. op normalized
2642 +
2643 +CPDO_suf_2nd_sub:
2644 +       subs    r5,r5,r6
2645 +       sbc     r3,r3,r4        @ do subtraction
2646 +
2647 +CPDO_suf_norm:
2648 +       teq     r3,#0           @ normalize 32bit
2649 +       moveq   r3,r5
2650 +       moveq   r5,#0
2651 +       subeq   r7,r7,#32
2652 +       
2653 +       cmp     r3,#0x00010000  @ 16bit
2654 +       movcc   r3,r3,lsl#16
2655 +       orrcc   r3,r3,r5,lsr#16
2656 +       movcc   r5,r5,lsl#16
2657 +       subcc   r7,r7,#16
2658 +       
2659 +       cmp     r3,#0x01000000  @ 8bit
2660 +       movcc   r3,r3,lsl#8
2661 +       orrcc   r3,r3,r5,lsr#24
2662 +       movcc   r5,r5,lsl#8
2663 +       subcc   r7,r7,#8
2664 +       
2665 +       cmp     r3,#0x10000000  @ 4bit
2666 +       movcc   r3,r3,lsl#4
2667 +       orrcc   r3,r3,r5,lsr#28
2668 +       movcc   r5,r5,lsl#4
2669 +       subcc   r7,r7,#4
2670 +       
2671 +       cmp     r3,#0x40000000  @ 2bit
2672 +       movcc   r3,r3,lsl#2
2673 +       orrcc   r3,r3,r5,lsr#30
2674 +       movcc   r5,r5,lsl#2
2675 +       subcc   r7,r7,#2
2676 +       
2677 +       cmp     r3,#0x80000000  @ 1bit
2678 +       movcc   r3,r3,lsl#1
2679 +       orrcc   r3,r3,r5,lsr#31
2680 +       movcc   r5,r5,lsl#1
2681 +       subcc   r7,r7,#1
2682 +
2683 +       cmp     r7,#0xe0000000
2684 +       ble     CPDO_zero_1
2685 +
2686 +       stmia   r0,{r1,r3,r5,r7}
2687 +       b       fastfpe_next
2688 +
2689 +CPDO_suf_extra:
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
2695 +       cmp     r3,#0
2696 +       cmpeq   r4,#0
2697 +       bne     CPDO_nan_12
2698 +       b       CPDO_nan                @ here is difference with adf !
2699 +
2700 +/*---------------------------------------------------------------------------*/
2701 +
2702 +       .globl CPDO_rsf
2703 +CPDO_rsf:
2704 +       mov     r3,r2
2705 +       ldmia   r1,{r2,r4,r6,r8}
2706 +       ldmia   r3,{r1,r3,r5,r7}
2707 +       b       CPDO_suf_l
2708 +       
2709 +/*---------------------------------------------------------------------------*/
2710 +
2711 +       .globl  CPDO_muf
2712 +CPDO_muf:
2713 +       ldmia   r1,{r1,r3,r5,r7}
2714 +       ldmia   r2,{r2,r4,r6,r8}
2715 +
2716 +       cmp     r7,#0x7fffffff
2717 +       cmpne   r8,#0x7fffffff
2718 +       beq     CPDO_muf_extra
2719 +       
2720 +       eor     r1,r1,r2
2721 +       adds    r8,r7,r8
2722 +       bvs     CPDO_zero_1
2723 +
2724 +       umull   r7,r2,r3,r4
2725 +       umull   r14,r3,r6,r3
2726 +       adds    r7,r7,r3        @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14
2727 +       adc     r2,r2,#0
2728 +       umull   r4,r3,r5,r4
2729 +       adds    r14,r14,r4      @ r2|r7|r14 += #0|r3|r4
2730 +       adcs    r7,r7,r3
2731 +       adc     r2,r2,#0
2732 +       umull   r4,r3,r5,r6
2733 +       adds    r14,r14,r3      @ r2|r7|r14 += #0|#0|r3
2734 +       adcs    r7,r7,#0
2735 +       adcs    r2,r2,#0
2736 +
2737 +       bpl     CPDO_muf_norm
2738 +       
2739 +       add     r8,r8,#1
2740 +       b       CPDO_muf_end
2741 +       
2742 +CPDO_muf_norm:
2743 +       adds    r14,r14,r14
2744 +       adcs    r7,r7,r7
2745 +       adcs    r2,r2,r2
2746 +
2747 +CPDO_muf_end:
2748 +       cmp     r8,#0x20000000
2749 +       bge     CPDO_inf
2750 +       cmp     r8,#0xe0000000
2751 +       ble     CPDO_zero_1
2752 +       stmia   r0,{r1,r2,r7,r8}
2753 +       b       fastfpe_next
2754 +
2755 +CPDO_muf_extra:
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
2762 +       b       CPDO_infnan_1
2763 +
2764 +CPDO_muf_extra_1st:
2765 +       cmp     r3,#0                   @ is it a nan?
2766 +       bne     CPDO_infnan_1
2767 +       cmp     r8,#0x80000000          @ is the second 0?
2768 +       beq     CPDO_nan
2769 +       eor     r1,r1,r2                @ correct sign for inf
2770 +       b       CPDO_inf
2771 +
2772 +CPDO_muf_extra_2nd:
2773 +       cmp     r4,#0                   @ is it a nan?
2774 +       bne     CPDO_infnan_2
2775 +       cmp     r7,#0x80000000          @ is the first 0?
2776 +       beq     CPDO_nan
2777 +       eor     r1,r1,r2                @ correct sign for inf
2778 +       b       CPDO_inf
2779 +
2780 +/*---------------------------------------------------------------------------*/
2781 +
2782 +       .globl  CPDO_dvf
2783 +CPDO_dvf:
2784 +       ldmia   r1,{r1,r3,r5,r7}
2785 +       ldmia   r2,{r2,r4,r6,r8}
2786 +
2787 +CPDO_dvf_l:
2788 +       cmp     r7,#0x7fffffff
2789 +       cmpne   r8,#0x7fffffff
2790 +       beq     CPDO_dvf_extra
2791 +       cmp     r8,#0x80000000
2792 +       beq     CPDO_dvf_by0
2793 +
2794 +       eor     r1,r1,r2
2795 +       cmp     r7,#0x80000000
2796 +       beq     CPDO_zero_1
2797 +       
2798 +       sub     r8,r7,r8
2799 +       
2800 +       mov     r2,#0
2801 +       mov     r7,#1
2802 +
2803 +       cmp     r3,r4
2804 +       cmpeq   r5,r6
2805 +       bcs     CPDO_dvf_loop_
2806 +
2807 +       sub     r8,r8,#1
2808 +
2809 +CPDO_dvf_loop:
2810 +       adds    r5,r5,r5
2811 +       adcs    r3,r3,r3
2812 +       bcs     CPDO_dvf_anyway
2813 +CPDO_dvf_loop_:
2814 +       subs    r5,r5,r6
2815 +       sbcs    r3,r3,r4
2816 +       bcs     CPDO_dvf_okay
2817 +
2818 +       adds    r5,r5,r6
2819 +       adc     r3,r3,r4
2820 +       adds    r7,r7,r7
2821 +       adcs    r2,r2,r2
2822 +       bcc     CPDO_dvf_loop
2823 +       b       CPDO_dvf_end
2824 +
2825 +CPDO_dvf_anyway:
2826 +       adcs    r7,r7,r7
2827 +       adcs    r2,r2,r2
2828 +       bcs     CPDO_dvf_end
2829 +       subs    r5,r5,r6
2830 +       sbc     r3,r3,r4
2831 +       b       CPDO_dvf_loop
2832 +
2833 +CPDO_dvf_okay:
2834 +       adcs    r7,r7,r7
2835 +       adcs    r2,r2,r2
2836 +       bcc     CPDO_dvf_loop
2837 +
2838 +CPDO_dvf_end:
2839 +       b       CPDO_muf_end
2840 +
2841 +CPDO_dvf_by0:
2842 +       cmp     R7,#0x80000000
2843 +       beq     CPDO_nan                @ first also 0 -> nan
2844 +       eor     r1,r1,r2                @ otherwise calculatesign for inf
2845 +       b       CPDO_inf
2846 +
2847 +CPDO_dvf_extra:
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
2852 +       orrs    r3,r3,r4
2853 +       beq     CPDO_nan                @ if both inf -> create nan
2854 +       b       CPDO_nan_12             @ otherwise keep nan
2855 +
2856 +CPDO_dvf_extra_1st:
2857 +       eor     r1,r1,r2                @ correct sign for inf
2858 +       b       CPDO_infnan_1
2859 +
2860 +CPDO_dvf_extra_2nd:
2861 +       cmp     r4,#0                   @ is it a nan?
2862 +       bne     CPDO_infnan_2
2863 +       eor     r1,r1,r2                @ correct sign for zero
2864 +       b       CPDO_zero_1
2865 +
2866 +/*---------------------------------------------------------------------------*/
2867 +
2868 +       .globl  CPDO_rdf
2869 +CPDO_rdf:
2870 +       mov     r3,r2
2871 +       ldmia   r1,{r2,r4,r6,r8}
2872 +       ldmia   r3,{r1,r3,r5,r7}
2873 +       b       CPDO_dvf_l
2874 +
2875 +/*---------------------------------------------------------------------------*/
2876 +
2877 +       .globl  CPDO_rmf
2878 +CPDO_rmf:
2879 +       b       fastfpe_next
2880 +       
2881 +/*---------------------------------------------------------------------------*/
2882 +
2883 +
2884 +
2885 +/*---------------------------------------------------------------------------*/
2886 +
2887 +       .globl  CPDO_mvf
2888 +CPDO_mvf:
2889 +       ldmia   r2,{r1,r2,r3,r4}
2890 +       stmia   r0,{r1,r2,r3,r4}
2891 +       b       fastfpe_next
2892 +
2893 +/*---------------------------------------------------------------------------*/
2894 +
2895 +       .globl  CPDO_mnf
2896 +CPDO_mnf:
2897 +       ldmia   r2,{r1,r2,r3,r4}
2898 +       eor     r1,r1,#0x80000000
2899 +       stmia   r0,{r1,r2,r3,r4}
2900 +       b       fastfpe_next
2901 +
2902 +/*---------------------------------------------------------------------------*/
2903 +
2904 +       .globl  CPDO_abs
2905 +CPDO_abs:
2906 +       ldmia   r2,{r1,r2,r3,r4}
2907 +       bic     r1,r1,#0x80000000
2908 +       stmia   r0,{r1,r2,r3,r4}
2909 +       b       fastfpe_next
2910 +
2911 +/*---------------------------------------------------------------------------*/
2912 +       
2913 +       .globl  CPDO_sqt
2914 +CPDO_sqt:
2915 +       ldmia   r2,{r1,r2,r3,r4}
2916 +       cmp     r1,#0
2917 +       bne     CPDO_nan
2918 +       cmp     r4,#0x7fffffff
2919 +       beq     CPDO_store_1234
2920 +
2921 +       tst     r4,r4,lsr#1             @carry=exponent bit 0
2922 +       bcc     CPDO_sqt_exponenteven
2923 +       adds    r3,r3,r3
2924 +       adcs    r2,r2,r2                @carry is needed in loop!
2925 +CPDO_sqt_exponenteven:
2926 +       mov     r4,r4,asr #1
2927 +       str     r4,[r0,#12]
2928 +
2929 +       mov     r4,#0x80000000
2930 +       mov     r5,#0
2931 +       sub     r2,r2,#0x80000000
2932 +
2933 +       mov     r8,#0x40000000
2934 +       mov     r14,#0x80000000
2935 +
2936 +       mov     r1,#1
2937 +       b       CPDO_sqt_loop1_first
2938 +CPDO_sqt_loop1:
2939 +       adds    r3,r3,r3
2940 +       adcs    r2,r2,r2
2941 +CPDO_sqt_loop1_first:
2942 +       add     r6,r4,r8,lsr r1         @r7 const = r5
2943 +       bcs     CPDO_sqt_loop1_1
2944 +       cmp     r2,r6
2945 +       cmpeq   r3,r5                   @r5 for r7
2946 +       bcc     CPDO_sqt_loop1_0
2947 +CPDO_sqt_loop1_1:
2948 +       orr     r4,r4,r14,lsr r1
2949 +       subs    r3,r3,r5                @r5 for r7
2950 +       sbc     r2,r2,r6
2951 +CPDO_sqt_loop1_0:
2952 +       add     r1,r1,#1
2953 +       cmp     r1,#30
2954 +       ble     CPDO_sqt_loop1
2955 +
2956 +       adds    r3,r3,r3
2957 +       adcs    r2,r2,r2
2958 +       bcs     CPDO_sqt_between_1
2959 +       adds    r7,r5,#0x80000000
2960 +       adc     r6,r4,#0
2961 +       cmp     r2,r6
2962 +       cmpeq   r3,r7
2963 +       bcc     CPDO_sqt_between_0
2964 +CPDO_sqt_between_1:
2965 +       orr     r4,r4,#0x00000001
2966 +       subs    r3,r3,r5
2967 +       sbc     r2,r2,r4
2968 +       subs    r3,r3,#0x80000000
2969 +       sbc     r2,r2,#0
2970 +CPDO_sqt_between_0:
2971 +       mov     r1,#0
2972 +
2973 +CPDO_sqt_loop2:
2974 +       adds    r3,r3,r3
2975 +       adcs    r2,r2,r2
2976 +       bcs     CPDO_sqt_loop2_1
2977 +       adds    r7,r5,r8,lsr r1
2978 +       adc     r6,r4,#0
2979 +       cmp     r2,r6
2980 +       cmpeq   r3,r7
2981 +       bcc     CPDO_sqt_loop2_0
2982 +CPDO_sqt_loop2_1:
2983 +       orr     r5,r5,r14,lsr r1
2984 +       subs    r3,r3,r5
2985 +       sbc     r2,r2,r4
2986 +       subs    r3,r3,r8,lsr r1
2987 +       sbc     r2,r2,#0
2988 +CPDO_sqt_loop2_0:
2989 +       add     r1,r1,#1
2990 +       cmp     r1,#30
2991 +       ble     CPDO_sqt_loop2
2992 +
2993 +       adds    r3,r3,r3
2994 +       adcs    r2,r2,r2
2995 +       bcs     CPDO_sqt_after_1
2996 +       cmp     r2,r6
2997 +       cmpeq   r3,r7
2998 +       bcc     CPDO_sqt_after_0
2999 +CPDO_sqt_after_1:
3000 +       orr     r5,r5,#0x00000001
3001 +CPDO_sqt_after_0:
3002 +
3003 +       mov     r1,#0
3004 +       stmia   r0,{r1,r4,r5}
3005 +       b       fastfpe_next
3006 +
3007 +/*---------------------------------------------------------------------------*/
3008 +       
3009 +       .globl  CPDO_rnd
3010 +CPDO_rnd:
3011 +       ldmia   r2,{r1,r2,r3,r5}
3012 +        bl      CPDO_rnd_core
3013 +
3014 +CPDO_rnd_store:
3015 +       stmia   r0,{r1,r2,r3,r5}
3016 +       b       fastfpe_next
3017 +       
3018 +/*---------------------------------------------------------------------------*/
3019 +
3020 +       .globl  CPDO_rnd_core
3021 +CPDO_rnd_core:
3022 +       and     r4,r4,#0x00000060
3023 +       add     pc,pc,r4,lsr#3
3024 +       mov     r0,r0
3025 +       b       CPDO_rnd_N
3026 +       b       CPDO_rnd_P
3027 +       b       CPDO_rnd_M
3028 +       b       CPDO_rnd_Z
3029 +       
3030 +CPDO_rnd_N:
3031 +       cmp     r5,#-1
3032 +       blt     CPDO_rnd_zero
3033 +       cmp     r5,#63
3034 +       movge   pc,r14
3035 +       mov     r4,#0x40000000
3036 +       cmp     r5,#31
3037 +       bge     CPDO_rnd_N_2
3038 +
3039 +       adds    r2,r2,r4,lsr r5
3040 +       bcc     CPDO_rnd_end
3041 +       b       CPDO_rnd_end_norm
3042 +
3043 +CPDO_rnd_N_2:
3044 +CPDO_rnd_P_2:
3045 +       sub     r6,r5,#32
3046 +       adds    r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly
3047 +       adcs    r2,r2,#0
3048 +       bcc     CPDO_rnd_end
3049 +       b       CPDO_rnd_end_norm
3050 +
3051 +CPDO_rnd_P:
3052 +       tst     r1,#0x80000000
3053 +       bne     CPDO_rnd_M_entry
3054 +CPDO_rnd_P_entry:
3055 +       cmp     r5,#0
3056 +       blt     CPDO_rnd_P_small
3057 +       cmp     r5,#63
3058 +       movge   pc,r14
3059 +       mov     r4,#0x7fffffff
3060 +       cmp     r5,#32
3061 +       bge     CPDO_rnd_P_2
3062 +
3063 +       adds    r3,r3,#0xffffffff
3064 +       adcs    r2,r2,r4,lsr r5
3065 +       bcc     CPDO_rnd_end
3066 +       b       CPDO_rnd_end_norm
3067 +
3068 +CPDO_rnd_P_small:
3069 +       cmp     r5,#0x80000000
3070 +       moveq   pc,r14
3071 +       b       CPDO_rnd_one
3072 +
3073 +CPDO_rnd_M:
3074 +       tst     r1,#0x80000000
3075 +       bne     CPDO_rnd_P_entry
3076 +CPDO_rnd_M_entry:
3077 +       cmp     r5,#0
3078 +       blt     CPDO_rnd_zero
3079 +       cmp     r5,#63
3080 +       movge   pc,r14
3081 +
3082 +       b       CPDO_rnd_end
3083 +       
3084 +CPDO_rnd_Z:
3085 +       cmp     r5,#0
3086 +       blt     CPDO_rnd_zero
3087 +       cmp     r5,#63
3088 +       movge   pc,r14
3089 +       b       CPDO_rnd_end
3090 +
3091 +CPDO_rnd_end_norm:
3092 +       add     r5,r5,#1
3093 +       movs    r2,r2,rrx
3094 +       mov     r3,r3,rrx
3095 +CPDO_rnd_end:
3096 +       rsbs    r4,r5,#31
3097 +       bmi     CPDO_rnd_end_2
3098 +       mov     r3,#0
3099 +       mov     r2,r2,lsr r4
3100 +       mov     r2,r2,lsl r4
3101 +       mov     pc,r14
3102 +
3103 +CPDO_rnd_end_2:
3104 +       rsb     r4,r5,#63
3105 +       mov     r3,r3,lsr r4
3106 +       mov     r3,r3,lsl r4
3107 +       mov     pc,r14
3108 +
3109 +CPDO_rnd_one:
3110 +       mov     r2,#0x80000000
3111 +       mov     r3,#0
3112 +       mov     r5,#0
3113 +       mov     pc,r14
3114 +       
3115 +CPDO_rnd_zero:
3116 +       mov     r1,#0
3117 +       mov     r2,#0
3118 +       mov     r3,#0
3119 +       mov     r5,#0x80000000
3120 +       mov     pc,r14
3121 +
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
3125 @@ -0,0 +1,185 @@
3126 +/*
3127 +The FP structure has 4 words reserved for each register, the first is used
3128 +just
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.
3132 +
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.
3135 +
3136 +If the exponent is 0x7fffffff, that is the biggest positive value, the
3137 +number
3138 +represented is infinity if the high 32 mantissa bit are also 0, otherwise it
3139 +is
3140 +a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
3141 +
3142 +Decimal and packed decimal numbers are not supported yet.
3143 +*/
3144 +
3145 +/*---------------------------------------------------------------------------*/
3146 +
3147 +       .text
3148 +       .globl  CPRT_flt
3149 +CPRT_flt:
3150 +       add     r0,r13,r0,lsr#10
3151 +       ldr     r2,[r0]
3152 +       mov     r3,#0
3153 +       cmp     r2,#0
3154 +       beq     CPRT_flt_zero
3155 +       
3156 +       ands    r0,r2,#0x80000000
3157 +       rsbne   r2,r2,#0
3158 +       mov     r4,#31
3159 +       
3160 +       cmp     r2,#0x00010000
3161 +       movcc   r2,r2,lsl#16
3162 +       subcc   r4,r4,#16
3163 +       
3164 +       cmp     r2,#0x01000000
3165 +       movcc   r2,r2,lsl#8
3166 +       subcc   r4,r4,#8
3167 +       
3168 +       cmp     r2,#0x10000000
3169 +       movcc   r2,r2,lsl#4
3170 +       subcc   r4,r4,#4
3171 +       
3172 +       cmp     r2,#0x40000000
3173 +       movcc   r2,r2,lsl#2
3174 +       subcc   r4,r4,#2
3175 +       
3176 +       cmp     r2,#0x80000000
3177 +       movcc   r2,r2,lsl#1
3178 +       subcc   r4,r4,#1
3179 +
3180 +       stmia   r1,{r0,r2,r3,r4}
3181 +       b       fastfpe_next
3182 +
3183 +CPRT_flt_zero:
3184 +       mov     r0,#0
3185 +       mov     r4,#0x80000000
3186 +       stmia   r1,{r0,r2,r3,r4}
3187 +       b       fastfpe_next
3188 +       
3189 +/*---------------------------------------------------------------------------*/
3190 +
3191 +       .globl  CPRT_fix
3192 +CPRT_fix:
3193 +       ldmia   r2,{r1,r2,r3,r5}
3194 +       bl      CPDO_rnd_core
3195 +       
3196 +CPRT_back:
3197 +       add     r0,r13,r0,lsr#10
3198 +       cmp     r5,#0
3199 +       blt     CPRT_int_zero
3200 +       cmp     r5,#30
3201 +       bgt     CPRT_overflow
3202 +       
3203 +       rsb     r5,r5,#31
3204 +       mov     r2,r2,lsr r5
3205 +       tst     r1,#0x80000000
3206 +       rsbne   r2,r2,#0
3207 +       
3208 +       str     r2,[r0]
3209 +       b       fastfpe_next
3210 +
3211 +CPRT_int_zero:
3212 +       mov     r2,#0
3213 +       str     r2,[r0]
3214 +       b       fastfpe_next
3215 +
3216 +CPRT_overflow:
3217 +       mov     r2,#0x80000000
3218 +       tst     r1,#0x80000000
3219 +       subeq   r2,r2,#1
3220 +       str     r2,[r0]
3221 +       b       fastfpe_next
3222 +
3223 +/*---------------------------------------------------------------------------*/
3224 +
3225 +       .globl  CPRT_wfs
3226 +CPRT_wfs:
3227 +       b       fastfpe_next
3228 +
3229 +/*---------------------------------------------------------------------------*/
3230 +
3231 +       .globl  CPRT_rfs
3232 +CPRT_rfs:
3233 +       add     r0,r13,r0,lsr#10
3234 +       mov     r1,#0x02000000          @ Software Emulation, not Acorn FPE
3235 +       str     r1,[r0]
3236 +       b       fastfpe_next
3237 +
3238 +/*---------------------------------------------------------------------------*/
3239 +
3240 +       .globl  CPRT_cmf
3241 +CPRT_cmf:
3242 +       ldmia   r1,{r1,r3,r5,r7}
3243 +       ldmia   r2,{r2,r4,r6,r8}
3244 +
3245 +CPRT_cmf_e:
3246 +       ldr     r0,[r13,#16*4]
3247 +       
3248 +       cmp     r7,#0x7fffffff
3249 +       bic     r0,r0,#0xf0000000
3250 +
3251 +       cmpeq   r3,#0xffffffff
3252 +       beq     CPRT_cmf_unordered
3253 +       cmp     r8,#0x7fffffff
3254 +       cmpeq   r4,#0xffffffff
3255 +       beq     CPRT_cmf_unordered
3256 +
3257 +       cmp     r1,r2
3258 +       beq     CPRT_cmf_equalsign
3259 +       b       CPRT_cmf_sign
3260 +
3261 +CPRT_cmf_equalsign:
3262 +       cmp     r7,r8
3263 +       beq     CPRT_cmf_equalexponent
3264 +       bgt     CPRT_cmf_sign
3265 +       b       CPRT_cmf_signb  
3266 +
3267 +CPRT_cmf_equalexponent:
3268 +       cmp     r3,r4
3269 +       cmpeq   r5,r6
3270 +       beq     CPRT_cmf_equal
3271 +       bhi     CPRT_cmf_sign
3272 +       b       CPRT_cmf_signb
3273 +
3274 +CPRT_cmf_sign:
3275 +       cmp     r7,#0x80000000          @ (0.0 == -0.0)?
3276 +       cmpeq   r7,r8
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]
3282 +       b       fastfpe_next
3283 +
3284 +CPRT_cmf_signb:
3285 +       tst     r1,#0x80000000
3286 +       orrne   r0,r0,#0x20000000
3287 +       orreq   r0,r0,#0x80000000
3288 +       str     r0,[r13,#16*4] 
3289 +       b       fastfpe_next
3290 +
3291 +CPRT_cmf_equal:
3292 +       orr     r0,r0,#0x60000000
3293 +       str     r0,[r13,#16*4]
3294 +       b       fastfpe_next
3295 +
3296 +CPRT_cmf_unordered:
3297 +       orr     r0,r0,#0x10000000
3298 +        str     r0,[r13,#16*4]
3299 +        b       fastfpe_next
3300 +
3301 +/*---------------------------------------------------------------------------*/
3302 +
3303 +       .globl  CPRT_cnf
3304 +CPRT_cnf:
3305 +       ldmia   r1,{r1,r3,r5,r7}
3306 +       ldmia   r2,{r2,r4,r6,r8}
3307 +       eor     r2,r2,#0x80000000
3308 +       b       CPRT_cmf_e
3309 +
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
3313 @@ -0,0 +1,430 @@
3314 +/*
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.
3319 +
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.
3322 +
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.
3326 +
3327 +Decimal and packed decimal numbers are not supported yet.
3328 +*/
3329 +
3330 +/*---------------------------------------------------------------------------*/
3331 +
3332 +       .globl  CPDT_load_single
3333 +CPDT_load_single:
3334 +       ldr     r1,[r6]
3335 +       
3336 +       and     r2,r1,#0x80000000       @ r2 = sign
3337 +       
3338 +       mov     r5,r1,lsr#23
3339 +       bics    r5,r5,#0x100
3340 +       beq     CPDT_ls_e0              @ exponent = 0; zero/denormalized
3341 +       teq     r5,#255
3342 +       beq     CPDT_ls_e255            @ exponent = 255; infinity/NaN
3343 +
3344 +       sub     r5,r5,#127              @ r5 = exponent, remove normalized bias
3345 +
3346 +       mov     r3,r1,lsl#8
3347 +       orr     r3,r3,#0x80000000
3348 +       mov     r4,#0                   @ r3,r4 = mantissa
3349 +
3350 +       stmia   r0,{r2-r5}
3351 +       b       fastfpe_next
3352 +
3353 +CPDT_ls_e0:
3354 +       movs    r3,r1,lsl#9
3355 +       beq     CPDT_load_zero
3356 +
3357 +       mov     r5,#-127
3358 +
3359 +CPDT_ls_e0_norm:
3360 +       tst     r3,#0x80000000
3361 +       subeq   r5,r5,#1
3362 +       moveq   r3,r3,lsl#1
3363 +       beq     CPDT_ls_e0_norm
3364 +
3365 +       mov     r4,#0
3366 +       stmia   r0,{r2-r5}
3367 +       b       fastfpe_next
3368 +
3369 +CPDT_ls_e255:
3370 +       mov     r3,r1,lsl#9
3371 +       mov     r4,#0
3372 +       mov     r5,#0x7fffffff
3373 +       stmia   r0,{r2-r5}
3374 +       b       fastfpe_next
3375 +
3376 +CPDT_load_zero:
3377 +       mov     r3,#0
3378 +       mov     r4,#0
3379 +       mov     r5,#0x80000000
3380 +       stmia   r0,{r2-r5}
3381 +       b       fastfpe_next
3382 +
3383 +/*---------------------------------------------------------------------------*/
3384 +
3385 +       .globl  CPDT_load_double
3386 +CPDT_load_double:
3387 +       ldr     r1,[r6]
3388 +       ldr     r6,[r6,#4]
3389 +
3390 +       and     r2,r1,#0x80000000       @ r2 = sign
3391 +
3392 +       mov     r5,r1,lsr#20
3393 +       bics    r5,r5,#0x800
3394 +       beq     CPDT_ld_e0              @ exponent = 0; zero/denormalized
3395 +       add     r4,r5,#1
3396 +       teq     r4,#2048
3397 +       beq     CPDT_ld_e2047           @ exponent = 2047; infinity/NaN
3398 +
3399 +       add     r5,r5,#1
3400 +       sub     r5,r5,#1024             @ r5 = exponent, remove normalized bias
3401 +
3402 +       mov     r3,r1,lsl#11
3403 +       orr     r3,r3,#0x80000000
3404 +       orr     r3,r3,r6,lsr #21
3405 +       mov     r4,r6,lsl#11            @ r3,r4 = mantissa
3406 +
3407 +       stmia   r0,{r2-r5}
3408 +       b       fastfpe_next
3409 +
3410 +CPDT_ld_e0:
3411 +       mov     r3,r1,lsl#12
3412 +       orr     r3,r3,r6,lsr#20
3413 +       movs    r4,r6,lsl#12
3414 +       teqeq   r3,#0
3415 +       beq     CPDT_load_zero
3416 +       
3417 +       mov     r5,#1
3418 +       sub     r5,r5,#1024
3419 +
3420 +CPDT_ld_e0_norm:
3421 +       tst     r3,#0x80000000
3422 +       subeq   r5,r5,#1
3423 +       moveqs  r4,r4,lsl#1
3424 +       adceq   r3,r3,r3
3425 +       beq     CPDT_ld_e0_norm
3426 +
3427 +       stmia   r0,{r2-r5}
3428 +       b       fastfpe_next
3429 +
3430 +CPDT_ld_e2047:
3431 +       mov     r3,r1,lsl#12
3432 +       orr     r3,r3,r6,lsr#1
3433 +       bic     r6,r6,#0x80000000
3434 +       orr     r3,r3,r6                @ to get all fraction bits !
3435 +       mov     r4,#0
3436 +       mov     r5,#0x7fffffff
3437 +       stmia   r0,{r2-r5}
3438 +       b       fastfpe_next
3439 +
3440 +/*---------------------------------------------------------------------------*/
3441 +
3442 +       .globl  CPDT_load_extended
3443 +CPDT_load_extended:
3444 +       ldr     r1,[r6]
3445 +       ldr     r3,[r6,#4]
3446 +       ldr     r4,[r6,#8]
3447 +       
3448 +       and     r2,r1,#0x80000000
3449 +       bics    r5,r1,#0x80000000
3450 +       beq     CPDT_le_e0
3451 +       add     r1,r5,#1
3452 +       teq     r4,#32768
3453 +       beq     CPDT_le_e32767
3454 +
3455 +       add     r5,r5,#1
3456 +       sub     r5,r5,#16384
3457 +
3458 +       stmia   r0,{r2-r5}
3459 +       b       fastfpe_next
3460 +
3461 +CPDT_le_e0:
3462 +       teq     r3,#0
3463 +       teqeq   r4,#0
3464 +       beq     CPDT_load_zero
3465 +       
3466 +       mov     r5,#2
3467 +       sub     r5,r5,#16384
3468 +       b       CPDT_ld_e0_norm
3469 +
3470 +CPDT_le_e32767:
3471 +       mov     r3,r3,lsl#1
3472 +       orr     r3,r3,r4,lsr#1
3473 +       bic     r4,r4,#0x80000000
3474 +       orr     r3,r3,r4
3475 +       mov     r5,#0x7fffffff
3476 +       stmia   r0,{r2-r5}
3477 +       b       fastfpe_next
3478 +
3479 +/*---------------------------------------------------------------------------*/
3480 +
3481 +       .globl  CPDT_load_decimal
3482 +CPDT_load_decimal:
3483 +       
3484 +       b       fastfpe_next
3485 +
3486 +/*---------------------------------------------------------------------------*/
3487 +
3488 +       .globl  CPDT_store_single
3489 +CPDT_store_single:
3490 +       ldmia   r0,{r1-r4}
3491 +       
3492 +       cmp     r4,#-127
3493 +       ble     CPDT_ss_e0
3494 +       cmp     r4,#128
3495 +       bge     CPDT_ss_e255
3496 +
3497 +       adds    r2,r2,#1<<7             @ round to nearest
3498 +       bcs     CPDT_ss_rnd_ovfl        @ very very seldom taken
3499 +
3500 +CPDT_ss_store:
3501 +       add     r4,r4,#127
3502 +       orr     r1,r1,r4,lsl#23
3503 +       
3504 +       bic     r2,r2,#0x80000000
3505 +       orr     r1,r1,r2,lsr#8
3506 +
3507 +       str     r1,[r6]
3508 +       b       fastfpe_next
3509 +
3510 +CPDT_ss_rnd_ovfl:
3511 +       add     r4,r4,#1
3512 +       cmp     r4,#128
3513 +       bge     CPDT_ss_e255
3514 +
3515 +       mov     r2,#0x80000000
3516 +       mov     r3,#0
3517 +       b       CPDT_ss_store
3518 +
3519 +CPDT_ss_e0:
3520 +       cmp     r4,#-150
3521 +       ble     CPDT_ss_zero
3522 +
3523 +       add     r4,r4,#126
3524 +CPDT_ss_unnormalize:
3525 +       mov     r2,r2,lsr#1
3526 +       adds    r4,r4,#1
3527 +       bne     CPDT_ss_unnormalize
3528 +
3529 +       orr     r1,r1,r2,lsr#8
3530 +
3531 +CPDT_ss_zero:
3532 +       str     r1,[r6]
3533 +       b       fastfpe_next
3534 +
3535 +CPDT_ss_e255:
3536 +       cmp     r4,#0x7fffffff
3537 +       bne     CPDT_ss_inf
3538 +       cmp     r2,#0
3539 +       beq     CPDT_ss_inf
3540 +
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
3543 +
3544 +CPDT_ss_inf:
3545 +       orr     r1,r1,#0x7f000000
3546 +       orr     r1,r1,#0x00800000
3547 +       str     r1,[r6]
3548 +       b       fastfpe_next
3549 +
3550 +/*---------------------------------------------------------------------------*/
3551 +
3552 +       .globl  CPDT_store_double
3553 +CPDT_store_double:
3554 +       ldmia   r0,{r1-r4}
3555 +       
3556 +       cmp     r4,#1024                @ this check has to be first, or
3557 +       bge     CPDT_sd_e2047           @ overflow can occur on second !
3558 +       add     r0,r4,#3
3559 +       cmp     r0,#-1023+3             @ cmp with -1023
3560 +       ble     CPDT_sd_e0
3561 +
3562 +       adds    r3,r3,#1<<10            @ round to nearest
3563 +       adcs    r2,r2,#0
3564 +       bcs     CPDT_sd_rnd_ovfl        @ very very seldom taken
3565 +
3566 +CPDT_sd_store:
3567 +       sub     r4,r4,#1
3568 +       add     r4,r4,#1024
3569 +       orr     r1,r1,r4,lsl#20
3570 +       
3571 +       bic     r2,r2,#0x80000000
3572 +       orr     r1,r1,r2,lsr#11
3573 +
3574 +       mov     r2,r2,lsl#21
3575 +       orr     r2,r2,r3,lsr#11
3576 +
3577 +       stmia   r6,{r1,r2}
3578 +       b       fastfpe_next
3579 +
3580 +CPDT_sd_rnd_ovfl:
3581 +       add     r4,r4,#1
3582 +       cmp     r4,#1024
3583 +       bge     CPDT_sd_e2047
3584 +
3585 +       mov     r2,#0x80000000
3586 +       mov     r3,#0
3587 +       b       CPDT_sd_store
3588 +
3589 +CPDT_sd_e0:
3590 +       add     r0,r4,#1075-1024
3591 +       cmp     r0,#-1024
3592 +       ble     CPDT_sd_zero
3593 +
3594 +       add     r4,r4,#1024
3595 +       sub     r4,r4,#2
3596 +CPDT_sd_unnormalize:
3597 +       movs    r2,r2,lsr#1
3598 +       mov     r3,r3,rrx
3599 +       adds    r4,r4,#1
3600 +       bne     CPDT_sd_unnormalize
3601 +
3602 +       orr     r1,r1,r2,lsr#11
3603 +       mov     r2,r2,lsl#21
3604 +       orr     r2,r2,r3,lsr#11
3605 +
3606 +       stmia   r6,{r1,r2}
3607 +       b       fastfpe_next
3608 +
3609 +CPDT_sd_zero:
3610 +       mov     r2,#0
3611 +       stmia   r6,{r1,r2}
3612 +       b       fastfpe_next
3613 +
3614 +CPDT_sd_e2047:
3615 +       cmp     r4,#0x7fffffff
3616 +       bne     CPDT_sd_inf
3617 +       cmp     r2,#0
3618 +       beq     CPDT_sd_inf
3619 +
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
3622 +
3623 +CPDT_sd_inf:
3624 +       orr     r1,r1,#0x7f000000
3625 +       orr     r1,r1,#0x00f00000
3626 +       stmia   r6,{r1,r2}
3627 +       b       fastfpe_next
3628 +
3629 +/*---------------------------------------------------------------------------*/
3630 +
3631 +       .globl  CPDT_store_extended
3632 +CPDT_store_extended:
3633 +       ldmia   r0,{r1-r4}
3634 +       
3635 +       cmp     r4,#16384               @ this check has to be first, or
3636 +       bge     CPDT_se_e32767          @ overflow can occur with second !
3637 +       add     r0,r4,#63
3638 +       cmp     r0,#-16383+63
3639 +       ble     CPDT_se_e0
3640 +
3641 +       sub     r4,r4,#1
3642 +       add     r4,r4,#16384
3643 +       orr     r1,r1,r4
3644 +       
3645 +       stmia   r6,{r1-r3}
3646 +       b       fastfpe_next
3647 +
3648 +CPDT_se_e0:
3649 +       add     r0,r4,#16446-16384
3650 +       cmp     r0,#-16384
3651 +       ble     CPDT_se_zero
3652 +
3653 +       add     r4,r4,#16384
3654 +       sub     r4,r4,#2
3655 +CPDT_se_unnormalize:
3656 +       movs    r2,r2,lsr#1
3657 +       mov     r3,r3,rrx
3658 +       adds    r4,r4,#1
3659 +       bne     CPDT_se_unnormalize
3660 +
3661 +       stmia   r6,{r1-r3}
3662 +       b       fastfpe_next
3663 +       
3664 +CPDT_se_zero:
3665 +       mov     r2,#0
3666 +       mov     r3,#0
3667 +       stmia   r6,{r1-r3}
3668 +       b       fastfpe_next
3669 +
3670 +CPDT_se_e32767:
3671 +       cmp     r4,#0x7fffffff
3672 +       bne     CPDT_se_inf
3673 +       cmp     r2,#0
3674 +       beq     CPDT_se_inf
3675 +
3676 +       mov     r2,r2,lsl#1
3677 +       orr     r2,r2,#0x20000000
3678 +
3679 +CPDT_se_inf:
3680 +       orr     r1,r1,#0x00007f00
3681 +       orr     r1,r1,#0x000000ff
3682 +       stmia   r6,{r1-r3}
3683 +       b       fastfpe_next
3684 +
3685 +/*---------------------------------------------------------------------------*/
3686 +
3687 +       .globl  CPDT_store_decimal
3688 +CPDT_store_decimal:
3689 +
3690 +       b       fastfpe_next
3691 +
3692 +/*---------------------------------------------------------------------------*/
3693 +
3694 +       .globl  CPDT_sfm
3695 +CPDT_sfm:
3696 +       add     r2,r10,r0,lsr#8
3697 +       ldr     r4,[r2,#0]
3698 +       ldr     r3,[r2,#4]
3699 +       bic     r3,r3,#0x80000000
3700 +       orr     r3,r3,r4
3701 +       str     r3,[r6],#4
3702 +       ldr     r3,[r2,#8]
3703 +       str     r3,[r6],#4
3704 +       ldr     r3,[r2,#12]
3705 +       str     r3,[r6],#4
3706 +
3707 +       add     r0,r0,#1<<12
3708 +       and     r0,r0,#7<<12
3709 +       subs    r1,r1,#1
3710 +       bne     CPDT_sfm
3711 +       b       fastfpe_next
3712 +       
3713 +/*---------------------------------------------------------------------------*/
3714 +
3715 +       .globl  CPDT_lfm
3716 +CPDT_lfm:
3717 +       add     r2,r10,r0,lsr#8
3718 +       ldr     r4,[r6],#4
3719 +       and     r3,r4,#0x80000000
3720 +       str     r3,[r2,#0]
3721 +       ldr     r3,[r6],#4
3722 +       str     r3,[r2,#8]
3723 +       ldr     r3,[r6],#4
3724 +       str     r3,[r2,#12]
3725 +
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
3733 +
3734 +CPDT_lfm_storer4:
3735 +       str     r4,[r2,#4]
3736 +
3737 +       add     r0,r0,#1<<12
3738 +       and     r0,r0,#7<<12
3739 +       subs    r1,r1,#1
3740 +       bne     CPDT_lfm
3741 +       b       fastfpe_next
3742 +       
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
3746 @@ -0,0 +1,14 @@
3747 +#
3748 +# linux/arch/arm/fastfpe/Makefile
3749 +#
3750 +# Copyright (C) Peter Teichmann
3751 +#
3752 +
3753 +obj-y  :=
3754 +obj-m  :=
3755 +obj-n  :=
3756 +obj-   :=
3757 +
3758 +fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o
3759 +
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
3763 @@ -0,0 +1,482 @@
3764 +/*
3765 + *  linux/arch/arm/common/rtctime.c
3766 + *
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
3770 + *
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.
3774 + */
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>
3784 +
3785 +#include <asm/rtc.h>
3786 +#include <asm/semaphore.h>
3787 +
3788 +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
3789 +static struct fasync_struct *rtc_async_queue;
3790 +
3791 +/*
3792 + * rtc_lock protects rtc_irq_data
3793 + */
3794 +static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
3795 +static unsigned long rtc_irq_data;
3796 +
3797 +/*
3798 + * rtc_sem protects rtc_inuse and rtc_ops
3799 + */
3800 +static DECLARE_MUTEX(rtc_sem);
3801 +static unsigned long rtc_inuse;
3802 +static struct rtc_ops *rtc_ops;
3803 +
3804 +#define rtc_epoch 1900UL
3805 +
3806 +static const unsigned char days_in_month[] = {
3807 +       31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
3808 +};
3809 +
3810 +#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
3811 +#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
3812 +
3813 +static int month_days(unsigned int month, unsigned int year)
3814 +{
3815 +       return days_in_month[month] + (LEAP_YEAR(year) && month == 1);
3816 +}
3817 +
3818 +/*
3819 + * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
3820 + */
3821 +void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
3822 +{
3823 +       int days, month, year;
3824 +
3825 +       days = time / 86400;
3826 +       time -= days * 86400;
3827 +
3828 +       tm->tm_wday = (days + 4) % 7;
3829 +
3830 +       year = 1970 + days / 365;
3831 +       days -= (year - 1970) * 365
3832 +               + LEAPS_THRU_END_OF(year - 1)
3833 +               - LEAPS_THRU_END_OF(1970 - 1);
3834 +       if (days < 0) {
3835 +               year -= 1;
3836 +               days += 365 + LEAP_YEAR(year);
3837 +       }
3838 +       tm->tm_year = year - 1900;
3839 +       tm->tm_yday = days + 1;
3840 +
3841 +       for (month = 0; month < 11; month++) {
3842 +               int newdays;
3843 +
3844 +               newdays = days - month_days(month, year);
3845 +               if (newdays < 0)
3846 +                       break;
3847 +               days = newdays;
3848 +       }
3849 +       tm->tm_mon = month;
3850 +       tm->tm_mday = days + 1;
3851 +
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;
3856 +}
3857 +
3858 +/*
3859 + * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
3860 + */
3861 +int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
3862 +{
3863 +       unsigned int yrs = tm->tm_year + 1900;
3864 +
3865 +       *time = 0;
3866 +
3867 +       if (yrs < 1970 ||
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 ||
3873 +           tm->tm_sec >= 60)
3874 +               return -EINVAL;
3875 +
3876 +       *time = mktime(yrs, tm->tm_mon + 1, tm->tm_mday,
3877 +                      tm->tm_hour, tm->tm_min, tm->tm_sec);
3878 +
3879 +       return 0;
3880 +}
3881 +
3882 +/*
3883 + * Calculate the next alarm time given the requested alarm time mask
3884 + * and the current time.
3885 + *
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.)
3889 + */
3890 +void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
3891 +{
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;
3898 +}
3899 +
3900 +static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
3901 +{
3902 +       memset(tm, 0, sizeof(struct rtc_time));
3903 +       ops->read_time(tm);
3904 +}
3905 +
3906 +static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
3907 +{
3908 +       return ops->set_time(tm);
3909 +}
3910 +
3911 +static inline void rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
3912 +{
3913 +       memset(alrm, 0, sizeof(struct rtc_wkalrm));
3914 +       ops->read_alarm(alrm);
3915 +}
3916 +
3917 +static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
3918 +{
3919 +       return ops->set_alarm(alrm);
3920 +}
3921 +
3922 +void rtc_update(unsigned long num, unsigned long events)
3923 +{
3924 +       spin_lock(&rtc_lock);
3925 +       rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
3926 +       spin_unlock(&rtc_lock);
3927 +
3928 +       wake_up_interruptible(&rtc_wait);
3929 +       kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
3930 +}
3931 +
3932 +
3933 +static ssize_t
3934 +rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
3935 +{
3936 +       DECLARE_WAITQUEUE(wait, current);
3937 +       unsigned long data;
3938 +       ssize_t ret;
3939 +
3940 +       if (count < sizeof(unsigned long))
3941 +               return -EINVAL;
3942 +
3943 +       add_wait_queue(&rtc_wait, &wait);
3944 +       do {
3945 +               __set_current_state(TASK_INTERRUPTIBLE);
3946 +
3947 +               spin_lock_irq(&rtc_lock);
3948 +               data = rtc_irq_data;
3949 +               rtc_irq_data = 0;
3950 +               spin_unlock_irq(&rtc_lock);
3951 +
3952 +               if (data != 0) {
3953 +                       ret = 0;
3954 +                       break;
3955 +               }
3956 +               if (file->f_flags & O_NONBLOCK) {
3957 +                       ret = -EAGAIN;
3958 +                       break;
3959 +               }
3960 +               if (signal_pending(current)) {
3961 +                       ret = -ERESTARTSYS;
3962 +                       break;
3963 +               }
3964 +               schedule();
3965 +       } while (1);
3966 +       set_current_state(TASK_RUNNING);
3967 +       remove_wait_queue(&rtc_wait, &wait);
3968 +
3969 +       if (ret == 0) {
3970 +               ret = put_user(data, (unsigned long *)buf);
3971 +               if (ret == 0)
3972 +                       ret = sizeof(unsigned long);
3973 +       }
3974 +       return ret;
3975 +}
3976 +
3977 +static unsigned int rtc_poll(struct file *file, poll_table *wait)
3978 +{
3979 +       unsigned long data;
3980 +
3981 +       poll_wait(file, &rtc_wait, wait);
3982 +
3983 +       spin_lock_irq(&rtc_lock);
3984 +       data = rtc_irq_data;
3985 +       spin_unlock_irq(&rtc_lock);
3986 +
3987 +       return data != 0 ? POLLIN | POLLRDNORM : 0;
3988 +}
3989 +
3990 +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
3991 +                    unsigned long arg)
3992 +{
3993 +       struct rtc_ops *ops = file->private_data;
3994 +       struct rtc_time tm;
3995 +       struct rtc_wkalrm alrm;
3996 +       int ret;
3997 +
3998 +       switch (cmd) {
3999 +       case RTC_ALM_READ:
4000 +               rtc_read_alarm(ops, &alrm);
4001 +               ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm));
4002 +               if (ret)
4003 +                       ret = -EFAULT;
4004 +               break;
4005 +
4006 +       case RTC_ALM_SET:
4007 +               ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm));
4008 +               alrm.enabled = 0;
4009 +               alrm.pending = 0;
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;
4016 +               if (ret == 0)
4017 +                       ret = rtc_set_alarm(ops, &alrm);
4018 +               else
4019 +                       ret = -EFAULT;
4020 +               break;
4021 +
4022 +       case RTC_RD_TIME:
4023 +               rtc_read_time(ops, &tm);
4024 +               ret = copy_to_user((void *)arg, &tm, sizeof(tm));
4025 +               if (ret)
4026 +                       ret = -EFAULT;
4027 +               break;
4028 +
4029 +       case RTC_SET_TIME:
4030 +               if (!capable(CAP_SYS_TIME)) {
4031 +                       ret = -EACCES;
4032 +                       break;
4033 +               }
4034 +               ret = copy_from_user(&tm, (void *)arg, sizeof(tm));
4035 +               if (ret == 0)
4036 +                       ret = rtc_set_time(ops, &tm);
4037 +               else
4038 +                       ret = -EFAULT;
4039 +               break;
4040 +
4041 +#ifndef rtc_epoch
4042 +       case RTC_EPOCH_SET:
4043 +               /*
4044 +                * There were no RTC clocks before 1900.
4045 +                */
4046 +               if (arg < 1900) {
4047 +                       ret = -EINVAL;
4048 +                       break;
4049 +               }
4050 +               if (!capable(CAP_SYS_TIME)) {
4051 +                       ret = -EACCES;
4052 +                       break;
4053 +               }
4054 +               rtc_epoch = arg;
4055 +               ret = 0;
4056 +               break;
4057 +#endif
4058 +
4059 +       case RTC_EPOCH_READ:
4060 +               ret = put_user(rtc_epoch, (unsigned long *)arg);
4061 +               break;
4062 +
4063 +       case RTC_WKALM_SET:
4064 +               ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm));
4065 +               if (ret == 0)
4066 +                       ret = rtc_set_alarm(ops, &alrm);
4067 +               else
4068 +                       ret = -EFAULT;
4069 +               break;
4070 +
4071 +       case RTC_WKALM_RD:
4072 +               rtc_read_alarm(ops, &alrm);
4073 +               ret = copy_to_user((void *)arg, &alrm, sizeof(alrm));
4074 +               if (ret)
4075 +                       ret = -EFAULT;
4076 +               break;
4077 +
4078 +       default:
4079 +               ret = ops->ioctl(cmd, arg);
4080 +       }
4081 +       return ret;
4082 +}
4083 +
4084 +static int rtc_open(struct inode *inode, struct file *file)
4085 +{
4086 +       int ret;
4087 +
4088 +       down(&rtc_sem);
4089 +
4090 +       if (rtc_inuse) {
4091 +               ret = -EBUSY;
4092 +       } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
4093 +               ret = -ENODEV;
4094 +       } else {
4095 +               file->private_data = rtc_ops;
4096 +
4097 +               ret = rtc_ops->open ? rtc_ops->open() : 0;
4098 +               if (ret == 0) {
4099 +                       spin_lock_irq(&rtc_lock);
4100 +                       rtc_irq_data = 0;
4101 +                       spin_unlock_irq(&rtc_lock);
4102 +
4103 +                       rtc_inuse = 1;
4104 +               }
4105 +       }
4106 +       up(&rtc_sem);
4107 +
4108 +       return ret;
4109 +}
4110 +
4111 +static int rtc_release(struct inode *inode, struct file *file)
4112 +{
4113 +       struct rtc_ops *ops = file->private_data;
4114 +
4115 +       if (ops->release)
4116 +               ops->release();
4117 +
4118 +       spin_lock_irq(&rtc_lock);
4119 +       rtc_irq_data = 0;
4120 +       spin_unlock_irq(&rtc_lock);
4121 +
4122 +       module_put(rtc_ops->owner);
4123 +       rtc_inuse = 0;
4124 +
4125 +       return 0;
4126 +}
4127 +
4128 +static int rtc_fasync(int fd, struct file *file, int on)
4129 +{
4130 +       return fasync_helper(fd, file, on, &rtc_async_queue);
4131 +}
4132 +
4133 +static struct file_operations rtc_fops = {
4134 +       .owner          = THIS_MODULE,
4135 +       .llseek         = no_llseek,
4136 +       .read           = rtc_read,
4137 +       .poll           = rtc_poll,
4138 +       .ioctl          = rtc_ioctl,
4139 +       .open           = rtc_open,
4140 +       .release        = rtc_release,
4141 +       .fasync         = rtc_fasync,
4142 +};
4143 +
4144 +static struct miscdevice rtc_miscdev = {
4145 +       .minor          = RTC_MINOR,
4146 +       .name           = "rtc",
4147 +       .fops           = &rtc_fops,
4148 +};
4149 +
4150 +
4151 +static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
4152 +{
4153 +       struct rtc_ops *ops = data;
4154 +       struct rtc_wkalrm alrm;
4155 +       struct rtc_time tm;
4156 +       char *p = page;
4157 +       int len;
4158 +
4159 +       rtc_read_time(ops, &tm);
4160 +
4161 +       p += sprintf(p,
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,
4167 +               rtc_epoch);
4168 +
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);
4173 +       else
4174 +               p += sprintf(p, "**:");
4175 +       if ((unsigned int)alrm.time.tm_min <= 59)
4176 +               p += sprintf(p, "%02d:", alrm.time.tm_min);
4177 +       else
4178 +               p += sprintf(p, "**:");
4179 +       if ((unsigned int)alrm.time.tm_sec <= 59)
4180 +               p += sprintf(p, "%02d\n", alrm.time.tm_sec);
4181 +       else
4182 +               p += sprintf(p, "**\n");
4183 +
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);
4187 +       else
4188 +               p += sprintf(p, "****-");
4189 +       if ((unsigned int)alrm.time.tm_mon <= 11)
4190 +               p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
4191 +       else
4192 +               p += sprintf(p, "**-");
4193 +       if ((unsigned int)alrm.time.tm_mday <= 31)
4194 +               p += sprintf(p, "%02d\n", alrm.time.tm_mday);
4195 +       else
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");
4199 +
4200 +       if (ops->proc)
4201 +               p += ops->proc(p);
4202 +
4203 +       len = (p - page) - off;
4204 +       if (len < 0)
4205 +               len = 0;
4206 +       *eof = len <= count;
4207 +       *start = page + off;
4208 +
4209 +       return len;
4210 +}
4211 +
4212 +int register_rtc(struct rtc_ops *ops)
4213 +{
4214 +       int ret = -EBUSY;
4215 +
4216 +       down(&rtc_sem);
4217 +       if (rtc_ops == NULL) {
4218 +               rtc_ops = ops;
4219 +
4220 +               ret = misc_register(&rtc_miscdev);
4221 +               if (ret == 0)
4222 +                       create_proc_read_entry("driver/rtc", 0, 0,
4223 +                                              rtc_read_proc, ops);
4224 +       }
4225 +       up(&rtc_sem);
4226 +
4227 +       return ret;
4228 +}
4229 +
4230 +void unregister_rtc(struct rtc_ops *rtc)
4231 +{
4232 +       down(&rtc_sem);
4233 +       if (rtc == rtc_ops) {
4234 +               remove_proc_entry("driver/rtc", NULL);
4235 +               misc_deregister(&rtc_miscdev);
4236 +               rtc_ops = NULL;
4237 +       }
4238 +       up(&rtc_sem);
4239 +}
4240 +
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
4248 @@ -2,7 +2,7 @@
4249  # Makefile for the linux kernel.
4250  #
4251  
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
4259 @@ -132,7 +132,7 @@
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
4270 @@ -0,0 +1,322 @@
4271 +/*
4272 + *  linux/arch/arm/mach-pxa/cpu-pxa.c
4273 + *
4274 + *  Copyright (C) 2002,2003 Intrinsyc Software
4275 + *
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.
4280 + *
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.
4285 + * 
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
4289 + *
4290 + * History:
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.)
4294 + * 
4295 + * Note:
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.
4301 + *
4302 + */
4303 +
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>
4309 +
4310 +#include <asm/hardware.h>
4311 +
4312 +#define DEBUG  0
4313 +
4314 +#ifdef DEBUG
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");
4318 +#else
4319 +  #define freq_debug  0
4320 +#endif  
4321 +
4322 +typedef struct
4323 +{
4324 +    unsigned int khz;
4325 +    unsigned int membus;
4326 +    unsigned int cccr;
4327 +    unsigned int div2;
4328 +} pxa_freqs_t;
4329 +
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))
4334 +
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
4341 +
4342 +
4343 +/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
4344 +static pxa_freqs_t pxa255_run_freqs[] =
4345 +{
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 */
4353 +    {0,}
4354 +};
4355 +#define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t))
4356 +
4357 +static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
4358 +
4359 +/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
4360 +static pxa_freqs_t pxa255_turbo_freqs[] =
4361 +{
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 */
4368 +    {0,}
4369 +};
4370 +#define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t))
4371 +
4372 +static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
4373 +
4374 +/* find a valid frequency point */
4375 +static int pxa_verify_policy(struct cpufreq_policy *policy)
4376 +{
4377 +    int ret;
4378 +    struct cpufreq_frequency_table *pxa_freqs_table;
4379 +
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;
4386 +    } else {
4387 +        printk("CPU PXA: Unknown policy found. "
4388 +               "Using CPUFREQ_POLICY_PERFORMANCE\n");
4389 +        pxa_freqs_table = pxa255_run_freq_table;
4390 +    } 
4391 +       ret=cpufreq_frequency_table_verify(policy, pxa_freqs_table);
4392 +    
4393 +    if(freq_debug) {
4394 +        printk("Verified CPU policy: %dKhz min to %dKhz max\n",
4395 +            policy->min, policy->max);
4396 +    }
4397 +
4398 +    return ret;
4399 +}
4400 +
4401 +static int pxa_set_target(struct cpufreq_policy *policy,
4402 +                 unsigned int target_freq,
4403 +                 unsigned int relation)
4404 +{
4405 +    int idx;
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;
4414 +
4415 +    /*
4416 +     * Save this threads cpus_allowed mask.
4417 +     */
4418 +    cpus_allowed = current->cpus_allowed;
4419 +
4420 +    /*
4421 +     * Bind to the specified CPU.  When this call returns,
4422 +     * we should be running on the right CPU.
4423 +     */
4424 +    set_cpus_allowed(current, 1 << cpu);
4425 +    BUG_ON(cpu != smp_processor_id());
4426 +
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;
4437 +    }else {
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;
4442 +    } 
4443 +
4444 +    /* Lookup the next frequency */
4445 +       if (cpufreq_frequency_table_target(policy, pxa_freqs_table, 
4446 +                                          target_freq, relation, &idx)) {
4447 +               return -EINVAL;
4448 +    }
4449 +
4450 +    freqs.old = policy->cur;
4451 +    freqs.new = pxa_freq_settings[idx].khz;
4452 +    freqs.cpu = policy->cpu;  
4453 +    if(freq_debug) {
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));
4458 +    }
4459 +
4460 +    void *ramstart = phys_to_virt(0xa0000000);
4461 +
4462 +    /* 
4463 +     * Tell everyone what we're about to do... 
4464 +     * you should add a notify client with any platform specific 
4465 +     * Vcc changing capability
4466 +     */
4467 +    cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
4468 +
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.  
4472 +     */
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);
4477 +    }
4478 +    postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) | 
4479 +                    MDREFR_DRI(pxa_freq_settings[idx].membus);
4480 +    
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.
4484 +     */
4485 +    if(pxa_freq_settings[idx].div2) { 
4486 +        preset_mdrefr  |= MDREFR_DB2_MASK;
4487 +        postset_mdrefr |= MDREFR_DB2_MASK;
4488 +    } else { 
4489 +        postset_mdrefr &= ~MDREFR_DB2_MASK; 
4490 +    }
4491 +    
4492 +    local_irq_save(flags);
4493 +    
4494 +    /* Set new the CCCR */
4495 +    CCCR = pxa_freq_settings[idx].cccr;
4496 +
4497 +    __asm__ __volatile__("                                  \
4498 +        ldr r4, [%1] ;  /* load MDREFR */                   \
4499 +        b   2f ;                                            \
4500 +        .align  5 ;                                         \
4501 +1:                                                          \
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 */    \
4505 +                                                            \
4506 +        b   3f       ;                                      \
4507 +2:      b   1b       ;                                      \
4508 +3:      nop          ;                                      \
4509 +        "                                                                            
4510 +        : "=&r" (unused)                                                             
4511 +        : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), \
4512 +          "r" (preset_mdrefr), "r" (postset_mdrefr)             
4513 +        : "r4", "r5");
4514 +    local_irq_restore(flags);
4515 +
4516 +    /*
4517 +     * Restore the CPUs allowed mask.
4518 +     */
4519 +    set_cpus_allowed(current, cpus_allowed);
4520 +
4521 +    /* 
4522 +     * Tell everyone what we've just done... 
4523 +     * you should add a notify client with any platform specific 
4524 +     * SDRAM refresh timer adjustments
4525 +     */
4526 +    cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
4527 +
4528 +    return 0;
4529 +}
4530 +
4531 +static int pxa_cpufreq_init(struct cpufreq_policy *policy)
4532 +{
4533 +    unsigned long cpus_allowed;
4534 +    unsigned int cpu = policy->cpu;
4535 +    int i;
4536 +
4537 +       cpus_allowed = current->cpus_allowed;
4538 +
4539 +       set_cpus_allowed(current, 1 << cpu);
4540 +       BUG_ON(cpu != smp_processor_id());
4541 +
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;
4549 +
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;    
4554 +    }
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;    
4560 +    }
4561 +    pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
4562 +    
4563 +    set_cpus_allowed(current, cpus_allowed);
4564 +    printk(KERN_INFO "PXA CPU frequency change support initialized\n");
4565 +
4566 +    return 0;
4567 +}
4568 +
4569 +static struct cpufreq_driver pxa_cpufreq_driver = {
4570 +    .verify     = pxa_verify_policy,
4571 +    .target     = pxa_set_target,
4572 +    .init       = pxa_cpufreq_init,
4573 +    .name       = "PXA25x",
4574 +};
4575 +
4576 +static int __init pxa_cpu_init(void)
4577 +{
4578 +    return cpufreq_register_driver(&pxa_cpufreq_driver);
4579 +}
4580 +
4581 +static void __exit pxa_cpu_exit(void)
4582 +{
4583 +    cpufreq_unregister_driver(&pxa_cpufreq_driver);
4584 +}
4585 +
4586 +
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);
4592 +
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
4595 @@ -113,7 +113,7 @@
4596   * gzip delarations
4597   */
4598  #define OF(args)  args
4599 -#define STATIC static
4600 +#define STATIC
4601  
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 */
4607  
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 */
4612  
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 */
4619  
4620  /* gzip flag byte */
4621  #define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
4622 @@ -166,9 +166,9 @@
4623  extern char input_data[];
4624  extern char input_data_end[];
4625  
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;
4632  
4633  static void *malloc(int size);
4634  static void free(void *where);
4635 @@ -179,8 +179,8 @@
4636  static void puts(const char *);
4637  
4638  extern int end;
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;
4643  
4644  #define HEAP_SIZE 0x2000
4645  
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
4648 @@ -13,15 +13,18 @@
4649   * virtual space.  One should *only* use readl, writel, memcpy_toio and
4650   * so on with such remapped areas.
4651   *
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:
4660 + *
4661 + *  1. We need set_pte, or something like set_pte to understand large
4662 + *     page mappings.
4663 + *
4664 + *  2. we need the unmap_* functions to likewise understand large page
4665 + *     mappings.
4666   */
4667  #include <linux/errno.h>
4668  #include <linux/mm.h>
4669 +#include <linux/slab.h>
4670  #include <linux/vmalloc.h>
4671  
4672  #include <asm/page.h>
4673 @@ -29,31 +32,162 @@
4674  #include <asm/io.h>
4675  #include <asm/tlbflush.h>
4676  
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;
4681 +
4682 +static struct vm_struct *
4683 +get_io_vm_area(unsigned long size, unsigned long align, unsigned long flags)
4684  {
4685 +       struct vm_struct **p, *tmp, *area;
4686 +       unsigned long addr;
4687 +
4688 +       area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL);
4689 +       if (!area)
4690 +               return NULL;
4691 +
4692 +       align -= 1;
4693 +
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)
4699 +                       continue;
4700 +               if ((size + addr) < addr)
4701 +                       goto out;
4702 +               if (size + addr <= (unsigned long) tmp->addr)
4703 +                       break;
4704 +               addr = tmp->size + (unsigned long) tmp->addr;
4705 +               if ((addr + align) < addr)
4706 +                       goto out;
4707 +               addr = (addr + align) & ~align;
4708 +               if (addr > VMALLOC_END - size)
4709 +                       goto out;
4710 +       }
4711 +       area->flags = flags;
4712 +       area->addr = (void *)addr;
4713 +       area->size = size;
4714 +       area->next = *p;
4715 +       *p = area;
4716 +       write_unlock(&vmlist_lock);
4717 +       return area;
4718 +
4719 +out:
4720 +       write_unlock(&vmlist_lock);
4721 +       kfree(area);
4722 +       return NULL;
4723 +}
4724 +
4725 +static inline void unmap_area_pte(pmd_t *pmd, unsigned long address, unsigned long size)
4726 +{
4727 +       pte_t *ptep;
4728         unsigned long end;
4729  
4730 +       if (pmd_none(*pmd))
4731 +               return;
4732 +       if (pmd_bad(*pmd)) {
4733 +               pmd_ERROR(*pmd);
4734 +               pmd_clear(pmd);
4735 +               return;
4736 +       }
4737 +       ptep = pte_offset_kernel(pmd, address);
4738         address &= ~PMD_MASK;
4739         end = address + size;
4740         if (end > PMD_SIZE)
4741                 end = PMD_SIZE;
4742 -       if (address >= end)
4743 -               BUG();
4744         do {
4745 -               if (!pte_none(*pte)) {
4746 -                       printk("remap_area_pte: page already exists\n");
4747 -                       BUG();
4748 +               pte_t pte;
4749 +               pte = ptep_get_and_clear(ptep);
4750 +               address += PAGE_SIZE;
4751 +               ptep++;
4752 +               if (pte_none(pte))
4753 +                       continue;
4754 +               if (pte_present(pte)) {
4755 +                       unsigned long pfn = pte_pfn(pte);
4756 +                       struct page *page;
4757 +
4758 +                       if (!pfn_valid(pfn))
4759 +                               continue;
4760 +                       page = pfn_to_page(pfn);
4761 +                       if (!PageReserved(page))
4762 +                               __free_page(page);
4763 +                       continue;
4764                 }
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);
4768 +}
4769 +
4770 +static inline void unmap_area_pmd(pgd_t *dir, unsigned long address, unsigned long size)
4771 +{
4772 +       pmd_t *pmd;
4773 +       unsigned long end;
4774 +
4775 +       if (pgd_none(*dir))
4776 +               return;
4777 +       if (pgd_bad(*dir)) {
4778 +               pgd_ERROR(*dir);
4779 +               pgd_clear(dir);
4780 +               return;
4781 +       }
4782 +       pmd = pmd_offset(dir, address);
4783 +       address &= ~PGDIR_MASK;
4784 +       end = address + size;
4785 +       if (end > PGDIR_SIZE)
4786 +               end = PGDIR_SIZE;
4787 +       do {
4788 +               unmap_area_pte(pmd, address, end - address);
4789 +               address = (address + PMD_SIZE) & PMD_MASK;
4790 +               pmd++;
4791 +       } while (address < end);
4792 +}
4793 +
4794 +static void
4795 +unmap_area_pages(unsigned long address, unsigned long size)
4796 +{
4797 +       unsigned long start = address;
4798 +       unsigned long end = address + size;
4799 +       pgd_t *dir;
4800 +
4801 +       dir = pgd_offset_k(address);
4802 +       flush_cache_vunmap(start, end);
4803 +       do {
4804 +               unmap_area_pmd(dir, address, end - address);
4805 +               address = (address + PGDIR_SIZE) & PGDIR_MASK;
4806 +               dir++;
4807 +       } while (address && (address < end));
4808 +       flush_tlb_kernel_range(start, end);
4809 +}
4810 +
4811 +static inline void
4812 +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
4813 +              unsigned long pfn, pgprot_t pgprot)
4814 +{
4815 +       unsigned long end;
4816 +
4817 +       address &= ~PMD_MASK;
4818 +       end = address + size;
4819 +       if (end > PMD_SIZE)
4820 +               end = PMD_SIZE;
4821 +       BUG_ON(address >= end);
4822 +       do {
4823 +               if (!pte_none(*pte))
4824 +                       goto bad;
4825 +
4826 +               set_pte(pte, pfn_pte(pfn, pgprot));
4827                 address += PAGE_SIZE;
4828 -               phys_addr += PAGE_SIZE;
4829 +               pfn++;
4830                 pte++;
4831         } while (address && (address < end));
4832 +       return;
4833 +
4834 + bad:
4835 +       printk("remap_area_pte: page already exists\n");
4836 +       BUG();
4837  }
4838  
4839 -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
4840 -       unsigned long phys_addr, unsigned long flags)
4841 +static inline int
4842 +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
4843 +              unsigned long pfn, unsigned long flags)
4844  {
4845         unsigned long end;
4846         pgprot_t pgprot;
4847 @@ -64,51 +198,53 @@
4848         if (end > PGDIR_SIZE)
4849                 end = PGDIR_SIZE;
4850  
4851 -       phys_addr -= address;
4852 -       if (address >= end)
4853 -               BUG();
4854 +       pfn -= address >> PAGE_SHIFT;
4855 +       BUG_ON(address >= end);
4856  
4857         pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
4858         do {
4859                 pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
4860                 if (!pte)
4861                         return -ENOMEM;
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;
4865                 pmd++;
4866         } while (address && (address < end));
4867         return 0;
4868  }
4869  
4870 -static int remap_area_pages(unsigned long address, unsigned long phys_addr,
4871 -                                unsigned long size, unsigned long flags)
4872 +static int
4873 +remap_area_pages(unsigned long start, unsigned long pfn,
4874 +                unsigned long size, unsigned long flags)
4875  {
4876 -       int error;
4877 +       unsigned long address = start;
4878 +       unsigned long end = start + size;
4879 +       int err = 0;
4880         pgd_t * dir;
4881 -       unsigned long end = address + size;
4882  
4883 -       phys_addr -= address;
4884 +       pfn -= address >> PAGE_SHIFT;
4885         dir = pgd_offset(&init_mm, address);
4886 -       flush_cache_all();
4887 -       if (address >= end)
4888 -               BUG();
4889 +       BUG_ON(address >= end);
4890         spin_lock(&init_mm.page_table_lock);
4891         do {
4892 -               pmd_t *pmd;
4893 -               pmd = pmd_alloc(&init_mm, dir, address);
4894 -               error = -ENOMEM;
4895 -               if (!pmd)
4896 +               pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
4897 +               if (!pmd) {
4898 +                       err = -ENOMEM;
4899                         break;
4900 +               }
4901                 if (remap_area_pmd(pmd, address, end - address,
4902 -                                        phys_addr + address, flags))
4903 +                                  pfn + (address >> PAGE_SHIFT), flags)) {
4904 +                       err = -ENOMEM;
4905                         break;
4906 -               error = 0;
4907 +               }
4908 +
4909                 address = (address + PGDIR_SIZE) & PGDIR_MASK;
4910                 dir++;
4911         } while (address && (address < end));
4912 +
4913         spin_unlock(&init_mm.page_table_lock);
4914 -       flush_tlb_all();
4915 -       return error;
4916 +       flush_cache_vmap(start, end);
4917 +       return err;
4918  }
4919  
4920  /*
4921 @@ -146,11 +282,11 @@
4922         /*
4923          * Ok, go for it..
4924          */
4925 -       area = get_vm_area(size, VM_IOREMAP);
4926 +       area = get_io_vm_area(size, align, VM_IOREMAP);
4927         if (!area)
4928                 return NULL;
4929         addr = area->addr;
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)) {
4932                 vfree(addr);
4933                 return NULL;
4934         }
4935 @@ -159,5 +295,26 @@
4936  
4937  void __iounmap(void *addr)
4938  {
4939 -       vfree((void *) (PAGE_MASK & (unsigned long) addr));
4940 +       struct vm_struct **p, *tmp;
4941 +
4942 +       if (!addr)
4943 +               return;
4944 +
4945 +       if ((PAGE_SIZE - 1) & (unsigned long)addr) {
4946 +               printk(KERN_ERR "Trying to iounmap() bad address (%p)\n", addr);
4947 +               return;
4948 +       }
4949 +
4950 +       write_lock(&vmlist_lock);
4951 +       for (p = &vmlist; (tmp = *p); p = &tmp->next) {
4952 +               if (tmp->addr == addr) {
4953 +                       *p = tmp->next;
4954 +                       unmap_area_pages((unsigned long) tmp->addr, tmp->size);
4955 +                       write_unlock(&vmlist_lock);
4956 +                       kfree(tmp);
4957 +                       return;
4958 +               }
4959 +       }
4960 +       write_unlock(&vmlist_lock);
4961 +       printk(KERN_ERR "Trying to iounmap nonexistent area (%p)\n", addr);
4962  }
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
4967  
4968         str     r2, [r0]                        @ hardware version
4969 +
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
4977 +       @ 64K boundary.
4978 +       tsteq   r1, #L_PTE_USER
4979 +       andeq   r1, r0, #(15 << 2)
4980 +       teqeq   r1, #(15 << 2)
4981 +       beq     1f
4982 +
4983         mov     ip, #0
4984         mcr     p15, 0, r0, c7, c10, 1          @ Clean D cache line
4985         mcr     p15, 0, ip, c7, c10, 4          @ Drain Write (& Fill) Buffer
4986         mov     pc, lr
4987  
4988 +       @ See if we have 16 identical PTEs but with consecutive base addresses
4989 +1:     bic     r3, r2, #0x0000f000
4990 +       mov     r1, #0x0000f000
4991 +2:     eor     r2, r2, r3
4992 +       teq     r2, r1
4993 +       bne     4f
4994 +       subs    r1, r1, #0x00001000
4995 +       ldr     r2, [r0, #-4]!
4996 +       bne     2b
4997 +       eors    r2, r2, r3
4998 +       bne     4f
4999 +
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
5010 +
5011 +       @ then put it in the pagetable
5012 +       mov     r3, r2
5013 +3:     strd    r2, [r0], #8
5014 +       tst     r0, #(15 << 2)
5015 +       bne     3b
5016 +
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
5022 +       mov     ip, #0
5023 +       mcr     p15, 0, ip, c7, c10, 4          @ Drain Write (& Fill) Buffer
5024 +       mov     pc, lr
5025  
5026         .ltorg
5027  
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
5030 @@ -3,7 +3,7 @@
5031  #
5032  
5033  # Common support
5034 -obj-y := generic.o irq.o dma.o
5035 +obj-y := generic.o irq.o dma.o nmi-oopser.o
5036  obj-m :=
5037  obj-n :=
5038  obj-  :=
5039 @@ -88,7 +88,7 @@
5040  obj-$(CONFIG_LEDS) += $(led-y)
5041  
5042  # SA1110 USB client support
5043 -#obj-$(CONFIG_SA1100_USB)              += usb/
5044 +obj-$(CONFIG_SA1100_USB)               += usb/
5045  
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
5050 @@ -0,0 +1,43 @@
5051 +/*
5052 + * usb/strings.h
5053 + *
5054 + * Copyright (C) 2002 Russell King.
5055 + *
5056 + * USB device string handling, built upon usb buffers.
5057 + */
5058 +#ifndef USBDEV_STRINGS_H
5059 +#define USBDEV_STRINGS_H
5060 +
5061 +#include <linux/spinlock.h>
5062 +
5063 +struct usb_buf;
5064 +
5065 +#define NR_STRINGS 8
5066 +
5067 +struct usb_string_descriptor;
5068 +
5069 +struct usbc_strs {
5070 +       spinlock_t lock;
5071 +       struct usb_buf *buf[NR_STRINGS];
5072 +};
5073 +
5074 +#define usbc_string_desc(buf)  ((struct usb_string_descriptor *)(buf)->data)
5075 +
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);
5079 +
5080 +int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf);
5081 +void usbc_string_del(struct usbc_strs *table, int nr);
5082 +
5083 +/*
5084 + * Note: usbc_string_find() increments the buffer use count.
5085 + * You must call usbb_put() after use.
5086 + */
5087 +struct usb_buf *
5088 +usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx);
5089 +
5090 +void usbc_string_free_all(struct usbc_strs *table);
5091 +void usbc_string_init(struct usbc_strs *table);
5092 +
5093 +#endif
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
5096 @@ -0,0 +1,114 @@
5097 +/*
5098 + *     Copyright (C)  Compaq Computer Corporation, 1998, 1999
5099 + *     Copyright (C)  Extenex Corporation 2001
5100 + *
5101 + *  usb_ctl.h
5102 + *
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.
5106 + *
5107 + */
5108 +
5109 +#ifndef _USB_CTL_H
5110 +#define _USB_CTL_H
5111 +
5112 +#include <asm/dma.h>  /* dmach_t */
5113 +
5114 +struct usb_client;
5115 +
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;
5121 +};
5122 +
5123 +struct usb_info_t
5124 +{
5125 +       struct usb_client *client;
5126 +       dma_regs_t *dmach_tx, *dmach_rx;
5127 +       int state;
5128 +       unsigned char address;
5129 +       struct usb_stats_t stats;
5130 +};
5131 +
5132 +/* in usb_ctl.c */
5133 +extern struct usb_info_t usbd_info;
5134 +
5135 +/*
5136 + * Function Prototypes
5137 + */
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 );
5141 +
5142 +/* endpoint zero */
5143 +void ep0_reset(void);
5144 +void ep0_int_hndlr(void);
5145 +
5146 +/* receiver */
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);
5152 +
5153 +/* xmitter */
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);
5158 +
5159 +#define UDC_write(reg, val) { \
5160 +       int i = 10000; \
5161 +       do { \
5162 +               (reg) = (val); \
5163 +               if (i-- <= 0) { \
5164 +                       printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
5165 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5166 +                       break; \
5167 +               } \
5168 +       } while((reg) != (val)); \
5169 +}
5170 +
5171 +#define UDC_set(reg, val) { \
5172 +       int i = 10000; \
5173 +       do { \
5174 +               (reg) |= (val); \
5175 +               if (i-- <= 0) { \
5176 +                       printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
5177 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5178 +                       break; \
5179 +               } \
5180 +       } while(!((reg) & (val))); \
5181 +}
5182 +
5183 +#define UDC_clear(reg, val) { \
5184 +       int i = 10000; \
5185 +       do { \
5186 +               (reg) &= ~(val); \
5187 +               if (i-- <= 0) { \
5188 +                       printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
5189 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5190 +                       break; \
5191 +               } \
5192 +       } while((reg) & (val)); \
5193 +}
5194 +
5195 +#define UDC_flip(reg, val) { \
5196 +       int i = 10000; \
5197 +       (reg) = (val); \
5198 +       do { \
5199 +               (reg) = (val); \
5200 +               if (i-- <= 0) { \
5201 +                       printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
5202 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
5203 +                       break; \
5204 +               } \
5205 +       } while(((reg) & (val))); \
5206 +}
5207 +
5208 +
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
5213 @@ -0,0 +1,302 @@
5214 +/*
5215 + * Generic xmit layer for the SA1100 USB client function
5216 + * Copyright (c) 2001 by Nicolas Pitre
5217 + *
5218 + * This code was loosely inspired by the original version which was
5219 + * Copyright (c) Compaq Computer Corporation, 1998-1999
5220 + *
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.
5224 + *
5225 + * This is still work in progress...
5226 + *
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
5230 + */
5231 +
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>
5237 +
5238 +#include <asm/dma.h>
5239 +
5240 +#include "usbdev.h"
5241 +#include "sa1100_usb.h"
5242 +#include "sa1100usb.h"
5243 +
5244 +static unsigned int ep2_curdmalen;
5245 +static unsigned int ep2_remain;
5246 +
5247 +static struct sausb_dev *ep2_dev;
5248 +
5249 +static void udc_set_cs2(u32 val, u32 mask, u32 check)
5250 +{
5251 +       int i = 0;
5252 +
5253 +       do {
5254 +               Ser0UDCCS2 = val;
5255 +               udelay(1);
5256 +               if ((Ser0UDCCS2 & mask) == check)
5257 +                       return;
5258 +       } while (i++ < 10000);
5259 +
5260 +       printk("UDC: UDCCS2 write timed out: val=0x%08x\n", val);
5261 +}
5262 +
5263 +/* set feature stall executing, async */
5264 +static void ep2_start(struct sausb_dev *usb)
5265 +{
5266 +       ep2_curdmalen = min(ep2_remain, usb->ep[1].maxpktsize);
5267 +       if (ep2_curdmalen == 0)
5268 +               return;
5269 +
5270 +       /*
5271 +        * must do this _before_ queue buffer..
5272 +        * stop NAKing IN tokens
5273 +        */
5274 +       udc_set_cs2(usb->ep[1].udccs | UDCCS2_TPC, UDCCS2_TPC, 0);
5275 +
5276 +       UDC_write(Ser0UDCIMP, ep2_curdmalen - 1);
5277 +
5278 +       /* Remove if never seen...8Mar01ww */
5279 +       {
5280 +               int massive_attack = 20;
5281 +               while (Ser0UDCIMP != ep2_curdmalen - 1 && massive_attack--) {
5282 +                       printk("usbsnd: Oh no you don't! Let me spin...");
5283 +                       udelay(500);
5284 +                       printk("and try again...\n");
5285 +                       UDC_write(Ser0UDCIMP, ep2_curdmalen - 1);
5286 +               }
5287 +               if (massive_attack != 20) {
5288 +                       if (Ser0UDCIMP != ep2_curdmalen - 1)
5289 +                               printk("usbsnd: Massive attack FAILED. %d\n",
5290 +                                    20 - massive_attack);
5291 +                       else
5292 +                               printk("usbsnd: Massive attack WORKED. %d\n",
5293 +                                    20 - massive_attack);
5294 +               }
5295 +       }
5296 +       /* End remove if never seen... 8Mar01ww */
5297 +
5298 +       /*
5299 +        * fight stupid silicon bug
5300 +        */
5301 +       Ser0UDCAR = usb->ctl->address;
5302 +
5303 +       sa1100_start_dma(usb->ep[1].dmach, usb->ep[1].pktdma, ep2_curdmalen);
5304 +}
5305 +
5306 +static void udc_ep2_done(struct sausb_dev *usb, int flag)
5307 +{
5308 +       int size = usb->ep[1].buflen - ep2_remain;
5309 +
5310 +       if (!usb->ep[1].buflen)
5311 +               return;
5312 +
5313 +       dma_unmap_single(usb->dev, usb->ep[1].bufdma, usb->ep[1].buflen,
5314 +                        DMA_TO_DEVICE);
5315 +
5316 +       usb->ep[1].bufdma = 0;
5317 +       usb->ep[1].buflen = 0;
5318 +       usb->ep[1].pktdma = 0;
5319 +
5320 +       if (usb->ep[1].cb_func)
5321 +               usb->ep[1].cb_func(usb->ep[1].cb_data, flag, size);
5322 +}
5323 +
5324 +/*
5325 + * Initialisation.  Clear out the status.
5326 + */
5327 +void udc_ep2_init(struct sausb_dev *usb)
5328 +{
5329 +       ep2_dev = usb;
5330 +
5331 +       usb->ep[1].udccs = UDCCS2_FST;
5332 +
5333 +       BUG_ON(usb->ep[1].buflen);
5334 +       BUG_ON(usb->ep[1].pktlen);
5335 +
5336 +       sa1100_reset_dma(usb->ep[1].dmach);
5337 +}
5338 +
5339 +/*
5340 + * Note: rev A0-B2 chips don't like FST
5341 + */
5342 +void udc_ep2_halt(struct sausb_dev *usb, int halt)
5343 +{
5344 +       usb->ep[1].host_halt = halt;
5345 +
5346 +       if (halt) {
5347 +               usb->ep[1].udccs |= UDCCS2_FST;
5348 +               udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
5349 +       } else {
5350 +               sa1100_clear_dma(usb->ep[1].dmach);
5351 +
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);
5355 +
5356 +               usb->ep[1].udccs &= ~UDCCS2_FST;
5357 +
5358 +               udc_ep2_done(usb, -EINTR);
5359 +       }
5360 +}
5361 +
5362 +/*
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.
5365 + */
5366 +void udc_ep2_config(struct sausb_dev *usb, unsigned int maxpktsize)
5367 +{
5368 +       /*
5369 +        * We shouldn't be transmitting anything...
5370 +        */
5371 +       BUG_ON(usb->ep[1].buflen);
5372 +       BUG_ON(usb->ep[1].pktlen);
5373 +
5374 +       /*
5375 +        * Set our configuration.
5376 +        */
5377 +       usb->ep[1].maxpktsize = maxpktsize;
5378 +       usb->ep[1].configured = 1;
5379 +
5380 +       /*
5381 +        * Clear any pending TPC status.
5382 +        */
5383 +       udc_set_cs2(UDCCS2_TPC, UDCCS2_TPC, 0);
5384 +
5385 +       /*
5386 +        * Enable EP2 interrupts.
5387 +        */
5388 +       usb->udccr &= ~UDCCR_TIM;
5389 +       UDC_write(Ser0UDCCR, usb->udccr);
5390 +
5391 +       usb->ep[1].udccs = 0;
5392 +}
5393 +
5394 +/*
5395 + * We saw a reset from the attached hub, or were deconfigured.
5396 + * This means we are no longer configured.
5397 + */
5398 +void udc_ep2_reset(struct sausb_dev *usb)
5399 +{
5400 +       /*
5401 +        * Disable EP2 interrupts.
5402 +        */
5403 +       usb->udccr |= UDCCR_TIM;
5404 +       UDC_write(Ser0UDCCR, usb->udccr);
5405 +
5406 +       usb->ep[1].configured = 0;
5407 +       usb->ep[1].maxpktsize = 0;
5408 +
5409 +       sa1100_reset_dma(usb->ep[1].dmach);
5410 +       udc_ep2_done(usb, -EINTR);
5411 +}
5412 +
5413 +void udc_ep2_int_hndlr(struct sausb_dev *usb)
5414 +{
5415 +       u32 status = Ser0UDCCS2;
5416 +
5417 +       // check for stupid silicon bug.
5418 +       if (Ser0UDCAR != usb->ctl->address)
5419 +               Ser0UDCAR = usb->ctl->address;
5420 +
5421 +       udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0);
5422 +
5423 +       if (!(status & UDCCS2_TPC)) {
5424 +               printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
5425 +               return;
5426 +       }
5427 +
5428 +       sa1100_stop_dma(usb->ep[1].dmach);
5429 +
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);
5434 +       } else {
5435 +               unsigned int imp;
5436 +#if 1          // 22Feb01ww/Oleg
5437 +               imp = ep2_curdmalen;
5438 +#else
5439 +               // this is workaround for case when setting
5440 +               // of Ser0UDCIMP was failed
5441 +               imp = Ser0UDCIMP + 1;
5442 +#endif
5443 +               usb->ep[1].pktdma += imp;
5444 +               ep2_remain -= imp;
5445 +
5446 +               usb->ep[1].bytes += imp;
5447 +               usb->ep[1].packets++;
5448 +
5449 +               sa1100_clear_dma(usb->ep[1].dmach);
5450 +
5451 +               if (ep2_remain != 0) {
5452 +                       ep2_start(usb);
5453 +               } else {
5454 +                       udc_ep2_done(usb, 0);
5455 +               }
5456 +       }
5457 +}
5458 +
5459 +int udc_ep2_send(struct sausb_dev *usb, char *buf, int len)
5460 +{
5461 +       unsigned long flags;
5462 +       dma_addr_t dma;
5463 +       int ret;
5464 +
5465 +       if (!buf || len == 0)
5466 +               return -EINVAL;
5467 +
5468 +       dma = dma_map_single(usb->dev, buf, len, DMA_TO_DEVICE);
5469 +
5470 +       spin_lock_irqsave(&usb->lock, flags);
5471 +       do {
5472 +               if (!usb->ep[1].configured) {
5473 +                       ret = -ENODEV;
5474 +                       break;
5475 +               }
5476 +
5477 +               if (usb->ep[1].buflen) {
5478 +                       ret = -EBUSY;
5479 +                       break;
5480 +               }
5481 +
5482 +               usb->ep[1].bufdma = dma;
5483 +               usb->ep[1].buflen = len;
5484 +               usb->ep[1].pktdma = dma;
5485 +               ep2_remain = len;
5486 +
5487 +               sa1100_clear_dma(usb->ep[1].dmach);
5488 +
5489 +               ep2_start(usb);
5490 +               ret = 0;
5491 +       } while (0);
5492 +       spin_unlock_irqrestore(&usb->lock, flags);
5493 +
5494 +       if (ret)
5495 +               dma_unmap_single(usb->dev, dma, len, DMA_TO_DEVICE);
5496 +
5497 +       return ret;
5498 +}
5499 +
5500 +void udc_ep2_send_reset(struct sausb_dev *usb)
5501 +{
5502 +       sa1100_reset_dma(usb->ep[1].dmach);
5503 +       udc_ep2_done(usb, -EINTR);
5504 +}
5505 +
5506 +int udc_ep2_idle(struct sausb_dev *usb)
5507 +{
5508 +       if (!usb->ep[1].configured)
5509 +               return -ENODEV;
5510 +
5511 +       if (usb->ep[1].buflen)
5512 +               return -EBUSY;
5513 +
5514 +       return 0;
5515 +}
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
5518 @@ -0,0 +1,709 @@
5519 +/*
5520 + * (C) Copyright 2000-2001 Extenex Corporation
5521 + *
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.
5526 + *
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.
5531 + *
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.
5535 + *
5536 + *  usb-char.c
5537 + *
5538 + *  Miscellaneous character device interface for SA1100 USB function
5539 + *     driver.
5540 + *
5541 + *  Background:
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.
5545 + *
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.
5549 + *
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
5553 + *  in instead.
5554 + *
5555 + *  Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
5556 + *
5557 + *  ward.willats@extenex.com
5558 + *
5559 + *  To do:
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.
5565 + */
5566 +
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>
5577 +
5578 +#include <asm/io.h>
5579 +#include <asm/semaphore.h>
5580 +#include <asm/page.h>
5581 +#include <asm/mach-types.h>
5582 +
5583 +#include "usb-char.h"
5584 +#include "client.h"
5585 +
5586 +
5587 +
5588 +//////////////////////////////////////////////////////////////////////////////
5589 +// Driver  Options
5590 +//////////////////////////////////////////////////////////////////////////////
5591 +
5592 +#define VERSION        "0.4"
5593 +
5594 +
5595 +#define VERBOSITY 1
5596 +
5597 +#if VERBOSITY
5598 +# define       PRINTK(x, a...) printk (x, ## a)
5599 +#else
5600 +# define       PRINTK(x, a...) /**/
5601 +#endif
5602 +
5603 +//////////////////////////////////////////////////////////////////////////////
5604 +// Globals - Macros - Enums - Structures
5605 +//////////////////////////////////////////////////////////////////////////////
5606 +#ifndef MIN
5607 +#define MIN( a, b ) ((a)<(b)?(a):(b))
5608 +#endif
5609 +
5610 +typedef int bool; enum { false = 0, true = 1 };
5611 +
5612 +static const char pszMe[] = "usbchr: ";
5613 +
5614 +static wait_queue_head_t wq_read;
5615 +static wait_queue_head_t wq_write;
5616 +static wait_queue_head_t wq_poll;
5617 +
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 );
5622 +
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)
5629 +
5630 +static struct wcirc_buf {
5631 +  char *buf;
5632 +  int in;
5633 +  int out;
5634 +} rx_ring = { NULL, 0, 0 };
5635 +
5636 +static struct {
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;
5643 +} charstats;
5644 +
5645 +
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;
5654 +
5655 +//////////////////////////////////////////////////////////////////////////////
5656 +// Prototypes
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 );
5663 +
5664 +static void     tx_timeout( unsigned long );
5665 +static void     tx_done_callback(void *data, int flag, int size );
5666 +
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 );
5673 +
5674 +#ifdef CONFIG_SA1100_EXTENEX1
5675 +static void     extenex_configured_notify_proc( void );
5676 +#endif
5677 +//////////////////////////////////////////////////////////////////////////////
5678 +// Private Helpers
5679 +//////////////////////////////////////////////////////////////////////////////
5680 +
5681 +static char * what_the_f( int e )
5682 +{
5683 +        char * p;
5684 +        switch( e ) {
5685 +        case 0:
5686 +                 p = "noErr";
5687 +                 break;
5688 +        case -ENODEV:
5689 +                 p = "ENODEV - usb not in config state";
5690 +                 break;
5691 +        case -EBUSY:
5692 +                 p = "EBUSY - another request on the hardware";
5693 +                 break;
5694 +        case -EAGAIN:
5695 +                 p = "EAGAIN";
5696 +                 break;
5697 +        case -EINTR:
5698 +                 p = "EINTR - interrupted\n";
5699 +                 break;
5700 +        case -EPIPE:
5701 +                 p = "EPIPE - zero length xfer\n";
5702 +                 break;
5703 +        default:
5704 +                 p = "????";
5705 +                 break;
5706 +        }
5707 +        return p;
5708 +}
5709 +
5710 +static void free_txrx_buffers( void )
5711 +{
5712 +        if ( rx_ring.buf != NULL ) {
5713 +                 kfree( rx_ring.buf );
5714 +                 rx_ring.buf = NULL;
5715 +        }
5716 +        if ( packet_buffer != NULL ) {
5717 +                 kfree( packet_buffer );
5718 +                 packet_buffer = NULL;
5719 +        }
5720 +        if ( tx_buf != NULL ) {
5721 +                 kfree( tx_buf );
5722 +                 tx_buf = NULL;
5723 +        }
5724 +}
5725 +
5726 +/* twiddle_descriptors()
5727 + * It is between open() and start(). Setup descriptors.
5728 + */
5729 +static void twiddle_descriptors(struct usb_client *client)
5730 +{
5731 +       struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
5732 +
5733 +       cdb->ep1.wMaxPacketSize = cpu_to_le16(RX_PACKET_SIZE);
5734 +       cdb->ep2.wMaxPacketSize = cpu_to_le16(TX_PACKET_SIZE);
5735 +
5736 +#ifdef CONFIG_SA1100_EXTENEX1
5737 +       if (machine_is_extenex1()) {
5738 +               int nr;
5739 +
5740 +               cdb->cfg.bmAttributes = USB_CONFIG_SELFPOWERED;
5741 +               cdb->cfg.MaxPower = 0;
5742 +
5743 +               nr = sa1100_usb_add_string(client->ctl, "HHT Bulk Transfer");
5744 +
5745 +               if (nr > 0)
5746 +                       cdb->intf.iInterface = nr;
5747 +       }
5748 +#endif
5749 +}
5750 +
5751 +//////////////////////////////////////////////////////////////////////////////
5752 +// ASYNCHRONOUS
5753 +//////////////////////////////////////////////////////////////////////////////
5754 +static  void kick_start_rx( void )
5755 +{
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);
5761 +                 }
5762 +        }
5763 +}
5764 +/*
5765 + * rx_done_callback_packet_buffer()
5766 + * We have completed a DMA xfer into the temp packet buffer.
5767 + * Move to ring.
5768 + *
5769 + * flag values:
5770 + * on init,  -EAGAIN
5771 + * on reset, -EINTR
5772 + * on RPE, -EIO
5773 + * on short packet -EPIPE
5774 + */
5775 +static void
5776 +rx_done_callback_packet_buffer(void *data, int flag, int size )
5777 +{
5778 +        charstats.cnt_rx_complete++;
5779 +
5780 +        if ( flag == 0 || flag == -EPIPE ) {
5781 +                 size_t n;
5782 +
5783 +                 charstats.bytes_rx += size;
5784 +
5785 +                 n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
5786 +                 n = MIN( n, size );
5787 +                 size -= n;
5788 +
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);
5793 +
5794 +                 wake_up_interruptible( &wq_read );
5795 +                 wake_up_interruptible( &wq_poll );
5796 +
5797 +                 last_rx_result = 0;
5798 +
5799 +                 kick_start_rx();
5800 +
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 );
5806 +        }
5807 +        else  /* init, start a read */
5808 +                 kick_start_rx();
5809 +}
5810 +
5811 +
5812 +static void tx_timeout( unsigned long unused )
5813 +{
5814 +       printk( "%stx timeout\n", pszMe );
5815 +       sa1100_usb_send_reset();
5816 +       charstats.cnt_tx_timeouts++;
5817 +}
5818 +
5819 +
5820 +// on init, -EAGAIN
5821 +// on reset, -EINTR
5822 +// on TPE, -EIO
5823 +static void tx_done_callback(void *data, int flags, int size )
5824 +{
5825 +        if ( flags == 0 )
5826 +                 charstats.bytes_tx += size;
5827 +        else
5828 +                 charstats.cnt_tx_errors++;
5829 +        last_tx_size = size;
5830 +        last_tx_result = flags;
5831 +        sending = 0;
5832 +        wake_up_interruptible( &wq_write );
5833 +        wake_up_interruptible( &wq_poll );
5834 +}
5835 +
5836 +
5837 +static struct usb_client usbc_client = {
5838 +       .name           = "usb-char",
5839 +
5840 +       /*
5841 +        * USB client identification for host use in CPU endian.
5842 +        */
5843 +       .vendor         = 0,
5844 +       .product        = 0,
5845 +       .version        = 0,
5846 +       .class          = 0xff,
5847 +       .subclass       = 0,
5848 +       .protocol       = 0,
5849 +};
5850 +
5851 +#ifdef CONFIG_SA1100_EXTENEX1
5852 +#include "../../../drivers/char/ex_gpio.h"
5853 +static void extenex_state_change(void *data, int state, int oldstate)
5854 +{
5855 +       if (exgpio_play_string( "440,1:698,1") == -EAGAIN)
5856 +               printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe );
5857 +}
5858 +#endif
5859 +
5860 +//////////////////////////////////////////////////////////////////////////////
5861 +// Workers
5862 +//////////////////////////////////////////////////////////////////////////////
5863 +
5864 +static int usbc_open(struct inode *pInode, struct file *pFile)
5865 +{
5866 +       int retval = 0;
5867 +
5868 +       PRINTK( KERN_DEBUG "%sopen()\n", pszMe );
5869 +
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;
5879 +       }
5880 +#endif
5881 +
5882 +        /* start usb core */
5883 +        retval = usbctl_open(&usbc_client);
5884 +        if (retval)
5885 +               return retval;
5886 +
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 );
5892 +                          goto malloc_fail;
5893 +                 }
5894 +                 rx_ring.buf =
5895 +                       (char*) kmalloc( RBUF_SIZE, GFP_KERNEL );
5896 +
5897 +                 if ( rx_ring.buf == NULL ) {
5898 +                          printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe );
5899 +                          goto malloc_fail;
5900 +                 }
5901 +
5902 +                 packet_buffer =
5903 +                       (char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA  );
5904 +
5905 +                 if ( packet_buffer == NULL ) {
5906 +                          printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe );
5907 +                          goto malloc_fail;
5908 +                 }
5909 +                 rx_ring.in = rx_ring.out = 0;
5910 +                 memset( &charstats, 0, sizeof( charstats ) );
5911 +                 sending = 0;
5912 +                 last_tx_result = 0;
5913 +                 last_tx_size = 0;
5914 +        }
5915 +
5916 +        /* modify default descriptors */
5917 +        twiddle_descriptors(&usbc_client);
5918 +
5919 +        retval = usbctl_start(&usbc_client);
5920 +        if ( retval ) {
5921 +                 printk( "%sAGHH! Could not USB core\n", pszMe );
5922 +                 free_txrx_buffers();
5923 +                 return retval;
5924 +        }
5925 +        usb_ref_count++;   /* must do _before_ kick_start() */
5926 +        MOD_INC_USE_COUNT;
5927 +        kick_start_rx();
5928 +        return 0;
5929 +
5930 + malloc_fail:
5931 +        free_txrx_buffers();
5932 +        return -ENOMEM;
5933 +}
5934 +
5935 +/*
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.
5939 + */
5940 +static ssize_t usbc_read( struct file *pFile, char *pUserBuffer,
5941 +                        size_t stCount, loff_t *pPos )
5942 +{
5943 +        ssize_t retval;
5944 +        unsigned long flags;
5945 +        DECLARE_WAITQUEUE( wait, current );
5946 +
5947 +        PRINTK( KERN_DEBUG "%sread()\n", pszMe );
5948 +
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;
5955 +                 kick_start_rx();
5956 +        }
5957 +
5958 +        add_wait_queue( &wq_read, &wait );
5959 +        while( 1 ) {
5960 +                 ssize_t bytes_avail;
5961 +                 ssize_t bytes_to_end;
5962 +
5963 +                 set_current_state( TASK_INTERRUPTIBLE );
5964 +
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 );
5970 +
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 ],
5978 +                                                                          n ) ) {
5979 +                                                retval = -EFAULT;
5980 +                                                break;
5981 +                                       }
5982 +                                       bytes_to_move -= n;
5983 +                                       retval += 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 ],
5988 +                                                                          bytes_to_move )
5989 +                                                ) {
5990 +                                                retval = -EFAULT;
5991 +                                                break;
5992 +                                       }
5993 +                                       rx_ring.out += bytes_to_move;           // cannot wrap
5994 +                                       retval += bytes_to_move;
5995 +                                       kick_start_rx();
5996 +                          }
5997 +                          break;
5998 +                 }
5999 +                 else if ( last_rx_result ) {
6000 +                          retval = last_rx_result;
6001 +                          break;
6002 +                 }
6003 +                 else if ( pFile->f_flags & O_NONBLOCK ) {  // no data, can't sleep
6004 +                          retval = -EAGAIN;
6005 +                          break;
6006 +                 }
6007 +                 else if ( signal_pending( current ) ) {   // no data, can sleep, but signal
6008 +                          retval = -ERESTARTSYS;
6009 +                          break;
6010 +                 }
6011 +                 schedule();                                                           // no data, can sleep
6012 +        }
6013 +        set_current_state( TASK_RUNNING );
6014 +        remove_wait_queue( &wq_read, &wait );
6015 +
6016 +        if ( retval < 0 )
6017 +                 printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) );
6018 +        return retval;
6019 +}
6020 +
6021 +/*
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.)
6026 + *
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
6031 + * is used.
6032 + *
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.
6038 + *
6039 +  */
6040 +static ssize_t  usbc_write( struct file *pFile, const char * pUserBuffer,
6041 +                                                        size_t stCount, loff_t *pPos )
6042 +{
6043 +        ssize_t retval = 0;
6044 +        ssize_t stSent = 0;
6045 +
6046 +        DECLARE_WAITQUEUE( wait, current );
6047 +
6048 +        PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount );
6049 +
6050 +        down( &xmit_sem );  // only one thread onto the hardware at a time
6051 +
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 );
6062 +                          sending = 0;
6063 +                          break;
6064 +                 }
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 );
6069 +                 while( 1 ) {
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;
6078 +                                       }
6079 +                                       else
6080 +                                                printk( "%sxmission error rc=%d - %s\n",
6081 +                                                                pszMe, retval, what_the_f(retval) );
6082 +                                       break;
6083 +                          }
6084 +                          else if ( signal_pending( current ) ) {
6085 +                                       del_timer( &tx_timer );
6086 +                                       printk( "%ssignal\n", pszMe  );
6087 +                                       retval = -ERESTARTSYS;
6088 +                                       break;
6089 +                          }
6090 +                          schedule();
6091 +                 }
6092 +                 set_current_state( TASK_RUNNING );
6093 +                 remove_wait_queue( &wq_write, &wait );
6094 +        }
6095 +
6096 +        up( &xmit_sem );
6097 +
6098 +        if ( 0 == retval )
6099 +                 retval = stSent;
6100 +        return retval;
6101 +}
6102 +
6103 +static unsigned int usbc_poll( struct file *pFile, poll_table * pWait )
6104 +{
6105 +        unsigned int retval = 0;
6106 +
6107 +        PRINTK( KERN_DEBUG "%poll()\n", pszMe );
6108 +
6109 +        poll_wait( pFile, &wq_poll, pWait );
6110 +
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;
6115 +        return retval;
6116 +}
6117 +
6118 +static int usbc_ioctl( struct inode *pInode, struct file *pFile,
6119 +                       unsigned int nCmd, unsigned long argument )
6120 +{
6121 +        int retval = 0;
6122 +
6123 +        switch( nCmd ) {
6124 +
6125 +        case USBC_IOC_FLUSH_RECEIVER:
6126 +                 sa1100_usb_recv_reset();
6127 +                 rx_ring.in = rx_ring.out = 0;
6128 +                 break;
6129 +
6130 +        case USBC_IOC_FLUSH_TRANSMITTER:
6131 +                 sa1100_usb_send_reset();
6132 +                 break;
6133 +
6134 +        case USBC_IOC_FLUSH_ALL:
6135 +                 sa1100_usb_recv_reset();
6136 +                 rx_ring.in = rx_ring.out = 0;
6137 +                 sa1100_usb_send_reset();
6138 +                 break;
6139 +
6140 +        default:
6141 +                 retval = -ENOIOCTLCMD;
6142 +                 break;
6143 +
6144 +        }
6145 +        return retval;
6146 +}
6147 +
6148 +
6149 +static int usbc_close( struct inode *pInode, struct file * pFile )
6150 +{
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);
6158 +                up(&xmit_sem);
6159 +       }
6160 +       MOD_DEC_USE_COUNT;
6161 +       return 0;
6162 +}
6163 +
6164 +//////////////////////////////////////////////////////////////////////////////
6165 +// Initialization
6166 +//////////////////////////////////////////////////////////////////////////////
6167 +
6168 +static struct file_operations usbc_fops = {
6169 +       owner:          THIS_MODULE,
6170 +       open:           usbc_open,
6171 +       read:           usbc_read,
6172 +       write:          usbc_write,
6173 +       poll:           usbc_poll,
6174 +       ioctl:          usbc_ioctl,
6175 +       release:        usbc_close,
6176 +};
6177 +
6178 +static struct miscdevice usbc_misc_device = {
6179 +       USBC_MINOR,
6180 +       "usb_char",
6181 +       &usbc_fops
6182 +};
6183 +
6184 +/*
6185 + * usbc_init()
6186 + */
6187 +
6188 +static int __init usbc_init( void )
6189 +{
6190 +        int rc;
6191 +
6192 +#if !defined( CONFIG_ARCH_SA1100 )
6193 +        return -ENODEV;
6194 +#endif
6195 +
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 );
6199 +                 return -EBUSY;
6200 +        }
6201 +
6202 +        // initialize wait queues
6203 +        init_waitqueue_head( &wq_read );
6204 +        init_waitqueue_head( &wq_write );
6205 +        init_waitqueue_head( &wq_poll );
6206 +
6207 +        // initialize tx timeout timer
6208 +        init_timer( &tx_timer );
6209 +        tx_timer.function = tx_timeout;
6210 +
6211 +         printk( KERN_INFO "USB Function Character Driver Interface"
6212 +                                 " - %s, (C) 2001, Extenex Corp.\n", VERSION
6213 +                  );
6214 +
6215 +        return rc;
6216 +}
6217 +
6218 +static void __exit usbc_exit( void )
6219 +{
6220 +}
6221 +
6222 +module_init(usbc_init);
6223 +module_exit(usbc_exit);
6224 +
6225 +// end: usb-char.c
6226 +
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
6230 @@ -0,0 +1,535 @@
6231 +/*
6232 + * Network driver for the SA1100 USB client function
6233 + * Copyright (c) 2001 by Nicolas Pitre
6234 + *
6235 + * This code was loosely inspired by the original initial ethernet test driver
6236 + * Copyright (c) Compaq Computer Corporation, 1999
6237 + *
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.
6241 + *
6242 + * Issues:
6243 + *  - DMA needs 8 byte aligned buffer, but causes inefficiencies
6244 + *    in the IP code.
6245 + *  - stall endpoint operations appeared to be very unstable.
6246 + */
6247 +
6248 +/*
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.
6252 + *
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.
6256 + */
6257 +#undef RX_NO_COPY
6258 +
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>
6268 +
6269 +#include "client.h"
6270 +
6271 +
6272 +#define ETHERNET_VENDOR_ID  0x049f
6273 +#define ETHERNET_PRODUCT_ID 0x505A
6274 +#define MAX_PACKET 32768
6275 +
6276 +/*
6277 + * This is our usb "packet size", and must match the host "packet size".
6278 + */
6279 +static int usb_rsize = 64;
6280 +static int usb_wsize = 64;
6281 +
6282 +struct usbe_info {
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;
6289 +#ifndef RX_NO_COPY
6290 +       char *dmabuf;   // dma expects it's buffers to be aligned on 8 bytes boundary
6291 +#endif
6292 +       struct net_device_stats stats;
6293 +};
6294 +
6295 +
6296 +static int usbeth_change_mtu(struct net_device *dev, int new_mtu)
6297 +{
6298 +       if (new_mtu <= sizeof(struct ethhdr) || new_mtu > MAX_PACKET)
6299 +               return -EINVAL;
6300 +
6301 +       // no second zero-length packet read wanted after mtu-sized packets
6302 +       if (((new_mtu + sizeof(struct ethhdr)) % usb_rsize) == 0)
6303 +               return -EDOM;
6304 +
6305 +       dev->mtu = new_mtu;
6306 +       return 0;
6307 +}
6308 +
6309 +static struct sk_buff *usb_new_recv_skb(struct usbe_info *usbe)
6310 +{
6311 +       struct sk_buff *skb;
6312 +
6313 +       skb = alloc_skb(2 + sizeof(struct ethhdr) + usbe->dev.mtu,
6314 +                       GFP_ATOMIC);
6315 +
6316 +       if (skb)
6317 +               skb_reserve(skb, 2);
6318 +
6319 +       return skb;
6320 +}
6321 +
6322 +static void usbeth_recv_callback(void *data, int flag, int len)
6323 +{
6324 +       struct usbe_info *usbe = data;
6325 +       struct sk_buff *skb;
6326 +       unsigned int size;
6327 +       char *buf;
6328 +
6329 +       skb = usbe->cur_rx_skb;
6330 +
6331 +       /* flag validation */
6332 +       if (flag != 0)
6333 +               goto error;
6334 +
6335 +       /*
6336 +        * Make sure we have enough room left in the buffer.
6337 +        */
6338 +       if (len > skb_tailroom(skb)) {
6339 +               usbe->stats.rx_over_errors++;
6340 +               usbe->stats.rx_errors++;
6341 +               goto oversize;
6342 +       }
6343 +
6344 +       /*
6345 +        * If the packet is smaller than usb_rsize bytes, the packet
6346 +        * is complete, and we need to use the next receive buffer.
6347 +        */
6348 +       if (len != usb_rsize)
6349 +               usbe->cur_rx_skb = usbe->next_rx_skb;
6350 +
6351 +       /*
6352 +        * Put the data onto the socket buffer and resume USB receive.
6353 +        */
6354 +#ifndef RX_NO_COPY
6355 +       memcpy(skb_put(skb, len), usbe->dmabuf, len);
6356 +       buf = usbe->dmabuf;
6357 +       size = usb_rsize;
6358 +#else
6359 +       skb_put(skb, len);
6360 +       buf = usbe->cur_rx_skb->tail;
6361 +       size = skb_tailroom(usbe->cur_rx_skb);
6362 +#endif
6363 +       usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
6364 +
6365 +       if (len == usb_rsize)
6366 +               return;
6367 +
6368 +       /*
6369 +        * A frame must contain at least an ethernet header.
6370 +        */
6371 +       if (skb->len < sizeof(struct ethhdr)) {
6372 +               usbe->stats.rx_length_errors++;
6373 +               usbe->stats.rx_errors++;
6374 +               goto recycle;
6375 +       }
6376 +
6377 +       /*
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.
6381 +        */
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++;
6386 +               goto recycle;
6387 +       }
6388 +
6389 +       /*
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.
6393 +        */
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",
6398 +                               usbe->dev.name);
6399 +               usbe->stats.rx_dropped++;
6400 +               goto recycle;
6401 +       }
6402 +
6403 +// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ?
6404 +
6405 +       usbe->stats.rx_packets++;
6406 +       usbe->stats.rx_bytes += skb->len;
6407 +       usbe->dev.last_rx = jiffies;
6408 +
6409 +       skb->dev = &usbe->dev;
6410 +       skb->protocol = eth_type_trans(skb, &usbe->dev);
6411 +       skb->ip_summed = CHECKSUM_NONE;
6412 +
6413 +       if (netif_rx(skb) == NET_RX_DROP)
6414 +               usbe->stats.rx_dropped++;
6415 +       return;
6416 +
6417 + error:
6418 +       /*
6419 +        * Oops, IO error, or stalled.
6420 +        */
6421 +       switch (flag) {
6422 +       case -EIO:      /* aborted transfer */
6423 +               usbe->stats.rx_errors++;
6424 +               break;
6425 +
6426 +       case -EPIPE:    /* fifo screwed/no data */
6427 +               usbe->stats.rx_fifo_errors++;
6428 +               usbe->stats.rx_errors++;
6429 +               break;
6430 +
6431 +       case -EINTR:    /* reset */
6432 +               break;
6433 +
6434 +       case -EAGAIN:   /* initialisation */
6435 +               break;
6436 +       }
6437 +
6438 + oversize:
6439 +       skb_trim(skb, 0);
6440 +
6441 +#ifndef RX_NO_COPY
6442 +       buf = usbe->dmabuf;
6443 +       size = usb_rsize;
6444 +#else
6445 +       buf = skb->tail;
6446 +       size = skb_tailroom(skb);
6447 +#endif
6448 +       usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
6449 +       return;
6450 +
6451 + recycle:
6452 +       skb_trim(skb, 0);
6453 +       usbe->next_rx_skb = skb;
6454 +       return;
6455 +}
6456 +
6457 +/*
6458 + * Send a skb.
6459 + *
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.
6463 + */
6464 +static void usbeth_send(struct sk_buff *skb, struct usbe_info *usbe)
6465 +{
6466 +       unsigned int len = skb->len;
6467 +       int ret;
6468 +
6469 +       if ((len % usb_wsize) == 0)
6470 +               len++;
6471 +
6472 +       ret = usbctl_ep_queue_buffer(usbe->client.ctl, 2, skb->data, len);
6473 +       if (ret) {
6474 +               printk(KERN_ERR "%s: tx dropping packet: %d\n",
6475 +                      usbe->dev.name, ret);
6476 +
6477 +               /*
6478 +                * If the USB core can't accept the packet, we drop it.
6479 +                */
6480 +               dev_kfree_skb_irq(skb);
6481 +
6482 +               usbe->cur_tx_skb = NULL;
6483 +               usbe->stats.tx_carrier_errors++;
6484 +       } else {
6485 +               usbe->dev.trans_start = jiffies;
6486 +       }
6487 +}
6488 +
6489 +static void usbeth_send_callback(void *data, int flag, int size)
6490 +{
6491 +       struct usbe_info *usbe = data;
6492 +       struct sk_buff *skb = usbe->cur_tx_skb;
6493 +
6494 +       switch (flag) {
6495 +       case 0:
6496 +               usbe->stats.tx_packets++;
6497 +               usbe->stats.tx_bytes += skb->len;
6498 +               break;
6499 +       case -EIO:
6500 +               usbe->stats.tx_errors++;
6501 +               break;
6502 +       default:
6503 +               usbe->stats.tx_dropped++;
6504 +               break;
6505 +       }
6506 +
6507 +       dev_kfree_skb_irq(skb);
6508 +
6509 +       skb = usbe->cur_tx_skb = usbe->next_tx_skb;
6510 +       usbe->next_tx_skb = NULL;
6511 +
6512 +       if (skb)
6513 +               usbeth_send(skb, usbe);
6514 +
6515 +       netif_wake_queue(&usbe->dev);
6516 +}
6517 +
6518 +static int usbeth_xmit(struct sk_buff *skb, struct net_device *dev)
6519 +{
6520 +       struct usbe_info *usbe = dev->priv;
6521 +       unsigned long flags;
6522 +
6523 +       if (usbe->next_tx_skb) {
6524 +               printk(KERN_ERR "%s: called with next_tx_skb != NULL\n",
6525 +                      usbe->dev.name);
6526 +               return 1;
6527 +       }
6528 +
6529 +       local_irq_save(flags);
6530 +       if (usbe->cur_tx_skb) {
6531 +               usbe->next_tx_skb = skb;
6532 +               netif_stop_queue(dev);
6533 +       } else {
6534 +               usbe->cur_tx_skb = skb;
6535 +
6536 +               usbeth_send(skb, usbe);
6537 +       }
6538 +       local_irq_restore(flags);
6539 +       return 0;
6540 +}
6541 +
6542 +/*
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.
6545 + */
6546 +static void usbeth_xmit_timeout(struct net_device *dev)
6547 +{
6548 +       struct usbe_info *usbe = dev->priv;
6549 +       unsigned long flags;
6550 +
6551 +       usbctl_ep_reset(usbe->client.ctl, 2);
6552 +
6553 +       local_irq_save(flags);
6554 +       if (usbe->cur_tx_skb)
6555 +               usbeth_send(usbe->cur_tx_skb, usbe);
6556 +
6557 +       if (usbe->next_tx_skb == NULL)
6558 +               netif_wake_queue(dev);
6559 +
6560 +       usbe->stats.tx_errors++;
6561 +       local_irq_restore(flags);
6562 +}
6563 +
6564 +static int usbeth_open(struct net_device *dev)
6565 +{
6566 +       struct usbe_info *usbe = dev->priv;
6567 +       unsigned char *buf;
6568 +       unsigned int size;
6569 +
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);
6572 +
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",
6578 +                       usbe->dev.name);
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);
6583 +               return -ENOMEM;;
6584 +       }
6585 +#ifndef RX_NO_COPY
6586 +       buf =  usbe->dmabuf;
6587 +       size = usb_rsize;
6588 +#else
6589 +       buf = usbe->cur_rx_skb->tail;
6590 +       size = skb_tailroom(usbe->cur_rx_skb);
6591 +#endif
6592 +       usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
6593 +
6594 +       if (netif_carrier_ok(dev))
6595 +               netif_start_queue(dev);
6596 +
6597 +       return 0;
6598 +}
6599 +
6600 +static int usbeth_close(struct net_device *dev)
6601 +{
6602 +       struct usbe_info *usbe = dev->priv;
6603 +
6604 +       netif_stop_queue(dev);
6605 +
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);
6610 +
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);
6619 +
6620 +       return 0;
6621 +}
6622 +
6623 +static struct net_device_stats *usbeth_stats(struct net_device *dev)
6624 +{
6625 +       struct usbe_info *usbe = dev->priv;
6626 +
6627 +       return &usbe->stats;
6628 +}
6629 +
6630 +static int __init usbeth_probe(struct net_device *dev)
6631 +{
6632 +       u8 node_id[ETH_ALEN];
6633 +
6634 +       SET_MODULE_OWNER(dev);
6635 +
6636 +       /*
6637 +        * Assign the hardware address of the board:
6638 +        * generate it randomly, as there can be many such
6639 +        * devices on the bus.
6640 +        */
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);
6644 +
6645 +       ether_setup(dev);
6646 +       dev->flags &= ~IFF_MULTICAST;
6647 +       dev->flags &= ~IFF_BROADCAST;
6648 +       //dev->flags |= IFF_NOARP;
6649 +
6650 +       return 0;
6651 +}
6652 +
6653 +/*
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?
6659 + */
6660 +static void usbeth_state_change(void *data, int state, int oldstate)
6661 +{
6662 +       struct usbe_info *usbe = data;
6663 +
6664 +       if (state == USB_STATE_CONFIGURED) {
6665 +               netif_carrier_on(&usbe->dev);
6666 +               if (netif_running(&usbe->dev))
6667 +                       netif_wake_queue(&usbe->dev);
6668 +       } else {
6669 +               if (netif_running(&usbe->dev))
6670 +                       netif_stop_queue(&usbe->dev);
6671 +               netif_carrier_off(&usbe->dev);
6672 +       }
6673 +}
6674 +
6675 +static struct usbe_info usbe_info = {
6676 +       .dev    = {
6677 +               .name                   = "usbf",
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,
6687 +       },
6688 +       .client = {
6689 +               .name                   = "usbeth",
6690 +               .priv                   = &usbe_info,
6691 +               .state_change           = usbeth_state_change,
6692 +
6693 +               /*
6694 +                * USB client identification for host use in CPU endian.
6695 +                */
6696 +               .vendor                 = ETHERNET_VENDOR_ID,
6697 +               .product                = ETHERNET_PRODUCT_ID,
6698 +               .version                = 0,
6699 +               .class                  = 0xff, /* vendor specific */
6700 +               .subclass               = 0,
6701 +               .protocol               = 0,
6702 +
6703 +               .product_str            = "SA1100 USB NIC",
6704 +       },
6705 +};
6706 +
6707 +static int __init usbeth_init(void)
6708 +{
6709 +       int rc;
6710 +
6711 +#ifndef RX_NO_COPY
6712 +       usbe_info.dmabuf = kmalloc(usb_rsize, GFP_KERNEL | GFP_DMA);
6713 +       if (!usbe_info.dmabuf)
6714 +               return -ENOMEM;
6715 +#endif
6716 +
6717 +       if (register_netdev(&usbe_info.dev) != 0) {
6718 +#ifndef RX_NO_COPY
6719 +               kfree(usbe_info.dmabuf);
6720 +#endif
6721 +               return -EIO;
6722 +       }
6723 +
6724 +       rc = usbctl_open(&usbe_info.client);
6725 +       if (rc == 0) {
6726 +               struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
6727 +
6728 +               cdb->ep1.wMaxPacketSize = cpu_to_le16(usb_rsize);
6729 +               cdb->ep2.wMaxPacketSize = cpu_to_le16(usb_wsize);
6730 +
6731 +               rc = usbctl_start(&usbe_info.client);
6732 +               if (rc)
6733 +                       usbctl_close(&usbe_info.client);
6734 +       }
6735 +
6736 +       if (rc) {
6737 +               unregister_netdev(&usbe_info.dev);
6738 +#ifndef RX_NO_COPY
6739 +               kfree(usbe_info.dmabuf);
6740 +#endif
6741 +       }
6742 +
6743 +       return rc;
6744 +}
6745 +
6746 +static void __exit usbeth_cleanup(void)
6747 +{
6748 +       usbctl_stop(&usbe_info.client);
6749 +       usbctl_close(&usbe_info.client);
6750 +
6751 +       unregister_netdev(&usbe_info.dev);
6752 +#ifndef RX_NO_COPY
6753 +       kfree(usbe_info.dmabuf);
6754 +#endif
6755 +}
6756 +
6757 +module_init(usbeth_init);
6758 +module_exit(usbeth_cleanup);
6759 +
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
6768 @@ -0,0 +1,318 @@
6769 +/*
6770 + * Generic receive layer for the SA1100 USB client function
6771 + * Copyright (c) 2001 by Nicolas Pitre
6772 + *
6773 + * This code was loosely inspired by the original version which was
6774 + * Copyright (c) Compaq Computer Corporation, 1998-1999
6775 + *
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.
6779 + *
6780 + * This is still work in progress...
6781 + *
6782 + * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
6783 + */
6784 +
6785 +#include <linux/module.h>
6786 +#include <linux/pci.h>
6787 +#include <linux/errno.h>
6788 +#include <linux/usb_ch9.h>
6789 +
6790 +#include <asm/byteorder.h>
6791 +#include <asm/dma.h>
6792 +
6793 +#include "sa1100_usb.h"
6794 +#include "sa1100usb.h"
6795 +
6796 +static int naking;
6797 +
6798 +#if 1
6799 +static void dump_buf(struct sausb_dev *usb, const char *prefix)
6800 +{
6801 +       printk("%s: buf [dma=%08x len=%3d] pkt [cpu=%08x dma=%08x len=%3d rem=%3d]\n",
6802 +               prefix,
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);
6809 +}
6810 +#endif
6811 +
6812 +static void udc_ep1_done(struct sausb_dev *usb, int flag, int size)
6813 +{
6814 +//     printk("UDC: rxd: %3d %3d\n", flag, size);
6815 +       dump_buf(usb, "UDC: rxd");
6816 +
6817 +       if (!usb->ep[0].buflen)
6818 +               return;
6819 +
6820 +       dma_unmap_single(usb->dev, usb->ep[0].bufdma, usb->ep[0].buflen,
6821 +                        DMA_FROM_DEVICE);
6822 +
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;
6829 +
6830 +       if (usb->ep[0].cb_func)
6831 +               usb->ep[0].cb_func(usb->ep[0].cb_data, flag, size);
6832 +}
6833 +
6834 +/*
6835 + * Initialisation.  Clear out the status, and set FST.
6836 + */
6837 +void udc_ep1_init(struct sausb_dev *usb)
6838 +{
6839 +       sa1100_reset_dma(usb->ep[0].dmach);
6840 +
6841 +       UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC);
6842 +
6843 +       BUG_ON(usb->ep[0].buflen);
6844 +       BUG_ON(usb->ep[0].pktlen);
6845 +}
6846 +
6847 +void udc_ep1_halt(struct sausb_dev *usb, int halt)
6848 +{
6849 +       if (halt) {
6850 +               /* force stall at UDC */
6851 +               UDC_set(Ser0UDCCS1, UDCCS1_FST);
6852 +       } else {
6853 +               sa1100_reset_dma(usb->ep[0].dmach);
6854 +
6855 +               UDC_clear(Ser0UDCCS1, UDCCS1_FST);
6856 +
6857 +               udc_ep1_done(usb, -EINTR, 0);
6858 +       }
6859 +}
6860 +
6861 +/*
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.
6864 + */
6865 +void udc_ep1_config(struct sausb_dev *usb, unsigned int maxpktsize)
6866 +{
6867 +       usb->ep[0].maxpktsize = maxpktsize;
6868 +       usb->ep[0].configured = 1;
6869 +
6870 +       Ser0UDCOMP = maxpktsize - 1;
6871 +
6872 +       sa1100_reset_dma(usb->ep[0].dmach);
6873 +       udc_ep1_done(usb, -EINTR, 0);
6874 +
6875 +       /*
6876 +        * Enable EP1 interrupts.
6877 +        */
6878 +       usb->udccr &= ~UDCCR_RIM;
6879 +       UDC_write(Ser0UDCCR, usb->udccr);
6880 +}
6881 +
6882 +/*
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.
6886 + */
6887 +void udc_ep1_reset(struct sausb_dev *usb)
6888 +{
6889 +       /*
6890 +        * Disable EP1 interrupts.
6891 +        */
6892 +       usb->udccr |= UDCCR_RIM;
6893 +       UDC_write(Ser0UDCCR, usb->udccr);
6894 +
6895 +       usb->ep[0].configured = 0;
6896 +       usb->ep[0].maxpktsize = 0;
6897 +
6898 +       sa1100_reset_dma(usb->ep[0].dmach);
6899 +       udc_ep1_done(usb, -EINTR, 0);
6900 +}
6901 +
6902 +void udc_ep1_int_hndlr(struct sausb_dev *usb)
6903 +{
6904 +       dma_addr_t dma_addr;
6905 +       unsigned int len;
6906 +       u32 status = Ser0UDCCS1;
6907 +
6908 +       dump_buf(usb, "UDC: int");
6909 +
6910 +       if (naking) {
6911 +               printk("UDC: usbrx: in ISR but naking [0x%02x]\n", status);
6912 +               return;
6913 +       }
6914 +
6915 +       if (!(status & UDCCS1_RPC))
6916 +               /* you can get here if we are holding NAK */
6917 +               return;
6918 +
6919 +       if (!usb->ep[0].buflen) {
6920 +               printk("UDC: usb_recv: RPC for non-existent buffer [0x%02x]\n", status);
6921 +               naking = 1;
6922 +               return;
6923 +       }
6924 +
6925 +       sa1100_stop_dma(usb->ep[0].dmach);
6926 +
6927 +       dma_addr = sa1100_get_dma_pos(usb->ep[0].dmach);
6928 +
6929 +       /*
6930 +        * We've finished with the DMA for this packet.
6931 +        */
6932 +       sa1100_clear_dma(usb->ep[0].dmach);
6933 +
6934 +       if (status & UDCCS1_SST) {
6935 +               printk("UDC: usb_recv: stall sent\n");
6936 +               UDC_flip(Ser0UDCCS1, UDCCS1_SST);
6937 +
6938 +               /*
6939 +                * UDC aborted current transfer, so we do.
6940 +                *
6941 +                * It would be better to re-queue this buffer IMHO.  It
6942 +                * hasn't gone anywhere yet. --rmk
6943 +                */
6944 +               UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
6945 +               udc_ep1_done(usb, -EIO, 0);
6946 +               return;
6947 +       }
6948 +
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);
6953 +               return;
6954 +       }
6955 +
6956 +       len = dma_addr - usb->ep[0].pktdma;
6957 +       if (len < 0) {
6958 +               printk("UDC: usb_recv: dma_addr (%x) < pktdma (%x)\n",
6959 +                       dma_addr, usb->ep[0].pktdma);
6960 +               len = 0;
6961 +       }
6962 +
6963 +       if (len > usb->ep[0].pktlen)
6964 +               len = usb->ep[0].pktlen;
6965 +
6966 +       /*
6967 +        * If our transfer was smaller, and we have bytes left in
6968 +        * the FIFO, we need to read them out manually.
6969 +        */
6970 +       if (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE)) {
6971 +               char *buf;
6972 +
6973 +               dma_sync_single(usb->dev, usb->ep[0].pktdma + len,
6974 +                               usb->ep[0].pktlen - len, DMA_FROM_DEVICE);
6975 +
6976 +               buf = (char *)usb->ep[0].pktcpu + len;
6977 +
6978 +               do {
6979 +                       *buf++ = Ser0UDCDR;
6980 +                       len++;
6981 +               } while (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE));
6982 +
6983 +               /*
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.
6986 +                */
6987 +               dma_sync_single(usb->dev, usb->ep[0].pktdma + len,
6988 +                               usb->ep[0].pktlen - len, DMA_TO_DEVICE);
6989 +       }
6990 +
6991 +       /*
6992 +        * If the FIFO still contains data, something's definitely wrong.
6993 +        */
6994 +       if (Ser0UDCCS1 & UDCCS1_RNE) {
6995 +               printk("UDC: usb_recv: fifo screwed, shouldn't contain data\n");
6996 +               usb->ep[0].fifo_errs++;
6997 +               naking = 1;
6998 +               udc_ep1_done(usb, -EPIPE, 0);
6999 +               return;
7000 +       }
7001 +
7002 +       /*
7003 +        * Do statistics.
7004 +        */
7005 +       if (len) {
7006 +               usb->ep[0].bytes += len;
7007 +               usb->ep[0].packets ++;
7008 +       }
7009 +
7010 +       /*
7011 +        * Update remaining byte count for this buffer.
7012 +        */
7013 +       usb->ep[0].pktrem -= len;
7014 +
7015 +       /*
7016 +        * If we received a full-sized packet, and there's more
7017 +        * data remaining, th, queue up another receive.
7018 +        */
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);
7024 +               /*
7025 +                * Clear RPC to receive next packet.
7026 +                */
7027 +               UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
7028 +               dump_buf(usb, "UDC: req");
7029 +               return;
7030 +       }
7031 +
7032 +       naking = 1;
7033 +       udc_ep1_done(usb, 0, usb->ep[0].buflen - usb->ep[0].pktrem);
7034 +}
7035 +
7036 +int udc_ep1_queue_buffer(struct sausb_dev *usb, char *buf, unsigned int len)
7037 +{
7038 +       unsigned long flags;
7039 +       dma_addr_t dma;
7040 +       int ret;
7041 +
7042 +       if (!buf || len == 0)
7043 +               return -EINVAL;
7044 +
7045 +       dma = dma_map_single(usb->dev, buf, len, DMA_FROM_DEVICE);
7046 +
7047 +       spin_lock_irqsave(&usb->lock, flags);
7048 +       do {
7049 +               if (usb->ep[0].buflen) {
7050 +                       ret = -EBUSY;
7051 +                       break;
7052 +               }
7053 +
7054 +               sa1100_clear_dma(usb->ep[0].dmach);
7055 +
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;
7062 +
7063 +               sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].bufdma, usb->ep[0].buflen);
7064 +               dump_buf(usb, "UDC: que");
7065 +
7066 +               if (naking) {
7067 +                       /* turn off NAK of OUT packets, if set */
7068 +                       UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
7069 +                       naking = 0;
7070 +               }
7071 +
7072 +               ret = 0;
7073 +       } while (0);
7074 +       spin_unlock_irqrestore(&usb->lock, flags);
7075 +
7076 +       if (ret)
7077 +               dma_unmap_single(usb->dev, dma, len, DMA_FROM_DEVICE);
7078 +
7079 +       return 0;
7080 +}
7081 +
7082 +void udc_ep1_recv_reset(struct sausb_dev *usb)
7083 +{
7084 +       sa1100_reset_dma(usb->ep[0].dmach);
7085 +       udc_ep1_done(usb, -EINTR, 0);
7086 +}
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
7089 @@ -0,0 +1,63 @@
7090 +/*
7091 + * usb/buffer.c
7092 + *
7093 + * Copyright (C) 2002 Russell King.
7094 + */
7095 +#include <linux/module.h>
7096 +#include <linux/slab.h>
7097 +#include <linux/init.h>
7098 +
7099 +#include "buffer.h"
7100 +
7101 +static LIST_HEAD(buffers);
7102 +
7103 +struct usb_buf *usbb_alloc(int size, int gfp)
7104 +{
7105 +       unsigned long flags;
7106 +       struct usb_buf *buf;
7107 +
7108 +       buf = kmalloc(sizeof(struct usb_buf) + size, gfp);
7109 +       if (buf) {
7110 +               atomic_set(&buf->users, 1);
7111 +               local_irq_save(flags);
7112 +               list_add(&buf->list, &buffers);
7113 +               local_irq_restore(flags);
7114 +               buf->len  = 0;
7115 +               buf->data = (unsigned char *) (buf + 1);
7116 +               buf->head = (unsigned char *) (buf + 1);
7117 +       }
7118 +
7119 +       return buf;
7120 +}
7121 +
7122 +void __usbb_free(struct usb_buf *buf)
7123 +{
7124 +       unsigned long flags;
7125 +       local_irq_save(flags);
7126 +       list_del(&buf->list);
7127 +       local_irq_restore(flags);
7128 +       kfree(buf);
7129 +}
7130 +
7131 +EXPORT_SYMBOL(usbb_alloc);
7132 +EXPORT_SYMBOL(__usbb_free);
7133 +
7134 +static void __exit usbb_exit(void)
7135 +{
7136 +       if (!list_empty(&buffers)) {
7137 +               struct list_head *l, *n;
7138 +               printk("usbb: buffers not freed:\n");
7139 +
7140 +               list_for_each_safe(l, n, &buffers) {
7141 +                       struct usb_buf *b = list_entry(l, struct usb_buf, list);
7142 +
7143 +                       printk(" %p: alloced from %p count %d\n",
7144 +                               b, b->alloced_by, atomic_read(&b->users));
7145 +
7146 +                       __usbb_free(b);
7147 +               }
7148 +       }
7149 +}
7150 +
7151 +module_exit(usbb_exit);
7152 +
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
7155 @@ -0,0 +1,34 @@
7156 +/*
7157 + * Copyright (C) 2001 Extenex Corporation
7158 + *
7159 + * usb-char.h
7160 + *
7161 + * Character device emulation client for SA-1100 client usb core.
7162 + *
7163 + *
7164 + *
7165 + */
7166 +#ifndef _USB_CHAR_H
7167 +#define _USB_CHAR_H
7168 +
7169 +#define USBC_MAJOR 10      /* miscellaneous character device */
7170 +#define USBC_MINOR 240     /* in the "reserved for local use" range */
7171 +
7172 +#define USBC_MAGIC 0x8E
7173 +
7174 +/* zap everything in receive ring buffer */
7175 +#define USBC_IOC_FLUSH_RECEIVER    _IO( USBC_MAGIC, 0x01 )
7176 +
7177 +/* reset transmitter */
7178 +#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 )
7179 +
7180 +/* do both of above */
7181 +#define USBC_IOC_FLUSH_ALL         _IO( USBC_MAGIC, 0x03 )
7182 +
7183 +
7184 +
7185 +
7186 +
7187 +
7188 +#endif /* _USB_CHAR_H */
7189 +
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
7192 @@ -0,0 +1,45 @@
7193 +/*
7194 + * usb/buffer.h: USB client buffers
7195 + *
7196 + * Copyright (C) 2002 Russell King.
7197 + *
7198 + * Loosely based on linux/skbuff.h
7199 + */
7200 +#ifndef USBDEV_BUFFER_H
7201 +#define USBDEV_BUFFER_H
7202 +
7203 +#include <linux/list.h>
7204 +
7205 +struct usb_buf {
7206 +       atomic_t        users;
7207 +       struct list_head list;
7208 +       void            *alloced_by;
7209 +       unsigned char   *data;
7210 +       unsigned char   *head;
7211 +       unsigned int    len;
7212 +};
7213 +
7214 +extern struct usb_buf *usbb_alloc(int size, int gfp);
7215 +extern void __usbb_free(struct usb_buf *);
7216 +
7217 +static inline struct usb_buf *usbb_get(struct usb_buf *buf)
7218 +{
7219 +       atomic_inc(&buf->users);
7220 +       return buf;
7221 +}
7222 +
7223 +static inline void usbb_put(struct usb_buf *buf)
7224 +{
7225 +       if (atomic_dec_and_test(&buf->users))
7226 +               __usbb_free(buf);
7227 +}
7228 +
7229 +static inline void *usbb_push(struct usb_buf *buf, int len)
7230 +{
7231 +       unsigned char *b = buf->head;
7232 +       buf->head += len;
7233 +       buf->len += len;
7234 +       return b;
7235 +}
7236 +
7237 +#endif
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
7240 @@ -0,0 +1,1160 @@
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>
7249 +
7250 +#include <asm/mach-types.h>
7251 +#include <asm/io.h>
7252 +#include <asm/dma.h>
7253 +#include <asm/irq.h>
7254 +
7255 +#include "buffer.h"
7256 +#include "usbdev.h"
7257 +#include "sa1100_usb.h"
7258 +#include "sa1100usb.h"
7259 +
7260 +#ifdef DEBUG
7261 +#define DPRINTK(fmt, args...) printk( fmt , ## args)
7262 +#else
7263 +#define DPRINTK(fmt, args...)
7264 +#endif
7265 +
7266 +static inline void pcs(const char *prefix)
7267 +{
7268 +#ifdef DEBUG
7269 +       __u32 foo = Ser0UDCCS0;
7270 +
7271 +       DPRINTK("%s UDCAR: %d\n", prefix, Ser0UDCAR);
7272 +
7273 +       printk("UDC: %s: %08x [ %s%s%s%s%s%s]\n", prefix,
7274 +              foo,
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 " : "");
7281 +#endif
7282 +}
7283 +
7284 +/*
7285 + * soft_connect_hook()
7286 + *
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.
7292 + */
7293 +static inline void soft_connect_hook(int enable)
7294 +{
7295 +#ifdef CONFIG_SA1100_EXTENEX1
7296 +       if (machine_is_extenex1()) {
7297 +               if (enable) {
7298 +                       PPDR |= PPC_USB_SOFT_CON;
7299 +                       PPSR |= PPC_USB_SOFT_CON;
7300 +               } else {
7301 +                       PPSR &= ~PPC_USB_SOFT_CON;
7302 +                       PPDR &= ~PPC_USB_SOFT_CON;
7303 +               }
7304 +       }
7305 +#endif
7306 +}
7307 +
7308 +/*
7309 + * disable the UDC at the source
7310 + */
7311 +static inline void udc_disable(struct sausb_dev *usb)
7312 +{
7313 +       soft_connect_hook(0);
7314 +
7315 +       usb->udccr = UDCCR_UDD | UDCCR_SUSIM;
7316 +
7317 +       UDC_write(Ser0UDCCR, usb->udccr);
7318 +}
7319 +
7320 +/*
7321 + * Clear any pending write from the EP0 write buffer.
7322 + */
7323 +static void ep0_clear_write(struct sausb_dev *usb)
7324 +{
7325 +       struct usb_buf *buf;
7326 +
7327 +       buf = usb->wrbuf;
7328 +       usb->wrint = NULL;
7329 +       usb->wrbuf = NULL;
7330 +       usb->wrptr = NULL;
7331 +       usb->wrlen = 0;
7332 +
7333 +       if (buf)
7334 +               usbb_put(buf);
7335 +}
7336 +
7337 +static int udc_start(void *priv)
7338 +{
7339 +       struct sausb_dev *usb = priv;
7340 +
7341 +       usb->ep[0].maxpktsize = 0;
7342 +       usb->ep[1].maxpktsize = 0;
7343 +
7344 +       /*
7345 +        * start UDC internal machinery running, but mask interrupts.
7346 +        */
7347 +       usb->udccr = UDCCR_SUSIM | UDCCR_TIM | UDCCR_RIM | UDCCR_EIM |
7348 +                    UDCCR_RESIM;
7349 +       UDC_write(Ser0UDCCR, usb->udccr);
7350 +
7351 +       udelay(100);
7352 +
7353 +       /*
7354 +        * clear all interrupt sources
7355 +        */
7356 +       Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR |
7357 +                   UDCSR_RIR | UDCSR_TIR | UDCSR_SUSIR;
7358 +
7359 +       /*
7360 +        * flush DMA and fire through some -EAGAINs
7361 +        */
7362 +       udc_ep1_init(usb);
7363 +       udc_ep2_init(usb);
7364 +
7365 +       /*
7366 +        * enable any platform specific hardware
7367 +        */
7368 +       soft_connect_hook(1);
7369 +
7370 +       /*
7371 +        * Enable resume, suspend and endpoint 0 interrupts.  Leave
7372 +        * endpoint 1 and 2 interrupts masked.
7373 +        *
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.
7378 +        */
7379 +       usb->udccr &= ~(UDCCR_SUSIM | UDCCR_EIM | UDCCR_RESIM);
7380 +       UDC_write(Ser0UDCCR, usb->udccr);
7381 +
7382 +       return 0;
7383 +}
7384 +
7385 +static int udc_stop(void *priv)
7386 +{
7387 +       struct sausb_dev *usb = priv;
7388 +
7389 +       ep0_clear_write(usb);
7390 +
7391 +       /* mask everything */
7392 +       Ser0UDCCR = 0xFC;
7393 +
7394 +       udc_ep1_reset(usb);
7395 +       udc_ep2_reset(usb);
7396 +
7397 +       udc_disable(usb);
7398 +
7399 +       return 0;
7400 +}
7401 +
7402 +
7403 +
7404 +
7405 +
7406 +/*
7407 + * some voodo I am adding, since the vanilla macros just aren't doing it
7408 + * 1Mar01ww
7409 + */
7410 +
7411 +#define ABORT_BITS     (UDCCS0_SST | UDCCS0_SE)
7412 +#define OK_TO_WRITE    (!(Ser0UDCCS0 & ABORT_BITS))
7413 +#define BOTH_BITS      (UDCCS0_IPR | UDCCS0_DE)
7414 +
7415 +static void set_de(void)
7416 +{
7417 +       int i = 1;
7418 +
7419 +       while (1) {
7420 +               if (OK_TO_WRITE) {
7421 +                       Ser0UDCCS0 |= UDCCS0_DE;
7422 +               } else {
7423 +                       DPRINTK("UDC: quitting set DE because SST or SE set\n");
7424 +                       break;
7425 +               }
7426 +               if (Ser0UDCCS0 & UDCCS0_DE)
7427 +                       break;
7428 +               udelay(i);
7429 +               if (++i == 50) {
7430 +                       printk("UDC: Dangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n",
7431 +                              UDCCS0_DE, Ser0UDCCS0);
7432 +                       break;
7433 +               }
7434 +       }
7435 +}
7436 +
7437 +static void set_ipr(void)
7438 +{
7439 +       int i = 1;
7440 +
7441 +       while (1) {
7442 +               if (OK_TO_WRITE) {
7443 +                       Ser0UDCCS0 |= UDCCS0_IPR;
7444 +               } else {
7445 +                       DPRINTK("UDC: Quitting set IPR because SST or SE set\n");
7446 +                       break;
7447 +               }
7448 +               if (Ser0UDCCS0 & UDCCS0_IPR)
7449 +                       break;
7450 +               udelay(i);
7451 +               if (++i == 50) {
7452 +                       printk("UDC: Dangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n",
7453 +                              UDCCS0_IPR, Ser0UDCCS0);
7454 +                       break;
7455 +               }
7456 +       }
7457 +}
7458 +
7459 +static void set_ipr_and_de(void)
7460 +{
7461 +       int i = 1;
7462 +
7463 +       while (1) {
7464 +               if (OK_TO_WRITE) {
7465 +                       Ser0UDCCS0 |= BOTH_BITS;
7466 +               } else {
7467 +                       DPRINTK("UDC: Quitting set IPR/DE because SST or SE set\n");
7468 +                       break;
7469 +               }
7470 +               if ((Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS)
7471 +                       break;
7472 +               udelay(i);
7473 +               if (++i == 50) {
7474 +                       printk("UDC: Dangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n",
7475 +                              UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0);
7476 +                       break;
7477 +               }
7478 +       }
7479 +}
7480 +
7481 +static inline void set_cs_bits(__u32 bits)
7482 +{
7483 +       if (bits & (UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST | UDCCS0_SST))
7484 +               Ser0UDCCS0 = bits;
7485 +       else if ((bits & BOTH_BITS) == BOTH_BITS)
7486 +               set_ipr_and_de();
7487 +       else if (bits & UDCCS0_IPR)
7488 +               set_ipr();
7489 +       else if (bits & UDCCS0_DE)
7490 +               set_de();
7491 +}
7492 +
7493 +/*
7494 + * udc_ep0_write_fifo()
7495 + *
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).
7504 + */
7505 +static void udc_ep0_write_fifo(struct sausb_dev *usb)
7506 +{
7507 +       unsigned int bytes_this_time = min(usb->wrlen, 8U);
7508 +       int bytes_written = 0;
7509 +
7510 +       DPRINTK("WF=%d: ", bytes_this_time);
7511 +
7512 +       while (bytes_this_time--) {
7513 +               unsigned int cwc;
7514 +               int i;
7515 +
7516 +               DPRINTK("%2.2X ", *usb->wrptr);
7517 +
7518 +               cwc = Ser0UDCWC & 15;
7519 +
7520 +               i = 10;
7521 +               do {
7522 +                       Ser0UDCD0 = *usb->wrptr;
7523 +                       udelay(20);     /* voodo 28Feb01ww */
7524 +               } while ((Ser0UDCWC & 15) == cwc && --i);
7525 +
7526 +               if (i == 0) {
7527 +                       printk("UDC: udc_ep0_write_fifo: write failure\n");
7528 +                       usb->ep0_wr_fifo_errs++;
7529 +               }
7530 +
7531 +               usb->wrptr++;
7532 +               bytes_written++;
7533 +       }
7534 +       usb->wrlen -= bytes_written;
7535 +
7536 +       /* following propagation voodo so maybe caller writing IPR in
7537 +          ..a moment might actually get it to stick 28Feb01ww */
7538 +       udelay(300);
7539 +
7540 +       usb->ep0_wr_bytes += bytes_written;
7541 +       DPRINTK("L=%d WCR=%8.8X\n", usb->wrlen, Ser0UDCWC);
7542 +}
7543 +
7544 +/*
7545 + * read_fifo()
7546 + *
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
7549 + * bytes read.
7550 + *
7551 + * Like write fifo above, this driver uses multiple reads checked
7552 + * against the count register with an overall timeout.
7553 + */
7554 +static int
7555 +udc_ep0_read_fifo(struct sausb_dev *usb, struct usb_ctrlrequest *request, int sz)
7556 +{
7557 +       unsigned char *pOut = (unsigned char *) request;
7558 +       unsigned int fifo_count, bytes_read = 0;
7559 +
7560 +       fifo_count = Ser0UDCWC & 15;
7561 +
7562 +       DPRINTK("RF=%d ", fifo_count);
7563 +       BUG_ON(fifo_count > sz);
7564 +
7565 +       while (fifo_count--) {
7566 +               unsigned int cwc;
7567 +               int i;
7568 +
7569 +               cwc = Ser0UDCWC & 15;
7570 +
7571 +               i = 10;
7572 +               do {
7573 +                       *pOut = (unsigned char) Ser0UDCD0;
7574 +                       udelay(20);
7575 +               } while ((Ser0UDCWC & 15) == cwc && --i);
7576 +
7577 +               if (i == 0) {
7578 +                       printk(KERN_ERR "UDC: udc_ep0_read_fifo: read failure\n");
7579 +                       usb->ep0_rd_fifo_errs++;
7580 +                       break;
7581 +               }
7582 +               pOut++;
7583 +               bytes_read++;
7584 +       }
7585 +
7586 +       DPRINTK("fc=%d\n", bytes_read);
7587 +       usb->ep0_rd_bytes += bytes_read;
7588 +       usb->ep0_rd_packets ++;
7589 +       return bytes_read;
7590 +}
7591 +
7592 +static void ep0_sh_write_data(struct sausb_dev *usb)
7593 +{
7594 +       /*
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
7599 +        */
7600 +       set_cs_bits(UDCCS0_DE);
7601 +}
7602 +
7603 +static void ep0_sh_write_with_empty_packet(struct sausb_dev *usb)
7604 +{
7605 +       /*
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
7609 +        */
7610 +       set_cs_bits(UDCCS0_IPR | UDCCS0_DE);
7611 +       DPRINTK("UDC: sh_write_empty: Sent empty packet\n");
7612 +}
7613 +
7614 +static int udc_clear_opr(void)
7615 +{
7616 +       int i = 10000;
7617 +       int is_clear;
7618 +
7619 +       /*FIXME*/
7620 +       do {
7621 +               Ser0UDCCS0 = UDCCS0_SO;
7622 +               is_clear = !(Ser0UDCCS0 & UDCCS0_OPR);
7623 +               if (i-- <= 0)
7624 +                       break;
7625 +       } while (!is_clear);
7626 +
7627 +       return is_clear;
7628 +}
7629 +
7630 +static int udc_ep0_queue(void *priv, struct usb_buf *buf,
7631 +                        unsigned int req_len)
7632 +{
7633 +       struct sausb_dev *usb = priv;
7634 +       __u32 cs_reg_bits = UDCCS0_IPR;
7635 +
7636 +       DPRINTK("a=%d r=%d\n", buf->len, req_len);
7637 +
7638 +       /*
7639 +        * thou shalt not enter data phase until
7640 +        * Out Packet Ready is clear
7641 +        */
7642 +       if (!udc_clear_opr()) {
7643 +               printk("UDC: SO did not clear OPR\n");
7644 +               set_cs_bits(UDCCS0_DE | UDCCS0_SO);
7645 +               usbb_put(buf);
7646 +               return 1;
7647 +       }
7648 +
7649 +       usb->ep0_wr_packets++;
7650 +
7651 +       usb->wrbuf = buf;
7652 +       usb->wrptr = buf->data;
7653 +       usb->wrlen = min(buf->len, req_len);
7654 +
7655 +       udc_ep0_write_fifo(usb);
7656 +
7657 +       if (usb->wrlen == 0) {
7658 +               /*
7659 +                * out in one, so data end
7660 +                */
7661 +               cs_reg_bits |= UDCCS0_DE;
7662 +               ep0_clear_write(usb);
7663 +       } else if (buf->len < req_len) {
7664 +               /*
7665 +                * we are going to short-change host
7666 +                * so need nul to not stall
7667 +                */
7668 +               usb->wrint = ep0_sh_write_with_empty_packet;
7669 +       } else {
7670 +               /*
7671 +                * we have as much or more than requested
7672 +                */
7673 +               usb->wrint = ep0_sh_write_data;
7674 +       }
7675 +
7676 +       /*
7677 +        * note: IPR was set uncondtionally at start of routine
7678 +        */
7679 +       set_cs_bits(cs_reg_bits);
7680 +       return 0;
7681 +}
7682 +
7683 +/*
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
7686 + * address.
7687 + *
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...
7693 + */
7694 +static void udc_set_address(void *priv, unsigned int addr)
7695 +{
7696 +       Ser0UDCAR = addr;
7697 +}
7698 +
7699 +static void udc_set_config(void *priv, struct cdb *cdb)
7700 +{
7701 +       struct sausb_dev *usb = priv;
7702 +
7703 +       if (cdb) {
7704 +               udc_ep1_config(usb, le16_to_cpu(cdb->ep1.wMaxPacketSize));
7705 +               udc_ep2_config(usb, le16_to_cpu(cdb->ep2.wMaxPacketSize));
7706 +       } else {
7707 +               udc_ep1_reset(usb);
7708 +               udc_ep2_reset(usb);
7709 +       }
7710 +}
7711 +
7712 +static unsigned int udc_ep_get_status(void *priv, unsigned int ep)
7713 +{
7714 +       unsigned int status;
7715 +
7716 +       switch (ep) {
7717 +       case 0:
7718 +               status = (Ser0UDCCS0 & UDCCS0_FST) ? 1 : 0;
7719 +               break;
7720 +
7721 +       case 1:
7722 +               status = (Ser0UDCCS1 & UDCCS1_FST) ? 1 : 0;
7723 +               break;
7724 +
7725 +       case 2:
7726 +               status = (Ser0UDCCS2 & UDCCS2_FST) ? 1 : 0;
7727 +               break;
7728 +
7729 +       default:
7730 +               printk(KERN_ERR "UDC: get_status: bad end point %d\n", ep);
7731 +               status = 0;
7732 +               break;
7733 +       }
7734 +
7735 +       return status;
7736 +}
7737 +
7738 +static void udc_ep_halt(void *priv, unsigned int ep, int halt)
7739 +{
7740 +       struct sausb_dev *usb = priv;
7741 +
7742 +       printk("UDC: ep%d %s halt\n", ep, halt ? "set" : "clear");
7743 +
7744 +       switch (ep) {
7745 +       case 1:
7746 +               udc_ep1_halt(usb, halt);
7747 +               break;
7748 +
7749 +       case 2:
7750 +               udc_ep2_halt(usb, halt);
7751 +               break;
7752 +       }
7753 +}
7754 +
7755 +static int udc_ep_queue(void *priv, unsigned int ep, char *buf, unsigned int len)
7756 +{
7757 +       struct sausb_dev *usb = priv;
7758 +       int ret = -EINVAL;
7759 +
7760 +       switch (ep) {
7761 +       case 1:
7762 +               ret = udc_ep1_queue_buffer(usb, buf, len);
7763 +               break;
7764 +       case 2:
7765 +               ret = udc_ep2_send(usb, buf, len);
7766 +               break;
7767 +       }
7768 +
7769 +       return ret;
7770 +}
7771 +
7772 +static void udc_ep_reset(void *priv, unsigned int ep)
7773 +{
7774 +       struct sausb_dev *usb = priv;
7775 +
7776 +       switch (ep) {
7777 +       case 1:
7778 +               udc_ep1_recv_reset(usb);
7779 +               break;
7780 +       case 2:
7781 +               udc_ep2_send_reset(usb);
7782 +               break;
7783 +       }
7784 +}
7785 +
7786 +static void udc_ep_callback(void *priv, unsigned int ep, usb_callback_t cb, void *data)
7787 +{
7788 +       struct sausb_dev *usb = priv;
7789 +       unsigned long flags;
7790 +
7791 +       if (ep == 1 || ep == 2) {
7792 +               ep -= 1;
7793 +
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);
7798 +       }
7799 +}
7800 +
7801 +static int udc_ep_idle(void *priv, unsigned int ep)
7802 +{
7803 +       struct sausb_dev *usb = priv;
7804 +       int ret = -EINVAL;
7805 +
7806 +       switch (ep) {
7807 +       case 1:
7808 +               break;
7809 +       case 2:
7810 +               ret = udc_ep2_idle(usb);
7811 +               break;
7812 +       }
7813 +
7814 +       return ret;
7815 +}
7816 +
7817 +static struct usbc_driver usb_sa1100_drv = {
7818 +       .owner          = THIS_MODULE,
7819 +       .name           = "SA1100",
7820 +       .start          = udc_start,
7821 +       .stop           = udc_stop,
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,
7831 +};
7832 +
7833 +
7834 +/*
7835 + * udc_ep0_read_packet()
7836 + *
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.
7842 + */
7843 +static void udc_ep0_read_packet(struct sausb_dev *usb, u32 cs_reg_in)
7844 +{
7845 +       struct usb_ctrlrequest req;
7846 +       int n, ret = RET_NOACTION;
7847 +
7848 +       /*
7849 +        * A control request has been received by EP0.
7850 +        * Read the request.
7851 +        */
7852 +       n = udc_ep0_read_fifo(usb, &req, sizeof(req));
7853 +
7854 +       if (n == sizeof(req)) {
7855 +               ret = usbctl_parse_request(usb->ctl, &req);
7856 +       } else {
7857 +               /*
7858 +                * The request wasn't fully received.  Force a
7859 +                * stall.
7860 +                */
7861 +               set_cs_bits(UDCCS0_FST | UDCCS0_SO);
7862 +               printk("UDC: fifo read error: wanted %d bytes got %d\n",
7863 +                      sizeof(req), n);
7864 +       }
7865 +
7866 +       switch (ret) {
7867 +       case RET_ERROR:
7868 +       case RET_NOACTION:
7869 +               break;
7870 +
7871 +       case RET_ACK:
7872 +               set_cs_bits(UDCCS0_DE | UDCCS0_SO);
7873 +               break;
7874 +
7875 +       case RET_REQERROR:
7876 +               /*
7877 +                * Send stall PID to host.
7878 +                */
7879 +               set_cs_bits(UDCCS0_DE | UDCCS0_SO | UDCCS0_FST);
7880 +               break;
7881 +       }
7882 +}
7883 +
7884 +/*
7885 + * HACK DEBUG  3Mar01ww
7886 + * Well, maybe not, it really seems to help!  08Mar01ww
7887 + */
7888 +static void core_kicker(struct sausb_dev *usb)
7889 +{
7890 +       __u32 car = Ser0UDCAR;
7891 +       __u32 imp = Ser0UDCIMP;
7892 +       __u32 omp = Ser0UDCOMP;
7893 +
7894 +       UDC_set(Ser0UDCCR, UDCCR_UDD);
7895 +       udelay(300);
7896 +       UDC_clear(Ser0UDCCR, UDCCR_UDD);
7897 +
7898 +       Ser0UDCAR = car;
7899 +       Ser0UDCIMP = imp;
7900 +       Ser0UDCOMP = omp;
7901 +}
7902 +
7903 +static void enable_resume_mask_suspend(struct sausb_dev *usb)
7904 +{
7905 +       int i;
7906 +
7907 +       usb->udccr |= UDCCR_SUSIM;
7908 +
7909 +       i = 1;
7910 +       do {
7911 +               Ser0UDCCR = usb->udccr;
7912 +               udelay(i);
7913 +               if (Ser0UDCCR == usb->udccr)
7914 +                       break;
7915 +               if (Ser0UDCSR & UDCSR_RSTIR)
7916 +                       break;
7917 +       } while (i++ < 50);
7918 +
7919 +       if (i == 50)
7920 +               printk("UDC: enable_resume: could not set SUSIM 0x%08x\n",
7921 +                      Ser0UDCCR);
7922 +
7923 +       usb->udccr &= ~UDCCR_RESIM;
7924 +
7925 +       i = 1;  
7926 +       do {
7927 +               Ser0UDCCR = usb->udccr;
7928 +               udelay(i);
7929 +               if (Ser0UDCCR == usb->udccr)
7930 +                       break;
7931 +               if (Ser0UDCSR & UDCSR_RSTIR)
7932 +                       break;
7933 +       } while (i++ < 50);
7934 +
7935 +       if (i == 50)
7936 +               printk("UDC: enable_resume: could not clear RESIM 0x%08x\n",
7937 +                      Ser0UDCCR);
7938 +}
7939 +
7940 +static void enable_suspend_mask_resume(struct sausb_dev *usb)
7941 +{
7942 +       int i;
7943 +
7944 +       usb->udccr |= UDCCR_RESIM;
7945 +
7946 +       i = 1;
7947 +       do {
7948 +               Ser0UDCCR = usb->udccr;
7949 +               udelay(i);
7950 +               if (Ser0UDCCR == usb->udccr)
7951 +                       break;
7952 +               if (Ser0UDCSR & UDCSR_RSTIR)
7953 +                       break;
7954 +       } while (i++ < 50);
7955 +
7956 +       if (i == 50)
7957 +               printk("UDC: enable_resume: could not set RESIM 0x%08x\n",
7958 +                      Ser0UDCCR);
7959 +
7960 +       usb->udccr &= ~UDCCR_SUSIM;
7961 +
7962 +       i = 1;  
7963 +       do {
7964 +               Ser0UDCCR = usb->udccr;
7965 +               udelay(i);
7966 +               if (Ser0UDCCR == usb->udccr)
7967 +                       break;
7968 +               if (Ser0UDCSR & UDCSR_RSTIR)
7969 +                       break;
7970 +       } while (i++ < 50);
7971 +
7972 +       if (i == 50)
7973 +               printk("UDC: enable_resume: could not clear SUSIM 0x%08x\n",
7974 +                      Ser0UDCCR);
7975 +}
7976 +
7977 +/*
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
7980 + */
7981 +static void udc_reset(struct sausb_dev *usb)
7982 +{
7983 +       if (usbctl_reset(usb->ctl)) {
7984 +               ep0_clear_write(usb);
7985 +
7986 +               /*
7987 +                * Clean up endpoints.
7988 +                */
7989 +               udc_ep1_reset(usb);
7990 +               udc_ep2_reset(usb);
7991 +       }
7992 +
7993 +       /*
7994 +        * mask reset ints, they flood during sequence, enable
7995 +        * suspend and resume
7996 +        */
7997 +       usb->udccr = (usb->udccr & ~(UDCCR_SUSIM | UDCCR_RESIM)) | UDCCR_REM;
7998 +       Ser0UDCCR = usb->udccr;
7999 +}
8000 +
8001 +/*
8002 + * handle interrupt for endpoint zero
8003 + */
8004 +static void udc_ep0_int_hndlr(struct sausb_dev *usb)
8005 +{
8006 +       u32 cs_reg_in;
8007 +
8008 +       pcs("-->");
8009 +
8010 +       cs_reg_in = Ser0UDCCS0;
8011 +
8012 +       /*
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.
8022 +        */
8023 +       if (cs_reg_in & UDCCS0_SE) {
8024 +               DPRINTK("UDC: early termination of setup\n");
8025 +
8026 +               /*
8027 +                * Clear setup end
8028 +                */
8029 +               set_cs_bits(UDCCS0_SSE);
8030 +
8031 +               /*
8032 +                * Clear any pending write.
8033 +                */
8034 +               ep0_clear_write(usb);
8035 +       }
8036 +
8037 +       /*
8038 +        * UDC sent a stall due to a protocol violation.
8039 +        */
8040 +       if (cs_reg_in & UDCCS0_SST) {
8041 +               usb->ep0_stall_sent++;
8042 +
8043 +               DPRINTK("UDC: write_preamble: UDC sent stall\n");
8044 +
8045 +               /*
8046 +                * Clear sent stall
8047 +                */
8048 +               set_cs_bits(UDCCS0_SST);
8049 +
8050 +               /*
8051 +                * Clear any pending write.
8052 +                */
8053 +               ep0_clear_write(usb);
8054 +       }
8055 +
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");
8060 +
8061 +               /*
8062 +                * very rarely, you can get OPR and
8063 +                * leftover IPR. Try to clear
8064 +                */
8065 +               UDC_clear(Ser0UDCCS0, UDCCS0_IPR);
8066 +
8067 +               /*
8068 +                * Clear any pending write.
8069 +                */
8070 +               ep0_clear_write(usb);
8071 +
8072 +               /*FALLTHROUGH*/
8073 +       case UDCCS0_OPR:
8074 +               /*
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.
8078 +                */
8079 +               udc_ep0_read_packet(usb, cs_reg_in);
8080 +               break;
8081 +
8082 +       case 0:
8083 +               if (usb->wrint) {
8084 +                       if (usb->wrlen != 0) {
8085 +                               /*
8086 +                                * More data to go
8087 +                                */
8088 +                               udc_ep0_write_fifo(usb);
8089 +                               set_ipr();
8090 +                       }
8091 +
8092 +                       if (usb->wrlen == 0) {
8093 +                               /*
8094 +                                * All data sent.
8095 +                                */
8096 +                               usb->wrint(usb);
8097 +
8098 +                               ep0_clear_write(usb);
8099 +                       }
8100 +               }
8101 +               break;
8102 +
8103 +       case UDCCS0_IPR:
8104 +               DPRINTK("UDC: IPR set, not writing\n");
8105 +               usb->ep0_early_irqs++;
8106 +               break;
8107 +       }
8108 +
8109 +       pcs("<--");
8110 +}
8111 +
8112 +static irqreturn_t udc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
8113 +{
8114 +       struct sausb_dev *usb = dev_id;
8115 +       u32 status = Ser0UDCSR;
8116 +
8117 +       /*
8118 +        * ReSeT Interrupt Request - UDC has been reset
8119 +        */
8120 +       if (status & UDCSR_RSTIR) {
8121 +               udc_reset(usb);
8122 +
8123 +               /*
8124 +                * clear all pending sources
8125 +                */
8126 +               UDC_flip(Ser0UDCSR, status);
8127 +               return IRQ_HANDLED;
8128 +       }
8129 +
8130 +       /*
8131 +        * else we have done something other than reset,
8132 +        * so be sure reset enabled
8133 +        */
8134 +       usb->udccr &= ~UDCCR_REM;
8135 +       UDC_write(Ser0UDCCR, usb->udccr);
8136 +
8137 +       /*
8138 +        * RESume Interrupt Request
8139 +        */
8140 +       if (status & UDCSR_RESIR) {
8141 +               usbctl_resume(usb->ctl);
8142 +               core_kicker(usb);
8143 +               enable_suspend_mask_resume(usb);
8144 +       }
8145 +
8146 +       /*
8147 +        * SUSpend Interrupt Request
8148 +        */
8149 +       if (status & UDCSR_SUSIR) {
8150 +               usbctl_suspend(usb->ctl);
8151 +               enable_resume_mask_suspend(usb);
8152 +       }
8153 +
8154 +       /*
8155 +        * clear all pending sources
8156 +        */
8157 +       UDC_flip(Ser0UDCSR, status);
8158 +
8159 +       if (status & UDCSR_EIR)
8160 +               udc_ep0_int_hndlr(usb);
8161 +
8162 +       if (status & UDCSR_RIR)
8163 +               udc_ep1_int_hndlr(usb);
8164 +
8165 +       if (status & UDCSR_TIR)
8166 +               udc_ep2_int_hndlr(usb);
8167 +
8168 +       return IRQ_HANDLED;
8169 +}
8170 +
8171 +#ifdef CONFIG_PROC_FS
8172 +
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 )
8177 +
8178 +static int
8179 +udc_read_proc(char *page, char **start, off_t off, int cnt, int *eof,
8180 +             void *data)
8181 +{
8182 +       struct sausb_dev *usb = data;
8183 +       char *p = page;
8184 +       u32 v;
8185 +       int len, i;
8186 +
8187 +       p += usbctl_proc_info(usb->ctl, p);
8188 +       p += sprintf(p, "\nUDC:\n");
8189 +       v = Ser0UDCAR;
8190 +       p += sprintf(p, "Address\t: %d (0x%02x)\n", v, v);
8191 +       v = Ser0UDCIMP;
8192 +       p += sprintf(p, "IN max\t: %d (0x%02x)\n", v + 1, v);
8193 +       v = Ser0UDCOMP;
8194 +       p += sprintf(p, "OUT max\t: %d (0x%02x)\n", v + 1, v);
8195 +       v = Ser0UDCCR;
8196 +       p += sprintf(p, "UDCCR\t: 0x%02x "
8197 +                       "[ %cSUSIM %cTIM %cRIM %cEIM %cRESIM %cUDA %cUDD ] "
8198 +                       "(0x%02x)\n",
8199 +                       v,
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);
8204 +       v = Ser0UDCCS0;
8205 +       p += sprintf(p, "UDCCS0\t: 0x%02x "
8206 +                       "[ %cSO    %cSE  %cDE  %cFST %cSST   %cIPR %cOPR ]\n",
8207 +                       v,
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 ? '+' : '-');
8212 +       v = Ser0UDCCS1;
8213 +       p += sprintf(p, "UDCCS1\t: 0x%02x "
8214 +                       "[         %cRNE %cFST %cSST %cRPE   %cRPC %cRFS ]\n",
8215 +                       v,
8216 +                       v & UDCCS1_RNE ? '+' : '-', v & UDCCS1_FST ? '+' : '-',
8217 +                       v & UDCCS1_SST ? '+' : '-', v & UDCCS1_RPE ? '+' : '-',
8218 +                       v & UDCCS1_RPC ? '+' : '-', v & UDCCS1_RFS ? '+' : '-');
8219 +       v = Ser0UDCCS2;
8220 +       p += sprintf(p, "UDCCS2\t: 0x%02x "
8221 +                       "[         %cFST %cSST %cTUR %cTPE   %cTPC %cTFS ]\n",
8222 +                       v,
8223 +                       v & UDCCS2_FST ? '+' : '-', v & UDCCS2_SST ? '+' : '-',
8224 +                       v & UDCCS2_TUR ? '+' : '-', v & UDCCS2_TPE ? '+' : '-',
8225 +                       v & UDCCS2_TPC ? '+' : '-', v & UDCCS2_TFS ? '+' : '-');
8226 +
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);
8237 +
8238 +       for (i = 0; i < 2; i++)
8239 +               p += sprintf(p, "EP%d   : %10ld %10ld %10ld %6d\n",
8240 +                            i + 1,
8241 +                            usb->ep[i].bytes,
8242 +                            usb->ep[i].packets,
8243 +                            usb->ep[i].fifo_errs,
8244 +                            usb->ep[i].maxpktsize);
8245 +
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);
8248 +
8249 +#if 0
8250 +       v = Ser0UDCSR;
8251 +       SAY("\nUDC Interrupt Request Register\n");
8252 +       SAYV(v);
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);
8259 +
8260 +#ifdef CONFIG_SA1100_EXTENEX1
8261 +       SAYC("\nSoft connect",
8262 +            (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden");
8263 +#endif
8264 +#endif
8265 +
8266 +       len = (p - page) - off;
8267 +       if (len < 0)
8268 +               len = 0;
8269 +       *eof = (len <= cnt) ? 1 : 0;
8270 +       *start = page + off;
8271 +
8272 +       return len;
8273 +}
8274 +
8275 +#endif
8276 +
8277 +extern struct usbctl usbctl;
8278 +
8279 +static int __devinit udc_probe(struct device *dev)
8280 +{
8281 +       struct sausb_dev *usb;
8282 +       int retval;
8283 +
8284 +       if (!request_mem_region(0x80000000, 0x10000, "sa11x0-udc"))
8285 +               return -EBUSY;
8286 +
8287 +       usb = kmalloc(sizeof(struct sausb_dev), GFP_KERNEL);
8288 +       if (!usb)
8289 +               return -ENOMEM;
8290 +
8291 +       memset(usb, 0, sizeof(struct sausb_dev));
8292 +       dev_set_drvdata(dev, usb);
8293 +
8294 +       usb_sa1100_drv.priv = usb;
8295 +
8296 +       usb->dev = dev;
8297 +       usb->ctl = &usbctl;
8298 +
8299 +       spin_lock_init(&usb->lock);
8300 +
8301 +       udc_disable(usb);
8302 +
8303 +       usbctl_init(usb->ctl, &usb_sa1100_drv);
8304 +
8305 +#ifdef CONFIG_PROC_FS
8306 +       create_proc_read_entry("sausb", 0, NULL, udc_read_proc, usb);
8307 +#endif
8308 +
8309 +       /* setup rx dma */
8310 +       retval = sa1100_request_dma(DMA_Ser0UDCRd, "USB receive",
8311 +                                   NULL, NULL, &usb->ep[0].dmach);
8312 +       if (retval) {
8313 +               printk("UDC: unable to register for rx dma rc=%d\n",
8314 +                      retval);
8315 +               goto err;
8316 +       }
8317 +
8318 +       /* setup tx dma */
8319 +       retval = sa1100_request_dma(DMA_Ser0UDCWr, "USB transmit",
8320 +                                   NULL, NULL, &usb->ep[1].dmach);
8321 +       if (retval) {
8322 +               printk("UDC: unable to register for tx dma rc=%d\n",
8323 +                      retval);
8324 +               goto err;
8325 +       }
8326 +
8327 +       /* now allocate the IRQ. */
8328 +       retval = request_irq(IRQ_Ser0UDC, udc_interrupt, SA_INTERRUPT,
8329 +                            "SA USB core", usb);
8330 +       if (retval) {
8331 +               printk("UDC: couldn't request USB irq rc=%d\n", retval);
8332 +               goto err;
8333 +       }
8334 +
8335 +       return retval;
8336 +
8337 + err:
8338 +       if (usb->ep[2].dmach) {
8339 +               sa1100_free_dma(usb->ep[2].dmach);
8340 +               usb->ep[2].dmach = NULL;
8341 +       }
8342 +       if (usb->ep[1].dmach) {
8343 +               sa1100_free_dma(usb->ep[1].dmach);
8344 +               usb->ep[1].dmach = NULL;
8345 +       }
8346 +#ifdef CONFIG_PROC_FS
8347 +       remove_proc_entry("sausb", NULL);
8348 +#endif
8349 +       release_mem_region(0x80000000, 0x10000);
8350 +       return retval;
8351 +}
8352 +
8353 +/*
8354 + * Release DMA and interrupt resources
8355 + */
8356 +static int __devexit udc_remove(struct device *dev)
8357 +{
8358 +       struct sausb_dev *usb = dev_get_drvdata(dev);
8359 +
8360 +       dev_set_drvdata(dev, NULL);
8361 +
8362 +#ifdef CONFIG_PROC_FS
8363 +       remove_proc_entry("sausb", NULL);
8364 +#endif
8365 +
8366 +       udc_disable(usb);
8367 +
8368 +       free_irq(IRQ_Ser0UDC, usb);
8369 +       sa1100_free_dma(usb->ep[1].dmach);
8370 +       sa1100_free_dma(usb->ep[0].dmach);
8371 +
8372 +       usbctl_exit(usb->ctl);
8373 +
8374 +       release_mem_region(0x80000000, 0x10000);
8375 +
8376 +       return 0;
8377 +}
8378 +
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),
8384 +};
8385 +
8386 +static int __init udc_init(void)
8387 +{
8388 +       return driver_register(&sa11x0usb_driver);
8389 +}
8390 +
8391 +static void __exit udc_exit(void)
8392 +{
8393 +       driver_unregister(&sa11x0usb_driver);
8394 +}
8395 +
8396 +module_init(udc_init);
8397 +module_exit(udc_exit);
8398 +
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
8403 @@ -0,0 +1,933 @@
8404 +/*
8405 + * usb/control.c
8406 + *
8407 + * This parses and handles all the control messages to/from endpoint 0.
8408 + */
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>
8415 +
8416 +#include "buffer.h"
8417 +#include "client.h"
8418 +#include "usbdev.h"
8419 +
8420 +#include "sa1100_usb.h"
8421 +
8422 +#define USB_ENDPOINT_HALT              0
8423 +#define USB_DEVICE_REMOTE_WAKEUP       1
8424 +
8425 +#undef DEBUG
8426 +
8427 +#ifdef DEBUG
8428 +#define DPRINTK(fmt, args...) printk(KERN_DEBUG fmt , ## args)
8429 +#else
8430 +#define DPRINTK(fmt, args...)
8431 +#endif
8432 +
8433 +/*
8434 + * print string descriptor
8435 + */
8436 +static char * __attribute__((unused))
8437 +psdesc(char *str, int len, struct usb_string_descriptor *desc)
8438 +{
8439 +       char *start = str;
8440 +       int nchars = (desc->bLength - 2) / sizeof(__u16) + 2;
8441 +       int i;
8442 +
8443 +       if (nchars >= len)
8444 +               nchars = len - 1;
8445 +
8446 +       nchars -= 2;
8447 +
8448 +       *str++ = '"';
8449 +       for(i = 0; i < nchars; i++)
8450 +               *str++ = le16_to_cpu(desc->wData[i]);
8451 +       *str++ = '"';
8452 +       *str = '\0';
8453 +
8454 +       return start;
8455 +}
8456 +
8457 +enum {
8458 +       kError          = -1,
8459 +       kEvSuspend      = 0,
8460 +       kEvReset        = 1,
8461 +       kEvResume       = 2,
8462 +       kEvAddress      = 3,
8463 +       kEvConfig       = 4,
8464 +       kEvDeConfig     = 5
8465 +};
8466 +
8467 +enum {
8468 +       kStateZombie            = 0,
8469 +       kStateZombieSuspend     = 1,
8470 +       kStateDefault           = 2,
8471 +       kStateDefaultSuspend    = 3,
8472 +       kStateAddr              = 4,
8473 +       kStateAddrSuspend       = 5,
8474 +       kStateConfig            = 6,
8475 +       kStateConfigSuspend     = 7
8476 +};
8477 +
8478 +#define kE     kError
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
8487 +
8488 +/*
8489 + * Fig 9-1 P192
8490 + *  Zombie == Attached | Powered
8491 + */
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 */
8502 +};
8503 +
8504 +/*
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
8508 + */
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 */
8518 +};
8519 +
8520 +static char * state_names[8] = {
8521 +       "zombie",
8522 +       "zombie suspended",
8523 +       "default",
8524 +       "default suspended",
8525 +       "address",
8526 +       "address suspended",
8527 +       "configured",
8528 +       "config suspended"
8529 +};
8530 +
8531 +static char * event_names[6] = {
8532 +       "suspend",
8533 +       "reset",
8534 +       "resume",
8535 +       "address assigned",
8536 +       "configure",
8537 +       "de-configure"
8538 +};
8539 +
8540 +static char * device_state_names[] = {
8541 +       "not attached",
8542 +       "attached",
8543 +       "powered",
8544 +       "default",
8545 +       "address",
8546 +       "configured",
8547 +       "suspended"
8548 +};
8549 +
8550 +static void usbctl_callbacks(struct usbctl *ctl, int state, int oldstate)
8551 +{
8552 +       struct usb_client *clnt = ctl->clnt;
8553 +
8554 +       /*
8555 +        * Inform any clients currently attached
8556 +        * that the connectivity state changed.
8557 +        */
8558 +       if (clnt && clnt->state_change)
8559 +               clnt->state_change(clnt->priv, state, oldstate);
8560 +}
8561 +
8562 +/*
8563 + * called by the interrupt handler here and the two endpoint
8564 + * files when interesting .."events" happen
8565 + */
8566 +static int usbctl_next_state_on_event(struct usbctl *ctl, int event)
8567 +{
8568 +       int next_state, next_dev_state, old_dev_state;
8569 +
8570 +       printk(KERN_DEBUG "usbctl: %s --[%s]--> ", state_names[ctl->sm_state],
8571 +               event_names[event]);
8572 +
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];
8576 +
8577 +               printk("%s. Device in %s state.\n",
8578 +                       state_names[next_state],
8579 +                       device_state_names[next_dev_state]);
8580 +
8581 +               old_dev_state = ctl->state;
8582 +               ctl->sm_state = next_state;
8583 +               ctl->state = next_dev_state;
8584 +
8585 +               if (old_dev_state != next_dev_state)
8586 +                       usbctl_callbacks(ctl, next_dev_state, old_dev_state);
8587 +       } else
8588 +               printk("(error)\n");
8589 +
8590 +       return next_state;
8591 +}
8592 +
8593 +/*
8594 + * Driver detected USB HUB reset.
8595 + */
8596 +int usbctl_reset(struct usbctl *ctl)
8597 +{
8598 +       int ret;
8599 +
8600 +       ret = usbctl_next_state_on_event(ctl, kEvReset) == kError;
8601 +
8602 +       if (!ret) {
8603 +               ctl->address = 0;
8604 +       }
8605 +       return ret;
8606 +}
8607 +
8608 +EXPORT_SYMBOL(usbctl_reset);
8609 +
8610 +void usbctl_suspend(struct usbctl *ctl)
8611 +{
8612 +       usbctl_next_state_on_event(ctl, kEvSuspend);
8613 +}
8614 +
8615 +EXPORT_SYMBOL(usbctl_suspend);
8616 +
8617 +void usbctl_resume(struct usbctl *ctl)
8618 +{
8619 +       usbctl_next_state_on_event(ctl, kEvResume);
8620 +}
8621 +
8622 +EXPORT_SYMBOL(usbctl_resume);
8623 +
8624 +static struct usb_interface_descriptor *
8625 +usbctl_get_interface_descriptor(struct usbctl *ctl, unsigned int interface)
8626 +{
8627 +       /*FIXME*/
8628 +       struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
8629 +
8630 +       return (struct usb_interface_descriptor *)&cdb->intf;
8631 +}
8632 +
8633 +static inline int
8634 +__usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req,
8635 +              struct usb_buf *buf)
8636 +{
8637 +       unsigned int reqlen = le16_to_cpu(req->wLength);
8638 +
8639 +       return ctl->driver->ep0_queue(ctl->driver->priv, buf, reqlen) ?
8640 +               RET_ERROR : RET_QUEUED;
8641 +}
8642 +
8643 +static int
8644 +usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req,
8645 +            void *data, unsigned int len)
8646 +{
8647 +       struct usb_buf *buf;
8648 +
8649 +       buf = usbb_alloc(len, GFP_ATOMIC);
8650 +       if (!buf) {
8651 +               printk(KERN_ERR "usb: out of memory\n");
8652 +               return RET_ERROR;
8653 +       }
8654 +
8655 +       if (data)
8656 +               memcpy(usbb_push(buf, len), data, len);
8657 +
8658 +       return __usbctl_queue(ctl, req, buf);
8659 +}
8660 +
8661 +/*
8662 + * 9.4.5: Get Status (device)
8663 + */
8664 +static int
8665 +usbctl_parse_dev_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
8666 +{
8667 +       u16 status;
8668 +
8669 +       status = /* self_powered_hook() ? 1 : 0 */1;
8670 +
8671 +       status = cpu_to_le16(status);
8672 +
8673 +       return usbctl_queue(ctl, req, &status, 2);
8674 +}
8675 +
8676 +/*
8677 + * Send USB device description to the host.
8678 + */
8679 +static int
8680 +usbctl_desc_device(struct usbctl *ctl, struct usb_ctrlrequest *req)
8681 +{
8682 +       return __usbctl_queue(ctl, req, usbb_get(ctl->dev_desc_buf));
8683 +}
8684 +
8685 +/*
8686 + * Send USB configuration information to the host.
8687 + */
8688 +static int
8689 +usbctl_desc_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
8690 +{
8691 +       /*FIXME*/
8692 +       struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
8693 +
8694 +       return usbctl_queue(ctl, req, cdb, sizeof(struct cdb));
8695 +}
8696 +
8697 +/*
8698 + * Send a string to the host from the string table.
8699 + */
8700 +static int
8701 +usbctl_desc_string(struct usbctl *ctl, struct usb_ctrlrequest *req,
8702 +                  unsigned int idx)
8703 +{
8704 +       struct usb_buf *buf;
8705 +       unsigned int lang = le16_to_cpu(req->wIndex);
8706 +       char string[32] __attribute__((unused));
8707 +       int ret;
8708 +
8709 +       DPRINTK("usbctl: desc_string (index %u, lang 0x%04x): ", idx, lang);
8710 +
8711 +       buf = usbc_string_find(&ctl->strings, lang, idx);
8712 +       if (buf) {
8713 +               DPRINTK("%s\n", idx == 0 ? "language" :
8714 +                        psdesc(string, sizeof(string), usbc_string_desc(buf)));
8715 +
8716 +               ret = __usbctl_queue(ctl, req, buf);
8717 +       } else {
8718 +               DPRINTK("not found -> stall\n");
8719 +               ret = RET_REQERROR;
8720 +       }
8721 +       return ret;
8722 +}
8723 +
8724 +/*
8725 + * Send an interface description (and endpoints) to the host.
8726 + */
8727 +static int
8728 +usbctl_desc_interface(struct usbctl *ctl, struct usb_ctrlrequest *req,
8729 +                     unsigned int idx)
8730 +{
8731 +       struct usb_interface_descriptor *desc;
8732 +       int ret;
8733 +
8734 +       DPRINTK("usbctl: desc_interface (index %d)\n", idx);
8735 +
8736 +       desc = usbctl_get_interface_descriptor(ctl, idx);
8737 +
8738 +       if (desc) {
8739 +               ret = usbctl_queue(ctl, req, desc, desc->bLength);
8740 +       } else {
8741 +               printk("usbctl: unknown interface %d\n", idx);
8742 +               ret = RET_REQERROR;
8743 +       }
8744 +
8745 +       return ret;
8746 +}
8747 +
8748 +/*
8749 + * Send an endpoint (1 .. n) to the host.
8750 + */
8751 +static int
8752 +usbctl_desc_endpoint(struct usbctl *ctl, struct usb_ctrlrequest *req,
8753 +                    unsigned int idx)
8754 +{
8755 +       int ret;
8756 +
8757 +       DPRINTK("usbctl: desc_endpoint (index %d)\n", idx);
8758 +
8759 +       if (idx >= 1 && idx <= ctl->nr_ep) {
8760 +               struct usb_endpoint_descriptor *ep = ctl->ep_desc[idx - 1];
8761 +
8762 +               ret = usbctl_queue(ctl, req, ep, ep->bLength);
8763 +       } else {
8764 +               printk("usbctl: unknown endpoint %d\n", idx);
8765 +               ret = RET_REQERROR;
8766 +       }
8767 +
8768 +       return ret;
8769 +}
8770 +
8771 +/*
8772 + * 9.4.3: Parse a request for a descriptor.
8773 + *  Unspecified conditions:
8774 + *   None
8775 + *  Valid states: default, address, configured.
8776 + */
8777 +static int
8778 +usbctl_parse_dev_descriptor(struct usbctl *ctl, struct usb_ctrlrequest *req)
8779 +{
8780 +       unsigned int idx = le16_to_cpu(req->wValue) & 255;
8781 +       unsigned int type = le16_to_cpu(req->wValue) >> 8;
8782 +       int ret;
8783 +
8784 +       switch (type) {
8785 +       case USB_DT_DEVICE:             /* check if idx matters */
8786 +               ret = usbctl_desc_device(ctl, req);
8787 +               break;
8788 +
8789 +       case USB_DT_CONFIG:             /* check if idx matters */
8790 +               ret = usbctl_desc_config(ctl, req);
8791 +               break;
8792 +
8793 +       case USB_DT_STRING:
8794 +               ret = usbctl_desc_string(ctl, req, idx);
8795 +               break;
8796 +
8797 +       case USB_DT_INTERFACE:
8798 +               ret = usbctl_desc_interface(ctl, req, idx);
8799 +               break;
8800 +
8801 +       case USB_DT_ENDPOINT:
8802 +               ret = usbctl_desc_endpoint(ctl, req, idx);
8803 +               break;
8804 +
8805 +       case USB_DT_DEVICE_QUALIFIER:
8806 +       case USB_DT_OTHER_SPEED_CONFIG:
8807 +       case USB_DT_INTERFACE_POWER:
8808 +       default:
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;
8813 +               break;
8814 +       }
8815 +
8816 +       return ret;
8817 +}
8818 +
8819 +/*
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.
8824 + */
8825 +static int
8826 +usbctl_parse_dev_set_address(struct usbctl *ctl, struct usb_ctrlrequest *req)
8827 +{
8828 +       unsigned int address = le16_to_cpu(req->wValue) & 0x7f;
8829 +
8830 +       if (ctl->state == USB_STATE_CONFIGURED)
8831 +               return RET_REQERROR;
8832 +
8833 +       if (address != 0) {
8834 +               ctl->address = address;
8835 +
8836 +               usbctl_next_state_on_event(ctl, kEvAddress);
8837 +
8838 +               ctl->driver->set_address(ctl->driver->priv, address);
8839 +       }
8840 +
8841 +       return RET_ACK;
8842 +}
8843 +
8844 +/*
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.
8850 + */
8851 +static int
8852 +usbctl_parse_dev_get_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
8853 +{
8854 +       u8 status = 0;
8855 +
8856 +       if (ctl->state == USB_STATE_CONFIGURED)
8857 +               status = 1;
8858 +
8859 +       return usbctl_queue(ctl, req, &status, 1);
8860 +}
8861 +
8862 +/*
8863 + * 9.4.7: Set Configuration.
8864 + *  Unspecified conditions:
8865 + *   - default state (request error)
8866 + */
8867 +static int
8868 +usbctl_parse_dev_set_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
8869 +{
8870 +       unsigned int cfg = le16_to_cpu(req->wValue);
8871 +       int ret = RET_REQERROR;
8872 +
8873 +       if (ctl->state == USB_STATE_DEFAULT)
8874 +               return ret;
8875 +
8876 +       if (cfg == 0) {
8877 +               /* enter address state, or remain in address state */
8878 +               usbctl_next_state_on_event(ctl, kEvDeConfig);
8879 +
8880 +               ctl->driver->set_config(ctl->driver->priv, NULL);
8881 +
8882 +               ret = RET_ACK;
8883 +       } else if (cfg == 1) {
8884 +               /* enter configured state, and set configuration */
8885 +               /*FIXME*/
8886 +               struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
8887 +
8888 +               usbctl_next_state_on_event(ctl, kEvConfig);
8889 +
8890 +               ctl->driver->set_config(ctl->driver->priv, cdb);
8891 +               ret = RET_ACK;
8892 +       }
8893 +
8894 +       return ret;
8895 +}
8896 +
8897 +/*
8898 + * Interface handling
8899 + */
8900 +
8901 +/*
8902 + * 9.4.5: Get Status (interface)
8903 + */
8904 +static int
8905 +usbctl_parse_int_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
8906 +{
8907 +       unsigned int interface = le16_to_cpu(req->wIndex) & 255;
8908 +       u16 status;
8909 +
8910 +       switch (ctl->state) {
8911 +       case USB_STATE_DEFAULT:
8912 +               return RET_REQERROR;
8913 +
8914 +       case USB_STATE_ADDRESS:
8915 +               if (interface != 0)
8916 +                       return RET_REQERROR;
8917 +               break;
8918 +
8919 +       case USB_STATE_CONFIGURED:
8920 +               if (interface != 1)
8921 +                       return RET_REQERROR;
8922 +               break;
8923 +       }
8924 +
8925 +       status = cpu_to_le16(0);
8926 +
8927 +       return usbctl_queue(ctl, req, &status, 2);
8928 +}
8929 +
8930 +/*
8931 + * 9.4.4: Get Interface
8932 + *  Unspecified conditions:
8933 + *   - 
8934 + *  States: Default (unspecified), Address (Request Error), Configured (ok)
8935 + */
8936 +static int
8937 +usbctl_parse_int_get_interface(struct usbctl *ctl, struct usb_ctrlrequest *req)
8938 +{
8939 +       unsigned int interface = le16_to_cpu(req->wIndex) & 255;
8940 +       u8 null = 0;
8941 +
8942 +       if (ctl->state != USB_STATE_CONFIGURED)
8943 +               return RET_REQERROR;
8944 +
8945 +       /*
8946 +        * If the interface doesn't exist, respond with request error
8947 +        */
8948 +       if (interface != 1)
8949 +               return RET_REQERROR;
8950 +
8951 +       printk("usbctl: get interface %d not supported\n", interface);
8952 +
8953 +       return usbctl_queue(ctl, req, &null, 1);
8954 +}
8955 +
8956 +static int
8957 +usbctl_parse_int_set_interface(struct usbctl *ctl, struct usb_ctrlrequest *req)
8958 +{
8959 +       unsigned int interface = le16_to_cpu(req->wIndex) & 255;
8960 +
8961 +       if (interface != 0)
8962 +               printk("usbctl: set interface %d not supported (ignored)\n",
8963 +                       interface);
8964 +
8965 +       return RET_ACK;
8966 +}
8967 +
8968 +/*
8969 + * Endpoint handling
8970 + */
8971 +
8972 +/*
8973 + * 9.4.5: Get Status (endpoint)
8974 + */
8975 +static int
8976 +usbctl_parse_ep_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
8977 +{
8978 +       unsigned int ep = le16_to_cpu(req->wIndex) & 15;
8979 +       u16 status;
8980 +
8981 +       if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
8982 +           ep <= ctl->nr_ep)
8983 +               return RET_REQERROR;
8984 +
8985 +       status = ctl->driver->ep_get_status(ctl->driver->priv, ep);
8986 +       status = cpu_to_le16(status);
8987 +
8988 +       return usbctl_queue(ctl, req, &status, 2);
8989 +}
8990 +
8991 +/*
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.
8996 + */
8997 +static int
8998 +usbctl_parse_ep_clear_feature(struct usbctl *ctl, struct usb_ctrlrequest *req)
8999 +{
9000 +       unsigned int feature = le16_to_cpu(req->wValue);
9001 +       unsigned int ep = le16_to_cpu(req->wIndex) & 15;
9002 +       int ret;
9003 +
9004 +       if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
9005 +           ep <= ctl->nr_ep)
9006 +               return RET_REQERROR;
9007 +
9008 +       if (feature == USB_ENDPOINT_HALT) {
9009 +               ctl->driver->ep_halt(ctl->driver->priv, ep, 0);
9010 +               ret = RET_ACK;
9011 +       } else {
9012 +               printk(KERN_ERR "usbctl: unsupported clear feature: "
9013 +                       "wValue = 0x%04x wIndex = 0x%04x\n",
9014 +                       feature, ep);
9015 +
9016 +               ret = RET_REQERROR;
9017 +       }
9018 +       return ret;
9019 +}
9020 +
9021 +/*
9022 + * 9.4.9: Set Feature (endpoint)
9023 + */
9024 +static int
9025 +usbctl_parse_ep_set_feature(struct usbctl *ctl, struct usb_ctrlrequest *req)
9026 +{
9027 +       unsigned int feature = le16_to_cpu(req->wValue);
9028 +       unsigned int ep = le16_to_cpu(req->wIndex) & 15;
9029 +       int ret;
9030 +
9031 +       if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
9032 +           ep <= ctl->nr_ep)
9033 +               return RET_REQERROR;
9034 +
9035 +       if (feature == USB_ENDPOINT_HALT) {
9036 +               ctl->driver->ep_halt(ctl->driver->priv, ep, 1);
9037 +               ret = RET_ACK;
9038 +       } else {
9039 +               printk(KERN_ERR "usbctl: unsupported set feature "
9040 +                       "wValue = 0x%04x wIndex = 0x%04x\n",
9041 +                       feature, ep);
9042 +
9043 +               ret = RET_REQERROR;
9044 +       }
9045 +       return ret;
9046 +}
9047 +
9048 +/*
9049 + * This reflects Table 9.3 (p186) in the USB1.1 spec.
9050 + *
9051 + * Some notes:
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
9056 + */
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,
9067 +       },
9068 +
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,
9075 +       },
9076 +
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,
9081 +       },
9082 +};
9083 +
9084 +static void __attribute__((unused))
9085 +usbctl_dump_request(const char *prefix, const struct usb_ctrlrequest *req)
9086 +{
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));
9092 +}
9093 +
9094 +int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req)
9095 +{
9096 +       unsigned int type;
9097 +       int (*fn)(struct usbctl *, struct usb_ctrlrequest *) = NULL;
9098 +       int ret = RET_REQERROR;
9099 +
9100 +       //usbctl_dump_request("usbctl: ", req);
9101 +
9102 +       type = req->bRequestType & USB_TYPE_MASK;
9103 +       if (type == USB_TYPE_STANDARD) {
9104 +               unsigned int recip;
9105 +
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];
9110 +       }
9111 +
9112 +       if (fn)
9113 +               ret = fn(ctl, req);
9114 +       else
9115 +               usbctl_dump_request(KERN_ERR "usbctl: unknown request: ",
9116 +                                   req);
9117 +
9118 +       /*
9119 +        * Make sure we're doing the right thing.
9120 +        */
9121 +       if (req->bRequestType & USB_DIR_IN) {
9122 +               if (ret != RET_QUEUED && ret != RET_REQERROR)
9123 +                       printk("Error: device to host transfer expected\n");
9124 +       } else {
9125 +               if (ret == RET_QUEUED)
9126 +                       printk("Error: no device to host transfer expected\n");
9127 +       }
9128 +
9129 +       return ret;
9130 +}
9131 +
9132 +EXPORT_SYMBOL(usbctl_parse_request);
9133 +
9134 +/* Start running. Must have called usb_open (above) first */
9135 +int usbctl_start(struct usb_client *client)
9136 +{
9137 +       struct usbctl *ctl = client->ctl;
9138 +
9139 +       if (ctl == NULL || ctl->clnt != client) {
9140 +               printk("usbctl: start: no client registered\n");
9141 +               return -EPERM;
9142 +       }
9143 +
9144 +       ctl->sm_state = kStateZombie;
9145 +       ctl->state = USB_STATE_POWERED;
9146 +
9147 +       /*
9148 +        * Notify the client as to our state.
9149 +        */
9150 +       usbctl_callbacks(ctl, USB_STATE_POWERED, USB_STATE_SUSPENDED);
9151 +
9152 +       return ctl->driver->start(ctl->driver->priv);
9153 +}
9154 +
9155 +EXPORT_SYMBOL(usbctl_start);
9156 +
9157 +/*
9158 + * Stop USB core from running
9159 + */
9160 +void usbctl_stop(struct usb_client *client)
9161 +{
9162 +       struct usbctl *ctl = client->ctl;
9163 +
9164 +       if (ctl == NULL || ctl->clnt != client) {
9165 +               printk("USBDEV: stop: no client/driver registered\n");
9166 +               return;
9167 +       }
9168 +
9169 +       ctl->driver->stop(ctl->driver->priv);
9170 +}
9171 +
9172 +EXPORT_SYMBOL(usbctl_stop);
9173 +
9174 +struct usbctl usbctl;
9175 +
9176 +EXPORT_SYMBOL(usbctl);
9177 +
9178 +/* Open SA usb core on behalf of a client, but don't start running */
9179 +
9180 +int usbctl_open(struct usb_client *client)
9181 +{
9182 +       struct usbctl *ctl = &usbctl;
9183 +       int ret;
9184 +printk("usbctl_open: ctl %p driver %p\n", ctl, ctl->driver);
9185 +       if (!ctl->driver || !try_module_get(ctl->driver->owner))
9186 +               return -ENODEV;
9187 +
9188 +       if (ctl->clnt != NULL) {
9189 +               ret = -EBUSY;
9190 +               goto err;
9191 +       }
9192 +
9193 +       ctl->clnt     = client;
9194 +       ctl->state    = USB_STATE_SUSPENDED;
9195 +       ctl->nr_ep    = 2;
9196 +       /* start in zombie suspended state */
9197 +       ctl->sm_state = kStateZombieSuspend;
9198 +       ctl->state    = USB_STATE_SUSPENDED;
9199 +       client->ctl   = ctl;
9200 +
9201 +       ctl->dev_desc_buf = usbb_alloc(sizeof(struct usb_device_descriptor),
9202 +                                      GFP_KERNEL);
9203 +       if (!ctl->dev_desc_buf) {
9204 +               ret = -ENOMEM;
9205 +               goto err;
9206 +       }
9207 +
9208 +       ctl->dev_desc = usbb_push(ctl->dev_desc_buf,
9209 +                                 sizeof(struct usb_device_descriptor));
9210 +
9211 +       /* create descriptors for enumeration */
9212 +       initialize_descriptors(ctl);
9213 +
9214 +       return 0;
9215 +
9216 + err:
9217 +       module_put(ctl->driver->owner);
9218 +       return ret;
9219 +}
9220 +
9221 +EXPORT_SYMBOL(usbctl_open);
9222 +
9223 +/* Tell SA core client is through using it */
9224 +void usbctl_close(struct usb_client *client)
9225 +{
9226 +       struct usbctl *ctl = client->ctl;
9227 +
9228 +       if (ctl == NULL || ctl->clnt != client) {
9229 +               printk("usbctl: close: no client registered\n");
9230 +               return;
9231 +       }
9232 +
9233 +       usbb_put(ctl->dev_desc_buf);
9234 +
9235 +       client->ctl       = NULL;
9236 +       ctl->clnt         = 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;
9242 +
9243 +       usbc_string_free_all(&ctl->strings);
9244 +
9245 +       if (ctl->driver->owner)
9246 +               module_put(ctl->driver->owner);
9247 +}
9248 +
9249 +EXPORT_SYMBOL(usbctl_close);
9250 +
9251 +int usbctl_proc_info(struct usbctl *ctl, char *buf)
9252 +{
9253 +       char *p = buf;
9254 +
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],
9263 +               ctl->sm_state);
9264 +       p += sprintf(p, "Address\t: %d\n", ctl->address);
9265 +
9266 +       return p - buf;
9267 +}
9268 +
9269 +EXPORT_SYMBOL(usbctl_proc_info);
9270 +
9271 +int
9272 +usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep,
9273 +                      char *buf, unsigned int len)
9274 +{
9275 +       return ctl->driver->ep_queue(ctl->driver->priv, ep, buf, len);
9276 +}
9277 +
9278 +EXPORT_SYMBOL(usbctl_ep_queue_buffer);
9279 +
9280 +void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep)
9281 +{
9282 +       return ctl->driver->ep_reset(ctl->driver->priv, ep);
9283 +}
9284 +
9285 +EXPORT_SYMBOL(usbctl_ep_reset);
9286 +
9287 +void
9288 +usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep,
9289 +                      usb_callback_t callback, void *data)
9290 +{
9291 +       ctl->driver->ep_callback(ctl->driver->priv, ep, callback, data);
9292 +}
9293 +
9294 +EXPORT_SYMBOL(usbctl_ep_set_callback);
9295 +
9296 +int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep)
9297 +{
9298 +       return ctl->driver->ep_idle(ctl->driver->priv, ep);
9299 +}
9300 +
9301 +EXPORT_SYMBOL(usbctl_ep_idle);
9302 +
9303 +/*
9304 + * usbctl_init()
9305 + * Module load time. Allocate dma and interrupt resources. Setup /proc fs
9306 + * entry. Leave UDC disabled.
9307 + */
9308 +int usbctl_init(struct usbctl *ctl, struct usbc_driver *drv)
9309 +{
9310 +       usbc_string_init(&ctl->strings);
9311 +printk("usbctl_init: %p %p\n", ctl, drv);
9312 +       /*
9313 +        * start in zombie suspended state
9314 +        */
9315 +       ctl->sm_state   = kStateZombieSuspend;
9316 +       ctl->state      = USB_STATE_SUSPENDED;
9317 +       ctl->driver     = drv;
9318 +
9319 +       return 0;
9320 +}
9321 +
9322 +/*
9323 + * usbctl_exit()
9324 + */
9325 +void usbctl_exit(struct usbctl *ctl)
9326 +{
9327 +       usbc_string_free_all(&ctl->strings);
9328 +
9329 +       ctl->driver     = NULL;
9330 +}
9331 +
9332 +EXPORT_SYMBOL(usbctl_init);
9333 +EXPORT_SYMBOL(usbctl_exit);
9334 +
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
9339 @@ -0,0 +1,40 @@
9340 +#ifndef USBDEV_CLIENT_H
9341 +#define USBDEV_CLIENT_H
9342 +
9343 +#include "sa1100_usb.h" /* grr */
9344 +
9345 +struct usbctl;
9346 +
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         */
9358 +       __u8            unused1;
9359 +       __u16           unused2;
9360 +       const char      *manufacturer_str;
9361 +       const char      *product_str;
9362 +       const char      *serial_str;
9363 +};
9364 +
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);
9369 +
9370 +int
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);
9374 +void
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);
9378 +
9379 +#endif
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
9382 @@ -0,0 +1,50 @@
9383 +/*
9384 + * sa1100_usb.h
9385 + *
9386 + * Public interface to the sa1100 USB core. For use by client modules
9387 + * like usb-eth and usb-char.
9388 + *
9389 + */
9390 +#ifndef _SA1100_USB_H
9391 +#define _SA1100_USB_H
9392 +
9393 +typedef void (*usb_callback_t)(void *data, int flag, int size);
9394 +
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);
9400 +
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);
9405 +
9406 +//////////////////////////////////////////////////////////////////////////////
9407 +// Descriptor Management
9408 +//////////////////////////////////////////////////////////////////////////////
9409 +
9410 +// MaxPower:
9411 +#define USB_POWER(x)  ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
9412 +
9413 +/* "config descriptor buffer" - that is, one config,
9414 +   ..one interface and 2 endpoints */
9415 +struct cdb {
9416 +        struct usb_config_descriptor           cfg;
9417 +        struct usb_interface_descriptor        intf;
9418 +        struct usb_endpoint_descriptor         ep1, ep2;
9419 +} __attribute__ ((packed));
9420 +
9421 +
9422 +/*=======================================================
9423 + * Descriptor API
9424 + */
9425 +
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()
9429 +*/
9430 +struct cdb *sa1100_usb_get_descriptor_ptr(void);
9431 +
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
9435 @@ -0,0 +1,136 @@
9436 +/*
9437 + *     Copyright (C)  Compaq Computer Corporation, 1998, 1999
9438 + *     Copyright (C)  Extenex Corporation 2001
9439 + *
9440 + *  usb_ctl.h
9441 + *
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.
9445 + *
9446 + */
9447 +#ifndef SA1100USB_H
9448 +#define SA1100USB_H
9449 +
9450 +struct usbctl;
9451 +
9452 +struct sausb_dev {
9453 +       struct device   *dev;
9454 +       struct usbctl   *ctl;
9455 +       spinlock_t      lock;
9456 +
9457 +       u32             udccr;
9458 +
9459 +       /*
9460 +        * EP0 write thread.
9461 +        */
9462 +       void            (*wrint)(struct sausb_dev *);
9463 +       struct usb_buf  *wrbuf;
9464 +       unsigned char   *wrptr;
9465 +       unsigned int    wrlen;
9466 +
9467 +       /*
9468 +        * EP0 statistics.
9469 +        */
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;
9478 +
9479 +       /*
9480 +        * EP1 .. n
9481 +        */
9482 +       struct {
9483 +               dma_regs_t      *dmach;
9484 +
9485 +               dma_addr_t      bufdma;
9486 +               unsigned int    buflen;
9487 +               void            *pktcpu;
9488 +               dma_addr_t      pktdma;
9489 +               unsigned int    pktlen;
9490 +               unsigned int    pktrem;
9491 +
9492 +               void            *cb_data;
9493 +               void            (*cb_func)(void *data, int flag, int size);
9494 +
9495 +               u32             udccs;
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;
9502 +       } ep[2];
9503 +};
9504 +
9505 +/* receiver */
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 *);
9512 +
9513 +/* xmitter */
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 *);
9519 +
9520 +#define UDC_write(reg, val) do { \
9521 +       int i = 10000; \
9522 +       do { \
9523 +               (reg) = (val); \
9524 +               if (i-- <= 0) { \
9525 +                       printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
9526 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9527 +                       break; \
9528 +               } \
9529 +       } while((reg) != (val)); \
9530 +} while (0)
9531 +
9532 +#define UDC_set(reg, val) do { \
9533 +       int i = 10000; \
9534 +       do { \
9535 +               (reg) |= (val); \
9536 +               if (i-- <= 0) { \
9537 +                       printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
9538 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9539 +                       break; \
9540 +               } \
9541 +       } while(!((reg) & (val))); \
9542 +} while (0)
9543 +
9544 +#define UDC_clear(reg, val) do { \
9545 +       int i = 10000; \
9546 +       do { \
9547 +               (reg) &= ~(val); \
9548 +               if (i-- <= 0) { \
9549 +                       printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
9550 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9551 +                       break; \
9552 +               } \
9553 +       } while((reg) & (val)); \
9554 +} while (0)
9555 +
9556 +#define UDC_flip(reg, val) do { \
9557 +       int i = 10000; \
9558 +       (reg) = (val); \
9559 +       do { \
9560 +               (reg) = (val); \
9561 +               if (i-- <= 0) { \
9562 +                       printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
9563 +                               __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
9564 +                       break; \
9565 +               } \
9566 +       } while(((reg) & (val))); \
9567 +} while (0)
9568 +
9569 +#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
9570 +
9571 +#endif
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
9574 @@ -0,0 +1,117 @@
9575 +/*
9576 + * usb/strings.c
9577 + *
9578 + * Copyright (C) 2002 Russell King.
9579 + */
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>
9586 +
9587 +#include "buffer.h"
9588 +#include "strings.h"
9589 +
9590 +struct usb_buf *usbc_string_alloc(int len)
9591 +{
9592 +       struct usb_buf *buf;
9593 +       int tot_len;
9594 +
9595 +       tot_len = sizeof(struct usb_descriptor_header) + sizeof(u16) * len;
9596 +
9597 +       buf = usbb_alloc(tot_len, GFP_KERNEL);
9598 +
9599 +       if (buf) {
9600 +               struct usb_string_descriptor *desc = usbb_push(buf, tot_len);
9601 +
9602 +               desc->bLength = tot_len;
9603 +               desc->bDescriptorType = USB_DT_STRING;
9604 +       }
9605 +       return buf;
9606 +}
9607 +
9608 +void usbc_string_free(struct usb_buf *buf)
9609 +{
9610 +       if (buf)
9611 +               usbb_put(buf);
9612 +}
9613 +
9614 +void usbc_string_from_cstr(struct usb_buf *buf, const char *str)
9615 +{
9616 +       struct usb_string_descriptor *desc = usbc_string_desc(buf);
9617 +       int i, len;
9618 +
9619 +       len = strlen(str);
9620 +       BUG_ON((sizeof(__u16) * len) > desc->bLength - sizeof(struct usb_descriptor_header));
9621 +
9622 +       for (i = 0; i < len; i++)
9623 +               desc->wData[i] = cpu_to_le16(str[i]);
9624 +}
9625 +
9626 +int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf)
9627 +{
9628 +       int nr, i;
9629 +       
9630 +       nr = -ENOSPC;
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;
9635 +                       nr = i;
9636 +                       break;
9637 +               }
9638 +       spin_unlock_irq(&table->lock);
9639 +
9640 +       return nr;
9641 +}
9642 +
9643 +void usbc_string_del(struct usbc_strs *table, int nr)
9644 +{
9645 +       if (nr < NR_STRINGS) {
9646 +               spin_lock_irq(&table->lock);
9647 +               table->buf[nr] = NULL;
9648 +               spin_unlock_irq(&table->lock);
9649 +       }
9650 +}
9651 +
9652 +struct usb_buf *
9653 +usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx)
9654 +{
9655 +       struct usb_buf *buf = NULL;
9656 +
9657 +       if (idx < NR_STRINGS) {
9658 +               spin_lock_irq(&table->lock);
9659 +               buf = usbb_get(table->buf[idx]);
9660 +               spin_unlock_irq(&table->lock);
9661 +       }
9662 +
9663 +       return buf;
9664 +}
9665 +
9666 +void usbc_string_free_all(struct usbc_strs *table)
9667 +{
9668 +       int i;
9669 +
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;
9674 +       }
9675 +       spin_unlock_irq(&table->lock);
9676 +}
9677 +
9678 +void usbc_string_init(struct usbc_strs *table)
9679 +{
9680 +       memset(table, 0, sizeof(struct usbc_strs));
9681 +       spin_lock_init(&table->lock);
9682 +}
9683 +
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
9694 @@ -0,0 +1,171 @@
9695 + /*
9696 + *     Copyright (C) Compaq Computer Corporation, 1998, 1999
9697 + *  Copyright (C) Extenex Corporation, 2001
9698 + *
9699 + *  usb_ctl.c
9700 + *
9701 + *  SA1100 USB controller core driver.
9702 + *
9703 + *  This file provides interrupt routing and overall coordination
9704 + *  of the three endpoints in usb_ep0, usb_receive (1),  and usb_send (2).
9705 + *
9706 + *  Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
9707 + *
9708 + */
9709 +#include <linux/module.h>
9710 +#include <linux/errno.h>
9711 +#include <linux/usb.h>
9712 +
9713 +#include "buffer.h"
9714 +#include "client.h"
9715 +#include "usbdev.h"
9716 +#include "sa1100_usb.h"
9717 +
9718 +//////////////////////////////////////////////////////////////////////////////
9719 +// Globals
9720 +//////////////////////////////////////////////////////////////////////////////
9721 +
9722 +/* device descriptors */
9723 +static struct cdb cdb;
9724 +
9725 +//////////////////////////////////////////////////////////////////////////////
9726 +// Private Helpers
9727 +//////////////////////////////////////////////////////////////////////////////
9728 +
9729 +int sa1100_usb_add_string(struct usbctl *ctl, const char *str)
9730 +{
9731 +       int nr = 0;
9732 +
9733 +       if (str) {
9734 +               struct usb_buf *buf;
9735 +               int len;
9736 +
9737 +               len = strlen(str);
9738 +
9739 +               nr = -ENOMEM;
9740 +               buf = usbc_string_alloc(len);
9741 +               if (buf) {
9742 +                       usbc_string_from_cstr(buf, str);
9743 +                       nr = usbc_string_add(&ctl->strings, buf);
9744 +
9745 +                       if (nr < 0)
9746 +                               usbc_string_free(buf);
9747 +               }
9748 +       }
9749 +
9750 +       return nr;
9751 +}
9752 +
9753 +EXPORT_SYMBOL(sa1100_usb_add_string);
9754 +
9755 +static int sa1100_usb_add_language(struct usbctl *ctl, unsigned int lang)
9756 +{
9757 +       struct usb_buf *buf;
9758 +       int nr = -ENOMEM;
9759 +
9760 +       buf = usbc_string_alloc(1);
9761 +       if (buf) {
9762 +               usbc_string_desc(buf)->wData[0] = cpu_to_le16(lang); /* American English */
9763 +               nr = usbc_string_add(&ctl->strings, buf);
9764 +
9765 +               if (nr < 0)
9766 +                       usbc_string_free(buf);
9767 +       }
9768 +
9769 +       return nr;
9770 +}
9771 +
9772 +/* setup default descriptors */
9773 +
9774 +void initialize_descriptors(struct usbctl *ctl)
9775 +{
9776 +       struct usb_client *clnt = ctl->clnt;
9777 +       int r;
9778 +
9779 +       ctl->ep_desc[0] = (struct usb_endpoint_descriptor *)&cdb.ep1;
9780 +       ctl->ep_desc[1] = (struct usb_endpoint_descriptor *)&cdb.ep2;
9781 +
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 );
9790 +
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;
9800 +
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;
9807 +
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;
9814 +
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;
9826 +
9827 +       /* set language */
9828 +       /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
9829 +       r = sa1100_usb_add_language(ctl, 0x409);
9830 +       if (r < 0)
9831 +               printk(KERN_ERR "usbc: couldn't add language\n");
9832 +
9833 +       r = sa1100_usb_add_string(ctl, clnt->manufacturer_str);
9834 +       if (r < 0)
9835 +               printk(KERN_ERR "usbc: couldn't add manufacturer string\n");
9836 +
9837 +       ctl->dev_desc->iManufacturer = r > 0 ? r : 0;
9838 +
9839 +       r = sa1100_usb_add_string(ctl, clnt->product_str);
9840 +       if (r < 0)
9841 +               printk(KERN_ERR "usbc: couldn't add product string\n");
9842 +
9843 +       ctl->dev_desc->iProduct      = r > 0 ? r : 0;
9844 +
9845 +       r = sa1100_usb_add_string(ctl, clnt->serial_str);
9846 +       if (r < 0)
9847 +               printk(KERN_ERR "usbc: couldn't add serial string\n");
9848 +
9849 +       ctl->dev_desc->iSerialNumber = r > 0 ? r : 0;
9850 +}
9851 +
9852 +
9853 +/*====================================================
9854 + * Descriptor Manipulation.
9855 + * Use these between open() and start() above to setup
9856 + * the descriptors for your device.
9857 + */
9858 +
9859 +/* get pointer to static default descriptor */
9860 +struct cdb *sa1100_usb_get_descriptor_ptr(void)
9861 +{
9862 +       return &cdb;
9863 +}
9864 +
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
9868 @@ -0,0 +1,12 @@
9869 +#
9870 +# Makefile for the USB client
9871 +#
9872 +
9873 +usbdevcore-objs        := buffer.o control.o strings.o usb_ctl.o
9874 +
9875 +sa1100-objs := sa1100usb.o usb_recv.o usb_send.o
9876 +
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
9880 +
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
9883 @@ -0,0 +1,91 @@
9884 +#ifndef USBDEV_H
9885 +#define USBDEV_H
9886 +
9887 +#include "strings.h"
9888 +
9889 +struct usb_buf;
9890 +struct module;
9891 +struct cdb;
9892 +struct usb_client;
9893 +
9894 +struct usbc_driver {
9895 +       struct module   *owner;
9896 +       const char      *name;
9897 +       void            *priv;
9898 +       int             (*start)(void *);
9899 +       int             (*stop)(void *);
9900 +
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);
9904 +
9905 +       /*
9906 +        * Get specified endpoint status, as defined in 9.4.5.
9907 +        */
9908 +       unsigned int    (*ep_get_status)(void *, unsigned int ep);
9909 +       void            (*ep_halt)(void *, unsigned int ep, int halt);
9910 +
9911 +       /*
9912 +        * Client
9913 +        */
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);
9918 +};
9919 +
9920 +struct usbc_endpoint {
9921 +       struct usb_endpoint_descriptor  *desc;
9922 +};
9923 +
9924 +struct usbc_interface {
9925 +       struct usb_interface_descriptor *desc;
9926 +       unsigned int                    nr_ep;
9927 +       struct usbc_endpoint            *ep[0];
9928 +};
9929 +
9930 +struct usbc_config {
9931 +       struct usb_config_descriptor    *desc;
9932 +       unsigned int                    nr_interface;
9933 +       struct usbc_interface           *interface[0];
9934 +};
9935 +
9936 +struct usbctl {
9937 +       struct usb_client               *clnt;
9938 +       const struct usbc_driver        *driver;
9939 +
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 */
9944 +
9945 +       struct usbc_config              *config;        /* active configuration */
9946 +       struct usbc_strs                strings;
9947 +
9948 +       /* Descriptors */
9949 +       struct usb_device_descriptor    *dev_desc;      /* device descriptor */
9950 +       struct usb_buf                  *dev_desc_buf;  /* device descriptor buffer */
9951 +
9952 +
9953 +       int                             nr_ep;
9954 +       struct usb_endpoint_descriptor  *ep_desc[2];
9955 +};
9956 +
9957 +/*
9958 + * Function Prototypes
9959 + */
9960 +
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)
9966 +
9967 +int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req);
9968 +
9969 +int usbctl_reset(struct usbctl *ctl);
9970 +void usbctl_suspend(struct usbctl *ctl);
9971 +void usbctl_resume(struct usbctl *ctl);
9972 +
9973 +#endif
9974 +
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
9977 @@ -150,6 +150,7 @@
9978   */
9979  static int sa11x0_pm_prepare(u32 state)
9980  {
9981 +       nmi_watchdog_disable();
9982         return 0;
9983  }
9984  
9985 @@ -158,6 +159,7 @@
9986   */
9987  static int sa11x0_pm_finish(u32 state)
9988  {
9989 +       nmi_watchdog_enable();
9990         return 0;
9991  }
9992  
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
9995 @@ -0,0 +1,104 @@
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>
10003 +
10004 +#include <asm/ptrace.h>
10005 +#include <asm/domain.h>
10006 +#include <asm/hardware.h>
10007 +
10008 +static void *nmi_stack;
10009 +
10010 +asm("                                          \n\
10011 +nmi_start:                                     \n\
10012 +       mrs     r8, spsr                        \n\
10013 +       ldr     r9, .Lstack                     \n\
10014 +       ldr     sp, [r9]                        \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\
10020 +       mrs     r2, cpsr                        \n\
10021 +       bic     r1, r2, #0x1f                   \n\
10022 +       orr     r1, r1, #0x13                   \n\
10023 +       msr     cpsr_c, r1                      \n\
10024 +       mov     r0, r0                          \n\
10025 +       stmia   r0, {r8 - lr}                   \n\
10026 +       mov     r0, r0                          \n\
10027 +       msr     cpsr_c, r2                      \n\
10028 +       mov     r0, r0                          \n\
10029 +       mov     r0, sp                          \n\
10030 +       mov     lr, pc                          \n\
10031 +       ldr     pc, .Lfn                        \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\
10036 +       msr     spsr, r8                        \n\
10037 +       movs    pc, lr                          \n\
10038 +                                               \n\
10039 +.Lstack: .long nmi_stack                       \n\
10040 +.Lfn:  .long   nmi_fn                          \n\
10041 +nmi_end:");
10042 +
10043 +extern unsigned char nmi_start, nmi_end;
10044 +
10045 +static void __attribute__((unused)) nmi_fn(struct pt_regs *regs)
10046 +{
10047 +       struct thread_info *thread;
10048 +       unsigned long osmr0, osmr1, oscr, ossr, icmr, icip;
10049 +
10050 +       oscr = OSCR;
10051 +       osmr0 = OSMR0;
10052 +       osmr1 = OSMR1;
10053 +       ossr = OSSR;
10054 +       icmr = ICMR;
10055 +       icip = ICIP;
10056 +
10057 +       OSSR = OSSR_M1;
10058 +       ICMR &= ~IC_OST1;
10059 +
10060 +       thread = (struct thread_info *)(regs->ARM_sp & ~8191);
10061 +
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);
10067 +
10068 +       OSSR = OSSR_M1;
10069 +       OSMR1 = OSSR + 36864000;
10070 +       ICMR |= IC_OST1;
10071 +}
10072 +
10073 +static int nmi_init(void)
10074 +{
10075 +       unsigned char *vec_base = (unsigned char *)vectors_base();
10076 +return 0;
10077 +       nmi_stack = (void *)__get_free_page(GFP_KERNEL);
10078 +       if (!nmi_stack)
10079 +               return -ENOMEM;
10080 +
10081 +       nmi_stack += PAGE_SIZE;
10082 +
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);
10086 +
10087 +       /*
10088 +        * Ensure timer 1 is set to FIQ, and enabled.
10089 +        */
10090 +       OSMR1 = OSCR - 1;
10091 +       OSSR = OSSR_M1;
10092 +       OIER |= OIER_E1;
10093 +       ICLR |= IC_OST1;
10094 +       ICMR |= IC_OST1;
10095 +
10096 +       return 0;
10097 +}
10098 +
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
10102 @@ -32,6 +32,8 @@
10103  
10104  source "drivers/media/common/Kconfig"
10105  
10106 +source "drivers/media/mmc/Kconfig"
10107 +
10108  config VIDEO_TUNER
10109         tristate
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
10113 @@ -0,0 +1,52 @@
10114 +#
10115 +# MMC subsystem configuration
10116 +#
10117 +
10118 +menu "MMC/SD Card support"
10119 +
10120 +config MMC
10121 +       tristate "MMC support"
10122 +       help
10123 +         MMC is the "multi-media card" bus protocol.
10124 +
10125 +         If you want MMC support, you should say Y here and also
10126 +         to the specific driver for your MMC interface.
10127 +
10128 +config MMC_DEBUG
10129 +       bool "MMC debugging"
10130 +       depends on MMC != n
10131 +       help
10132 +         This is an option for use by developers; most people should
10133 +         say N here.  This enables MMC core and driver debugging.
10134 +
10135 +config MMC_BLOCK
10136 +       tristate "MMC block device driver"
10137 +       depends on MMC
10138 +       default y
10139 +       help
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.
10144 +
10145 +config MMC_ARMMMCI
10146 +       tristate "ARM AMBA Multimedia Card Interface support"
10147 +       depends on ARM_AMBA && MMC
10148 +       help
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.
10152 +
10153 +         If unsure, say N.
10154 +
10155 +config MMC_PXA
10156 +       tristate "Intel PXA255 Multimedia Card Interface support"
10157 +       depends on ARCH_PXA && MMC
10158 +       help
10159 +         This selects the Intel(R) PXA(R) Multimedia card Interface.
10160 +         If you have a PXA(R) platform with a Multimedia Card slot,
10161 +         say Y or M here.
10162 +
10163 +         If unsure, say N.
10164 +
10165 +endmenu
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
10168 @@ -0,0 +1,171 @@
10169 +/*
10170 + *  linux/drivers/media/mmc/mmc_queue.c
10171 + *
10172 + *  Copyright (C) 2003 Russell King, All Rights Reserved.
10173 + *
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.
10177 + *
10178 + */
10179 +#include <linux/module.h>
10180 +#include <linux/blkdev.h>
10181 +
10182 +#include <linux/mmc/card.h>
10183 +#include <linux/mmc/host.h>
10184 +#include "mmc_queue.h"
10185 +
10186 +/*
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.
10190 + */
10191 +static int mmc_prep_request(struct request_queue *q, struct request *req)
10192 +{
10193 +       struct mmc_queue *mq = q->queuedata;
10194 +       int ret = BLKPREP_KILL;
10195 +
10196 +       if (req->flags & REQ_SPECIAL) {
10197 +               /*
10198 +                * Special commands already have the command
10199 +                * blocks already setup in req->special.
10200 +                */
10201 +               BUG_ON(!req->special);
10202 +
10203 +               ret = BLKPREP_OK;
10204 +       } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
10205 +               /*
10206 +                * Block I/O requests need translating according
10207 +                * to the protocol.
10208 +                */
10209 +               ret = mq->prep_fn(mq, req);
10210 +       } else {
10211 +               /*
10212 +                * Everything else is invalid.
10213 +                */
10214 +               blk_dump_rq_flags(req, "MMC bad request");
10215 +       }
10216 +
10217 +       if (ret == BLKPREP_OK)
10218 +               req->flags |= REQ_DONTPREP;
10219 +
10220 +       return ret;
10221 +}
10222 +
10223 +static int mmc_queue_thread(void *d)
10224 +{
10225 +       struct mmc_queue *mq = d;
10226 +       struct request_queue *q = mq->queue;
10227 +       DECLARE_WAITQUEUE(wait, current);
10228 +       int ret;
10229 +
10230 +       /*
10231 +        * Set iothread to ensure that we aren't put to sleep by
10232 +        * the process freezing.  We handle suspension ourselves.
10233 +        */
10234 +       current->flags |= PF_MEMALLOC|PF_IOTHREAD;
10235 +
10236 +       daemonize("mmcqd");
10237 +
10238 +       spin_lock_irq(&current->sighand->siglock);
10239 +       sigfillset(&current->blocked);
10240 +       recalc_sigpending();
10241 +       spin_unlock_irq(&current->sighand->siglock);
10242 +
10243 +       mq->thread = current;
10244 +       complete(&mq->thread_complete);
10245 +
10246 +       add_wait_queue(&mq->thread_wq, &wait);
10247 +       spin_lock_irq(q->queue_lock);
10248 +       do {
10249 +               struct request *req = NULL;
10250 +
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);
10255 +
10256 +               if (!req) {
10257 +                       if (!mq->thread)
10258 +                               break;
10259 +                       schedule();
10260 +                       continue;
10261 +               }
10262 +               set_current_state(TASK_RUNNING);
10263 +
10264 +               ret = mq->issue_fn(mq, req);
10265 +
10266 +               spin_lock_irq(q->queue_lock);
10267 +               end_request(req, ret);
10268 +       } while (1);
10269 +       remove_wait_queue(&mq->thread_wq, &wait);
10270 +
10271 +       complete_and_exit(&mq->thread_complete, 0);
10272 +       return 0;
10273 +}
10274 +
10275 +/*
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.
10280 + */
10281 +static void mmc_request(request_queue_t *q)
10282 +{
10283 +       struct mmc_queue *mq = q->queuedata;
10284 +
10285 +       if (!mq->req && !blk_queue_plugged(q))
10286 +               wake_up(&mq->thread_wq);
10287 +}
10288 +
10289 +/**
10290 + * mmc_init_queue - initialise a queue structure.
10291 + * @mq: mmc queue
10292 + * @card: mmc card to attach this queue
10293 + * @lock: queue lock
10294 + *
10295 + * Initialise a MMC card request queue.
10296 + */
10297 +int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
10298 +{
10299 +       u64 limit = BLK_BOUNCE_HIGH;
10300 +       int ret;
10301 +
10302 +       if (card->host->dev->dma_mask)
10303 +               limit = *card->host->dev->dma_mask;
10304 +
10305 +       mq->card = card;
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);
10309 +
10310 +       mq->queue->queuedata = mq;
10311 +       mq->req = NULL;
10312 +
10313 +       init_completion(&mq->thread_complete);
10314 +       init_waitqueue_head(&mq->thread_wq);
10315 +
10316 +       ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL);
10317 +       if (ret < 0) {
10318 +               blk_cleanup_queue(mq->queue);
10319 +       } else {
10320 +               wait_for_completion(&mq->thread_complete);
10321 +               init_completion(&mq->thread_complete);
10322 +       }
10323 +
10324 +       return ret;
10325 +}
10326 +
10327 +EXPORT_SYMBOL(mmc_init_queue);
10328 +
10329 +void mmc_cleanup_queue(struct mmc_queue *mq)
10330 +{
10331 +       mq->thread = NULL;
10332 +       wake_up(&mq->thread_wq);
10333 +       wait_for_completion(&mq->thread_complete);
10334 +       blk_cleanup_queue(mq->queue);
10335 +
10336 +       mq->card = NULL;
10337 +}
10338 +
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
10342 @@ -0,0 +1,587 @@
10343 +/*
10344 + *  linux/drivers/media/mmc/pxa.c - PXA MMCI driver
10345 + *
10346 + *  Copyright (C) 2003 Russell King, All Rights Reserved.
10347 + *
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.
10351 + *
10352 + *  This hardware is really sick.  No way to clear interrupts.  Have
10353 + *  to turn off the clock whenever we touch the device.  Yuck!
10354 + *
10355 + *     1 and 3 byte data transfers not supported
10356 + *     max block length up to 1023
10357 + */
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>
10368 +
10369 +#include <asm/dma.h>
10370 +#include <asm/io.h>
10371 +#include <asm/irq.h>
10372 +#include <asm/sizes.h>
10373 +
10374 +#include "pxamci.h"
10375 +
10376 +#ifdef CONFIG_MMC_DEBUG
10377 +#define DBG(x...)      printk(KERN_DEBUG x)
10378 +#else
10379 +#define DBG(x...)      do { } while (0)
10380 +#endif
10381 +
10382 +struct pxamci_host {
10383 +       struct mmc_host         mmc;
10384 +       spinlock_t              lock;
10385 +       struct resource         *res;
10386 +       void                    *base;
10387 +       int                     irq;
10388 +       int                     dma;
10389 +       unsigned int            clkrt;
10390 +       unsigned int            cmdat;
10391 +       unsigned int            imask;
10392 +       unsigned int            power_mode;
10393 +
10394 +       struct mmc_request      *req;
10395 +       struct mmc_command      *cmd;
10396 +       struct mmc_data         *data;
10397 +
10398 +       dma_addr_t              sg_dma;
10399 +       struct pxa_dma_desc     *sg_cpu;
10400 +
10401 +       dma_addr_t              dma_buf;
10402 +       unsigned int            dma_size;
10403 +       unsigned int            dma_dir;
10404 +};
10405 +
10406 +#define to_pxamci_host(x)      container_of(x, struct pxamci_host, mmc)
10407 +
10408 +/*
10409 + * The base MMC clock rate
10410 + */
10411 +#define CLOCKRATE      20000000
10412 +
10413 +static inline unsigned int ns_to_clocks(unsigned int ns)
10414 +{
10415 +       return (ns * (CLOCKRATE / 1000000) + 999) / 1000;
10416 +}
10417 +
10418 +static void pxamci_stop_clock(struct pxamci_host *host)
10419 +{
10420 +       if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
10421 +               unsigned long flags;
10422 +               unsigned int v;
10423 +
10424 +               writel(STOP_CLOCK, host->base + MMC_STRPCL);
10425 +
10426 +               /*
10427 +                * Wait for the "clock has stopped" interrupt.
10428 +                * We need to unmask the interrupt to receive
10429 +                * the notification.  Sigh.
10430 +                */
10431 +               spin_lock_irqsave(&host->lock, flags);
10432 +               writel(host->imask & ~CLK_IS_OFF, host->base + MMC_I_MASK);
10433 +               do {
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);
10438 +       }
10439 +}
10440 +
10441 +static void pxamci_enable_irq(struct pxamci_host *host, unsigned int mask)
10442 +{
10443 +       unsigned long flags;
10444 +
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);
10449 +}
10450 +
10451 +static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask)
10452 +{
10453 +       unsigned long flags;
10454 +
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);
10459 +}
10460 +
10461 +static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
10462 +{
10463 +       unsigned int nob = data->blocks;
10464 +       unsigned int timeout, size;
10465 +       dma_addr_t dma;
10466 +       u32 dcmd;
10467 +       int i;
10468 +
10469 +       host->data = data;
10470 +
10471 +       if (data->flags & MMC_DATA_STREAM)
10472 +               nob = 0xffff;
10473 +
10474 +       writel(nob, host->base + MMC_NOB);
10475 +       writel(1 << data->blksz_bits, host->base + MMC_BLKLEN);
10476 +
10477 +       timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks;
10478 +       writel((timeout + 255) / 256, host->base + MMC_RDTO);
10479 +
10480 +       if (data->flags & MMC_DATA_READ) {
10481 +               host->dma_dir = DMA_FROM_DEVICE;
10482 +               dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG;
10483 +               DRCMRTXMMC = 0;
10484 +               DRCMRRXMMC = host->dma | DRCMR_MAPVLD;
10485 +       } else {
10486 +               host->dma_dir = DMA_TO_DEVICE;
10487 +               dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC;
10488 +               DRCMRRXMMC = 0;
10489 +               DRCMRTXMMC = host->dma | DRCMR_MAPVLD;
10490 +       }
10491 +
10492 +       dcmd |= DCMD_BURST32 | DCMD_WIDTH1;
10493 +
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);
10497 +
10498 +       for (i = 0, size = host->dma_size, dma = host->dma_buf; size; i++) {
10499 +               u32 len = size;
10500 +
10501 +               if (len > DCMD_LENGTH)
10502 +                       len = 0x1000;
10503 +
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;
10507 +               } else {
10508 +                       host->sg_cpu[i].dsadr = dma;
10509 +                       host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
10510 +               }
10511 +               host->sg_cpu[i].dcmd = dcmd | len;
10512 +
10513 +               dma += len;
10514 +               size -= len;
10515 +
10516 +               if (size) {
10517 +                       host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
10518 +                                                sizeof(struct pxa_dma_desc);
10519 +               } else {
10520 +                       host->sg_cpu[i].ddadr = DDADR_STOP;
10521 +               }
10522 +       }
10523 +       wmb();
10524 +
10525 +       DDADR(host->dma) = host->sg_dma;
10526 +       DCSR(host->dma) = DCSR_RUN;
10527 +}
10528 +
10529 +static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
10530 +{
10531 +       WARN_ON(host->cmd != NULL);
10532 +       host->cmd = cmd;
10533 +
10534 +       if (cmd->flags & MMC_RSP_BUSY)
10535 +               cmdat |= CMDAT_BUSY;
10536 +
10537 +       switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) {
10538 +       case MMC_RSP_SHORT | MMC_RSP_CRC:
10539 +               cmdat |= CMDAT_RESP_SHORT;
10540 +               break;
10541 +       case MMC_RSP_SHORT:
10542 +               cmdat |= CMDAT_RESP_R3;
10543 +               break;
10544 +       case MMC_RSP_LONG | MMC_RSP_CRC:
10545 +               cmdat |= CMDAT_RESP_R2;
10546 +               break;
10547 +       default:
10548 +               break;
10549 +       }
10550 +
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);
10556 +
10557 +       writel(START_CLOCK, host->base + MMC_STRPCL);
10558 +
10559 +       pxamci_enable_irq(host, END_CMD_RES);
10560 +}
10561 +
10562 +static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *req)
10563 +{
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);
10569 +}
10570 +
10571 +static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
10572 +{
10573 +       struct mmc_command *cmd = host->cmd;
10574 +       int i;
10575 +       u32 v;
10576 +
10577 +       if (!cmd)
10578 +               return 0;
10579 +
10580 +       host->cmd = NULL;
10581 +
10582 +       /*
10583 +        * Did I mention this is Sick.  We always need to
10584 +        * discard the upper 8 bits of the first 16-bit word.
10585 +        */
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;
10591 +               v = w2;
10592 +       }
10593 +
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;
10598 +       }
10599 +
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);
10603 +       } else {
10604 +               pxamci_finish_request(host, host->req);
10605 +       }
10606 +
10607 +       return 1;
10608 +}
10609 +
10610 +static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
10611 +{
10612 +       struct mmc_data *data = host->data;
10613 +
10614 +       if (!data)
10615 +               return 0;
10616 +
10617 +       DCSR(host->dma) = 0;
10618 +       dma_unmap_single(host->mmc.dev, host->dma_buf, host->dma_size,
10619 +                        host->dma_dir);
10620 +
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;
10625 +
10626 +       data->bytes_xfered = (data->blocks - readl(host->base + MMC_NOB))
10627 +                              << data->blksz_bits;
10628 +
10629 +       pxamci_disable_irq(host, DATA_TRAN_DONE);
10630 +
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);
10635 +       } else {
10636 +               pxamci_finish_request(host, host->req);
10637 +       }
10638 +
10639 +       return 1;
10640 +}
10641 +
10642 +static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs)
10643 +{
10644 +       struct pxamci_host *host = devid;
10645 +       unsigned int ireg;
10646 +       int handled = 0;
10647 +
10648 +       ireg = readl(host->base + MMC_I_REG);
10649 +
10650 +       DBG("PXAMCI: irq %08x\n", ireg);
10651 +
10652 +       if (ireg) {
10653 +               unsigned stat = readl(host->base + MMC_STAT);
10654 +
10655 +               DBG("PXAMCI: stat %08x\n", stat);
10656 +
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);
10661 +       }
10662 +
10663 +       return IRQ_RETVAL(handled);
10664 +}
10665 +
10666 +static void pxamci_request(struct mmc_host *mmc, struct mmc_request *req)
10667 +{
10668 +       struct pxamci_host *host = to_pxamci_host(mmc);
10669 +       unsigned int cmdat;
10670 +
10671 +       WARN_ON(host->req != NULL);
10672 +
10673 +       host->req = req;
10674 +
10675 +       pxamci_stop_clock(host);
10676 +
10677 +       cmdat = host->cmdat;
10678 +       host->cmdat &= ~CMDAT_INIT;
10679 +
10680 +       if (req->data) {
10681 +               pxamci_setup_data(host, req->data);
10682 +
10683 +               cmdat &= ~CMDAT_BUSY;
10684 +               cmdat |= CMDAT_DATAEN | CMDAT_DMAEN;
10685 +               if (req->data->flags & MMC_DATA_WRITE)
10686 +                       cmdat |= CMDAT_WRITE;
10687 +
10688 +               if (req->data->flags & MMC_DATA_STREAM)
10689 +                       cmdat |= CMDAT_STREAM;
10690 +       }
10691 +
10692 +       pxamci_start_cmd(host, req->cmd, cmdat);
10693 +}
10694 +
10695 +static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
10696 +{
10697 +       struct pxamci_host *host = to_pxamci_host(mmc);
10698 +
10699 +       DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n",
10700 +           ios->clock, ios->power_mode, ios->vdd / 100,
10701 +           ios->vdd % 100);
10702 +
10703 +       if (ios->clock) {
10704 +               unsigned int clk = CLOCKRATE / ios->clock;
10705 +               if (CLOCKRATE / clk > ios->clock)
10706 +                       clk <<= 1;
10707 +               host->clkrt = fls(clk) - 1;
10708 +
10709 +               /*
10710 +                * we write clkrt on the next command
10711 +                */
10712 +       } else if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
10713 +               /*
10714 +                * Ensure that the clock is off.
10715 +                */
10716 +               writel(STOP_CLOCK, host->base + MMC_STRPCL);
10717 +       }
10718 +
10719 +       if (host->power_mode != ios->power_mode) {
10720 +               host->power_mode = ios->power_mode;
10721 +
10722 +               /*
10723 +                * power control?  none on the lubbock.
10724 +                */
10725 +
10726 +               if (ios->power_mode == MMC_POWER_ON)
10727 +                       host->cmdat |= CMDAT_INIT;
10728 +       }
10729 +
10730 +       DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n",
10731 +           host->clkrt, host->cmdat);
10732 +}
10733 +
10734 +static struct mmc_host_ops pxamci_ops = {
10735 +       .request        = pxamci_request,
10736 +       .set_ios        = pxamci_set_ios,
10737 +};
10738 +
10739 +static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
10740 +{
10741 +       int i;
10742 +
10743 +       for (i = 0; i < dev->num_resources; i++)
10744 +               if (dev->resource[i].flags == mask && nr-- == 0)
10745 +                       return &dev->resource[i];
10746 +       return NULL;
10747 +}
10748 +
10749 +static int platform_device_irq(struct platform_device *dev, int nr)
10750 +{
10751 +       int i;
10752 +
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;
10756 +       return NO_IRQ;
10757 +}
10758 +
10759 +static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
10760 +{
10761 +       printk(KERN_ERR "DMA%d: IRQ???\n", dma);
10762 +       DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
10763 +}
10764 +
10765 +static int pxamci_probe(struct device *dev)
10766 +{
10767 +       struct platform_device *pdev = to_platform_device(dev);
10768 +       struct pxamci_host *host;
10769 +       struct resource *r;
10770 +       int ret, irq;
10771 +
10772 +       r = platform_device_resource(pdev, IORESOURCE_MEM, 0);
10773 +       irq = platform_device_irq(pdev, 0);
10774 +       if (!r || irq == NO_IRQ)
10775 +               return -ENXIO;
10776 +
10777 +       r = request_mem_region(r->start, SZ_4K, "PXAMCI");
10778 +       if (!r)
10779 +               return -EBUSY;
10780 +
10781 +       host = kmalloc(sizeof(struct pxamci_host), GFP_KERNEL);
10782 +       if (!host) {
10783 +               ret = -ENOMEM;
10784 +               goto out;
10785 +       }
10786 +
10787 +       memset(host, 0, sizeof(struct pxamci_host));
10788 +       host->dma = -1;
10789 +
10790 +       host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
10791 +       if (!host->sg_cpu) {
10792 +               ret = -ENOMEM;
10793 +               goto out;
10794 +       }
10795 +
10796 +       ret = mmc_init_host(&host->mmc);
10797 +       if (ret)
10798 +               goto out;
10799 +
10800 +       spin_lock_init(&host->lock);
10801 +       host->res = r;
10802 +       host->irq = irq;
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;
10810 +
10811 +       host->base = ioremap(r->start, SZ_4K);
10812 +       if (!host->base) {
10813 +               ret = -ENOMEM;
10814 +               goto out;
10815 +       }
10816 +
10817 +       /*
10818 +        * Ensure that the host controller is shut down, and setup
10819 +        * with our defaults.
10820 +        */
10821 +       pxamci_stop_clock(host);
10822 +       writel(0, host->base + MMC_SPI);
10823 +       writel(64, host->base + MMC_RESTO);
10824 +
10825 +#ifdef CONFIG_PREEMPT
10826 +#error Not Preempt-safe
10827 +#endif
10828 +       pxa_gpio_mode(GPIO6_MMCCLK_MD);
10829 +       pxa_gpio_mode(GPIO8_MMCCS0_MD);
10830 +       CKEN |= CKEN12_MMC;
10831 +
10832 +       host->dma = pxa_request_dma("PXAMCI", DMA_PRIO_LOW, pxamci_dma_irq, host);
10833 +       if (host->dma < 0)
10834 +               goto out;
10835 +
10836 +       ret = request_irq(host->irq, pxamci_irq, 0, "PXAMCI", host);
10837 +       if (ret)
10838 +               goto out;
10839 +
10840 +       dev_set_drvdata(dev, host);
10841 +
10842 +       mmc_add_host(&host->mmc);
10843 +
10844 +       return 0;
10845 +
10846 + out:
10847 +       if (host) {
10848 +               if (host->dma >= 0)
10849 +                       pxa_free_dma(host->dma);
10850 +               if (host->base)
10851 +                       iounmap(host->base);
10852 +               if (host->sg_cpu)
10853 +                       dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
10854 +               kfree(host);
10855 +       }
10856 +       release_resource(r);
10857 +       return ret;
10858 +}
10859 +
10860 +static int pxamci_remove(struct device *dev)
10861 +{
10862 +       struct pxamci_host *host = dev_get_drvdata(dev);
10863 +
10864 +       dev_set_drvdata(dev, NULL);
10865 +
10866 +       if (host) {
10867 +               mmc_remove_host(&host->mmc);
10868 +
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);
10873 +
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);
10878 +
10879 +               release_resource(host->res);
10880 +
10881 +               kfree(host);
10882 +       }
10883 +       return 0;
10884 +}
10885 +
10886 +static int pxamci_suspend(struct device *dev, u32 state, u32 level)
10887 +{
10888 +       struct pxamci_host *host = dev_get_drvdata(dev);
10889 +       int ret = 0;
10890 +
10891 +       if (host && level == SUSPEND_DISABLE)
10892 +               ret = mmc_suspend_host(&host->mmc, state);
10893 +       return ret;
10894 +}
10895 +
10896 +static int pxamci_resume(struct device *dev, u32 level)
10897 +{
10898 +       struct pxamci_host *host = dev_get_drvdata(dev);
10899 +       int ret = 0;
10900 +
10901 +       if (host && level == RESUME_ENABLE)
10902 +               ret = mmc_resume_host(&host->mmc);
10903 +       return ret;
10904 +}
10905 +
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,
10913 +};
10914 +
10915 +static int __init pxamci_init(void)
10916 +{
10917 +       return driver_register(&pxamci_driver);
10918 +}
10919 +
10920 +static void __exit pxamci_exit(void)
10921 +{
10922 +       driver_unregister(&pxamci_driver);
10923 +}
10924 +
10925 +module_init(pxamci_init);
10926 +module_exit(pxamci_exit);
10927 +
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
10932 @@ -0,0 +1,15 @@
10933 +/*
10934 + *  linux/drivers/media/mmc/mmc.h
10935 + *
10936 + *  Copyright (C) 2003 Russell King, All Rights Reserved.
10937 + *
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.
10941 + */
10942 +#ifndef _MMC_H
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);
10947 +#endif
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
10950 @@ -0,0 +1,231 @@
10951 +/*
10952 + *  linux/drivers/media/mmc/mmc_sysfs.c
10953 + *
10954 + *  Copyright (C) 2003 Russell King, All Rights Reserved.
10955 + *
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.
10959 + *
10960 + *  MMC sysfs/driver model support.
10961 + */
10962 +#include <linux/module.h>
10963 +#include <linux/init.h>
10964 +#include <linux/device.h>
10965 +
10966 +#include <linux/mmc/card.h>
10967 +#include <linux/mmc/host.h>
10968 +
10969 +#include "mmc.h"
10970 +
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)
10973 +
10974 +static void mmc_release_card(struct device *dev)
10975 +{
10976 +       struct mmc_card *card = dev_to_mmc_card(dev);
10977 +
10978 +       kfree(card);
10979 +}
10980 +
10981 +/*
10982 + * This currently matches any MMC driver to any MMC card - drivers
10983 + * themselves make the decision whether to drive this card in their
10984 + * probe method.
10985 + */
10986 +static int mmc_bus_match(struct device *dev, struct device_driver *drv)
10987 +{
10988 +       return 1;
10989 +}
10990 +
10991 +static int
10992 +mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
10993 +               int buf_size)
10994 +{
10995 +       struct mmc_card *card = dev_to_mmc_card(dev);
10996 +       char ccc[13];
10997 +       int i = 0;
10998 +
10999 +#define add_env(fmt,val)                                               \
11000 +       ({                                                              \
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;                                \
11006 +                       buf += len;                                     \
11007 +                       if (buf_size >= 0)                              \
11008 +                               ret = 0;                                \
11009 +               }                                                       \
11010 +               ret;                                                    \
11011 +       })
11012 +
11013 +       for (i = 0; i < 12; i++)
11014 +               ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';
11015 +       ccc[12] = '\0';
11016 +
11017 +       i = 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);
11021 +
11022 +       return 0;
11023 +}
11024 +
11025 +static int mmc_bus_suspend(struct device *dev, u32 state)
11026 +{
11027 +       struct mmc_driver *drv = to_mmc_driver(dev->driver);
11028 +       struct mmc_card *card = dev_to_mmc_card(dev);
11029 +       int ret = 0;
11030 +
11031 +       if (dev->driver && drv->suspend)
11032 +               ret = drv->suspend(card, state);
11033 +       return ret;
11034 +}
11035 +
11036 +static int mmc_bus_resume(struct device *dev)
11037 +{
11038 +       struct mmc_driver *drv = to_mmc_driver(dev->driver);
11039 +       struct mmc_card *card = dev_to_mmc_card(dev);
11040 +       int ret = 0;
11041 +
11042 +       if (dev->driver && drv->resume)
11043 +               ret = drv->resume(card);
11044 +       return ret;
11045 +}
11046 +
11047 +static struct bus_type mmc_bus_type = {
11048 +       .name           = "mmc",
11049 +       .match          = mmc_bus_match,
11050 +       .hotplug        = mmc_bus_hotplug,
11051 +       .suspend        = mmc_bus_suspend,
11052 +       .resume         = mmc_bus_resume,
11053 +};
11054 +
11055 +
11056 +static int mmc_drv_probe(struct device *dev)
11057 +{
11058 +       struct mmc_driver *drv = to_mmc_driver(dev->driver);
11059 +       struct mmc_card *card = dev_to_mmc_card(dev);
11060 +
11061 +       return drv->probe(card);
11062 +}
11063 +
11064 +static int mmc_drv_remove(struct device *dev)
11065 +{
11066 +       struct mmc_driver *drv = to_mmc_driver(dev->driver);
11067 +       struct mmc_card *card = dev_to_mmc_card(dev);
11068 +
11069 +       drv->remove(card);
11070 +
11071 +       return 0;
11072 +}
11073 +
11074 +
11075 +/**
11076 + *     mmc_register_driver - register a media driver
11077 + *     @drv: MMC media driver
11078 + */
11079 +int mmc_register_driver(struct mmc_driver *drv)
11080 +{
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);
11085 +}
11086 +
11087 +EXPORT_SYMBOL(mmc_register_driver);
11088 +
11089 +/**
11090 + *     mmc_unregister_driver - unregister a media driver
11091 + *     @drv: MMC media driver
11092 + */
11093 +void mmc_unregister_driver(struct mmc_driver *drv)
11094 +{
11095 +       drv->drv.bus = &mmc_bus_type;
11096 +       driver_unregister(&drv->drv);
11097 +}
11098 +
11099 +EXPORT_SYMBOL(mmc_unregister_driver);
11100 +
11101 +
11102 +#define MMC_ATTR(name, fmt, args...)                                   \
11103 +static ssize_t mmc_dev_show_##name (struct device *dev, char *buf)     \
11104 +{                                                                      \
11105 +       struct mmc_card *card = dev_to_mmc_card(dev);                   \
11106 +       return sprintf(buf, fmt, args);                                 \
11107 +}                                                                      \
11108 +static DEVICE_ATTR(name, S_IRUGO, mmc_dev_show_##name, NULL)
11109 +
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);
11116 +
11117 +static struct device_attribute *mmc_dev_attributes[] = {
11118 +       &dev_attr_date,
11119 +       &dev_attr_fwrev,
11120 +       &dev_attr_hwrev,
11121 +       &dev_attr_manfid,
11122 +       &dev_attr_serial,
11123 +       &dev_attr_name,
11124 +};
11125 +
11126 +/*
11127 + * Internal function.  Initialise a MMC card structure.
11128 + */
11129 +void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
11130 +{
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;
11137 +}
11138 +
11139 +/*
11140 + * Internal function.  Register a new MMC card with the driver model.
11141 + */
11142 +int mmc_register_card(struct mmc_card *card)
11143 +{
11144 +       int ret, i;
11145 +
11146 +       snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
11147 +                "mmc%02x:%04x", card->host->host_num, card->rca);
11148 +
11149 +       ret = device_add(&card->dev);
11150 +       if (ret == 0)
11151 +               for (i = 0; i < ARRAY_SIZE(mmc_dev_attributes); i++)
11152 +                       device_create_file(&card->dev, mmc_dev_attributes[i]);
11153 +
11154 +       return ret;
11155 +}
11156 +
11157 +/*
11158 + * Internal function.  Unregister a new MMC card with the
11159 + * driver model, and (eventually) free it.
11160 + */
11161 +void mmc_remove_card(struct mmc_card *card)
11162 +{
11163 +       if (mmc_card_present(card))
11164 +               device_del(&card->dev);
11165 +
11166 +       put_device(&card->dev);
11167 +}
11168 +
11169 +
11170 +static int __init mmc_init(void)
11171 +{
11172 +       return bus_register(&mmc_bus_type);
11173 +}
11174 +
11175 +static void __exit mmc_exit(void)
11176 +{
11177 +       bus_unregister(&mmc_bus_type);
11178 +}
11179 +
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
11184 @@ -0,0 +1,445 @@
11185 +/*
11186 + *  linux/drivers/media/mmc/mmci.c - ARM PrimeCell MMCI PL180/1 driver
11187 + *
11188 + *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
11189 + *
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.
11193 + */
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>
11205 +
11206 +#include <asm/io.h>
11207 +#include <asm/irq.h>
11208 +#include <asm/hardware/amba.h>
11209 +
11210 +#include "mmci.h"
11211 +
11212 +#define DRIVER_NAME "mmci-pl18x"
11213 +
11214 +#ifdef CONFIG_MMC_DEBUG
11215 +#define DBG(x...)      printk(KERN_DEBUG x)
11216 +#else
11217 +#define DBG(x...)      do { } while (0)
11218 +#endif
11219 +
11220 +static int fmax = 515633;
11221 +
11222 +static void
11223 +mmci_request_end(struct mmci_host *host, struct mmc_request *req)
11224 +{
11225 +       writel(0, host->base + MMCICOMMAND);
11226 +       host->req = NULL;
11227 +       host->cmd = NULL;
11228 +       host->data = NULL;
11229 +
11230 +       if (req->data)
11231 +               req->data->bytes_xfered = host->data_xfered;
11232 +
11233 +       mmc_request_done(&host->mmc, req);
11234 +}
11235 +
11236 +static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
11237 +{
11238 +       unsigned int datactrl;
11239 +
11240 +       DBG("MMCI: data: blksz %04x blks %04x flags %08x\n",
11241 +           1 << data->blksz_bits, data->blocks, data->flags);
11242 +
11243 +       datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4;
11244 +
11245 +       if (data->flags & MMC_DATA_READ)
11246 +               datactrl |= MCI_DPSM_DIRECTION;
11247 +
11248 +       host->data = data;
11249 +       host->buffer = data->rq->buffer;
11250 +       host->size = data->blocks << data->blksz_bits;
11251 +       host->data_xfered = 0;
11252 +
11253 +       writel(0x800000, host->base + MMCIDATATIMER);
11254 +       writel(host->size, host->base + MMCIDATALENGTH);
11255 +       writel(datactrl, host->base + MMCIDATACTRL);
11256 +}
11257 +
11258 +static void
11259 +mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
11260 +{
11261 +       DBG("MMCI: cmd: op %02x arg %08x flags %08x\n",
11262 +           cmd->opcode, cmd->arg, cmd->flags);
11263 +
11264 +       if (readl(host->base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
11265 +               writel(0, host->base + MMCICOMMAND);
11266 +               udelay(1);
11267 +       }
11268 +
11269 +       c |= cmd->opcode | MCI_CPSM_ENABLE;
11270 +       switch (cmd->flags & MMC_RSP_MASK) {
11271 +       case MMC_RSP_NONE:
11272 +       default:
11273 +               break;
11274 +       case MMC_RSP_LONG:
11275 +               c |= MCI_CPSM_LONGRSP;
11276 +       case MMC_RSP_SHORT:
11277 +               c |= MCI_CPSM_RESPONSE;
11278 +               break;
11279 +       }
11280 +       if (/*interrupt*/0)
11281 +               c |= MCI_CPSM_INTERRUPT;
11282 +
11283 +       host->cmd = cmd;
11284 +
11285 +       writel(cmd->arg, host->base + MMCIARGUMENT);
11286 +       writel(c, host->base + MMCICOMMAND);
11287 +}
11288 +
11289 +static void
11290 +mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
11291 +             unsigned int status)
11292 +{
11293 +       if (status & MCI_DATABLOCKEND) {
11294 +               host->data_xfered += 1 << data->blksz_bits;
11295 +       }
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;
11304 +       }
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);
11311 +               }
11312 +       }
11313 +}
11314 +
11315 +static void
11316 +mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
11317 +            unsigned int status)
11318 +{
11319 +       host->cmd = NULL;
11320 +
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);
11325 +
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;
11330 +       }
11331 +
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);
11336 +       }
11337 +}
11338 +
11339 +static irqreturn_t mmci_irq(int irq, void *dev_id, struct pt_regs *regs)
11340 +{
11341 +       struct mmci_host *host = dev_id;
11342 +       u32 status;
11343 +       int ret = 0;
11344 +
11345 +       do {
11346 +               struct mmc_command *cmd;
11347 +               struct mmc_data *data;
11348 +
11349 +               status = readl(host->base + MMCISTATUS);
11350 +               writel(status, host->base + MMCICLEAR);
11351 +
11352 +               if (!(status & MCI_IRQMASK))
11353 +                       break;
11354 +
11355 +               DBG("MMCI: irq %08x\n", status);
11356 +
11357 +               if (status & (MCI_RXDATAAVLBL|MCI_RXFIFOHALFFULL)) {
11358 +                       int count = host->size - (readl(host->base + MMCIFIFOCNT) << 2);
11359 +                       if (count < 0)
11360 +                               count = 0;
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;
11367 +                       } else {
11368 +                               static int first = 1;
11369 +                               if (first) {
11370 +                                       first = 0;
11371 +                                       printk(KERN_ERR "MMCI: sinking excessive data\n");
11372 +                               }
11373 +                               readl(host->base + MMCIFIFO);
11374 +                       }
11375 +               }
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;
11386 +                       } else {
11387 +                               static int first = 1;
11388 +                               if (first) {
11389 +                                       first = 0;
11390 +                                       printk(KERN_ERR "MMCI: ran out of source data\n");
11391 +                               }
11392 +                       }
11393 +               }
11394 +
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);
11399 +
11400 +               cmd = host->cmd;
11401 +               if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd)
11402 +                       mmci_cmd_irq(host, cmd, status);
11403 +
11404 +               ret = 1;
11405 +       } while (status);
11406 +
11407 +       return IRQ_RETVAL(ret);
11408 +}
11409 +
11410 +static void mmci_request(struct mmc_host *mmc, struct mmc_request *req)
11411 +{
11412 +       struct mmci_host *host = to_mmci_host(mmc);
11413 +
11414 +       WARN_ON(host->req != NULL);
11415 +
11416 +       host->req = req;
11417 +
11418 +       if (req->data && req->data->flags & MMC_DATA_READ)
11419 +               mmci_start_data(host, req->data);
11420 +
11421 +       mmci_start_command(host, req->cmd, 0);
11422 +}
11423 +
11424 +static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
11425 +{
11426 +       struct mmci_host *host = to_mmci_host(mmc);
11427 +       u32 clk = 0, pwr = 0;
11428 +
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);
11432 +
11433 +       if (ios->clock) {
11434 +               clk = host->mclk / (2 * ios->clock) - 1;
11435 +               if (clk > 256)
11436 +                       clk = 255;
11437 +               clk |= MCI_CLK_ENABLE;
11438 +       }
11439 +
11440 +       switch (ios->power_mode) {
11441 +       case MMC_POWER_OFF:
11442 +               break;
11443 +       case MMC_POWER_UP:
11444 +               pwr |= MCI_PWR_UP;
11445 +               break;
11446 +       case MMC_POWER_ON:
11447 +               pwr |= MCI_PWR_ON;
11448 +               break;
11449 +       }
11450 +
11451 +       if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
11452 +               pwr |= MCI_ROD;
11453 +
11454 +       writel(clk, host->base + MMCICLOCK);
11455 +
11456 +       if (host->pwr != pwr) {
11457 +               host->pwr = pwr;
11458 +               writel(pwr, host->base + MMCIPOWER);
11459 +       }
11460 +}
11461 +
11462 +static struct mmc_host_ops mmci_ops = {
11463 +       .request        = mmci_request,
11464 +       .set_ios        = mmci_set_ios,
11465 +};
11466 +
11467 +static int mmci_probe(struct amba_device *dev, void *id)
11468 +{
11469 +       struct mmci_host *host;
11470 +       int ret;
11471 +//     void *tmp;
11472 +
11473 +       /* enable the interrupt via the VIC */
11474 +//     tmp = ioremap(0xc3000000, SZ_4K);
11475 +//     if (tmp) {
11476 +//             u32 val = readl(tmp + 0x10);
11477 +//             writel(val | 0x180, tmp + 0x10);
11478 +//             iounmap(tmp);
11479 +//     }
11480 +
11481 +       if (!request_mem_region(dev->res.start, SZ_4K, DRIVER_NAME))
11482 +               return -EBUSY;
11483 +
11484 +       host = kmalloc(sizeof(struct mmci_host), GFP_KERNEL);
11485 +       if (!host) {
11486 +               ret = -ENOMEM;
11487 +               goto out;
11488 +       }
11489 +
11490 +       memset(host, 0, sizeof(struct mmci_host));
11491 +
11492 +       ret = mmc_init_host(&host->mmc);
11493 +       if (ret)
11494 +               goto out;
11495 +
11496 +       host->base = ioremap(dev->res.start, SZ_4K);
11497 +       if (!host->base) {
11498 +               ret = -ENOMEM;
11499 +               goto out;
11500 +       }
11501 +
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;
11510 +
11511 +       host->mmc.ocr_avail = MMC_VDD_35_36;
11512 +
11513 +       writel(0, host->base + MMCIMASK0);
11514 +       writel(0, host->base + MMCIMASK1);
11515 +       writel(0xfff, host->base + MMCICLEAR);
11516 +
11517 +       ret = request_irq(host->irq, mmci_irq, SA_SHIRQ, DRIVER_NAME, host);
11518 +       if (ret)
11519 +               goto out;
11520 +
11521 +       writel(MCI_IRQENABLE, host->base + MMCIMASK0);
11522 +
11523 +       amba_set_drvdata(dev, host);
11524 +
11525 +       mmc_add_host(&host->mmc);
11526 +
11527 +       return 0;
11528 +
11529 + out:
11530 +       if (host) {
11531 +               if (host->base)
11532 +                       iounmap(host->base);
11533 +               kfree(host);
11534 +       }
11535 +       release_mem_region(dev->res.start, SZ_4K);
11536 +       return ret;
11537 +}
11538 +
11539 +static int mmci_remove(struct amba_device *dev)
11540 +{
11541 +       struct mmci_host *host = amba_get_drvdata(dev);
11542 +
11543 +       amba_set_drvdata(dev, NULL);
11544 +
11545 +       if (host) {
11546 +               mmc_remove_host(&host->mmc);
11547 +
11548 +               writel(0, host->base + MMCIMASK0);
11549 +               writel(0, host->base + MMCIMASK1);
11550 +
11551 +               writel(0, host->base + MMCICOMMAND);
11552 +               writel(0, host->base + MMCIDATACTRL);
11553 +
11554 +               free_irq(host->irq, host);
11555 +
11556 +               iounmap(host->base);
11557 +
11558 +               kfree(host);
11559 +
11560 +               release_mem_region(dev->res.start, SZ_4K);
11561 +       }
11562 +
11563 +       return 0;
11564 +}
11565 +
11566 +#ifdef CONFIG_PM
11567 +static int mmci_suspend(struct amba_device *dev, u32 state)
11568 +{
11569 +       struct mmci_host *host = amba_get_drvdata(dev);
11570 +
11571 +       return host ? mmc_suspend_host(&host->mmc, state) : 0;
11572 +}
11573 +
11574 +static int mmci_resume(struct amba_device *dev)
11575 +{
11576 +       struct mmci_host *host = amba_get_drvdata(dev);
11577 +       int ret = 0;
11578 +
11579 +       if (host) {
11580 +               writel(MCI_IRQENABLE, host->base + MMCIMASK0);
11581 +               ret = mmc_resume_host(&host->mmc);
11582 +       }
11583 +
11584 +       return ret;
11585 +}
11586 +#else
11587 +#define mmci_suspend   NULL
11588 +#define mmci_resume    NULL
11589 +#endif
11590 +
11591 +static struct amba_id mmci_ids[] = {
11592 +       {
11593 +               .id     = 0x00041180,
11594 +               .mask   = 0x000fffff,
11595 +       },
11596 +       {
11597 +               .id     = 0x00041181,
11598 +               .mask   = 0x000fffff,
11599 +       },
11600 +       { 0, 0 },
11601 +};
11602 +
11603 +static struct amba_driver mmci_driver = {
11604 +       .drv            = {
11605 +               .name   = DRIVER_NAME,
11606 +       },
11607 +       .probe          = mmci_probe,
11608 +       .remove         = mmci_remove,
11609 +       .suspend        = mmci_suspend,
11610 +       .resume         = mmci_resume,
11611 +       .id_table       = mmci_ids,
11612 +};
11613 +
11614 +static int __init mmci_init(void)
11615 +{
11616 +       return amba_driver_register(&mmci_driver);
11617 +}
11618 +
11619 +static void __exit mmci_exit(void)
11620 +{
11621 +       amba_driver_unregister(&mmci_driver);
11622 +}
11623 +
11624 +module_init(mmci_init);
11625 +module_exit(mmci_exit);
11626 +module_param(fmax, int, 0444);
11627 +
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
11632 @@ -0,0 +1,29 @@
11633 +#ifndef MMC_QUEUE_H
11634 +#define MMC_QUEUE_H
11635 +
11636 +struct request;
11637 +struct task_struct;
11638 +
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 *);
11647 +       void                    *data;
11648 +       struct request_queue    *queue;
11649 +};
11650 +
11651 +struct mmc_io_request {
11652 +       struct request          *rq;
11653 +       int                     num;
11654 +       struct mmc_command      selcmd;         /* mmc_queue private */
11655 +       struct mmc_command      cmd[4];         /* max 4 commands */
11656 +};
11657 +
11658 +extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
11659 +extern void mmc_cleanup_queue(struct mmc_queue *);
11660 +
11661 +#endif
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
11664 @@ -0,0 +1,482 @@
11665 +/*
11666 + * Block driver for media (i.e., flash cards)
11667 + *
11668 + * Copyright 2002 Hewlett-Packard Company
11669 + *
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.
11673 + *
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.
11677 + *
11678 + * Many thanks to Alessandro Rubini and Jonathan Corbet!
11679 + *
11680 + * Author:  Andrew Christian
11681 + *          28 May 2002
11682 + */
11683 +#include <linux/moduleparam.h>
11684 +#include <linux/module.h>
11685 +#include <linux/init.h>
11686 +
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>
11695 +
11696 +#include <linux/mmc/card.h>
11697 +#include <linux/mmc/protocol.h>
11698 +
11699 +#include <asm/system.h>
11700 +#include <asm/uaccess.h>
11701 +
11702 +#include "mmc_queue.h"
11703 +
11704 +#define MMC_SHIFT      3       /* max 8 partitions per card */
11705 +
11706 +static int mmc_major;
11707 +static int maxsectors = 8;
11708 +
11709 +/*
11710 + * There is one mmc_blk_data per slot.
11711 + */
11712 +struct mmc_blk_data {
11713 +       spinlock_t      lock;
11714 +       struct gendisk  *disk;
11715 +       struct mmc_queue queue;
11716 +
11717 +       unsigned int    usage;
11718 +       unsigned int    block_bits;
11719 +       unsigned int    suspended;
11720 +};
11721 +
11722 +static DECLARE_MUTEX(open_lock);
11723 +
11724 +static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
11725 +{
11726 +       struct mmc_blk_data *md;
11727 +
11728 +       down(&open_lock);
11729 +       md = disk->private_data;
11730 +       if (md && md->usage == 0)
11731 +               md = NULL;
11732 +       if (md)
11733 +               md->usage++;
11734 +       up(&open_lock);
11735 +
11736 +       return md;
11737 +}
11738 +
11739 +static void mmc_blk_put(struct mmc_blk_data *md)
11740 +{
11741 +       down(&open_lock);
11742 +       md->usage--;
11743 +       if (md->usage == 0) {
11744 +               put_disk(md->disk);
11745 +               mmc_cleanup_queue(&md->queue);
11746 +               kfree(md);
11747 +       }
11748 +       up(&open_lock);
11749 +}
11750 +
11751 +static int mmc_blk_open(struct inode *inode, struct file *filp)
11752 +{
11753 +       struct mmc_blk_data *md;
11754 +       int ret = -ENXIO;
11755 +
11756 +       md = mmc_blk_get(inode->i_bdev->bd_disk);
11757 +       if (md) {
11758 +               if (md->usage == 2)
11759 +                       check_disk_change(inode->i_bdev);
11760 +               ret = 0;
11761 +       }
11762 +
11763 +       return ret;
11764 +}
11765 +
11766 +static int mmc_blk_release(struct inode *inode, struct file *filp)
11767 +{
11768 +       struct mmc_blk_data *md = inode->i_bdev->bd_disk->private_data;
11769 +
11770 +       mmc_blk_put(md);
11771 +       return 0;
11772 +}
11773 +
11774 +static int
11775 +mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
11776 +{
11777 +       struct block_device *bdev = inode->i_bdev;
11778 +
11779 +       if (cmd == HDIO_GETGEO) {
11780 +               struct hd_geometry geo;
11781 +
11782 +               memset(&geo, 0, sizeof(struct hd_geometry));
11783 +
11784 +               geo.cylinders   = get_capacity(bdev->bd_disk) / (4 * 16);
11785 +               geo.heads       = 4;
11786 +               geo.sectors     = 16;
11787 +               geo.start       = get_start_sect(bdev);
11788 +
11789 +               return copy_to_user((void *)arg, &geo, sizeof(geo))
11790 +                       ? -EFAULT : 0;
11791 +       }
11792 +
11793 +       return -ENOTTY;
11794 +}
11795 +
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,
11801 +};
11802 +
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;
11808 +};
11809 +
11810 +static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
11811 +{
11812 +       struct mmc_blk_data *md = mq->data;
11813 +
11814 +       /*
11815 +        * If we have no device, we haven't finished initialising.
11816 +        */
11817 +       if (!md || !mq->card) {
11818 +               printk("killing request - no device/host\n");
11819 +               goto kill;
11820 +       }
11821 +
11822 +       if (md->suspended) {
11823 +               blk_plug_device(md->queue.queue);
11824 +               goto defer;
11825 +       }
11826 +
11827 +       /*
11828 +        * Check for excessive requests.
11829 +        */
11830 +       if (req->sector + req->nr_sectors > get_capacity(req->rq_disk)) {
11831 +               printk("bad request size\n");
11832 +               goto kill;
11833 +       }
11834 +
11835 +       return BLKPREP_OK;
11836 +
11837 + defer:
11838 +       return BLKPREP_DEFER;
11839 + kill:
11840 +       return BLKPREP_KILL;
11841 +}
11842 +
11843 +static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
11844 +{
11845 +       struct mmc_blk_data *md = mq->data;
11846 +       struct mmc_card *card = md->queue.card;
11847 +       int err, sz = 0;
11848 +
11849 +       err = mmc_card_claim_host(card);
11850 +       if (err)
11851 +               goto cmd_err;
11852 +
11853 +       do {
11854 +               struct mmc_blk_request rq;
11855 +               struct mmc_command cmd;
11856 +
11857 +               memset(&rq, 0, sizeof(struct mmc_blk_request));
11858 +               rq.req.cmd = &rq.cmd;
11859 +               rq.req.data = &rq.data;
11860 +
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;
11869 +               rq.stop.arg = 0;
11870 +               rq.stop.flags = MMC_RSP_SHORT | MMC_RSP_CRC | MMC_RSP_BUSY;
11871 +
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;
11875 +               } else {
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;
11880 +               }
11881 +               rq.req.stop = rq.data.blocks > 1 ? &rq.stop : NULL;
11882 +
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);
11887 +                       goto cmd_err;
11888 +               }
11889 +
11890 +               if (rq_data_dir(req) == READ) {
11891 +                       sz = rq.data.bytes_xfered;
11892 +               } else {
11893 +                       sz = 0;
11894 +               }
11895 +
11896 +               if (rq.data.error) {
11897 +                       err = rq.data.error;
11898 +                       printk("error %d transferring data\n", err);
11899 +                       goto cmd_err;
11900 +               }
11901 +
11902 +               if (rq.stop.error) {
11903 +                       err = rq.stop.error;
11904 +                       printk("error %d sending stop command\n", err);
11905 +                       goto cmd_err;
11906 +               }
11907 +
11908 +               do {
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);
11913 +                       if (err) {
11914 +                               printk("error %d requesting status\n", err);
11915 +                               goto cmd_err;
11916 +                       }
11917 +               } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
11918 +
11919 +#if 0
11920 +               if (cmd.resp[0] & ~0x00000900)
11921 +                       printk("status = %08x\n", cmd.resp[0]);
11922 +               err = mmc_decode_status(cmd.resp);
11923 +               if (err)
11924 +                       goto cmd_err;
11925 +#endif
11926 +
11927 +               sz = rq.data.bytes_xfered;
11928 +       } while (end_that_request_chunk(req, 1, sz));
11929 +
11930 +       mmc_card_release_host(card);
11931 +
11932 +       return 1;
11933 +
11934 + cmd_err:
11935 +       mmc_card_release_host(card);
11936 +
11937 +       end_that_request_chunk(req, 1, sz);
11938 +       req->errors = err;
11939 +
11940 +       return 0;
11941 +}
11942 +
11943 +#define MMC_NUM_MINORS (256 >> MMC_SHIFT)
11944 +
11945 +static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))];
11946 +
11947 +static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
11948 +{
11949 +       struct mmc_blk_data *md;
11950 +       int devidx;
11951 +
11952 +       devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS);
11953 +       if (devidx >= MMC_NUM_MINORS)
11954 +               return NULL;
11955 +       __set_bit(devidx, dev_use);
11956 +
11957 +       md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
11958 +       if (md) {
11959 +               memset(md, 0, sizeof(struct mmc_blk_data));
11960 +
11961 +               md->disk = alloc_disk(1 << MMC_SHIFT);
11962 +               if (md->disk == NULL) {
11963 +                       kfree(md);
11964 +                       md = NULL;
11965 +                       goto out;
11966 +               }
11967 +
11968 +               spin_lock_init(&md->lock);
11969 +               md->usage = 1;
11970 +
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;
11975 +
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;
11982 +
11983 +               sprintf(md->disk->disk_name, "mmcblk%d", devidx);
11984 +               sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
11985 +
11986 +               md->block_bits = md->queue.card->csd.read_blkbits;
11987 +
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);
11991 +       }
11992 + out:
11993 +       return md;
11994 +}
11995 +
11996 +static int
11997 +mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
11998 +{
11999 +       struct mmc_command cmd;
12000 +       int err;
12001 +
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);
12008 +
12009 +       if (err) {
12010 +               printk(KERN_ERR "%s: unable to set block size to %d: %d\n",
12011 +                       md->disk->disk_name, cmd.arg, err);
12012 +               return -EINVAL;
12013 +       }
12014 +
12015 +       return 0;
12016 +}
12017 +
12018 +static int mmc_blk_probe(struct mmc_card *card)
12019 +{
12020 +       struct mmc_blk_data *md;
12021 +       int err;
12022 +
12023 +       if (card->csd.cmdclass & ~0x1ff)
12024 +               return -ENODEV;
12025 +
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);
12029 +               return -ENODEV;
12030 +       }
12031 +
12032 +       md = mmc_blk_alloc(card);
12033 +       if (md == NULL)
12034 +               return -ENOMEM;
12035 +
12036 +       err = mmc_blk_set_blksize(md, card);
12037 +       if (err)
12038 +               goto out;
12039 +
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);
12043 +
12044 +       mmc_set_drvdata(card, md);
12045 +       add_disk(md->disk);
12046 +       return 0;
12047 +
12048 + out:
12049 +       mmc_blk_put(md);
12050 +
12051 +       return err;
12052 +}
12053 +
12054 +static void mmc_blk_remove(struct mmc_card *card)
12055 +{
12056 +       struct mmc_blk_data *md = mmc_get_drvdata(card);
12057 +
12058 +       if (md) {
12059 +               int devidx;
12060 +
12061 +               del_gendisk(md->disk);
12062 +
12063 +               /*
12064 +                * I think this is needed.
12065 +                */
12066 +               md->disk->queue = NULL;
12067 +
12068 +               devidx = md->disk->first_minor >> MMC_SHIFT;
12069 +               __clear_bit(devidx, dev_use);
12070 +
12071 +               mmc_blk_put(md);
12072 +       }
12073 +       mmc_set_drvdata(card, NULL);
12074 +}
12075 +
12076 +#ifdef CONFIG_PM
12077 +static int mmc_blk_suspend(struct mmc_card *card, u32 state)
12078 +{
12079 +       struct mmc_blk_data *md = mmc_get_drvdata(card);
12080 +
12081 +       if (md) {
12082 +               blk_stop_queue(md->queue.queue);
12083 +       }
12084 +       return 0;
12085 +}
12086 +
12087 +static int mmc_blk_resume(struct mmc_card *card)
12088 +{
12089 +       struct mmc_blk_data *md = mmc_get_drvdata(card);
12090 +
12091 +       if (md) {
12092 +               mmc_blk_set_blksize(md, md->queue.card);
12093 +               blk_start_queue(md->queue.queue);
12094 +       }
12095 +       return 0;
12096 +}
12097 +#else
12098 +#define        mmc_blk_suspend NULL
12099 +#define mmc_blk_resume NULL
12100 +#endif
12101 +
12102 +static struct mmc_driver mmc_driver = {
12103 +       .drv            = {
12104 +               .name   = "mmcblk",
12105 +       },
12106 +       .probe          = mmc_blk_probe,
12107 +       .remove         = mmc_blk_remove,
12108 +       .suspend        = mmc_blk_suspend,
12109 +       .resume         = mmc_blk_resume,
12110 +};
12111 +
12112 +static int __init mmc_blk_init(void)
12113 +{
12114 +       int res = -ENOMEM;
12115 +
12116 +       res = register_blkdev(mmc_major, "mmc");
12117 +       if (res < 0) {
12118 +               printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n",
12119 +                      mmc_major, res);
12120 +               goto out;
12121 +       }
12122 +       if (mmc_major == 0)
12123 +               mmc_major = res;
12124 +
12125 +       devfs_mk_dir("mmc");
12126 +       return mmc_register_driver(&mmc_driver);
12127 +
12128 + out:
12129 +       return res;
12130 +}
12131 +
12132 +static void __exit mmc_blk_exit(void)
12133 +{
12134 +       mmc_unregister_driver(&mmc_driver);
12135 +       devfs_remove("mmc");
12136 +       unregister_blkdev(mmc_major, "mmc");
12137 +}
12138 +
12139 +module_init(mmc_blk_init);
12140 +module_exit(mmc_blk_exit);
12141 +module_param(maxsectors, int, 0444);
12142 +
12143 +MODULE_PARM_DESC(maxsectors, "Maximum number of sectors for a single request");
12144 +
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
12149 @@ -0,0 +1,94 @@
12150 +#undef MMC_STRPCL
12151 +#undef MMC_STAT
12152 +#undef MMC_CLKRT
12153 +#undef MMC_SPI
12154 +#undef MMC_CMDAT
12155 +#undef MMC_RESTO
12156 +#undef MMC_RDTO
12157 +#undef MMC_BLKLEN
12158 +#undef MMC_NOB
12159 +#undef MMC_PRTBUF
12160 +#undef MMC_I_MASK
12161 +#undef END_CMD_RES
12162 +#undef PRG_DONE
12163 +#undef DATA_TRAN_DONE
12164 +#undef MMC_I_REG
12165 +#undef MMC_CMD
12166 +#undef MMC_ARGH
12167 +#undef MMC_ARGL
12168 +#undef MMC_RES
12169 +#undef MMC_RXFIFO
12170 +#undef MMC_TXFIFO
12171 +
12172 +#define MMC_STRPCL     0x0000
12173 +#define STOP_CLOCK             (1 << 0)
12174 +#define START_CLOCK            (2 << 0)
12175 +
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)
12189 +
12190 +#define MMC_CLKRT      0x0008          /* 3 bit */
12191 +
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)
12197 +
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)
12209 +
12210 +#define MMC_RESTO      0x0014  /* 7 bit */
12211 +
12212 +#define MMC_RDTO       0x0018  /* 16 bit */
12213 +
12214 +#define MMC_BLKLEN     0x001c  /* 10 bit */
12215 +
12216 +#define MMC_NOB                0x0020  /* 16 bit */
12217 +
12218 +#define MMC_PRTBUF     0x0024
12219 +#define BUF_PART_FULL          (1 << 0)
12220 +
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)
12229 +
12230 +#define MMC_I_REG      0x002c
12231 +/* same as MMC_I_MASK */
12232 +
12233 +#define MMC_CMD                0x0030
12234 +
12235 +#define MMC_ARGH       0x0034  /* 16 bit */
12236 +
12237 +#define MMC_ARGL       0x0038  /* 16 bit */
12238 +
12239 +#define MMC_RES                0x003c  /* 16 bit */
12240 +
12241 +#define MMC_RXFIFO     0x0040  /* 8 bit */
12242 +
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
12246 @@ -0,0 +1,147 @@
12247 +/*
12248 + *  linux/drivers/media/mmc/mmci.h - ARM PrimeCell MMCI PL180/1 driver
12249 + *
12250 + *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
12251 + *
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.
12255 + */
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)
12262 +
12263 +#define MMCICLOCK              0x004
12264 +#define MCI_CLK_ENABLE         (1 << 8)
12265 +#define MCI_PWRSAVE            (1 << 9)
12266 +#define MCI_BYPASS             (1 << 10)
12267 +
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)
12275 +
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)
12288 +
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)
12312 +
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)
12324 +
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)
12347 +
12348 +#define MMCIMASK1              0x040
12349 +#define MMCIFIFOCNT            0x048
12350 +#define MMCIFIFO               0x080 /* to 0x0bc */
12351 +
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)
12358 +
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)
12365 +
12366 +#define MCI_FIFOSIZE   16
12367 +       
12368 +#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
12369 +
12370 +struct mmci_host {
12371 +       struct mmc_host         mmc;
12372 +       void                    *base;
12373 +       int                     irq;
12374 +       unsigned int            mclk;
12375 +       u32                     pwr;
12376 +
12377 +       struct mmc_request      *req;
12378 +       struct mmc_command      *cmd;
12379 +       struct mmc_data         *data;
12380 +
12381 +       unsigned int            data_xfered;
12382 +
12383 +       /* pio stuff */
12384 +       void                    *buffer;
12385 +       unsigned int            size;
12386 +
12387 +       /* dma stuff */
12388 +//     struct scatterlist      *sg_list;
12389 +//     int                     sg_len;
12390 +//     int                     sg_dir;
12391 +};
12392 +
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
12396 @@ -0,0 +1,801 @@
12397 +/*
12398 + *  linux/drivers/media/mmc/mmc.c
12399 + *
12400 + *  Copyright (C) 2003 Russell King, All Rights Reserved.
12401 + *
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.
12405 + */
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>
12414 +
12415 +#include <linux/mmc/card.h>
12416 +#include <linux/mmc/host.h>
12417 +#include <linux/mmc/protocol.h>
12418 +
12419 +#include "mmc.h"
12420 +
12421 +#ifdef CONFIG_MMC_DEBUG
12422 +#define DBG(x...)      printk(KERN_DEBUG x)
12423 +#else
12424 +#define DBG(x...)      do { } while (0)
12425 +#endif
12426 +
12427 +#define CMD_RETRIES    3
12428 +
12429 +/*
12430 + * OCR Bit positions to 10s of Vdd mV.
12431 + */
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
12436 +};
12437 +
12438 +static const unsigned int tran_exp[] = {
12439 +       10000,          100000,         1000000,        10000000,
12440 +       0,              0,              0,              0
12441 +};
12442 +
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,
12446 +};
12447 +
12448 +static const unsigned int tacc_exp[] = {
12449 +       1,      10,     100,    1000,   10000,  100000, 1000000, 10000000,
12450 +};
12451 +
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,
12455 +};
12456 +
12457 +
12458 +/**
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
12463 + *
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.
12467 + */
12468 +void mmc_request_done(struct mmc_host *host, struct mmc_request *req)
12469 +{
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]);
12474 +
12475 +       if (err && cmd->retries) {
12476 +               cmd->retries--;
12477 +               cmd->error = 0;
12478 +               host->ops->request(host, req);
12479 +       } else if (req->done) {
12480 +               req->done(req);
12481 +       }
12482 +}
12483 +
12484 +EXPORT_SYMBOL(mmc_request_done);
12485 +
12486 +/**
12487 + *     mmc_start_request - start a command on a host
12488 + *     @host: MMC host to start command on
12489 + *     @cmd: MMC command to start
12490 + *
12491 + *     Queue a command on the specified host.  We expect the
12492 + *     caller to be holding the host lock with interrupts disabled.
12493 + */
12494 +void
12495 +mmc_start_request(struct mmc_host *host, struct mmc_request *req)
12496 +{
12497 +       DBG("MMC: starting cmd %02x arg %08x flags %08x\n",
12498 +           req->cmd->opcode, req->cmd->arg, req->cmd->flags);
12499 +
12500 +       req->cmd->error = 0;
12501 +       req->cmd->req = req;
12502 +       if (req->data) {
12503 +               req->cmd->data = req->data;
12504 +               req->data->error = 0;
12505 +               req->data->req = req;
12506 +               if (req->stop) {
12507 +                       req->data->stop = req->stop;
12508 +                       req->stop->error = 0;
12509 +                       req->stop->req = req;
12510 +               }
12511 +       }
12512 +       host->ops->request(host, req);
12513 +}
12514 +
12515 +EXPORT_SYMBOL(mmc_start_request);
12516 +
12517 +static void mmc_wait_done(struct mmc_request *req)
12518 +{
12519 +       complete(req->done_data);
12520 +}
12521 +
12522 +int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *req)
12523 +{
12524 +       DECLARE_COMPLETION(complete);
12525 +
12526 +       req->done_data = &complete;
12527 +       req->done = mmc_wait_done;
12528 +
12529 +       mmc_start_request(host, req);
12530 +
12531 +       wait_for_completion(&complete);
12532 +
12533 +       return 0;
12534 +}
12535 +
12536 +EXPORT_SYMBOL(mmc_wait_for_req);
12537 +
12538 +/**
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
12543 + *
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.
12547 + */
12548 +int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
12549 +{
12550 +       struct mmc_request req;
12551 +
12552 +       BUG_ON(host->card_busy == NULL);
12553 +
12554 +       memset(&req, 0, sizeof(struct mmc_request));
12555 +
12556 +       memset(cmd->resp, 0, sizeof(cmd->resp));
12557 +       cmd->retries = retries;
12558 +
12559 +       req.cmd = cmd;
12560 +       cmd->data = NULL;
12561 +
12562 +       mmc_wait_for_req(host, &req);
12563 +
12564 +       return cmd->error;
12565 +}
12566 +
12567 +EXPORT_SYMBOL(mmc_wait_for_cmd);
12568 +
12569 +
12570 +
12571 +/**
12572 + *     __mmc_claim_host - exclusively claim a host
12573 + *     @host: mmc host to claim
12574 + *     @card: mmc card to claim host for
12575 + *
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.
12579 + *
12580 + *     Note: you should use mmc_card_claim_host or mmc_claim_host.
12581 + */
12582 +int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
12583 +{
12584 +       DECLARE_WAITQUEUE(wait, current);
12585 +       unsigned long flags;
12586 +       int err = 0;
12587 +
12588 +       add_wait_queue(&host->wq, &wait);
12589 +       spin_lock_irqsave(&host->lock, flags);
12590 +       while (1) {
12591 +               set_current_state(TASK_UNINTERRUPTIBLE);
12592 +               if (host->card_busy == NULL)
12593 +                       break;
12594 +               spin_unlock_irqrestore(&host->lock, flags);
12595 +               schedule();
12596 +               spin_lock_irqsave(&host->lock, flags);
12597 +       }
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);
12602 +
12603 +       if (card != (void *)-1 && host->card_selected != card) {
12604 +               struct mmc_command cmd;
12605 +
12606 +               host->card_selected = card;
12607 +
12608 +               cmd.opcode = MMC_SELECT_CARD;
12609 +               cmd.arg = card->rca << 16;
12610 +               cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
12611 +
12612 +               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12613 +       }
12614 +
12615 +       return err;
12616 +}
12617 +
12618 +EXPORT_SYMBOL(__mmc_claim_host);
12619 +
12620 +/**
12621 + *     mmc_release_host - release a host
12622 + *     @host: mmc host to release
12623 + *
12624 + *     Release a MMC host, allowing others to claim the host
12625 + *     for their operations.
12626 + */
12627 +void mmc_release_host(struct mmc_host *host)
12628 +{
12629 +       unsigned long flags;
12630 +
12631 +       BUG_ON(host->card_busy == NULL);
12632 +
12633 +       spin_lock_irqsave(&host->lock, flags);
12634 +       host->card_busy = NULL;
12635 +       spin_unlock_irqrestore(&host->lock, flags);
12636 +
12637 +       wake_up(&host->wq);
12638 +}
12639 +
12640 +EXPORT_SYMBOL(mmc_release_host);
12641 +
12642 +static void mmc_deselect_cards(struct mmc_host *host)
12643 +{
12644 +       struct mmc_command cmd;
12645 +
12646 +       /*
12647 +        * Ensure that no card is selected.
12648 +        */
12649 +       if (host->card_selected) {
12650 +               host->card_selected = NULL;
12651 +
12652 +               cmd.opcode = MMC_SELECT_CARD;
12653 +               cmd.arg = 0;
12654 +               cmd.flags = MMC_RSP_NONE;
12655 +
12656 +               mmc_wait_for_cmd(host, &cmd, 0);
12657 +       }
12658 +}
12659 +
12660 +
12661 +static inline void mmc_delay(unsigned int ms)
12662 +{
12663 +       if (ms < HZ / 1000) {
12664 +               yield();
12665 +               mdelay(ms);
12666 +       } else {
12667 +               set_current_state(TASK_INTERRUPTIBLE);
12668 +               schedule_timeout(ms * HZ / 1000);
12669 +       }
12670 +}
12671 +
12672 +static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
12673 +{
12674 +       int bit;
12675 +
12676 +       /*
12677 +        * Mask off any voltages we don't support
12678 +        */
12679 +       ocr &= host->ocr_avail;
12680 +
12681 +       /*
12682 +        * Select the lowest voltage
12683 +        */
12684 +       bit = ffs(ocr);
12685 +       if (bit) {
12686 +               bit -= 1;
12687 +
12688 +               ocr = 1 << bit;
12689 +
12690 +               host->ios.vdd = mmc_ocr_bit_to_vdd[bit];
12691 +               host->ops->set_ios(host, &host->ios);
12692 +       } else {
12693 +               ocr = 0;
12694 +       }
12695 +
12696 +       return ocr;
12697 +}
12698 +
12699 +static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp)
12700 +{
12701 +       memset(cid, 0, sizeof(struct mmc_cid));
12702 +
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;
12717 +}
12718 +
12719 +static void mmc_decode_csd(struct mmc_csd *csd, u32 *resp)
12720 +{
12721 +       unsigned int e, m;
12722 +
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;
12728 +
12729 +       m = (resp[0] >> 3) & 15;
12730 +       e = resp[0] & 7;
12731 +       csd->max_dtr      = tran_exp[e] * tran_mant[m];
12732 +       csd->cmdclass     = (resp[1] >> 20) & 0xfff;
12733 +
12734 +       e = (resp[2] >> 15) & 7;
12735 +       m = (resp[1] << 2 | resp[2] >> 30) & 0x3fff;
12736 +       csd->capacity     = (1 + m) << (e + 2);
12737 +
12738 +       csd->read_blkbits = (resp[1] >> 16) & 15;
12739 +}
12740 +
12741 +/*
12742 + * Locate a MMC card on this MMC host given a CID.
12743 + */
12744 +static struct mmc_card *
12745 +mmc_find_card(struct mmc_host *host, struct mmc_cid *cid)
12746 +{
12747 +       struct mmc_card *card;
12748 +
12749 +       list_for_each_entry(card, &host->cards, node) {
12750 +               if (memcmp(&card->cid, cid, sizeof(struct mmc_cid)) == 0)
12751 +                       return card;
12752 +       }
12753 +       return NULL;
12754 +}
12755 +
12756 +/*
12757 + * Allocate a new MMC card, and assign a unique RCA.
12758 + */
12759 +static struct mmc_card *
12760 +mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca)
12761 +{
12762 +       struct mmc_card *card, *c;
12763 +       unsigned int rca = *frca;
12764 +
12765 +       card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
12766 +       if (!card)
12767 +               return ERR_PTR(-ENOMEM);
12768 +
12769 +       mmc_init_card(card, host);
12770 +       memcpy(&card->cid, cid, sizeof(struct mmc_cid));
12771 +
12772 + again:
12773 +       list_for_each_entry(c, &host->cards, node)
12774 +               if (c->rca == rca) {
12775 +                       rca++;
12776 +                       goto again;
12777 +               }
12778 +
12779 +       card->rca = rca;
12780 +
12781 +       *frca = rca;
12782 +
12783 +       return card;
12784 +}
12785 +
12786 +/*
12787 + * Apply power to the MMC stack.
12788 + */
12789 +static void mmc_power_up(struct mmc_host *host)
12790 +{
12791 +       struct mmc_command cmd;
12792 +       int bit = fls(host->ocr_avail) - 1;
12793 +
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);
12798 +
12799 +       mmc_delay(1);
12800 +
12801 +       host->ios.clock = host->f_min;
12802 +       host->ios.power_mode = MMC_POWER_ON;
12803 +       host->ops->set_ios(host, &host->ios);
12804 +
12805 +       mmc_delay(2);
12806 +
12807 +       cmd.opcode = MMC_GO_IDLE_STATE;
12808 +       cmd.arg = 0;
12809 +       cmd.flags = MMC_RSP_NONE;
12810 +
12811 +       mmc_wait_for_cmd(host, &cmd, 0);
12812 +}
12813 +
12814 +static void mmc_power_off(struct mmc_host *host)
12815 +{
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);
12821 +}
12822 +
12823 +static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
12824 +{
12825 +       struct mmc_command cmd;
12826 +       int i, err = 0;
12827 +
12828 +       cmd.opcode = MMC_SEND_OP_COND;
12829 +       cmd.arg = ocr;
12830 +       cmd.flags = MMC_RSP_SHORT;
12831 +
12832 +       for (i = 100; i; i--) {
12833 +               err = mmc_wait_for_cmd(host, &cmd, 0);
12834 +               if (err != MMC_ERR_NONE)
12835 +                       break;
12836 +
12837 +               if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
12838 +                       break;
12839 +
12840 +               err = MMC_ERR_TIMEOUT;
12841 +       }
12842 +
12843 +       if (rocr)
12844 +               *rocr = cmd.resp[0];
12845 +
12846 +       return err;
12847 +}
12848 +
12849 +/*
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.
12853 + *
12854 + * Create a mmc_card entry for each discovered card, assigning
12855 + * it an RCA, and save the CID.
12856 + */
12857 +static void mmc_discover_cards(struct mmc_host *host)
12858 +{
12859 +       struct mmc_card *card;
12860 +       unsigned int first_rca = 1, err;
12861 +
12862 +       while (1) {
12863 +               struct mmc_command cmd;
12864 +               struct mmc_cid cid;
12865 +
12866 +               /*
12867 +                * Read CID
12868 +                */
12869 +               cmd.opcode = MMC_ALL_SEND_CID;
12870 +               cmd.arg = 0;
12871 +               cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
12872 +
12873 +               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12874 +               if (err == MMC_ERR_TIMEOUT) {
12875 +                       err = MMC_ERR_NONE;
12876 +                       break;
12877 +               }
12878 +               if (err != MMC_ERR_NONE) {
12879 +                       printk(KERN_ERR "MMC: mmc%d error requesting CID: %d\n",
12880 +                               host->host_num, err);
12881 +                       break;
12882 +               }
12883 +
12884 +               mmc_decode_cid(&cid, cmd.resp);
12885 +
12886 +               card = mmc_find_card(host, &cid);
12887 +               if (!card) {
12888 +                       card = mmc_alloc_card(host, &cid, &first_rca);
12889 +                       if (IS_ERR(card)) {
12890 +                               err = PTR_ERR(card);
12891 +                               break;
12892 +                       }
12893 +                       list_add(&card->node, &host->cards);
12894 +               }
12895 +
12896 +               card->state &= ~MMC_STATE_DEAD;
12897 +
12898 +               cmd.opcode = MMC_SET_RELATIVE_ADDR;
12899 +               cmd.arg = card->rca << 16;
12900 +               cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
12901 +
12902 +               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12903 +               if (err != MMC_ERR_NONE)
12904 +                       card->state |= MMC_STATE_DEAD;
12905 +       }
12906 +}
12907 +
12908 +static void mmc_read_csds(struct mmc_host *host)
12909 +{
12910 +       struct mmc_card *card;
12911 +
12912 +       list_for_each_entry(card, &host->cards, node) {
12913 +               struct mmc_command cmd;
12914 +               int err;
12915 +
12916 +               if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
12917 +                       continue;
12918 +
12919 +               cmd.opcode = MMC_SEND_CSD;
12920 +               cmd.arg = card->rca << 16;
12921 +               cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
12922 +
12923 +               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12924 +               if (err != MMC_ERR_NONE) {
12925 +                       card->state |= MMC_STATE_DEAD;
12926 +                       continue;
12927 +               }
12928 +
12929 +               mmc_decode_csd(&card->csd, cmd.resp);
12930 +       }
12931 +}
12932 +
12933 +static unsigned int mmc_calculate_clock(struct mmc_host *host)
12934 +{
12935 +       struct mmc_card *card;
12936 +       unsigned int max_dtr = host->f_max;
12937 +
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;
12941 +
12942 +       DBG("MMC: selected %d.%03dMHz transfer rate\n",
12943 +           max_dtr / 1000000, (max_dtr / 1000) % 1000);
12944 +
12945 +       return max_dtr;
12946 +}
12947 +
12948 +/*
12949 + * Check whether cards we already know about are still present.
12950 + * We do this by requesting status, and checking whether a card
12951 + * responds.
12952 + *
12953 + * A request for status does not cause a state change in data
12954 + * transfer mode.
12955 + */
12956 +static void mmc_check_cards(struct mmc_host *host)
12957 +{
12958 +       struct list_head *l, *n;
12959 +
12960 +       mmc_deselect_cards(host);
12961 +
12962 +       list_for_each_safe(l, n, &host->cards) {
12963 +               struct mmc_card *card = mmc_list_to_card(l);
12964 +               struct mmc_command cmd;
12965 +               int err;
12966 +
12967 +               cmd.opcode = MMC_SEND_STATUS;
12968 +               cmd.arg = card->rca << 16;
12969 +               cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
12970 +
12971 +               err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
12972 +               if (err == MMC_ERR_NONE)
12973 +                       continue;
12974 +
12975 +               /*
12976 +                * Ok, we believe this card has been removed.
12977 +                */
12978 +               card->state |= MMC_STATE_DEAD;
12979 +       }
12980 +}
12981 +
12982 +static void mmc_setup(struct mmc_host *host)
12983 +{
12984 +       if (host->ios.power_mode != MMC_POWER_ON) {
12985 +               int err;
12986 +               u32 ocr;
12987 +
12988 +               mmc_power_up(host);
12989 +
12990 +               err = mmc_send_op_cond(host, 0, &ocr);
12991 +               if (err != MMC_ERR_NONE)
12992 +                       return;
12993 +
12994 +               host->ocr = mmc_select_voltage(host, ocr);
12995 +       } else {
12996 +               host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
12997 +               host->ios.clock = host->f_min;
12998 +               host->ops->set_ios(host, &host->ios);
12999 +
13000 +               /*
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.
13008 +                *
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.
13012 +                */
13013 +       }
13014 +
13015 +       if (host->ocr == 0)
13016 +               return;
13017 +
13018 +       /*
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.)
13022 +        */
13023 +       mmc_send_op_cond(host, host->ocr, NULL);
13024 +
13025 +       mmc_discover_cards(host);
13026 +
13027 +       /*
13028 +        * Ok, now switch to push-pull mode.
13029 +        */
13030 +       host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
13031 +       host->ops->set_ios(host, &host->ios);
13032 +
13033 +       mmc_read_csds(host);
13034 +}
13035 +
13036 +
13037 +/**
13038 + *     mmc_detect_change - process change of state on a MMC socket
13039 + *     @host: host which changed state.
13040 + *
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.
13043 + */
13044 +void mmc_detect_change(struct mmc_host *host)
13045 +{
13046 +       struct list_head *l, *n;
13047 +
13048 +       mmc_claim_host(host);
13049 +
13050 +       if (host->ios.power_mode == MMC_POWER_ON)
13051 +               mmc_check_cards(host);
13052 +
13053 +       mmc_setup(host);
13054 +
13055 +       if (!list_empty(&host->cards)) {
13056 +               /*
13057 +                * (Re-)calculate the fastest clock rate which the
13058 +                * attached cards and the host support.
13059 +                */
13060 +               host->ios.clock = mmc_calculate_clock(host);
13061 +               host->ops->set_ios(host, &host->ios);
13062 +       }
13063 +
13064 +       mmc_release_host(host);
13065 +
13066 +       list_for_each_safe(l, n, &host->cards) {
13067 +               struct mmc_card *card = mmc_list_to_card(l);
13068 +
13069 +               /*
13070 +                * If this is a new and good card, register it.
13071 +                */
13072 +               if (!mmc_card_present(card) && !mmc_card_dead(card)) {
13073 +                       if (mmc_register_card(card))
13074 +                               card->state |= MMC_STATE_DEAD;
13075 +                       else
13076 +                               card->state |= MMC_STATE_PRESENT;
13077 +               }
13078 +
13079 +               /*
13080 +                * If this card is dead, destroy it.
13081 +                */
13082 +               if (mmc_card_dead(card)) {
13083 +                       list_del(&card->node);
13084 +                       mmc_remove_card(card);
13085 +               }
13086 +       }
13087 +
13088 +       /*
13089 +        * If we discover that there are no cards on the
13090 +        * bus, turn off the clock and power down.
13091 +        */
13092 +       if (list_empty(&host->cards))
13093 +               mmc_power_off(host);
13094 +}
13095 +
13096 +EXPORT_SYMBOL(mmc_detect_change);
13097 +
13098 +
13099 +/**
13100 + *     mmc_init_host - initialise the per-host structure.
13101 + *     @host: mmc host
13102 + *
13103 + *     Initialise the per-host structure.
13104 + */
13105 +int mmc_init_host(struct mmc_host *host)
13106 +{
13107 +       static unsigned int host_num;
13108 +
13109 +       memset(host, 0, sizeof(struct mmc_host));
13110 +
13111 +       host->host_num = host_num++;
13112 +
13113 +       spin_lock_init(&host->lock);
13114 +       init_waitqueue_head(&host->wq);
13115 +       INIT_LIST_HEAD(&host->cards);
13116 +
13117 +       return 0;
13118 +}
13119 +
13120 +EXPORT_SYMBOL(mmc_init_host);
13121 +
13122 +/**
13123 + *     mmc_add_host - initialise host hardware
13124 + *     @host: mmc host
13125 + */
13126 +int mmc_add_host(struct mmc_host *host)
13127 +{
13128 +       mmc_power_off(host);
13129 +       mmc_detect_change(host);
13130 +
13131 +       return 0;
13132 +}
13133 +
13134 +EXPORT_SYMBOL(mmc_add_host);
13135 +
13136 +/**
13137 + *     mmc_remove_host - remove host hardware
13138 + *     @host: mmc host
13139 + *
13140 + *     Unregister and remove all cards associated with this host,
13141 + *     and power down the MMC bus.
13142 + */
13143 +void mmc_remove_host(struct mmc_host *host)
13144 +{
13145 +       struct list_head *l, *n;
13146 +
13147 +       list_for_each_safe(l, n, &host->cards) {
13148 +               struct mmc_card *card = mmc_list_to_card(l);
13149 +
13150 +               mmc_remove_card(card);
13151 +       }
13152 +
13153 +       mmc_power_off(host);
13154 +}
13155 +
13156 +EXPORT_SYMBOL(mmc_remove_host);
13157 +
13158 +#ifdef CONFIG_PM
13159 +
13160 +/**
13161 + *     mmc_suspend_host - suspend a host
13162 + *     @host: mmc host
13163 + *     @state: suspend mode (PM_SUSPEND_xxx)
13164 + */
13165 +int mmc_suspend_host(struct mmc_host *host, u32 state)
13166 +{
13167 +       mmc_claim_host(host);
13168 +       mmc_deselect_cards(host);
13169 +       mmc_power_off(host);
13170 +       mmc_release_host(host);
13171 +
13172 +       return 0;
13173 +}
13174 +
13175 +/**
13176 + *     mmc_resume_host - resume a previously suspended host
13177 + *     @host: mmc host
13178 + */
13179 +int mmc_resume_host(struct mmc_host *host)
13180 +{
13181 +       mmc_detect_change(host);
13182 +
13183 +       return 0;
13184 +}
13185 +
13186 +
13187 +#else /* CONFIG_PM is not set */
13188 +
13189 +int mmc_suspend_host(struct mmc_host *host, u32 state) { return 0; }
13190 +int mmc_resume_host(struct mmc_host *host) { return 0; }
13191 +
13192 +#endif
13193 +
13194 +EXPORT_SYMBOL(mmc_suspend_host);
13195 +EXPORT_SYMBOL(mmc_resume_host);
13196 +
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
13200 @@ -0,0 +1,21 @@
13201 +#
13202 +# Makefile for the kernel mmc device drivers.
13203 +#
13204 +
13205 +#
13206 +# Core
13207 +#
13208 +obj-$(CONFIG_MMC)              += mmc_core.o
13209 +
13210 +#
13211 +# Media drivers
13212 +#
13213 +obj-$(CONFIG_MMC_BLOCK)                += mmc_block.o
13214 +
13215 +#
13216 +# Host drivers
13217 +#
13218 +obj-$(CONFIG_MMC_ARMMMCI)      += mmci.o
13219 +obj-$(CONFIG_MMC_PXA)          += pxamci.o
13220 +
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
13224 @@ -3,3 +3,6 @@
13225  #
13226  
13227  obj-y        := video/ radio/ dvb/ common/
13228 +
13229 +obj-$(CONFIG_MMC)      += mmc/
13230 +
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.)
13236  
13237 +config SERIAL_PXA
13238 +       bool "PXA serial port support"
13239 +       depends on ARM && ARCH_PXA
13240 +       select SERIAL_CORE
13241 +       help
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.
13244 +
13245 +config SERIAL_PXA_CONSOLE
13246 +       bool "Console on PXA serial port"
13247 +       depends on SERIAL_PXA
13248 +       select SERIAL_CORE_CONSOLE
13249 +       help
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.
13252 +
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.)
13259 +
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;
13267         unsigned int ret;
13268  
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,
13275                 .line           = 2,
13276         },
13277 +  }, {  /* HWUART */
13278 +       .name   = "HWUART",
13279 +       .cken   = CKEN4_HWUART,
13280 +       .port = {
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,
13287 +               .fifosize       = 64,
13288 +               .flags          = ASYNC_SKIP_TEST,
13289 +               .ops            = &serial_pxa_pops,
13290 +               .line           = 3,
13291 +       },
13292    }
13293  };
13294  
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;
13299  
13300         /*
13301 +        * If we don't support modem control lines, don't allow
13302 +        * these to be set.
13303 +        */
13304 +       if (0) {
13305 +               termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR);
13306 +               termios->c_cflag |= CLOCAL;
13307 +       }
13308 +
13309 +       /*
13310          * We only support CS7 and CS8.
13311          */
13312         while ((termios->c_cflag & CSIZE) != CS7 &&
13313 @@ -894,6 +903,7 @@
13314                         if (sa1100_ports[i].port.mapbase != res->start)
13315                                 continue;
13316  
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]);
13320                         break;
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
13323 @@ -81,7 +81,7 @@
13324         struct request_queue *rq = tr->blkcore_priv->rq;
13325  
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;
13329  
13330         daemonize("%sd", tr->name);
13331  
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
13334 @@ -1,6 +1,6 @@
13335  /*======================================================================
13336  
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 $
13339  
13340  ======================================================================*/
13341  
13342 @@ -20,6 +20,7 @@
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 @@
13351                         else
13352                                 priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
13353                 }
13354 -               else if (erase->time + erase_timeout < jiffies)
13355 +               else if (time_after(jiffies, erase->time + erase_timeout))
13356                 {
13357                         printk("Flash erase timed out. The world is broken.\n");
13358  
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
13361 @@ -7,7 +7,7 @@
13362   *
13363   * This code is GPL
13364   *
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 $
13367   */
13368  
13369  #include <linux/module.h>
13370 @@ -26,7 +26,7 @@
13371   */
13372  struct mtd_concat {
13373         struct mtd_info mtd;
13374 -       int             num_subdev;
13375 +       int num_subdev;
13376         struct mtd_info **subdev;
13377  };
13378  
13379 @@ -37,21 +37,20 @@
13380  #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev)   \
13381         ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *)))
13382  
13383 -
13384  /*
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.
13387   */
13388  #define CONCAT(x)  ((struct mtd_concat *)(x))
13389  
13390 -       
13391  /* 
13392   * MTD methods which look up the relevant subdevice, translate the
13393   * effective address and pass through to the subdevice.
13394   */
13395  
13396 -static int concat_read (struct mtd_info *mtd, loff_t from, size_t len, 
13397 -                       size_t *retlen, u_char *buf)
13398 +static int
13399 +concat_read(struct mtd_info *mtd, loff_t from, size_t len,
13400 +           size_t * retlen, u_char * buf)
13401  {
13402         struct mtd_concat *concat = CONCAT(mtd);
13403         int err = -EINVAL;
13404 @@ -59,43 +58,43 @@
13405  
13406         *retlen = 0;
13407  
13408 -       for(i = 0; i < concat->num_subdev; i++)
13409 -       {
13410 +       for (i = 0; i < concat->num_subdev; i++) {
13411                 struct mtd_info *subdev = concat->subdev[i];
13412                 size_t size, retsize;
13413  
13414 -               if (from >= subdev->size)
13415 -               {   /* Not destined for this subdev */
13416 -                       size  = 0;
13417 +               if (from >= subdev->size) {
13418 +                       /* Not destined for this subdev */
13419 +                       size = 0;
13420                         from -= subdev->size;
13421 +                       continue;
13422                 }
13423 +               if (from + len > subdev->size)
13424 +                       /* First part goes into this subdev */
13425 +                       size = subdev->size - from;
13426                 else
13427 -               {
13428 -                       if (from + len > subdev->size)
13429 -                               size = subdev->size - from; /* First part goes into this subdev */
13430 -                       else
13431 -                               size = len; /* Entire transaction goes into this subdev */
13432 +                       /* Entire transaction goes into this subdev */
13433 +                       size = len;
13434  
13435 -                       err = subdev->read(subdev, from, size, &retsize, buf);
13436 +               err = subdev->read(subdev, from, size, &retsize, buf);
13437  
13438 -                       if(err)
13439 -                               break;
13440 +               if (err)
13441 +                       break;
13442  
13443 -                       *retlen += retsize;
13444 -                       len -= size;
13445 -                       if(len == 0)
13446 -                               break;
13447 +               *retlen += retsize;
13448 +               len -= size;
13449 +               if (len == 0)
13450 +                       break;
13451  
13452 -                       err = -EINVAL;
13453 -                       buf += size;
13454 -                       from = 0;
13455 -               }
13456 +               err = -EINVAL;
13457 +               buf += size;
13458 +               from = 0;
13459         }
13460         return err;
13461  }
13462  
13463 -static int concat_write (struct mtd_info *mtd, loff_t to, size_t len,
13464 -                       size_t *retlen, const u_char *buf)
13465 +static int
13466 +concat_write(struct mtd_info *mtd, loff_t to, size_t len,
13467 +            size_t * retlen, const u_char * buf)
13468  {
13469         struct mtd_concat *concat = CONCAT(mtd);
13470         int err = -EINVAL;
13471 @@ -106,46 +105,44 @@
13472  
13473         *retlen = 0;
13474  
13475 -       for(i = 0; i < concat->num_subdev; i++)
13476 -       {
13477 +       for (i = 0; i < concat->num_subdev; i++) {
13478                 struct mtd_info *subdev = concat->subdev[i];
13479                 size_t size, retsize;
13480  
13481 -               if (to >= subdev->size)
13482 -               {
13483 -                       size  = 0;
13484 +               if (to >= subdev->size) {
13485 +                       size = 0;
13486                         to -= subdev->size;
13487 +                       continue;
13488                 }
13489 +               if (to + len > subdev->size)
13490 +                       size = subdev->size - to;
13491                 else
13492 -               {
13493 -                       if (to + len > subdev->size)
13494 -                               size = subdev->size - to;
13495 -                       else
13496 -                               size = len;
13497 +                       size = len;
13498  
13499 -                       if (!(subdev->flags & MTD_WRITEABLE))
13500 -                               err = -EROFS;
13501 -                       else
13502 -                               err = subdev->write(subdev, to, size, &retsize, buf);
13503 +               if (!(subdev->flags & MTD_WRITEABLE))
13504 +                       err = -EROFS;
13505 +               else
13506 +                       err = subdev->write(subdev, to, size, &retsize, buf);
13507  
13508 -                       if(err)
13509 -                               break;
13510 +               if (err)
13511 +                       break;
13512  
13513 -                       *retlen += retsize;
13514 -                       len -= size;
13515 -                       if(len == 0)
13516 -                               break;
13517 +               *retlen += retsize;
13518 +               len -= size;
13519 +               if (len == 0)
13520 +                       break;
13521  
13522 -                       err = -EINVAL;
13523 -                       buf += size;
13524 -                       to = 0;
13525 -               }
13526 +               err = -EINVAL;
13527 +               buf += size;
13528 +               to = 0;
13529         }
13530         return err;
13531  }
13532  
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)
13535 +static int
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)
13539  {
13540         struct mtd_concat *concat = CONCAT(mtd);
13541         int err = -EINVAL;
13542 @@ -153,53 +150,56 @@
13543  
13544         *retlen = 0;
13545  
13546 -       for(i = 0; i < concat->num_subdev; i++)
13547 -       {
13548 +       for (i = 0; i < concat->num_subdev; i++) {
13549                 struct mtd_info *subdev = concat->subdev[i];
13550                 size_t size, retsize;
13551 -        
13552 -               if (from >= subdev->size)
13553 -               {   /* Not destined for this subdev */
13554 -                       size  = 0;
13555 +
13556 +               if (from >= subdev->size) {
13557 +                       /* Not destined for this subdev */
13558 +                       size = 0;
13559                         from -= subdev->size;
13560 +                       continue;
13561                 }
13562 +
13563 +               if (from + len > subdev->size)
13564 +                       /* First part goes into this subdev */
13565 +                       size = subdev->size - from;
13566                 else
13567 -               {
13568 -                       if (from + len > subdev->size)
13569 -                               size = subdev->size - from; /* First part goes into this subdev */
13570 -                       else
13571 -                               size = len; /* Entire transaction goes into this subdev */
13572 -            
13573 -            if (subdev->read_ecc)
13574 -                       err = subdev->read_ecc(subdev, from, size, &retsize, buf, eccbuf, oobsel);
13575 -            else
13576 -                err = -EINVAL;
13577 +                       /* Entire transaction goes into this subdev */
13578 +                       size = len;
13579  
13580 -                       if(err)
13581 -                               break;
13582 +               if (subdev->read_ecc)
13583 +                       err = subdev->read_ecc(subdev, from, size,
13584 +                                              &retsize, buf, eccbuf, oobsel);
13585 +               else
13586 +                       err = -EINVAL;
13587  
13588 -                       *retlen += retsize;
13589 -                       len -= size;
13590 -                       if(len == 0)
13591 -                               break;
13592 +               if (err)
13593 +                       break;
13594  
13595 -                       err = -EINVAL;
13596 -                       buf += size;
13597 -            if (eccbuf)
13598 -            {
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)); 
13603 -            }
13604 -                       from = 0;
13605 +               *retlen += retsize;
13606 +               len -= size;
13607 +               if (len == 0)
13608 +                       break;
13609 +
13610 +               err = -EINVAL;
13611 +               buf += size;
13612 +               if (eccbuf) {
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));
13618                 }
13619 +               from = 0;
13620         }
13621         return err;
13622  }
13623  
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)
13626 +static int
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)
13630  {
13631         struct mtd_concat *concat = CONCAT(mtd);
13632         int err = -EINVAL;
13633 @@ -210,50 +210,48 @@
13634  
13635         *retlen = 0;
13636  
13637 -       for(i = 0; i < concat->num_subdev; i++)
13638 -       {
13639 +       for (i = 0; i < concat->num_subdev; i++) {
13640                 struct mtd_info *subdev = concat->subdev[i];
13641                 size_t size, retsize;
13642 -        
13643 -               if (to >= subdev->size)
13644 -               {
13645 -                       size  = 0;
13646 +
13647 +               if (to >= subdev->size) {
13648 +                       size = 0;
13649                         to -= subdev->size;
13650 +                       continue;
13651                 }
13652 +               if (to + len > subdev->size)
13653 +                       size = subdev->size - to;
13654                 else
13655 -               {
13656 -                       if (to + len > subdev->size)
13657 -                               size = subdev->size - to;
13658 -                       else
13659 -                               size = len;
13660 +                       size = len;
13661  
13662 -                       if (!(subdev->flags & MTD_WRITEABLE))
13663 -                               err = -EROFS;
13664 -                       else if (subdev->write_ecc)
13665 -                               err = subdev->write_ecc(subdev, to, size, &retsize, buf, eccbuf, oobsel);
13666 -            else
13667 -                err = -EINVAL;
13668 +               if (!(subdev->flags & MTD_WRITEABLE))
13669 +                       err = -EROFS;
13670 +               else if (subdev->write_ecc)
13671 +                       err = subdev->write_ecc(subdev, to, size,
13672 +                                               &retsize, buf, eccbuf, oobsel);
13673 +               else
13674 +                       err = -EINVAL;
13675  
13676 -                       if(err)
13677 -                               break;
13678 +               if (err)
13679 +                       break;
13680  
13681 -                       *retlen += retsize;
13682 -                       len -= size;
13683 -                       if(len == 0)
13684 -                               break;
13685 +               *retlen += retsize;
13686 +               len -= size;
13687 +               if (len == 0)
13688 +                       break;
13689  
13690 -                       err = -EINVAL;
13691 -                       buf += size;
13692 -            if (eccbuf)
13693 -                eccbuf += subdev->oobsize;
13694 -                       to = 0;
13695 -               }
13696 +               err = -EINVAL;
13697 +               buf += size;
13698 +               if (eccbuf)
13699 +                       eccbuf += subdev->oobsize;
13700 +               to = 0;
13701         }
13702         return err;
13703  }
13704  
13705 -static int concat_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
13706 -            size_t *retlen, u_char *buf)
13707 +static int
13708 +concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
13709 +               size_t * retlen, u_char * buf)
13710  {
13711         struct mtd_concat *concat = CONCAT(mtd);
13712         int err = -EINVAL;
13713 @@ -261,46 +259,47 @@
13714  
13715         *retlen = 0;
13716  
13717 -       for(i = 0; i < concat->num_subdev; i++)
13718 -       {
13719 +       for (i = 0; i < concat->num_subdev; i++) {
13720                 struct mtd_info *subdev = concat->subdev[i];
13721                 size_t size, retsize;
13722 -        
13723 -               if (from >= subdev->size)
13724 -               {   /* Not destined for this subdev */
13725 -                       size  = 0;
13726 +
13727 +               if (from >= subdev->size) {
13728 +                       /* Not destined for this subdev */
13729 +                       size = 0;
13730                         from -= subdev->size;
13731 +                       continue;
13732                 }
13733 +               if (from + len > subdev->size)
13734 +                       /* First part goes into this subdev */
13735 +                       size = subdev->size - from;
13736                 else
13737 -               {
13738 -                       if (from + len > subdev->size)
13739 -                               size = subdev->size - from; /* First part goes into this subdev */
13740 -                       else
13741 -                               size = len; /* Entire transaction goes into this subdev */
13742 -            
13743 -            if (subdev->read_oob)
13744 -                       err = subdev->read_oob(subdev, from, size, &retsize, buf);
13745 -            else
13746 -                err = -EINVAL;
13747 +                       /* Entire transaction goes into this subdev */
13748 +                       size = len;
13749  
13750 -                       if(err)
13751 -                               break;
13752 +               if (subdev->read_oob)
13753 +                       err = subdev->read_oob(subdev, from, size,
13754 +                                              &retsize, buf);
13755 +               else
13756 +                       err = -EINVAL;
13757  
13758 -                       *retlen += retsize;
13759 -                       len -= size;
13760 -                       if(len == 0)
13761 -                               break;
13762 +               if (err)
13763 +                       break;
13764  
13765 -                       err = -EINVAL;
13766 -                       buf += size;
13767 -                       from = 0;
13768 -               }
13769 +               *retlen += retsize;
13770 +               len -= size;
13771 +               if (len == 0)
13772 +                       break;
13773 +
13774 +               err = -EINVAL;
13775 +               buf += size;
13776 +               from = 0;
13777         }
13778         return err;
13779  }
13780  
13781 -static int concat_write_oob (struct mtd_info *mtd, loff_t to, size_t len, 
13782 -            size_t *retlen, const u_char *buf)
13783 +static int
13784 +concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
13785 +                size_t * retlen, const u_char * buf)
13786  {
13787         struct mtd_concat *concat = CONCAT(mtd);
13788         int err = -EINVAL;
13789 @@ -311,50 +310,46 @@
13790  
13791         *retlen = 0;
13792  
13793 -       for(i = 0; i < concat->num_subdev; i++)
13794 -       {
13795 +       for (i = 0; i < concat->num_subdev; i++) {
13796                 struct mtd_info *subdev = concat->subdev[i];
13797                 size_t size, retsize;
13798 -        
13799 -               if (to >= subdev->size)
13800 -               {
13801 -                       size  = 0;
13802 +
13803 +               if (to >= subdev->size) {
13804 +                       size = 0;
13805                         to -= subdev->size;
13806 +                       continue;
13807                 }
13808 +               if (to + len > subdev->size)
13809 +                       size = subdev->size - to;
13810                 else
13811 -               {
13812 -                       if (to + len > subdev->size)
13813 -                               size = subdev->size - to;
13814 -                       else
13815 -                               size = len;
13816 +                       size = len;
13817  
13818 -                       if (!(subdev->flags & MTD_WRITEABLE))
13819 -                               err = -EROFS;
13820 -                       else if (subdev->write_oob)
13821 -                               err = subdev->write_oob(subdev, to, size, &retsize, buf);
13822 -            else
13823 -                err = -EINVAL;
13824 +               if (!(subdev->flags & MTD_WRITEABLE))
13825 +                       err = -EROFS;
13826 +               else if (subdev->write_oob)
13827 +                       err = subdev->write_oob(subdev, to, size, &retsize,
13828 +                                               buf);
13829 +               else
13830 +                       err = -EINVAL;
13831  
13832 -                       if(err)
13833 -                               break;
13834 +               if (err)
13835 +                       break;
13836  
13837 -                       *retlen += retsize;
13838 -                       len -= size;
13839 -                       if(len == 0)
13840 -                               break;
13841 +               *retlen += retsize;
13842 +               len -= size;
13843 +               if (len == 0)
13844 +                       break;
13845  
13846 -                       err = -EINVAL;
13847 -                       buf += size;
13848 -                       to = 0;
13849 -               }
13850 +               err = -EINVAL;
13851 +               buf += size;
13852 +               to = 0;
13853         }
13854         return err;
13855  }
13856  
13857 -
13858 -static void concat_erase_callback (struct erase_info *instr)
13859 +static void concat_erase_callback(struct erase_info *instr)
13860  {
13861 -       wake_up((wait_queue_head_t *)instr->priv);
13862 +       wake_up((wait_queue_head_t *) instr->priv);
13863  }
13864  
13865  static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
13866 @@ -370,18 +365,18 @@
13867  
13868         erase->mtd = mtd;
13869         erase->callback = concat_erase_callback;
13870 -       erase->priv = (unsigned long)&waitq;
13871 -                       
13872 +       erase->priv = (unsigned long) &waitq;
13873 +
13874         /*
13875          * FIXME: Allow INTERRUPTIBLE. Which means
13876          * not having the wait_queue head on the stack.
13877          */
13878         err = mtd->erase(mtd, erase);
13879 -       if (!err)
13880 -       {
13881 +       if (!err) {
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)
13887                         schedule();
13888                 remove_wait_queue(&waitq, &wait);
13889                 set_current_state(TASK_RUNNING);
13890 @@ -391,7 +386,7 @@
13891         return err;
13892  }
13893  
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)
13896  {
13897         struct mtd_concat *concat = CONCAT(mtd);
13898         struct mtd_info *subdev;
13899 @@ -402,10 +397,10 @@
13900         if (!(mtd->flags & MTD_WRITEABLE))
13901                 return -EROFS;
13902  
13903 -       if(instr->addr > concat->mtd.size)
13904 +       if (instr->addr > concat->mtd.size)
13905                 return -EINVAL;
13906  
13907 -       if(instr->len + instr->addr > concat->mtd.size)
13908 +       if (instr->len + instr->addr > concat->mtd.size)
13909                 return -EINVAL;
13910  
13911         /*
13912 @@ -414,23 +409,22 @@
13913          * region info rather than looking at each particular sub-device
13914          * in turn.
13915          */
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))
13922                         return -EINVAL;
13923 -               if(instr->len & (concat->mtd.erasesize - 1))
13924 +               if (instr->len & (concat->mtd.erasesize - 1))
13925                         return -EINVAL;
13926 -       }
13927 -       else
13928 -       {       /* device has variable erase size */
13929 -               struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions;
13930 +       } else {
13931 +               /* device has variable erase size */
13932 +               struct mtd_erase_region_info *erase_regions =
13933 +                   concat->mtd.eraseregions;
13934  
13935                 /*
13936                  * Find the erase region where the to-be-erased area begins:
13937                  */
13938 -               for(i = 0; i < concat->mtd.numeraseregions && 
13939 -                          instr->addr >= erase_regions[i].offset; i++)
13940 -                       ;
13941 +               for (i = 0; i < concat->mtd.numeraseregions &&
13942 +                    instr->addr >= erase_regions[i].offset; i++) ;
13943                 --i;
13944  
13945                 /*
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:
13949                  */
13950 -               if (instr->addr & (erase_regions[i].erasesize-1))
13951 +               if (instr->addr & (erase_regions[i].erasesize - 1))
13952                         return -EINVAL;
13953  
13954                 /*
13955                  * now find the erase region where the to-be-erased area ends:
13956                  */
13957 -               for(; i < concat->mtd.numeraseregions && 
13958 -                     (instr->addr + instr->len) >=  erase_regions[i].offset ; ++i)
13959 -                       ;
13960 +               for (; i < concat->mtd.numeraseregions &&
13961 +                    (instr->addr + instr->len) >= erase_regions[i].offset;
13962 +                    ++i) ;
13963                 --i;
13964                 /*
13965                  * check if the ending offset is aligned to this region's erase size
13966                  */
13967 -               if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1))
13968 +               if ((instr->addr + instr->len) & (erase_regions[i].erasesize -
13969 +                                                 1))
13970                         return -EINVAL;
13971         }
13972  
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);
13976  
13977         if (!erase)
13978                 return -ENOMEM;
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
13982          */
13983 -       for(i = 0; i < concat->num_subdev; i++)
13984 -       {
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;
13990                 else
13991                         break;
13992 -    }
13993 -       if(i >= concat->num_subdev)     /* must never happen since size */
13994 -               BUG();                                  /* limit has been verified above */
13995 +       }
13996 +
13997 +       /* must never happen since size limit has been verified above */
13998 +       if (i >= concat->num_subdev)
13999 +               BUG();
14000  
14001         /* now do the erase: */
14002         err = 0;
14003 -       for(;length > 0; i++)   /* loop for all subevices affected by this request */
14004 -       {
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 */
14009  
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;
14014                 else
14015                         erase->len = length;
14016  
14017 -               if (!(subdev->flags & MTD_WRITEABLE))
14018 -               {
14019 +               if (!(subdev->flags & MTD_WRITEABLE)) {
14020                         err = -EROFS;
14021                         break;
14022                 }
14023                 length -= erase->len;
14024 -               if ((err = concat_dev_erase(subdev, erase)))
14025 -               {
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)
14032 +                               BUG();
14033                         break;
14034                 }
14035                 /*
14036 @@ -523,85 +519,79 @@
14037         return 0;
14038  }
14039  
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)
14042  {
14043         struct mtd_concat *concat = CONCAT(mtd);
14044         int i, err = -EINVAL;
14045  
14046 -       if ((len + ofs) > mtd->size) 
14047 +       if ((len + ofs) > mtd->size)
14048                 return -EINVAL;
14049  
14050 -       for(i = 0; i < concat->num_subdev; i++)
14051 -       {
14052 +       for (i = 0; i < concat->num_subdev; i++) {
14053                 struct mtd_info *subdev = concat->subdev[i];
14054                 size_t size;
14055  
14056 -               if (ofs >= subdev->size)
14057 -               {
14058 -                       size  = 0;
14059 +               if (ofs >= subdev->size) {
14060 +                       size = 0;
14061                         ofs -= subdev->size;
14062 +                       continue;
14063                 }
14064 +               if (ofs + len > subdev->size)
14065 +                       size = subdev->size - ofs;
14066                 else
14067 -               {
14068 -                       if (ofs + len > subdev->size)
14069 -                               size = subdev->size - ofs;
14070 -                       else
14071 -                               size = len;
14072 +                       size = len;
14073  
14074 -                       err = subdev->lock(subdev, ofs, size);
14075 +               err = subdev->lock(subdev, ofs, size);
14076  
14077 -                       if(err)
14078 -                               break;
14079 +               if (err)
14080 +                       break;
14081  
14082 -                       len -= size;
14083 -                       if(len == 0)
14084 -                               break;
14085 +               len -= size;
14086 +               if (len == 0)
14087 +                       break;
14088  
14089 -                       err = -EINVAL;
14090 -                       ofs = 0;
14091 -               }
14092 +               err = -EINVAL;
14093 +               ofs = 0;
14094         }
14095 +
14096         return err;
14097  }
14098  
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)
14101  {
14102         struct mtd_concat *concat = CONCAT(mtd);
14103         int i, err = 0;
14104  
14105 -       if ((len + ofs) > mtd->size) 
14106 +       if ((len + ofs) > mtd->size)
14107                 return -EINVAL;
14108  
14109 -       for(i = 0; i < concat->num_subdev; i++)
14110 -       {
14111 +       for (i = 0; i < concat->num_subdev; i++) {
14112                 struct mtd_info *subdev = concat->subdev[i];
14113                 size_t size;
14114  
14115 -               if (ofs >= subdev->size)
14116 -               {
14117 -                       size  = 0;
14118 +               if (ofs >= subdev->size) {
14119 +                       size = 0;
14120                         ofs -= subdev->size;
14121 +                       continue;
14122                 }
14123 +               if (ofs + len > subdev->size)
14124 +                       size = subdev->size - ofs;
14125                 else
14126 -               {
14127 -                       if (ofs + len > subdev->size)
14128 -                               size = subdev->size - ofs;
14129 -                       else
14130 -                               size = len;
14131 +                       size = len;
14132  
14133 -                       err = subdev->unlock(subdev, ofs, size);
14134 +               err = subdev->unlock(subdev, ofs, size);
14135  
14136 -                       if(err)
14137 -                               break;
14138 +               if (err)
14139 +                       break;
14140  
14141 -                       len -= size;
14142 -                       if(len == 0)
14143 -                               break;
14144 +               len -= size;
14145 +               if (len == 0)
14146 +                       break;
14147  
14148 -                       err = -EINVAL;
14149 -                       ofs = 0;
14150 -               }
14151 +               err = -EINVAL;
14152 +               ofs = 0;
14153         }
14154 +
14155         return err;
14156  }
14157  
14158 @@ -610,8 +600,7 @@
14159         struct mtd_concat *concat = CONCAT(mtd);
14160         int i;
14161  
14162 -       for(i = 0; i < concat->num_subdev; i++)
14163 -       {
14164 +       for (i = 0; i < concat->num_subdev; i++) {
14165                 struct mtd_info *subdev = concat->subdev[i];
14166                 subdev->sync(subdev);
14167         }
14168 @@ -622,10 +611,9 @@
14169         struct mtd_concat *concat = CONCAT(mtd);
14170         int i, rc = 0;
14171  
14172 -       for(i = 0; i < concat->num_subdev; i++)
14173 -       {
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)
14178                         return rc;
14179         }
14180         return rc;
14181 @@ -636,8 +624,7 @@
14182         struct mtd_concat *concat = CONCAT(mtd);
14183         int i;
14184  
14185 -       for(i = 0; i < concat->num_subdev; i++)
14186 -       {
14187 +       for (i = 0; i < concat->num_subdev; i++) {
14188                 struct mtd_info *subdev = concat->subdev[i];
14189                 subdev->resume(subdev);
14190         }
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.
14194   */
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   */
14199 -{
14200 +struct mtd_info *mtd_concat_create(struct mtd_info *subdev[],  /* subdevices to concatenate */
14201 +                                  int num_devs,        /* number of subdevices      */
14202 +                                  char *name)
14203 +{                              /* name for the new device   */
14204         int i;
14205         size_t size;
14206         struct mtd_concat *concat;
14207 @@ -661,94 +647,103 @@
14208         int num_erase_region;
14209  
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);
14215  
14216         /* allocate the device structure */
14217         size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
14218 -       concat = kmalloc (size, GFP_KERNEL);
14219 -       if(!concat)
14220 -       {
14221 -               printk ("memory allocation error while creating concatenated device \"%s\"\n",
14222 -                               name);
14223 -                       return NULL;
14224 +       concat = kmalloc(size, GFP_KERNEL);
14225 +       if (!concat) {
14226 +               printk
14227 +                   ("memory allocation error while creating concatenated device \"%s\"\n",
14228 +                    name);
14229 +               return NULL;
14230         }
14231         memset(concat, 0, size);
14232 -       concat->subdev = (struct mtd_info **)(concat + 1);
14233 +       concat->subdev = (struct mtd_info **) (concat + 1);
14234  
14235         /*
14236          * Set up the new "super" device's MTD object structure, check for
14237          * incompatibilites between the subdevices.
14238          */
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;
14262  
14263 -       concat->subdev[0]   = subdev[0];
14264 +       concat->subdev[0] = subdev[0];
14265  
14266 -       for(i = 1; i < num_devs; i++)
14267 -       {
14268 -               if(concat->mtd.type != subdev[i]->type)
14269 -               {
14270 +       for (i = 1; i < num_devs; i++) {
14271 +               if (concat->mtd.type != subdev[i]->type) {
14272                         kfree(concat);
14273 -                       printk ("Incompatible device type on \"%s\"\n", subdev[i]->name);
14274 +                       printk("Incompatible device type on \"%s\"\n",
14275 +                              subdev[i]->name);
14276                         return NULL;
14277                 }
14278 -               if(concat->mtd.flags != subdev[i]->flags)
14279 -               {       /*
14280 -                        * Expect all flags except MTD_WRITEABLE to be equal on
14281 -                        * all subdevices.
14282 +               if (concat->mtd.flags != subdev[i]->flags) {
14283 +                       /*
14284 +                        * Expect all flags except MTD_WRITEABLE to be
14285 +                        * equal on all subdevices.
14286                          */
14287 -                       if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE)
14288 -                       {
14289 +                       if ((concat->mtd.flags ^ subdev[i]->
14290 +                            flags) & ~MTD_WRITEABLE) {
14291                                 kfree(concat);
14292 -                               printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name);
14293 +                               printk("Incompatible device flags on \"%s\"\n",
14294 +                                      subdev[i]->name);
14295                                 return NULL;
14296 -                       }
14297 -                       else    /* if writeable attribute differs, make super device writeable */
14298 -                               concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE;
14299 +                       } else
14300 +                               /* if writeable attribute differs,
14301 +                                  make super device writeable */
14302 +                               concat->mtd.flags |=
14303 +                                   subdev[i]->flags & MTD_WRITEABLE;
14304                 }
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)
14310 -               {
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) {
14319                         kfree(concat);
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);
14323                         return NULL;
14324                 }
14325                 concat->subdev[i] = subdev[i];
14326 -               
14327 +
14328         }
14329  
14330 -       concat->num_subdev  = num_devs;
14331 -       concat->mtd.name    = name;
14332 +       concat->num_subdev = num_devs;
14333 +       concat->mtd.name = name;
14334  
14335         /*
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.
14339          */
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;
14352 -
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;
14361  
14362         /*
14363          * Combine the erase block size info of the subdevices:
14364 @@ -758,44 +753,44 @@
14365          */
14366         max_erasesize = curr_erasesize = subdev[0]->erasesize;
14367         num_erase_region = 1;
14368 -       for(i = 0; i < num_devs; i++)
14369 -       {
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;
14384                         }
14385 -               }
14386 -               else
14387 -               {       /* current subdevice has variable erase size */
14388 +               } else {
14389 +                       /* current subdevice has variable erase size */
14390                         int j;
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)
14394 -                               {
14395 +                       for (j = 0; j < subdev[i]->numeraseregions; j++) {
14396 +
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)
14403 +                                       curr_erasesize =
14404 +                                           subdev[i]->eraseregions[j].
14405 +                                           erasesize;
14406 +                                       if (curr_erasesize > max_erasesize)
14407                                                 max_erasesize = curr_erasesize;
14408                                 }
14409                         }
14410                 }
14411         }
14412  
14413 -       if(num_erase_region == 1)
14414 -       {       /*
14415 +       if (num_erase_region == 1) {
14416 +               /*
14417                  * All subdevices have the same uniform erase size.
14418                  * This is easy:
14419                  */
14420                 concat->mtd.erasesize = curr_erasesize;
14421                 concat->mtd.numeraseregions = 0;
14422 -       }
14423 -       else
14424 -       {       /*
14425 +       } else {
14426 +               /*
14427                  * erase block size varies across the subdevices: allocate
14428                  * space to store the data describing the variable erase regions
14429                  */
14430 @@ -804,13 +799,14 @@
14431  
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)
14437 -               {
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) {
14442                         kfree(concat);
14443 -                       printk ("memory allocation error while creating erase region list"
14444 -                               " for device \"%s\"\n", name);
14445 +                       printk
14446 +                           ("memory allocation error while creating erase region list"
14447 +                            " for device \"%s\"\n", name);
14448                         return NULL;
14449                 }
14450  
14451 @@ -820,46 +816,53 @@
14452                  */
14453                 curr_erasesize = subdev[0]->erasesize;
14454                 begin = position = 0;
14455 -               for(i = 0; i < num_devs; i++)
14456 -               {
14457 -                       if(subdev[i]->numeraseregions == 0)
14458 -                       {       /* current subdevice has uniform erase size */
14459 -                               if(subdev[i]->erasesize != curr_erasesize)
14460 -                               {       /*
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) {
14465 +                                       /*
14466                                          *  fill in an mtd_erase_region_info structure for the area
14467                                          *  we have walked so far:
14468                                          */
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 =
14474 +                                           curr_erasesize;
14475 +                                       erase_region_p->numblocks =
14476 +                                           (position - begin) / curr_erasesize;
14477                                         begin = position;
14478  
14479                                         curr_erasesize = subdev[i]->erasesize;
14480                                         ++erase_region_p;
14481                                 }
14482                                 position += subdev[i]->size;
14483 -                       }
14484 -                       else
14485 -                       {       /* current subdevice has variable erase size */
14486 +                       } else {
14487 +                               /* current subdevice has variable erase size */
14488                                 int j;
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)
14492 -                                       {
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 =
14502 +                                                   curr_erasesize;
14503 +                                               erase_region_p->numblocks =
14504 +                                                   (position -
14505 +                                                    begin) / curr_erasesize;
14506                                                 begin = position;
14507  
14508 -                                               curr_erasesize = subdev[i]->eraseregions[j].erasesize;
14509 +                                               curr_erasesize =
14510 +                                                   subdev[i]->eraseregions[j].
14511 +                                                   erasesize;
14512                                                 ++erase_region_p;
14513                                         }
14514 -                                       position += subdev[i]->eraseregions[j].numblocks * curr_erasesize;
14515 +                                       position +=
14516 +                                           subdev[i]->eraseregions[j].
14517 +                                           numblocks * curr_erasesize;
14518                                 }
14519                         }
14520                 }
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;
14526         }
14527 @@ -874,16 +877,14 @@
14528  void mtd_concat_destroy(struct mtd_info *mtd)
14529  {
14530         struct mtd_concat *concat = CONCAT(mtd);
14531 -       if(concat->mtd.numeraseregions)
14532 +       if (concat->mtd.numeraseregions)
14533                 kfree(concat->mtd.eraseregions);
14534         kfree(concat);
14535  }
14536  
14537 -
14538  EXPORT_SYMBOL(mtd_concat_create);
14539  EXPORT_SYMBOL(mtd_concat_destroy);
14540  
14541 -
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
14564 @@ -14,6 +14,7 @@
14565  #include <linux/init.h>
14566  #include <linux/errno.h>
14567  #include <linux/slab.h>
14568 +#include <linux/device.h>
14569  
14570  #include <linux/mtd/mtd.h>
14571  #include <linux/mtd/map.h>
14572 @@ -887,6 +888,7 @@
14573         int width;
14574         void *vbase;
14575          void (*set_vpp)(struct map_info *, int);
14576 +        char name[16];
14577         struct map_info *map;
14578         struct mtd_info *mtd;
14579         struct resource *res;
14580 @@ -925,6 +927,8 @@
14581                 }
14582  
14583                 sa[i].map = maps + i;
14584 +               sa[i].map->name = sa[i].name;
14585 +               sprintf(sa[i].name, "sa1100-%d", i);
14586  
14587                 sa[i].vbase = ioremap(sa[i].base, sa[i].size);
14588                 if (!sa[i].vbase) {
14589 @@ -986,7 +990,7 @@
14590                          */
14591  #ifdef CONFIG_MTD_CONCAT
14592                         *rmtd = mtd_concat_create(subdev, found,
14593 -                                                 "sa1100 flash");
14594 +                                                 "sa1100");
14595                         if (*rmtd == NULL)
14596                                 ret = -ENXIO;
14597  #else
14598 @@ -1044,13 +1048,9 @@
14599   *  - Is the MSC setup for flash (no -> failure)
14600   *  - Probe for flash
14601   */
14602 -
14603 -static struct map_info sa1100_probe_map __initdata = {
14604 -       .name           = "SA1100-flash",
14605 -};
14606 -
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)
14609  {
14610 +       struct map_info map;
14611         struct mtd_info *mtd;
14612  
14613         printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
14614 @@ -1066,19 +1066,23 @@
14615                 return;
14616         }
14617  
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));
14624 +
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)
14631                 goto fail;
14632 -       simple_map_init(&sa1100_probe_map);
14633 +
14634 +       simple_map_init(&map);
14635  
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);
14639         if (mtd)
14640                 map_destroy(mtd);
14641 -       iounmap((void *)sa1100_probe_map.virt);
14642 +       iounmap((void *)map.virt);
14643  
14644         if (!mtd)
14645                 goto fail;
14646 @@ -1090,7 +1094,7 @@
14647         printk("failed\n");
14648  }
14649  
14650 -static void __init sa1100_probe_flash(void)
14651 +static void sa1100_probe_flash(void)
14652  {
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);
14657  }
14658  
14659 -static struct mtd_info *mymtd;
14660 -
14661 -static int __init sa1100_mtd_init(void)
14662 +static int __init sa1100_mtd_probe(struct device *dev)
14663  {
14664 +       struct mtd_info *mtd;
14665         int ret;
14666         int nr;
14667  
14668 @@ -1332,21 +1335,74 @@
14669         if (nr < 0)
14670                 return nr;
14671  
14672 -       ret = sa1100_setup_mtd(info, nr, &mymtd);
14673 -       if (ret == 0)
14674 -               sa1100_locate_partitions(mymtd);
14675 +       ret = sa1100_setup_mtd(info, nr, &mtd);
14676 +       if (ret == 0) {
14677 +               sa1100_locate_partitions(mtd);
14678 +               dev_set_drvdata(dev, mtd);
14679 +       }
14680  
14681         return ret;
14682  }
14683  
14684 -static void __exit sa1100_mtd_cleanup(void)
14685 +static int __exit sa1100_mtd_remove(struct device *dev)
14686  {
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();
14691 +       return 0;
14692 +}
14693 +
14694 +static int sa1100_mtd_suspend(struct device *dev, u32 level, u32 state)
14695 +{
14696 +       struct mtd_info *mtd = dev_get_drvdata(dev);
14697 +       if (level == SUSPEND_SAVE_STATE)
14698 +               mtd->suspend(mtd);
14699 +       return 0;
14700 +}
14701 +
14702 +static int sa1100_mtd_resume(struct device *dev, u32 level)
14703 +{
14704 +       struct mtd_info *mtd = dev_get_drvdata(dev);
14705 +       if (level == RESUME_RESTORE_STATE)
14706 +               mtd->resume(mtd);
14707 +       return 0;
14708 +}
14709 +
14710 +static struct platform_device sa1100_mtd_device = {
14711 +       .name           = "flash",
14712 +       .id             = 0,
14713 +};
14714 +
14715 +static struct device_driver sa1100_mtd_driver = {
14716 +       .name           = "flash",
14717 +       .bus            = &platform_bus_type,
14718 +       .probe          = sa1100_mtd_probe,
14719 +#ifdef MODULE
14720 +       .remove         = sa1100_mtd_remove,
14721 +#endif
14722 +       .suspend        = sa1100_mtd_suspend,
14723 +       .resume         = sa1100_mtd_resume,
14724 +};
14725 +
14726 +static int __init sa1100_mtd_init(void)
14727 +{
14728 +       int ret = driver_register(&sa1100_mtd_driver);
14729 +       if (ret == 0) {
14730 +               ret = platform_device_register(&sa1100_mtd_device);
14731 +               if (ret)
14732 +                       driver_unregister(&sa1100_mtd_driver);
14733 +       }
14734 +       return ret;
14735 +}
14736 +
14737 +static void __exit sa1100_mtd_exit(void)
14738 +{
14739 +       platform_device_unregister(&sa1100_mtd_device);
14740 +       driver_unregister(&sa1100_mtd_driver);
14741  }
14742  
14743  module_init(sa1100_mtd_init);
14744 -module_exit(sa1100_mtd_cleanup);
14745 +module_exit(sa1100_mtd_exit);
14746  
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
14751 @@ -25,10 +25,9 @@
14752  #include <pcmcia/ds.h>
14753  
14754  #include <linux/mtd/map.h>
14755 -#include <linux/mtd/mtd.h>
14756  
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");
14763  #undef DEBUG
14764 @@ -88,7 +87,7 @@
14765  static int setvpp;
14766  
14767  /* Force card to be treated as FLASH, ROM or RAM */
14768 -static int mem_type;
14769 +static int mem_type = 1;
14770  
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
14775 @@ -22,6 +22,8 @@
14776  #include <linux/mtd/map.h>
14777  #include <linux/mtd/partitions.h>
14778  
14779 +#include <asm/io.h>
14780 +
14781  struct map_pci_info;
14782  
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
14786 @@ -80,7 +80,7 @@
14787           module will be called joydev.
14788  
14789  config INPUT_TSDEV
14790 -       tristate "Touchscreen interface"
14791 +       tristate "Compaq Touchscreen interface"
14792         depends on INPUT
14793         ---help---
14794           Say Y here if you have an application that only can understand the
14795 @@ -102,6 +102,10 @@
14796         depends on INPUT_TSDEV
14797         default "320"
14798  
14799 +config INPUT_TSLIBDEV
14800 +       tristate "TSLIB Touchscreen interface"
14801 +       depends on INPUT
14802 +
14803  config INPUT_EVDEV
14804         tristate "Event interface"
14805         depends on INPUT
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
14808 @@ -80,7 +80,7 @@
14809  
14810  config SERIO_RPCKBD
14811         tristate "Acorn RiscPC keyboard controller"
14812 -       depends on ARCH_ACORN && SERIO
14813 +       depends on (ARCH_ACORN || ARCH_CLPS7500) && SERIO
14814         default y
14815         help
14816           Say Y here if you have the Acorn RiscPC and want to use an AT
14817 @@ -89,6 +89,18 @@
14818           To compile this driver as a module, choose M here: the
14819           module will be called rpckbd.
14820  
14821 +config SERIO_CLPS7500
14822 +       tristate "CLPS7500 PS/2 mouse port controller"
14823 +       depends on ARCH_CLPS7500 && SERIO
14824 +       help
14825 +         Say Y here if you have CLPS7500 based hardware and want to use
14826 +         the mouse port.
14827 +
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>.
14832 +
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
14838 @@ -0,0 +1,90 @@
14839 +/*
14840 + *  linux/drivers/input/serio/sa1100ir.c
14841 + *
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.
14845 + */
14846 +#include <linux/module.h>
14847 +#include <linux/init.h>
14848 +#include <linux/serio.h>
14849 +
14850 +#include <asm/io.h>
14851 +#include <asm/irq.h>
14852 +#include <asm/hardware.h>
14853 +
14854 +
14855 +
14856 +struct sa1100_kbd {
14857 +       struct serio    io;
14858 +       void            *base;
14859 +       int             irq;
14860 +};
14861 +
14862 +static void sa1100ir_int(int irq, void *dev_id, struct pt_regs *regs)
14863 +{
14864 +       struct sa1100_kbd *kbd = dev_id;
14865 +       unsigned int status;
14866 +
14867 +       do {
14868 +               unsigned int flag, data;
14869 +
14870 +               status = readl(kbd->base + UTSR1);
14871 +               if (!(status & UTSR1_RNE))
14872 +                       break;
14873 +
14874 +               flag = (status & UTSR1_FRE ? SERIO_FRAME : 0) |
14875 +                      (status & UTSR1_PRE ? SERIO_PARITY : 0);
14876 +
14877 +               data = readl(kbd->base + UTDR);
14878 +
14879 +               serio_interrupt(&kbd->io, data, flag);
14880 +       } while (1);
14881 +
14882 +       status = readl(kbd->base + UTSR0) & UTSR0_RID | UTSR0_RBB | UTSR0_REB;
14883 +       if (status)
14884 +               writel(status, kbd->base + UTSR0);
14885 +}
14886 +
14887 +static int sa1100ir_kbd_open(struct serio *io)
14888 +{
14889 +       struct sa1100_kbd *kbd = io->driver;
14890 +       int ret;
14891 +
14892 +       ret = request_irq(kbd->irq, sa1100ir_int, 0, kbd->io.phys, kbd);
14893 +       if (ret)
14894 +               return ret;
14895 +
14896 +       return 0;
14897 +}
14898 +
14899 +static void sa1100ir_kbd_close(struct serio *io)
14900 +{
14901 +       struct sa1100_kbd *kbd = io->driver;
14902 +
14903 +       free_irq(kbd->irq, kbd);
14904 +}
14905 +
14906 +static struct sa1100_kbd sa1100_kbd = {
14907 +       .io = {
14908 +               .type   = 0,
14909 +               .open   = sa1100ir_kbd_open,
14910 +               .close  = sa1100ir_kbd_close,
14911 +               .name   = "SA11x0 IR port",
14912 +               .phys   = "sa11x0/ir",
14913 +               .driver = &sa1100_kbd,
14914 +       },
14915 +};
14916 +
14917 +static int __init sa1100_kbd_init(void)
14918 +{
14919 +       serio_register_port(&sa1100_kbd.io);
14920 +}
14921 +
14922 +static void __exit sa1100_kbd_exit(void)
14923 +{
14924 +       serio_unregister_port(&sa1100_kbd.io);
14925 +}
14926 +
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
14931 @@ -10,6 +10,7 @@
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
14941 @@ -0,0 +1,358 @@
14942 +/*
14943 + *  linux/drivers/input/tslibdev.c
14944 + *
14945 + *  Copyright (C) 2002 Russell King
14946 + *
14947 + * From tsdev.c:
14948 + *
14949 + *  Copyright (c) 2001 "Crazy" james Simmons 
14950 + *
14951 + *  Input driver to Touchscreen device driver module.
14952 + *
14953 + *  Sponsored by Transvirtual Technology
14954 + */
14955 +
14956 +/*
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.
14961 + * 
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.
14966 + * 
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
14970 + * 
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>.
14973 + */
14974 +
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>
14986 +
14987 +struct ucb1x00_dev {
14988 +       int             exist;
14989 +       char            name[16];
14990 +       wait_queue_head_t wait;
14991 +       struct list_head list;
14992 +       struct input_handle handle;
14993 +       int             x;
14994 +       int             y;
14995 +       int             pressure;
14996 +};
14997 +
14998 +struct ts_event {
14999 +       u16             pressure;
15000 +       u16             x;
15001 +       u16             y;
15002 +       u16             pad;
15003 +       struct timeval  stamp;
15004 +};
15005 +
15006 +#define TSDEV_BUFFER_SIZE      64
15007 +
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];
15015 +};
15016 +
15017 +static struct input_handler ucb1x00_handler;
15018 +static struct ucb1x00_dev *ucb1x00_dev;
15019 +
15020 +static void ucb1x00_remove(struct ucb1x00_dev *tsdev);
15021 +
15022 +
15023 +static int ucb1x00_fasync(int fd, struct file *file, int on)
15024 +{
15025 +       struct ucb1x00_list *list = file->private_data;
15026 +       int retval;
15027 +
15028 +       retval = fasync_helper(fd, file, on, &list->fasync);
15029 +       return retval < 0 ? retval : 0;
15030 +}
15031 +
15032 +static int ucb1x00_open(struct inode *inode, struct file *file)
15033 +{
15034 +       struct ucb1x00_list *list;
15035 +       int empty;
15036 +
15037 +       if (!ucb1x00_dev || !ucb1x00_dev->exist)
15038 +               return -ENODEV;
15039 +
15040 +       printk(KERN_WARNING
15041 +               "tslibdev: process %s (%d) uses obsolete tslib device\n",
15042 +               current->comm, current->pid);
15043 +
15044 +       list = kmalloc(sizeof(struct ucb1x00_list), GFP_KERNEL);
15045 +       if (!list)
15046 +               return -ENOMEM;
15047 +
15048 +       memset(list, 0, sizeof(struct ucb1x00_list));
15049 +
15050 +       empty = list_empty(&ucb1x00_dev->list);
15051 +
15052 +       list->tsdev = ucb1x00_dev;
15053 +       list_add(&list->list, &list->tsdev->list);
15054 +
15055 +       file->private_data = list;
15056 +
15057 +       if (empty && list->tsdev->exist)
15058 +               input_open_device(&list->tsdev->handle);
15059 +
15060 +       return 0;
15061 +}
15062 +
15063 +static int ucb1x00_release(struct inode *inode, struct file *file)
15064 +{
15065 +       struct ucb1x00_list *list = file->private_data;
15066 +
15067 +       ucb1x00_fasync(-1, file, 0);
15068 +
15069 +       list_del(&list->list);
15070 +
15071 +       ucb1x00_remove(list->tsdev);
15072 +
15073 +       kfree(list);
15074 +
15075 +       return 0;
15076 +}
15077 +
15078 +static ssize_t
15079 +ucb1x00_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
15080 +{
15081 +       DECLARE_WAITQUEUE(wait, current);
15082 +       struct ucb1x00_list *list = file->private_data;
15083 +       int retval = 0;
15084 +
15085 +       if (list->head == list->tail) {
15086 +               add_wait_queue(&list->tsdev->wait, &wait);
15087 +
15088 +               while (list->head == list->tail) {
15089 +                       set_current_state(TASK_INTERRUPTIBLE);
15090 +
15091 +                       if (!list->tsdev->exist) {
15092 +                               retval = -ENODEV;
15093 +                               break;
15094 +                       }
15095 +                       if (file->f_flags & O_NONBLOCK) {
15096 +                               retval = -EAGAIN;
15097 +                               break;
15098 +                       }
15099 +                       if (signal_pending(current)) {
15100 +                               retval = -ERESTARTSYS;
15101 +                               break;
15102 +                       }
15103 +                       schedule();
15104 +               }
15105 +               set_current_state(TASK_RUNNING);
15106 +               remove_wait_queue(&list->tsdev->wait, &wait);
15107 +       }
15108 +
15109 +       if (retval)
15110 +               return retval;
15111 +
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);
15120 +       }
15121 +       return retval;
15122 +}
15123 +
15124 +/* No kernel lock - fine */
15125 +static unsigned int ucb1x00_poll(struct file *file, poll_table * wait)
15126 +{
15127 +       struct ucb1x00_list *list = file->private_data;
15128 +
15129 +       poll_wait(file, &list->tsdev->wait, wait);
15130 +       if (list->head != list->tail || !list->tsdev->exist)
15131 +               return POLLIN | POLLRDNORM;
15132 +       return 0;
15133 +}
15134 +
15135 +static int
15136 +ucb1x00_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
15137 +           unsigned long arg)
15138 +{
15139 +       return -EINVAL;
15140 +}
15141 +
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,
15150 +};
15151 +
15152 +/*
15153 + * The official UCB1x00 touchscreen is a miscdevice:
15154 + *   10 char        Non-serial mice, misc features
15155 + *                   14 = /dev/touchscreen/ucb1x00  UCB 1x00 touchscreen
15156 + */
15157 +static struct miscdevice ucb1x00_ts_dev = {
15158 +       .minor          = 14,
15159 +       .name           = "touchscreen/ucb1x00",
15160 +       .fops           = &ucb1x00_fops,
15161 +       .devfs_name     = "touchscreen/ucb1x00",
15162 +};
15163 +
15164 +static void ucb1x00_remove(struct ucb1x00_dev *tsdev)
15165 +{
15166 +       if (list_empty(&tsdev->list)) {
15167 +               if (tsdev->exist) {
15168 +                       input_close_device(&tsdev->handle);
15169 +                       wake_up_interruptible(&tsdev->wait);
15170 +               } else {
15171 +                       misc_deregister(&ucb1x00_ts_dev);
15172 +                       ucb1x00_dev = NULL;
15173 +                       kfree(tsdev);
15174 +               }
15175 +       }
15176 +}
15177 +
15178 +
15179 +static void
15180 +ucb1x00_event(struct input_handle *handle, unsigned int type, unsigned int code,
15181 +           int value)
15182 +{
15183 +       struct ucb1x00_dev *tsdev = handle->private;
15184 +       struct list_head *l;
15185 +
15186 +       /* sorry, we only handle absolute stuff */
15187 +       if (type == EV_ABS) {
15188 +               switch (code) {
15189 +               case ABS_X:
15190 +                       tsdev->x = value;
15191 +                       break;
15192 +               case ABS_Y:
15193 +                       tsdev->y = value;
15194 +                       break;
15195 +               case ABS_PRESSURE:
15196 +                       tsdev->pressure = value;
15197 +                       break;
15198 +               }
15199 +               return;
15200 +       }
15201 +
15202 +       if (type != EV_SYN || code != SYN_REPORT)
15203 +               return;
15204 +
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;
15211 +               } else {
15212 +                       list->event[list->head].x = 0;
15213 +                       list->event[list->head].y = 0;
15214 +               }
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);
15218 +       }
15219 +       wake_up_interruptible(&tsdev->wait);
15220 +}
15221 +
15222 +static struct input_handle *
15223 +ucb1x00_connect(struct input_handler *handler, struct input_dev *dev,
15224 +             struct input_device_id *id)
15225 +{
15226 +       struct ucb1x00_dev *tsdev;
15227 +
15228 +       if (ucb1x00_dev)
15229 +               return NULL;
15230 +
15231 +       tsdev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL);
15232 +       if (!tsdev)
15233 +               return NULL;
15234 +
15235 +       memset(tsdev, 0, sizeof(struct ucb1x00_dev));
15236 +       init_waitqueue_head(&tsdev->wait);
15237 +       INIT_LIST_HEAD(&tsdev->list);
15238 +
15239 +       ucb1x00_dev = tsdev;
15240 +
15241 +       strcpy(tsdev->name, ucb1x00_ts_dev.name);
15242 +
15243 +       tsdev->handle.dev     = dev;
15244 +       tsdev->handle.name    = tsdev->name;
15245 +       tsdev->handle.handler = handler;
15246 +       tsdev->handle.private = tsdev;
15247 +
15248 +       misc_register(&ucb1x00_ts_dev);
15249 +
15250 +       tsdev->exist = 1;
15251 +
15252 +       return &tsdev->handle;
15253 +}
15254 +
15255 +static void ucb1x00_disconnect(struct input_handle *handle)
15256 +{
15257 +       struct ucb1x00_dev *tsdev = handle->private;
15258 +
15259 +       tsdev->exist = 0;
15260 +       ucb1x00_remove(tsdev);
15261 +}
15262 +
15263 +static struct input_device_id ucb1x00_ids[] = {
15264 +       {
15265 +             .flags    = INPUT_DEVICE_ID_MATCH_ABSBIT,
15266 +             .evbit    = { BIT(EV_ABS) },
15267 +             .absbit   = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
15268 +       },
15269 +
15270 +       {},/* Terminating entry */
15271 +};
15272 +
15273 +MODULE_DEVICE_TABLE(input, ucb1x00_ids);
15274 +
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,
15281 +};
15282 +
15283 +static int __init ucb1x00_init(void)
15284 +{
15285 +       input_register_handler(&ucb1x00_handler);
15286 +       printk(KERN_INFO "ts: UCB1x00 touchscreen protocol output\n");
15287 +       return 0;
15288 +}
15289 +
15290 +static void __exit ucb1x00_exit(void)
15291 +{
15292 +       input_unregister_handler(&ucb1x00_handler);
15293 +}
15294 +
15295 +module_init(ucb1x00_init);
15296 +module_exit(ucb1x00_exit);
15297 +
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
15302 @@ -8,6 +8,7 @@
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
15312 @@ -0,0 +1,416 @@
15313 +/*
15314 + *     Real Time Clock interface for Linux on Intel SA11x0/PXA2xx
15315 + *
15316 + *     Copyright (c) 2000 Nils Faerber
15317 + *
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! ;)
15323 + *
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.
15328 + *
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
15334 + *
15335 + *     0.03    2001-03-07      CIH <cih@coventive.com>
15336 + *     - Modify the bug setups RTC clock.
15337 + *
15338 + *     0.02    2001-02-27      Nils Faerber <nils@@kernelconcepts.de>
15339 + *     - removed mktime(), added alarm irq clear
15340 + *
15341 + *     0.01    2000-10-01      Nils Faerber <nils@@kernelconcepts.de>
15342 + *     - initial release
15343 + */
15344 +
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>
15354 +
15355 +#include <asm/bitops.h>
15356 +#include <asm/hardware.h>
15357 +#include <asm/irq.h>
15358 +#include <asm/rtc.h>
15359 +
15360 +#define TIMER_FREQ             3686400
15361 +
15362 +#define RTC_DEF_DIVIDER                32768 - 1
15363 +#define RTC_DEF_TRIM           0
15364 +
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
15370 +
15371 +static unsigned long rtc_freq = 1024;
15372 +static struct rtc_time rtc_alarm = {
15373 +       .tm_year        = 0,
15374 +       .tm_mon         = 0,
15375 +       .tm_mday        = 0,
15376 +       .tm_hour        = 0,
15377 +       .tm_mon         = 0,
15378 +       .tm_sec         = 0,
15379 +};
15380 +
15381 +extern spinlock_t rtc_lock;
15382 +
15383 +static int rtc_update_alarm(struct rtc_time *alrm)
15384 +{
15385 +       struct rtc_time alarm_tm, now_tm;
15386 +       unsigned long now, time;
15387 +       int ret;
15388 +
15389 +       do {
15390 +               now = RCNR;
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);
15394 +               if (ret != 0)
15395 +                       break;
15396 +
15397 +               RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
15398 +               RTAR = time;
15399 +       } while (now != RCNR);
15400 +
15401 +       return ret;
15402 +}
15403 +
15404 +static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15405 +{
15406 +       unsigned int rtsr;
15407 +       unsigned long events = 0;
15408 +
15409 +       spin_lock(&rtc_lock);
15410 +
15411 +       rtsr = RTSR;
15412 +       /* clear interrupt sources */
15413 +       RTSR = 0;
15414 +       RTSR = (RTSR_AL|RTSR_HZ) & (rtsr >> 2);
15415 +
15416 +       /* clear alarm interrupt if it has occurred */
15417 +       if (rtsr & RTSR_AL)
15418 +               rtsr &= ~RTSR_ALE;
15419 +       RTSR = rtsr & (RTSR_ALE|RTSR_HZE);
15420 +
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);
15426 +
15427 +       rtc_update(1, events);
15428 +
15429 +       if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
15430 +               rtc_update_alarm(&rtc_alarm);
15431 +
15432 +       spin_unlock(&rtc_lock);
15433 +
15434 +       return IRQ_HANDLED;
15435 +}
15436 +
15437 +#if 0
15438 +static unsigned long rtc_irq_data;
15439 +
15440 +static irqreturn_t timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
15441 +{
15442 +       /*
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.
15448 +        */
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;
15452 +       } else {
15453 +               rtc_update(1, RTC_PF | RTC_IRQF);
15454 +       }
15455 +
15456 +       wake_up_interruptible(&rtc_wait);
15457 +       kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
15458 +
15459 +       return IRQ_HANDLED;
15460 +}
15461 +#endif
15462 +
15463 +static int sa1100_rtc_open(void)
15464 +{
15465 +       int ret;
15466 +
15467 +       ret = request_irq(IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
15468 +       if (ret) {
15469 +               printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
15470 +               goto fail_ui;
15471 +       }
15472 +       ret = request_irq(IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
15473 +       if (ret) {
15474 +               printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
15475 +               goto fail_ai;
15476 +       }
15477 +#if 0
15478 +       ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL);
15479 +       if (ret) {
15480 +               printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1);
15481 +               goto fail_pi;
15482 +       }
15483 +       rtc_irq_data = 0;
15484 +#endif
15485 +       return 0;
15486 +
15487 + fail_pi:
15488 +       free_irq(IRQ_RTCAlrm, NULL);
15489 + fail_ai:
15490 +       free_irq(IRQ_RTC1Hz, NULL);
15491 + fail_ui:
15492 +       return ret;
15493 +}
15494 +
15495 +static void sa1100_rtc_release(void)
15496 +{
15497 +       spin_lock_irq (&rtc_lock);
15498 +       RTSR = 0;
15499 +       OIER &= ~OIER_E1;
15500 +       OSSR = OSSR_M1;
15501 +       spin_unlock_irq (&rtc_lock);
15502 +
15503 +//     free_irq(IRQ_OST1, NULL);
15504 +       free_irq(IRQ_RTCAlrm, NULL);
15505 +       free_irq(IRQ_RTC1Hz, NULL);
15506 +}
15507 +
15508 +#if 0
15509 +ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
15510 +{
15511 +       DECLARE_WAITQUEUE(wait, current);
15512 +       unsigned long data;
15513 +       ssize_t retval;
15514 +
15515 +       if (count < sizeof(unsigned long))
15516 +               return -EINVAL;
15517 +
15518 +       add_wait_queue(&rtc_wait, &wait);
15519 +       set_current_state(TASK_INTERRUPTIBLE);
15520 +       for (;;) {
15521 +               spin_lock_irq (&rtc_lock);
15522 +               data = rtc_irq_data;
15523 +               if (data != 0) {
15524 +                       rtc_irq_data = 0;
15525 +                       break;
15526 +               }
15527 +               spin_unlock_irq (&rtc_lock);
15528 +
15529 +               if (file->f_flags & O_NONBLOCK) {
15530 +                       retval = -EAGAIN;
15531 +                       goto out;
15532 +               }
15533 +
15534 +               if (signal_pending(current)) {
15535 +                       retval = -ERESTARTSYS;
15536 +                       goto out;
15537 +               }
15538 +
15539 +               schedule();
15540 +       }
15541 +
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 ) {
15553 +                       data += 0x100;
15554 +                       OSSR = OSSR_M1; /* clear match on timer 1 */
15555 +                       OSMR1 = osmr1 + period;
15556 +               }
15557 +       }
15558 +       spin_unlock_irq (&rtc_lock);
15559 +
15560 +       data -= 0x100;  /* the first IRQ wasn't actually missed */
15561 +
15562 +       retval = put_user(data, (unsigned long *)buf);
15563 +       if (!retval)
15564 +               retval = sizeof(unsigned long);
15565 +
15566 +out:
15567 +       set_current_state(TASK_RUNNING);
15568 +       remove_wait_queue(&rtc_wait, &wait);
15569 +       return retval;
15570 +}
15571 +#endif
15572 +
15573 +static int sa1100_rtc_ioctl(unsigned int cmd, unsigned long arg)
15574 +{
15575 +       switch (cmd) {
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);
15581 +               return 0;
15582 +       case RTC_AIE_ON:
15583 +               spin_lock_irq(&rtc_lock);
15584 +               RTSR |= RTSR_ALE;
15585 +//             rtc_irq_data = 0;
15586 +               spin_unlock_irq(&rtc_lock);
15587 +               return 0;
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);
15593 +               return 0;
15594 +       case RTC_UIE_ON:
15595 +               spin_lock_irq(&rtc_lock);
15596 +               RTSR |= RTSR_HZE;
15597 +//             rtc_irq_data = 0;
15598 +               spin_unlock_irq(&rtc_lock);
15599 +               return 0;
15600 +#if 0
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);
15606 +               return 0;
15607 +       case RTC_PIE_ON:
15608 +               if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
15609 +                       return -EACCES;
15610 +               spin_lock_irq(&rtc_lock);
15611 +               OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
15612 +               OIER |= OIER_E1;
15613 +//             rtc_irq_data = 0;
15614 +               spin_unlock_irq(&rtc_lock);
15615 +               return 0;
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)
15620 +                               return -EINVAL;
15621 +               if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
15622 +                               return -EACCES;
15623 +               rtc_freq = arg;
15624 +               return 0;
15625 +#endif
15626 +       }
15627 +       return -EINVAL;
15628 +}
15629 +
15630 +static void sa1100_rtc_read_time(struct rtc_time *tm)
15631 +{
15632 +       rtc_time_to_tm(RCNR, tm);
15633 +}
15634 +
15635 +static int sa1100_rtc_set_time(struct rtc_time *tm)
15636 +{
15637 +       unsigned long time;
15638 +       int ret;
15639 +
15640 +       ret = rtc_tm_to_time(tm, &time);
15641 +       if (ret == 0)
15642 +               RCNR = time;
15643 +       return ret;
15644 +}
15645 +
15646 +static void sa1100_rtc_read_alarm(struct rtc_wkalrm *alrm)
15647 +{
15648 +       memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
15649 +       alrm->pending = RTSR & RTSR_AL ? 1 : 0;
15650 +}
15651 +
15652 +static int sa1100_rtc_set_alarm(struct rtc_wkalrm *alrm)
15653 +{
15654 +       int ret;
15655 +
15656 +       spin_lock_irq(&rtc_lock);
15657 +       ret = rtc_update_alarm(&alrm->time);
15658 +       if (ret == 0) {
15659 +               memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time));
15660 +
15661 +               if (alrm->enabled)
15662 +                       enable_irq_wake(IRQ_RTCAlrm);
15663 +               else
15664 +                       disable_irq_wake(IRQ_RTCAlrm);
15665 +       }
15666 +       spin_unlock_irq(&rtc_lock);
15667 +
15668 +       return ret;
15669 +}
15670 +
15671 +static int sa1100_rtc_proc(char *buf)
15672 +{
15673 +       char *p = buf;
15674 +
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);
15680 +
15681 +       return p - buf;
15682 +}
15683 +
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,
15689 +
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,
15695 +};
15696 +
15697 +static int __init rtc_init(void)
15698 +{
15699 +       /*
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.
15705 +        */
15706 +       if (RTTR == 0) {
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 */
15710 +               RCNR = 0;
15711 +       }
15712 +
15713 +       register_rtc(&sa1100_rtc_ops);
15714 +
15715 +       return 0;
15716 +}
15717 +
15718 +static void __exit rtc_exit(void)
15719 +{
15720 +       unregister_rtc(&sa1100_rtc_ops);
15721 +}
15722 +
15723 +module_init(rtc_init);
15724 +module_exit(rtc_exit);
15725 +
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 @@
15732  
15733           If unsure, say N.
15734  
15735 +config SA1100_RTC
15736 +       tristate "SA1100 or PXA Real Time Clock"
15737 +       depends on ARCH_SA1100 || ARCH_PXA
15738 +
15739  config DTLK
15740         tristate "Double Talk PC internal speech card support"
15741         help
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 @@
15745         return 0;
15746  }
15747  
15748 +/*
15749 + * In the case of pty's, "tty" is the master side
15750 + * and "real_tty" is the slave side.
15751 + */
15752  static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
15753         struct winsize * arg)
15754  {
15755         struct winsize tmp_ws;
15756 +       struct task_struct *p;
15757 +       struct list_head *l;
15758 +       struct pid *pid;
15759  
15760         if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
15761                 return -EFAULT;
15762 @@ -1558,8 +1565,21 @@
15763  #endif
15764         if (tty->pgrp > 0)
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);
15768 +
15769 +       /*
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.
15773 +        */
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);
15779 +               }
15780 +               read_unlock(&tasklist_lock);
15781 +       }
15782 +
15783         tty->winsize = tmp_ws;
15784         real_tty->winsize = tmp_ws;
15785         return 0;
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
15788 @@ -11,6 +11,8 @@
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/
15794  
15795  # char/ comes before serial/ etc so that the VT console is the boot-time
15796  # default.
15797 @@ -41,7 +43,6 @@
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
15807 @@ -0,0 +1,24 @@
15808 +#
15809 +# L3 bus configuration
15810 +#
15811 +
15812 +menu "L3 serial bus support"
15813 +
15814 +config L3
15815 +       tristate "L3 support"
15816 +
15817 +config L3_ALGOBIT
15818 +       bool "L3 bit-banging interfaces"
15819 +       depends on L3=y
15820 +
15821 +config L3_BIT_SA1100_GPIO
15822 +       bool "SA11x0 GPIO adapter"
15823 +       depends on L3_ALGOBIT && ARCH_SA1100
15824 +
15825 +# i2c must come before this
15826 +config BIT_SA1100_GPIO
15827 +       bool
15828 +       depends on L3_BIT_SA1100_GPIO || I2C_BIT_SA1100_GPIO=y
15829 +       default y
15830 +
15831 +endmenu
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
15834 @@ -0,0 +1,203 @@
15835 +/*
15836 + *  linux/drivers/l3/l3-core.c
15837 + *
15838 + *  Copyright (C) 2001 Russell King
15839 + *
15840 + *  General structure taken from i2c-core.c by Simon G. Vogl
15841 + *
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.
15845 + *
15846 + *  See linux/Documentation/l3 for further documentation.
15847 + */
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>
15856 +
15857 +static DECLARE_MUTEX(adapter_lock);
15858 +static LIST_HEAD(adapter_list);
15859 +
15860 +static DECLARE_MUTEX(driver_lock);
15861 +static LIST_HEAD(driver_list);
15862 +
15863 +/**
15864 + * l3_add_adapter - register a new L3 bus adapter
15865 + * @adap: l3_adapter structure for the registering adapter
15866 + *
15867 + * Make the adapter available for use by clients using name adap->name.
15868 + * The adap->adapters list is initialised by this function.
15869 + *
15870 + * Returns 0;
15871 + */
15872 +int l3_add_adapter(struct l3_adapter *adap)
15873 +{
15874 +       down(&adapter_lock);
15875 +       list_add(&adap->adapters, &adapter_list);
15876 +       up(&adapter_lock);
15877 +       return 0;       
15878 +}
15879 +
15880 +/**
15881 + * l3_del_adapter - unregister a L3 bus adapter
15882 + * @adap: l3_adapter structure to unregister
15883 + *
15884 + * Remove an adapter from the list of available L3 Bus adapters.
15885 + *
15886 + * Returns 0;
15887 + */
15888 +int l3_del_adapter(struct l3_adapter *adap)
15889 +{
15890 +       down(&adapter_lock);
15891 +       list_del(&adap->adapters);
15892 +       up(&adapter_lock);
15893 +       return 0;
15894 +}
15895 +
15896 +static struct l3_adapter *__l3_get_adapter(const char *name)
15897 +{
15898 +       struct list_head *l;
15899 +
15900 +       list_for_each(l, &adapter_list) {
15901 +               struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters);
15902 +
15903 +               if (strcmp(adap->name, name) == 0)
15904 +                       return adap;
15905 +       }
15906 +
15907 +       return NULL;
15908 +}
15909 +
15910 +/**
15911 + * l3_get_adapter - get a reference to an adapter
15912 + * @name: driver name
15913 + *
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.
15917 + */
15918 +struct l3_adapter *l3_get_adapter(const char *name)
15919 +{
15920 +       struct l3_adapter *adap;
15921 +       int try;
15922 +
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))
15927 +                       adap = NULL;
15928 +               up(&adapter_lock);
15929 +
15930 +               if (adap)
15931 +                       break;
15932 +
15933 +               if (try == 0)
15934 +                       request_module(name);
15935 +       }
15936 +
15937 +       return adap;
15938 +}
15939 +
15940 +/**
15941 + * l3_put_adapter - release a reference to an adapter
15942 + * @adap: driver to release reference
15943 + *
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.
15947 + *
15948 + * You must not use the reference after calling this function.
15949 + */
15950 +void l3_put_adapter(struct l3_adapter *adap)
15951 +{
15952 +       if (adap && adap->owner)
15953 +               module_put(adap->owner);
15954 +}
15955 +
15956 +/**
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
15961 + *
15962 + * Transfer the specified messages to/from a device on the L3 bus.
15963 + *
15964 + * Returns number of messages successfully transferred, otherwise negative
15965 + * error code.
15966 + */
15967 +int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
15968 +{
15969 +       int ret = -ENOSYS;
15970 +
15971 +       if (adap->algo->xfer) {
15972 +               down(adap->lock);
15973 +               ret = adap->algo->xfer(adap, msgs, num);
15974 +               up(adap->lock);
15975 +       }
15976 +       return ret;
15977 +}
15978 +
15979 +/**
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
15985 + *
15986 + * Send len bytes pointed to by buf to device address addr on the L3 bus
15987 + * described by client.
15988 + *
15989 + * Returns the number of bytes transferred, or negative error code.
15990 + */
15991 +int l3_write(struct l3_adapter *adap, int addr, const char *buf, int len)
15992 +{
15993 +       struct l3_msg msg;
15994 +       int ret;
15995 +
15996 +       msg.addr = addr;
15997 +       msg.flags = 0;
15998 +       msg.buf = (char *)buf;
15999 +       msg.len = len;
16000 +
16001 +       ret = l3_transfer(adap, &msg, 1);
16002 +       return ret == 1 ? len : ret;
16003 +}
16004 +
16005 +/**
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
16011 + *
16012 + * Receive len bytes from device address addr on the L3 bus described by
16013 + * client to a buffer pointed to by buf.
16014 + *
16015 + * Returns the number of bytes transferred, or negative error code.
16016 + */
16017 +int l3_read(struct l3_adapter *adap, int addr, char *buf, int len)
16018 +{
16019 +       struct l3_msg msg;
16020 +       int ret;
16021 +
16022 +       msg.addr = addr;
16023 +       msg.flags = L3_M_RD;
16024 +       msg.buf = buf;
16025 +       msg.len = len;
16026 +
16027 +       ret = l3_transfer(adap, &msg, 1);
16028 +       return ret == 1 ? len : ret;
16029 +}
16030 +
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
16040 @@ -0,0 +1,175 @@
16041 +/*
16042 + * L3 bus algorithm module.
16043 + *
16044 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
16045 + *
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.
16049 + *
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
16054 + *  clock is low.
16055 + */
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>
16065 +
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)
16072 +
16073 +/*
16074 + * Send one byte of data to the chip.  Data is latched into the chip on
16075 + * the rising edge of the clock.
16076 + */
16077 +static void sendbyte(struct l3_algo_bit_data *adap, unsigned int byte)
16078 +{
16079 +       int i;
16080 +
16081 +       for (i = 0; i < 8; i++) {
16082 +               setclk(adap, 0);
16083 +               udelay(adap->data_hold);
16084 +               setdat(adap, byte & 1);
16085 +               udelay(adap->data_setup);
16086 +               setclk(adap, 1);
16087 +               udelay(adap->clock_high);
16088 +               byte >>= 1;
16089 +       }
16090 +}
16091 +
16092 +/*
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
16095 + * transfer.
16096 + */
16097 +static void sendbytes(struct l3_algo_bit_data *adap, const char *buf, int len)
16098 +{
16099 +       int i;
16100 +
16101 +       for (i = 0; i < len; i++) {
16102 +               if (i) {
16103 +                       udelay(adap->mode_hold);
16104 +                       setmode(adap, 0);
16105 +                       udelay(adap->mode);
16106 +               }
16107 +               setmode(adap, 1);
16108 +               udelay(adap->mode_setup);
16109 +               sendbyte(adap, buf[i]);
16110 +       }
16111 +}
16112 +
16113 +/*
16114 + * Read one byte of data from the chip.  Data is latched into the chip on
16115 + * the rising edge of the clock.
16116 + */
16117 +static unsigned int readbyte(struct l3_algo_bit_data *adap)
16118 +{
16119 +       unsigned int byte = 0;
16120 +       int i;
16121 +
16122 +       for (i = 0; i < 8; i++) {
16123 +               setclk(adap, 0);
16124 +               udelay(adap->data_hold + adap->data_setup);
16125 +               setclk(adap, 1);
16126 +               if (getdat(adap))
16127 +                       byte |= 1 << i;
16128 +               udelay(adap->clock_high);
16129 +       }
16130 +
16131 +       return byte;
16132 +}
16133 +
16134 +/*
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
16137 + * transfer.
16138 + */
16139 +static void readbytes(struct l3_algo_bit_data *adap, char *buf, int len)
16140 +{
16141 +       int i;
16142 +
16143 +       for (i = 0; i < len; i++) {
16144 +               if (i) {
16145 +                       udelay(adap->mode_hold);
16146 +                       setmode(adap, 0);
16147 +               }
16148 +               setmode(adap, 1);
16149 +               udelay(adap->mode_setup);
16150 +               buf[i] = readbyte(adap);
16151 +       }
16152 +}
16153 +
16154 +static int l3_xfer(struct l3_adapter *l3_adap, struct l3_msg msgs[], int num)
16155 +{
16156 +       struct l3_algo_bit_data *adap = l3_adap->algo_data;
16157 +       int i;
16158 +
16159 +       /*
16160 +        * If we share an I2C bus, ensure that it is in STOP mode
16161 +        */
16162 +       setclk(adap, 1);
16163 +       setdat(adap, 1);
16164 +       setmode(adap, 1);
16165 +       setdatout(adap);
16166 +       udelay(adap->mode);
16167 +
16168 +       for (i = 0; i < num; i++) {
16169 +               struct l3_msg *pmsg = &msgs[i];
16170 +
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);
16176 +               }
16177 +
16178 +               if (pmsg->flags & L3_M_RD) {
16179 +                       setdatin(adap);
16180 +                       readbytes(adap, pmsg->buf, pmsg->len);
16181 +               } else {
16182 +                       setdatout(adap);
16183 +                       sendbytes(adap, pmsg->buf, pmsg->len);
16184 +               }
16185 +       }
16186 +
16187 +       /*
16188 +        * Ensure that we leave the bus in I2C stop mode.
16189 +        */
16190 +       setclk(adap, 1);
16191 +       setdat(adap, 1);
16192 +       setmode(adap, 0);
16193 +       setdatin(adap);
16194 +
16195 +       return num;
16196 +}
16197 +
16198 +static struct l3_algorithm l3_bit_algo = {
16199 +       name:   "L3 bit-shift algorithm",
16200 +       xfer:   l3_xfer,
16201 +};
16202 +
16203 +int l3_bit_add_bus(struct l3_adapter *adap)
16204 +{
16205 +       adap->algo = &l3_bit_algo;
16206 +       return l3_add_adapter(adap);
16207 +}
16208 +
16209 +int l3_bit_del_bus(struct l3_adapter *adap)
16210 +{
16211 +       return l3_del_adapter(adap);
16212 +}
16213 +
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
16218 @@ -0,0 +1,11 @@
16219 +#
16220 +# Makefile for the L3 bus driver.
16221 +#
16222 +
16223 +# Link order:
16224 +#  (core, adapters, algorithms, drivers) then clients
16225 +
16226 +l3-$(CONFIG_L3_ALGOBIT)                += l3-algo-bit.o
16227 +l3-$(CONFIG_BIT_SA1100_GPIO)   += l3-bit-sa1100.o
16228 +
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
16232 @@ -0,0 +1,271 @@
16233 +/*
16234 + *  linux/drivers/l3/l3-bit-sa1100.c
16235 + *
16236 + *  Copyright (C) 2001 Russell King
16237 + *
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.
16241 + *
16242 + *  This is a combined I2C and L3 bus driver.
16243 + */
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>
16254 +
16255 +#include <asm/system.h>
16256 +#include <asm/hardware.h>
16257 +#include <asm/mach-types.h>
16258 +#include <asm/arch/assabet.h>
16259 +
16260 +#define NAME "l3-bit-sa1100-gpio"
16261 +
16262 +struct bit_data {
16263 +       unsigned int    sda;
16264 +       unsigned int    scl;
16265 +       unsigned int    l3_mode;
16266 +};
16267 +
16268 +static int getsda(void *data)
16269 +{
16270 +       struct bit_data *bits = data;
16271 +
16272 +       return GPLR & bits->sda;
16273 +}
16274 +
16275 +#ifdef CONFIG_I2C_BIT_SA1100_GPIO
16276 +static void i2c_setsda(void *data, int state)
16277 +{
16278 +       struct bit_data *bits = data;
16279 +       unsigned long flags;
16280 +
16281 +       local_irq_save(flags);
16282 +       if (state)
16283 +               GPDR &= ~bits->sda;
16284 +       else {
16285 +               GPCR = bits->sda;
16286 +               GPDR |= bits->sda;
16287 +       }
16288 +       local_irq_restore(flags);
16289 +}
16290 +
16291 +static void i2c_setscl(void *data, int state)
16292 +{
16293 +       struct bit_data *bits = data;
16294 +       unsigned long flags;
16295 +
16296 +       local_irq_save(flags);
16297 +       if (state)
16298 +               GPDR &= ~bits->scl;
16299 +       else {
16300 +               GPCR = bits->scl;
16301 +               GPDR |= bits->scl;
16302 +       }
16303 +       local_irq_restore(flags);
16304 +}
16305 +
16306 +static int i2c_getscl(void *data)
16307 +{
16308 +       struct bit_data *bits = data;
16309 +
16310 +       return GPLR & bits->scl;
16311 +}
16312 +
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,
16318 +       .udelay         = 10,
16319 +       .mdelay         = 10,
16320 +       .timeout        = 100,
16321 +};
16322 +
16323 +static struct i2c_adapter i2c_adapter = {
16324 +       .algo_data      = &i2c_bit_data,
16325 +};
16326 +
16327 +#define LOCK   &i2c_adapter.bus_lock
16328 +
16329 +static int __init i2c_init(struct bit_data *bits)
16330 +{
16331 +       i2c_bit_data.data = bits;
16332 +       return i2c_bit_add_bus(&i2c_adapter);
16333 +}
16334 +
16335 +static void i2c_exit(void)
16336 +{
16337 +       i2c_bit_del_bus(&i2c_adapter);
16338 +}
16339 +
16340 +#else
16341 +static DECLARE_MUTEX(l3_lock);
16342 +#define LOCK           &l3_lock
16343 +#define i2c_init(bits) (0)
16344 +#define i2c_exit()     do { } while (0)
16345 +#endif
16346 +
16347 +#ifdef CONFIG_L3_BIT_SA1100_GPIO
16348 +/*
16349 + * iPAQs need the clock line driven hard high and low.
16350 + */
16351 +static void l3_setscl(void *data, int state)
16352 +{
16353 +       struct bit_data *bits = data;
16354 +       unsigned long flags;
16355 +
16356 +       local_irq_save(flags);
16357 +       if (state)
16358 +               GPSR = bits->scl;
16359 +       else
16360 +               GPCR = bits->scl;
16361 +       GPDR |= bits->scl;
16362 +       local_irq_restore(flags);
16363 +}
16364 +
16365 +static void l3_setsda(void *data, int state)
16366 +{
16367 +       struct bit_data *bits = data;
16368 +
16369 +       if (state)
16370 +               GPSR = bits->sda;
16371 +       else
16372 +               GPCR = bits->sda;
16373 +}
16374 +
16375 +static void l3_setdir(void *data, int in)
16376 +{
16377 +       struct bit_data *bits = data;
16378 +       unsigned long flags;
16379 +
16380 +       local_irq_save(flags);
16381 +       if (in)
16382 +               GPDR &= ~bits->sda;
16383 +       else
16384 +               GPDR |= bits->sda;
16385 +       local_irq_restore(flags);
16386 +}
16387 +
16388 +static void l3_setmode(void *data, int state)
16389 +{
16390 +       struct bit_data *bits = data;
16391 +
16392 +       if (state)
16393 +               GPSR = bits->l3_mode;
16394 +       else
16395 +               GPCR = bits->l3_mode;
16396 +}
16397 +
16398 +static struct l3_algo_bit_data l3_bit_data = {
16399 +       .data           = NULL,
16400 +       .setdat         = l3_setsda,
16401 +       .setclk         = l3_setscl,
16402 +       .setmode        = l3_setmode,
16403 +       .setdir         = l3_setdir,
16404 +       .getdat         = getsda,
16405 +       .data_hold      = 1,
16406 +       .data_setup     = 1,
16407 +       .clock_high     = 1,
16408 +       .mode_hold      = 1,
16409 +       .mode_setup     = 1,
16410 +};
16411 +
16412 +static struct l3_adapter l3_adapter = {
16413 +       .owner          = THIS_MODULE,
16414 +       .name           = NAME,
16415 +       .algo_data      = &l3_bit_data,
16416 +       .lock           = LOCK,
16417 +};
16418 +
16419 +static int __init l3_init(struct bit_data *bits)
16420 +{
16421 +       l3_bit_data.data = bits;
16422 +       return l3_bit_add_bus(&l3_adapter);
16423 +}
16424 +
16425 +static void __exit l3_exit(void)
16426 +{
16427 +       l3_bit_del_bus(&l3_adapter);
16428 +}
16429 +#else
16430 +#define l3_init(bits)  (0)
16431 +#define l3_exit()      do { } while (0)
16432 +#endif
16433 +
16434 +static struct bit_data bit_data;
16435 +
16436 +static int __init bus_init(void)
16437 +{
16438 +       struct bit_data *bit = &bit_data;
16439 +       unsigned long flags;
16440 +       int ret;
16441 +
16442 +       if (machine_is_assabet() || machine_is_pangolin()) {
16443 +               bit->sda     = GPIO_GPIO15;
16444 +               bit->scl     = GPIO_GPIO18;
16445 +               bit->l3_mode = GPIO_GPIO17;
16446 +       }
16447 +
16448 +       if (machine_is_h3600() || machine_is_h3100()) {
16449 +               bit->sda     = GPIO_GPIO14;
16450 +               bit->scl     = GPIO_GPIO16;
16451 +               bit->l3_mode = GPIO_GPIO15;
16452 +       }
16453 +
16454 +       if (machine_is_stork()) {
16455 +               bit->sda     = GPIO_GPIO15;
16456 +               bit->scl     = GPIO_GPIO18;
16457 +               bit->l3_mode = GPIO_GPIO17;
16458 +       }
16459 +
16460 +       if (!bit->sda)
16461 +               return -ENODEV;
16462 +
16463 +       /*
16464 +        * Default level for L3 mode is low.
16465 +        * We set SCL and SDA high (i2c idle state).
16466 +        */
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);
16472 +
16473 +       if (machine_is_assabet()) {
16474 +               /*
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.
16478 +                */
16479 +               ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
16480 +               mdelay(1);
16481 +               ASSABET_BCR_clear(ASSABET_BCR_CODEC_RST);
16482 +               mdelay(1);
16483 +               ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
16484 +       }
16485 +
16486 +       ret = i2c_init(bit);
16487 +       if (ret == 0 && bit->l3_mode) {
16488 +               ret = l3_init(bit);
16489 +               if (ret)
16490 +                       i2c_exit();
16491 +       }
16492 +
16493 +       return ret;
16494 +}
16495 +
16496 +static void __exit bus_exit(void)
16497 +{
16498 +       l3_exit();
16499 +       i2c_exit();
16500 +}
16501 +
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
16506 @@ -0,0 +1,22 @@
16507 +/*
16508 + *  linux/drivers/misc/switches.h
16509 + *
16510 + *  Copyright (C) 2001 John Dorsey
16511 + *
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.
16515 + *
16516 + *  19 December 2001 - created.
16517 + */
16518 +
16519 +#if !defined(_SWITCHES_H)
16520 +# define _SWITCHES_H
16521 +
16522 +#include <linux/switches.h>
16523 +
16524 +#define SWITCHES_NAME "switches"
16525 +
16526 +extern int  switches_event(switches_mask_t *mask);
16527 +
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
16531 @@ -21,5 +21,62 @@
16532  
16533           If unsure, say N.
16534  
16535 +menu "Multimedia Capabilities Port drivers"
16536 +
16537 +config MCP
16538 +       tristate "Multimedia drivers"
16539 +
16540 +# Interface drivers
16541 +config MCP_SA1100
16542 +       tristate "Support SA1100 MCP interface"
16543 +       depends on MCP && ARCH_SA1100
16544 +
16545 +# Chip drivers
16546 +config MCP_UCB1200
16547 +       tristate "Support for UCB1200 / UCB1300"
16548 +       depends on MCP
16549 +
16550 +config MCP_UCB1200_AUDIO
16551 +       tristate "Audio / Telephony interface support"
16552 +       depends on MCP_UCB1200 && SOUND
16553 +
16554 +config MCP_UCB1200_TS
16555 +       tristate "Touchscreen interface support"
16556 +       depends on MCP_UCB1200 && INPUT
16557 +
16558 +endmenu
16559 +
16560 +
16561 +menu "Console Switches"
16562 +
16563 +config SWITCHES
16564 +       tristate "Console Switch Support"
16565 +       help
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
16571 +         server.
16572 +
16573 +         It is also possible to say M to build this driver as a module (named
16574 +         `switches.o').
16575 +
16576 +config SWITCHES_SA1100
16577 +       tristate "SA-1100 switches"
16578 +       depends on SWITCHES && ARCH_SA1100
16579 +       help
16580 +         Say Y here to include support for switches routed directly to
16581 +         interruptable signals on StrongARM SA-1100 systems.
16582 +
16583 +config SWITCHES_UCB1X00
16584 +       tristate "UCB1x00 switches"
16585 +       depends on SWITCHES && MCP_UCB1200
16586 +       help
16587 +         Say Y here to include support for switches routed through a
16588 +         UCB1x00 modem/audio analog front-end device.
16589 +
16590 +endmenu
16591 +
16592  endmenu
16593  
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
16596 @@ -0,0 +1,73 @@
16597 +/*
16598 + *  linux/drivers/misc/ucb1x00-assabet.c
16599 + *
16600 + *  Copyright (C) 2001-2003 Russell King, All Rights Reserved.
16601 + *
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.
16605 + *
16606 + *  We handle the machine-specific bits of the UCB1x00 driver here.
16607 + */
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>
16613 +
16614 +#include <asm/dma.h>
16615 +
16616 +#include "ucb1x00.h"
16617 +
16618 +#define UCB1X00_ATTR(name,input)\
16619 +static ssize_t name##_show(struct class_device *dev, char *buf)        \
16620 +{                                                              \
16621 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);         \
16622 +       int val;                                                \
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);                       \
16627 +}                                                              \
16628 +static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL)
16629 +
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);
16633 +
16634 +static int ucb1x00_assabet_add(struct class_device *dev)
16635 +{
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);
16639 +       return 0;
16640 +}
16641 +
16642 +static void ucb1x00_assabet_remove(struct class_device *dev)
16643 +{
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);
16647 +}
16648 +
16649 +static struct class_interface ucb1x00_assabet_interface = {
16650 +       .add    = ucb1x00_assabet_add,
16651 +       .remove = ucb1x00_assabet_remove,
16652 +};
16653 +
16654 +static int __init ucb1x00_assabet_init(void)
16655 +{
16656 +       return ucb1x00_register_interface(&ucb1x00_assabet_interface);
16657 +}
16658 +
16659 +static void __exit ucb1x00_assabet_exit(void)
16660 +{
16661 +       ucb1x00_unregister_interface(&ucb1x00_assabet_interface);
16662 +}
16663 +
16664 +module_init(ucb1x00_assabet_init);
16665 +module_exit(ucb1x00_assabet_exit);
16666 +
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
16672 @@ -0,0 +1,57 @@
16673 +/*
16674 + *  linux/drivers/misc/mcp-pxa.c
16675 + *
16676 + *  2002-01-10 Jeff Sutherland <jeffs@accelent.com>
16677 + *
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.
16681 + *
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.
16685 + */
16686 +
16687 +#include <linux/module.h>
16688 +#include <linux/types.h>
16689 +#include <linux/ac97_codec.h>
16690 +
16691 +#include "mcp.h"
16692 +
16693 +
16694 +extern int pxa_ac97_get(struct ac97_codec **codec);
16695 +extern void pxa_ac97_put(void);
16696 +
16697 +
16698 +struct mcp *mcp_get(void)
16699 +{
16700 +       struct ac97_codec *codec;
16701 +       if (pxa_ac97_get(&codec) < 0)
16702 +               return NULL;
16703 +       return (struct mcp *)codec;
16704 +}
16705 +
16706 +void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
16707 +{
16708 +       struct ac97_codec *codec = (struct ac97_codec *)mcp;
16709 +       codec->codec_write(codec, reg, val);
16710 +}
16711 +
16712 +unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
16713 +{
16714 +       struct ac97_codec *codec = (struct ac97_codec *)mcp;
16715 +       return codec->codec_read(codec, reg);
16716 +}
16717 +
16718 +void mcp_enable(struct mcp *mcp)
16719 +{
16720 +       /* 
16721 +        * Should we do something here to make sure the aclink
16722 +        * codec is alive???
16723 +        * A: not for now  --NP
16724 +       */
16725 +}
16726 +
16727 +void mcp_disable(struct mcp *mcp)
16728 +{
16729 +}
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
16732 @@ -0,0 +1,235 @@
16733 +/*
16734 + *  linux/drivers/misc/mcp-core.c
16735 + *
16736 + *  Copyright (C) 2001 Russell King
16737 + *
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.
16741 + *
16742 + *  Generic MCP (Multimedia Communications Port) layer.  All MCP locking
16743 + *  is solely held within this file.
16744 + */
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>
16750 +
16751 +#include <asm/dma.h>
16752 +#include <asm/system.h>
16753 +
16754 +#include "mcp.h"
16755 +
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)
16758 +
16759 +static int mcp_bus_match(struct device *dev, struct device_driver *drv)
16760 +{
16761 +       return 1;
16762 +}
16763 +
16764 +static int mcp_bus_probe(struct device *dev)
16765 +{
16766 +       struct mcp *mcp = to_mcp(dev);
16767 +       struct mcp_driver *drv = to_mcp_driver(dev->driver);
16768 +
16769 +       return drv->probe(mcp);
16770 +}
16771 +
16772 +static int mcp_bus_remove(struct device *dev)
16773 +{
16774 +       struct mcp *mcp = to_mcp(dev);
16775 +       struct mcp_driver *drv = to_mcp_driver(dev->driver);
16776 +
16777 +       drv->remove(mcp);
16778 +       return 0;
16779 +}
16780 +
16781 +static int mcp_bus_suspend(struct device *dev, u32 state)
16782 +{
16783 +       struct mcp *mcp = to_mcp(dev);
16784 +       int ret = 0;
16785 +
16786 +       if (dev->driver) {
16787 +               struct mcp_driver *drv = to_mcp_driver(dev->driver);
16788 +
16789 +               ret = drv->suspend(mcp, state);
16790 +       }
16791 +       return ret;
16792 +}
16793 +
16794 +static int mcp_bus_resume(struct device *dev)
16795 +{
16796 +       struct mcp *mcp = to_mcp(dev);
16797 +       int ret = 0;
16798 +
16799 +       if (dev->driver) {
16800 +               struct mcp_driver *drv = to_mcp_driver(dev->driver);
16801 +
16802 +               ret = drv->resume(mcp);
16803 +       }
16804 +       return ret;
16805 +}
16806 +
16807 +static struct bus_type mcp_bus_type = {
16808 +       .name           = "mcp",
16809 +       .match          = mcp_bus_match,
16810 +       .suspend        = mcp_bus_suspend,
16811 +       .resume         = mcp_bus_resume,
16812 +};
16813 +
16814 +/**
16815 + *     mcp_set_telecom_divisor - set the telecom divisor
16816 + *     @mcp: MCP interface structure
16817 + *     @div: SIB clock divisor
16818 + *
16819 + *     Set the telecom divisor on the MCP interface.  The resulting
16820 + *     sample rate is SIBCLOCK/div.
16821 + */
16822 +void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
16823 +{
16824 +       spin_lock_irq(&mcp->lock);
16825 +       mcp->set_telecom_divisor(mcp, div);
16826 +       spin_unlock_irq(&mcp->lock);
16827 +}
16828 +
16829 +/**
16830 + *     mcp_set_audio_divisor - set the audio divisor
16831 + *     @mcp: MCP interface structure
16832 + *     @div: SIB clock divisor
16833 + *
16834 + *     Set the audio divisor on the MCP interface.
16835 + */
16836 +void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
16837 +{
16838 +       spin_lock_irq(&mcp->lock);
16839 +       mcp->set_audio_divisor(mcp, div);
16840 +       spin_unlock_irq(&mcp->lock);
16841 +}
16842 +
16843 +/**
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
16848 + *
16849 + *     Write a device register.  The MCP interface must be enabled
16850 + *     to prevent this function hanging.
16851 + */
16852 +void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
16853 +{
16854 +       unsigned long flags;
16855 +
16856 +       spin_lock_irqsave(&mcp->lock, flags);
16857 +       mcp->reg_write(mcp, reg, val);
16858 +       spin_unlock_irqrestore(&mcp->lock, flags);
16859 +}
16860 +
16861 +/**
16862 + *     mcp_reg_read - read a device register
16863 + *     @mcp: MCP interface structure
16864 + *     @reg: 4-bit register index
16865 + *
16866 + *     Read a device register and return its value.  The MCP interface
16867 + *     must be enabled to prevent this function hanging.
16868 + */
16869 +unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
16870 +{
16871 +       unsigned long flags;
16872 +       unsigned int val;
16873 +
16874 +       spin_lock_irqsave(&mcp->lock, flags);
16875 +       val = mcp->reg_read(mcp, reg);
16876 +       spin_unlock_irqrestore(&mcp->lock, flags);
16877 +
16878 +       return val;
16879 +}
16880 +
16881 +/**
16882 + *     mcp_enable - enable the MCP interface
16883 + *     @mcp: MCP interface to enable
16884 + *
16885 + *     Enable the MCP interface.  Each call to mcp_enable will need
16886 + *     a corresponding call to mcp_disable to disable the interface.
16887 + */
16888 +void mcp_enable(struct mcp *mcp)
16889 +{
16890 +       spin_lock_irq(&mcp->lock);
16891 +       if (mcp->use_count++ == 0)
16892 +               mcp->enable(mcp);
16893 +       spin_unlock_irq(&mcp->lock);
16894 +}
16895 +
16896 +/**
16897 + *     mcp_disable - disable the MCP interface
16898 + *     @mcp: MCP interface to disable
16899 + *
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.
16903 + */
16904 +void mcp_disable(struct mcp *mcp)
16905 +{
16906 +       unsigned long flags;
16907 +
16908 +       spin_lock_irqsave(&mcp->lock, flags);
16909 +       if (--mcp->use_count == 0)
16910 +               mcp->disable(mcp);
16911 +       spin_unlock_irqrestore(&mcp->lock, flags);
16912 +}
16913 +
16914 +int mcp_host_register(struct mcp *mcp, struct device *parent)
16915 +{
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);
16921 +}
16922 +
16923 +void mcp_host_unregister(struct mcp *mcp)
16924 +{
16925 +       device_unregister_wait(&mcp->attached_device);
16926 +}
16927 +
16928 +int mcp_driver_register(struct mcp_driver *mcpdrv)
16929 +{
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);
16934 +}
16935 +
16936 +void mcp_driver_unregister(struct mcp_driver *mcpdrv)
16937 +{
16938 +       driver_unregister(&mcpdrv->drv);
16939 +}
16940 +
16941 +static int __init mcp_init(void)
16942 +{
16943 +       return bus_register(&mcp_bus_type);
16944 +}
16945 +
16946 +static void __exit mcp_exit(void)
16947 +{
16948 +       bus_unregister(&mcp_bus_type);
16949 +}
16950 +
16951 +module_init(mcp_init);
16952 +module_exit(mcp_exit);
16953 +
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);
16964 +
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
16970 @@ -0,0 +1,465 @@
16971 +/*
16972 + *  linux/drivers/misc/ucb1x00-ts.c
16973 + *
16974 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
16975 + *
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.
16979 + *
16980 + * 21-Jan-2002 <jco@ict.es> :
16981 + *
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.
16988 + */
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>
17001 +
17002 +#include <asm/dma.h>
17003 +#include <asm/semaphore.h>
17004 +
17005 +#include "ucb1x00.h"
17006 +
17007 +
17008 +struct ucb1x00_ts {
17009 +       struct input_dev        idev;
17010 +       struct ucb1x00          *ucb;
17011 +
17012 +       struct semaphore        irq_wait;
17013 +       struct semaphore        sem;
17014 +       struct completion       init_exit;
17015 +       struct task_struct      *rtask;
17016 +       int                     use_count;
17017 +       u16                     x_res;
17018 +       u16                     y_res;
17019 +
17020 +       int                     restart:1;
17021 +       int                     adcsync:1;
17022 +};
17023 +
17024 +static int adcsync = UCB_NOSYNC;
17025 +
17026 +static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
17027 +{
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);
17032 +}
17033 +
17034 +static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
17035 +{
17036 +       input_report_abs(&ts->idev, ABS_PRESSURE, 0);
17037 +       input_sync(&ts->idev);
17038 +}
17039 +
17040 +/*
17041 + * Switch to interrupt mode.
17042 + */
17043 +static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
17044 +{
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);
17049 +       else
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);
17054 +}
17055 +
17056 +/*
17057 + * Switch to pressure mode, and read pressure.  We don't need to wait
17058 + * here, since both plates are being driven.
17059 + */
17060 +static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
17061 +{
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);
17066 +
17067 +       return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
17068 +}
17069 +
17070 +/*
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.
17075 + */
17076 +static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
17077 +{
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);
17087 +
17088 +       udelay(55);
17089 +
17090 +       return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
17091 +}
17092 +
17093 +/*
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.
17098 + */
17099 +static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
17100 +{
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);
17110 +
17111 +       udelay(55);
17112 +
17113 +       return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
17114 +}
17115 +
17116 +/*
17117 + * Switch to X plate resistance mode.  Set MX to ground, PX to
17118 + * supply.  Measure current.
17119 + */
17120 +static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
17121 +{
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);
17126 +}
17127 +
17128 +/*
17129 + * Switch to Y plate resistance mode.  Set MY to ground, PY to
17130 + * supply.  Measure current.
17131 + */
17132 +static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
17133 +{
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);
17138 +}
17139 +
17140 +/*
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).
17145 + */
17146 +static int ucb1x00_thread(void *_ts)
17147 +{
17148 +       struct ucb1x00_ts *ts = _ts;
17149 +       struct task_struct *tsk = current;
17150 +       int valid;
17151 +
17152 +       ts->rtask = tsk;
17153 +
17154 +       daemonize("ktsd");
17155 +       /* only want to receive SIGKILL */
17156 +       allow_signal(SIGKILL);
17157 +
17158 +       /*
17159 +        * We could run as a real-time thread.  However, thus far
17160 +        * this doesn't seem to be necessary.
17161 +        */
17162 +//     tsk->policy = SCHED_FIFO;
17163 +//     tsk->rt_priority = 1;
17164 +
17165 +       complete(&ts->init_exit);
17166 +
17167 +       valid = 0;
17168 +
17169 +       for (;;) {
17170 +               unsigned int x, y, p, val;
17171 +
17172 +               ts->restart = 0;
17173 +
17174 +               ucb1x00_adc_enable(ts->ucb);
17175 +
17176 +               x = ucb1x00_ts_read_xpos(ts);
17177 +               y = ucb1x00_ts_read_ypos(ts);
17178 +               p = ucb1x00_ts_read_pressure(ts);
17179 +
17180 +               /*
17181 +                * Switch back to interrupt mode.
17182 +                */
17183 +               ucb1x00_ts_mode_int(ts);
17184 +               ucb1x00_adc_disable(ts->ucb);
17185 +
17186 +               set_task_state(tsk, TASK_UNINTERRUPTIBLE);
17187 +               schedule_timeout(HZ / 100);
17188 +               if (signal_pending(tsk))
17189 +                       break;
17190 +
17191 +               ucb1x00_enable(ts->ucb);
17192 +               val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
17193 +
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);
17197 +
17198 +                       /*
17199 +                        * If we spat out a valid sample set last time,
17200 +                        * spit out a "pen off" sample here.
17201 +                        */
17202 +                       if (valid) {
17203 +                               ucb1x00_ts_event_release(ts);
17204 +                               valid = 0;
17205 +                       }
17206 +
17207 +                       /*
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.
17214 +                        */
17215 +                       down_interruptible(&ts->irq_wait);
17216 +               } else {
17217 +                       ucb1x00_disable(ts->ucb);
17218 +
17219 +                       /*
17220 +                        * Filtering is policy.  Policy belongs in user
17221 +                        * space.  We therefore leave it to user space
17222 +                        * to do any filtering they please.
17223 +                        */
17224 +                       if (!ts->restart) {
17225 +                               ucb1x00_ts_evt_add(ts, p, x, y);
17226 +                               valid = 1;
17227 +                       }
17228 +
17229 +                       set_task_state(tsk, TASK_INTERRUPTIBLE);
17230 +               }
17231 +
17232 +               schedule_timeout(HZ / 100);
17233 +               if (signal_pending(tsk))
17234 +                       break;
17235 +       }
17236 +
17237 +       ts->rtask = NULL;
17238 +       complete_and_exit(&ts->init_exit, 0);
17239 +}
17240 +
17241 +/*
17242 + * We only detect touch screen _touches_ with this interrupt
17243 + * handler, and even then we just schedule our task.
17244 + */
17245 +static void ucb1x00_ts_irq(int idx, void *id)
17246 +{
17247 +       struct ucb1x00_ts *ts = id;
17248 +       ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
17249 +       up(&ts->irq_wait);
17250 +}
17251 +
17252 +static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
17253 +{
17254 +       input_report_abs(&ts->idev, ABS_PRESSURE, 0);
17255 +}
17256 +
17257 +static int ucb1x00_ts_open(struct input_dev *idev)
17258 +{
17259 +       struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
17260 +       int ret = 0;
17261 +
17262 +       if (down_interruptible(&ts->sem))
17263 +               return -EINTR;
17264 +
17265 +       if (ts->use_count++ != 0)
17266 +               goto out;
17267 +
17268 +       if (ts->rtask)
17269 +               panic("ucb1x00: rtask running?");
17270 +
17271 +       sema_init(&ts->irq_wait, 0);
17272 +       ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
17273 +       if (ret < 0)
17274 +               goto out;
17275 +
17276 +       /*
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.
17279 +        */
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);
17284 +
17285 +       init_completion(&ts->init_exit);
17286 +       ret = kernel_thread(ucb1x00_thread, ts, CLONE_KERNEL);
17287 +       if (ret >= 0) {
17288 +               wait_for_completion(&ts->init_exit);
17289 +               ret = 0;
17290 +       } else {
17291 +               ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
17292 +       }
17293 +
17294 + out:
17295 +       if (ret)
17296 +               ts->use_count--;
17297 +       up(&ts->sem);
17298 +       return ret;
17299 +}
17300 +
17301 +/*
17302 + * Release touchscreen resources.  Disable IRQs.
17303 + */
17304 +static void ucb1x00_ts_close(struct input_dev *idev)
17305 +{
17306 +       struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
17307 +
17308 +       down(&ts->sem);
17309 +       if (--ts->use_count == 0) {
17310 +               if (ts->rtask) {
17311 +                       send_sig(SIGKILL, ts->rtask, 1);
17312 +                       wait_for_completion(&ts->init_exit);
17313 +               }
17314 +
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);
17319 +       }
17320 +       up(&ts->sem);
17321 +}
17322 +
17323 +#if 0
17324 +static int ucb1x00_ts_resume(struct device *_dev, u32 level)
17325 +{
17326 +       struct ucb1x00_device *dev = ucb1x00_dev(_dev);
17327 +       struct ucb1x00_ts *ts = ucb1x00_get_drvdata(dev);
17328 +
17329 +       if (level == RESUME_ENABLE && ts->rtask != NULL) {
17330 +               /*
17331 +                * Restart the TS thread to ensure the
17332 +                * TS interrupt mode is set up again
17333 +                * after sleep.
17334 +                */
17335 +               ts->restart = 1;
17336 +               up(&ts->irq_wait);
17337 +       }
17338 +       return 0;
17339 +}
17340 +#endif
17341 +
17342 +
17343 +/*
17344 + * Initialisation.
17345 + */
17346 +static int ucb1x00_ts_add(struct class_device *dev)
17347 +{
17348 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
17349 +       struct ucb1x00_ts *ts;
17350 +
17351 +       ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
17352 +       if (!ts)
17353 +               return -ENOMEM;
17354 +
17355 +       memset(ts, 0, sizeof(struct ucb1x00_ts));
17356 +
17357 +       ts->ucb = ucb;
17358 +       ts->adcsync = adcsync;
17359 +       init_MUTEX(&ts->sem);
17360 +
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;
17365 +
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);
17370 +
17371 +       input_register_device(&ts->idev);
17372 +
17373 +       ucb->ts_data = ts;
17374 +
17375 +       return 0;
17376 +}
17377 +
17378 +static void ucb1x00_ts_remove(struct class_device *dev)
17379 +{
17380 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
17381 +       struct ucb1x00_ts *ts = ucb->ts_data;
17382 +
17383 +       input_unregister_device(&ts->idev);
17384 +       kfree(ts);
17385 +}
17386 +
17387 +static struct class_interface ucb1x00_ts_interface = {
17388 +       .add            = ucb1x00_ts_add,
17389 +       .remove         = ucb1x00_ts_remove,
17390 +};
17391 +
17392 +static int __init ucb1x00_ts_init(void)
17393 +{
17394 +       return ucb1x00_register_interface(&ucb1x00_ts_interface);
17395 +}
17396 +
17397 +static void __exit ucb1x00_ts_exit(void)
17398 +{
17399 +       ucb1x00_unregister_interface(&ucb1x00_ts_interface);
17400 +}
17401 +
17402 +#ifndef MODULE
17403 +
17404 +/*
17405 + * Parse kernel command-line options.
17406 + *
17407 + * syntax : ucbts=[sync|nosync],...
17408 + */
17409 +static int __init ucb1x00_ts_setup(char *str)
17410 +{
17411 +       char *p;
17412 +
17413 +       while ((p = strsep(&str, ",")) != NULL) {
17414 +               if (strcmp(p, "sync") == 0)
17415 +                       adcsync = UCB_SYNC;
17416 +       }
17417 +
17418 +       return 1;
17419 +}
17420 +
17421 +__setup("ucbts=", ucb1x00_ts_setup);
17422 +
17423 +#else
17424 +
17425 +MODULE_PARM(adcsync, "i");
17426 +MODULE_PARM_DESC(adcsync, "Enable use of ADCSYNC signal");
17427 +
17428 +#endif
17429 +
17430 +module_init(ucb1x00_ts_init);
17431 +module_exit(ucb1x00_ts_exit);
17432 +
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
17438 @@ -0,0 +1,624 @@
17439 +/*
17440 + *  linux/drivers/misc/ucb1x00-core.c
17441 + *
17442 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
17443 + *
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.
17447 + *
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.
17453 + *
17454 + *  Note that all locks are private to this file.  Nothing else may
17455 + *  touch them.
17456 + */
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>
17465 +
17466 +#include <asm/dma.h>
17467 +#include <asm/hardware.h>
17468 +#include <asm/irq.h>
17469 +
17470 +#include "ucb1x00.h"
17471 +
17472 +/**
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
17477 + *
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.
17482 + *
17483 + *     ucb1x00_enable must have been called to enable the comms
17484 + *     before using this function.
17485 + *
17486 + *     This function takes a spinlock, disabling interrupts.
17487 + */
17488 +void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out)
17489 +{
17490 +       unsigned long flags;
17491 +
17492 +       spin_lock_irqsave(&ucb->io_lock, flags);
17493 +       ucb->io_dir |= out;
17494 +       ucb->io_dir &= ~in;
17495 +
17496 +       ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
17497 +       spin_unlock_irqrestore(&ucb->io_lock, flags);
17498 +}
17499 +
17500 +/**
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'
17505 + *
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.
17510 + *
17511 + *     ucb1x00_enable must have been called to enable the comms
17512 + *     before using this function.
17513 + *
17514 + *     This function takes a spinlock, disabling interrupts.
17515 + */
17516 +void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
17517 +{
17518 +       unsigned long flags;
17519 +
17520 +       spin_lock_irqsave(&ucb->io_lock, flags);
17521 +       ucb->io_out |= set;
17522 +       ucb->io_out &= ~clear;
17523 +
17524 +       ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
17525 +       spin_unlock_irqrestore(&ucb->io_lock, flags);
17526 +}
17527 +
17528 +/**
17529 + *     ucb1x00_io_read - read the current state of the IO pins
17530 + *     @ucb: UCB1x00 structure describing chip
17531 + *
17532 + *     Return a bitfield describing the logic state of the ten
17533 + *     general purpose IO pins.
17534 + *
17535 + *     ucb1x00_enable must have been called to enable the comms
17536 + *     before using this function.
17537 + *
17538 + *     This function does not take any semaphores or spinlocks.
17539 + */
17540 +unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
17541 +{
17542 +       return ucb1x00_reg_read(ucb, UCB_IO_DATA);
17543 +}
17544 +
17545 +/*
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
17552 + */
17553 +
17554 +/**
17555 + *     ucb1x00_adc_enable - enable the ADC converter
17556 + *     @ucb: UCB1x00 structure describing chip
17557 + *
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.
17561 + *
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
17565 + *     context.
17566 + *
17567 + *     You should release the ADC as soon as possible using
17568 + *     ucb1x00_adc_disable.
17569 + */
17570 +void ucb1x00_adc_enable(struct ucb1x00 *ucb)
17571 +{
17572 +       down(&ucb->adc_sem);
17573 +
17574 +       ucb->adc_cr |= UCB_ADC_ENA;
17575 +
17576 +       ucb1x00_enable(ucb);
17577 +       ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
17578 +}
17579 +
17580 +/**
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.
17585 + *
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.
17589 + *
17590 + *     This function currently spins waiting for the conversion to
17591 + *     complete (2 frames max without sync).
17592 + *
17593 + *     If called for a synchronised ADC conversion, it may sleep
17594 + *     with the ADC semaphore held.
17595 + *     
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
17599 + */
17600 +unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
17601 +{
17602 +       unsigned int val;
17603 +
17604 +       if (sync)
17605 +               adc_channel |= UCB_ADC_SYNC_ENA;
17606 +
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);
17609 +
17610 +       for (;;) {
17611 +               val = ucb1x00_reg_read(ucb, UCB_ADC_DATA);
17612 +               if (val & UCB_ADC_DAT_VAL)
17613 +                       break;
17614 +               /* yield to other processes */
17615 +               set_current_state(TASK_INTERRUPTIBLE);
17616 +               schedule_timeout(1);
17617 +       }
17618 +
17619 +       return UCB_ADC_DAT(val);
17620 +}
17621 +
17622 +/**
17623 + *     ucb1x00_adc_disable - disable the ADC converter
17624 + *     @ucb: UCB1x00 structure describing chip
17625 + *
17626 + *     Disable the ADC converter and release the ADC semaphore.
17627 + */
17628 +void ucb1x00_adc_disable(struct ucb1x00 *ucb)
17629 +{
17630 +       ucb->adc_cr &= ~UCB_ADC_ENA;
17631 +       ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
17632 +       ucb1x00_disable(ucb);
17633 +
17634 +       up(&ucb->adc_sem);
17635 +}
17636 +
17637 +/*
17638 + * UCB1x00 Interrupt handling.
17639 + *
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.
17644 + *
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.
17653 + */
17654 +
17655 +static int ucb1x00_thread(void *_ucb)
17656 +{
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;
17662 +
17663 +       ucb->rtask = tsk;
17664 +
17665 +       daemonize();
17666 +       reparent_to_init();
17667 +       tsk->tty = NULL;
17668 +       tsk->policy = SCHED_FIFO;
17669 +       tsk->rt_priority = 1;
17670 +       strcpy(tsk->comm, "kUCB1x00d");
17671 +
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);
17677 +
17678 +       add_wait_queue(&ucb->irq_wait, &wait);
17679 +       set_task_state(tsk, TASK_INTERRUPTIBLE);
17680 +       complete(&ucb->complete);
17681 +
17682 +       for (;;) {
17683 +               if (signal_pending(tsk))
17684 +                       break;
17685 +               enable_irq(ucb->irq);
17686 +               schedule();
17687 +
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);
17692 +
17693 +               for (i = 0, irq = ucb->irq_handler;
17694 +                    i < 16 && isr; 
17695 +                    i++, isr >>= 1, irq++)
17696 +                       if (isr & 1 && irq->fn)
17697 +                               irq->fn(i, irq->devid);
17698 +               ucb1x00_disable(ucb);
17699 +
17700 +               set_task_state(tsk, TASK_INTERRUPTIBLE);
17701 +       }
17702 +
17703 +       remove_wait_queue(&ucb->irq_wait, &wait);
17704 +       ucb->rtask = NULL;
17705 +       complete_and_exit(&ucb->complete, 0);
17706 +}
17707 +
17708 +static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
17709 +{
17710 +       struct ucb1x00 *ucb = devid;
17711 +       disable_irq(irqnr);
17712 +       wake_up(&ucb->irq_wait);
17713 +       return IRQ_HANDLED;
17714 +}
17715 +
17716 +/**
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
17722 + *
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.
17726 + *
17727 + *     Interrupt handlers will be called with other interrupts enabled.
17728 + *
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
17732 + */
17733 +int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
17734 +{
17735 +       struct ucb1x00_irq *irq;
17736 +       int ret = -EINVAL;
17737 +
17738 +       if (idx < 16) {
17739 +               irq = ucb->irq_handler + idx;
17740 +               ret = -EBUSY;
17741 +
17742 +               spin_lock_irq(&ucb->lock);
17743 +               if (irq->fn == NULL) {
17744 +                       irq->devid = devid;
17745 +                       irq->fn = fn;
17746 +                       ret = 0;
17747 +               }
17748 +               spin_unlock_irq(&ucb->lock);
17749 +       }
17750 +       return ret;
17751 +}
17752 +
17753 +/**
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
17758 + *
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.
17762 + */
17763 +void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
17764 +{
17765 +       unsigned long flags;
17766 +
17767 +       if (idx < 16) {
17768 +               spin_lock_irqsave(&ucb->lock, flags);
17769 +
17770 +               ucb1x00_enable(ucb);
17771 +
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);
17775 +
17776 +               if (edges & UCB_RISING) {
17777 +                       ucb->irq_ris_enbl |= 1 << idx;
17778 +                       ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
17779 +               }
17780 +               if (edges & UCB_FALLING) {
17781 +                       ucb->irq_fal_enbl |= 1 << idx;
17782 +                       ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
17783 +               }
17784 +               ucb1x00_disable(ucb);
17785 +               spin_unlock_irqrestore(&ucb->lock, flags);
17786 +       }
17787 +}
17788 +
17789 +/**
17790 + *     ucb1x00_disable_irq - disable an UCB1x00 interrupt source
17791 + *     @ucb: UCB1x00 structure describing chip
17792 + *     @edges: interrupt edges to disable
17793 + *
17794 + *     Disable the specified interrupt triggering on the specified
17795 + *     (%UCB_RISING, %UCB_FALLING or both) edges.
17796 + */
17797 +void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
17798 +{
17799 +       unsigned long flags;
17800 +
17801 +       if (idx < 16) {
17802 +               spin_lock_irqsave(&ucb->lock, flags);
17803 +
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);
17808 +               }
17809 +               if (edges & UCB_FALLING) {
17810 +                       ucb->irq_fal_enbl &= ~(1 << idx);
17811 +                       ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
17812 +               }
17813 +               ucb1x00_disable(ucb);
17814 +               spin_unlock_irqrestore(&ucb->lock, flags);
17815 +       }
17816 +}
17817 +
17818 +/**
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.
17823 + *
17824 + *     Disable the interrupt source and remove the handler.  devid must
17825 + *     match the devid passed when hooking the interrupt.
17826 + *
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
17830 + */
17831 +int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
17832 +{
17833 +       struct ucb1x00_irq *irq;
17834 +       int ret;
17835 +
17836 +       if (idx >= 16)
17837 +               goto bad;
17838 +
17839 +       irq = ucb->irq_handler + idx;
17840 +       ret = -ENOENT;
17841 +
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);
17846 +
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);
17851 +
17852 +               irq->fn = NULL;
17853 +               irq->devid = NULL;
17854 +               ret = 0;
17855 +       }
17856 +       spin_unlock_irq(&ucb->lock);
17857 +       return ret;
17858 +
17859 +bad:
17860 +       printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx);
17861 +       return -EINVAL;
17862 +}
17863 +
17864 +/*
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:
17868 + *
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
17882 + */
17883 +static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
17884 +{
17885 +       unsigned long mask;
17886 +
17887 +       mask = probe_irq_on();
17888 +       if (!mask)
17889 +               return NO_IRQ;
17890 +
17891 +       /*
17892 +        * Enable the ADC interrupt.
17893 +        */
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);
17898 +
17899 +       /*
17900 +        * Cause an ADC interrupt.
17901 +        */
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);
17904 +
17905 +       /*
17906 +        * Wait for the conversion to complete.
17907 +        */
17908 +       while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0);
17909 +       ucb1x00_reg_write(ucb, UCB_ADC_CR, 0);
17910 +
17911 +       /*
17912 +        * Disable and clear interrupt.
17913 +        */
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);
17918 +
17919 +       /*
17920 +        * Read triggered interrupt.
17921 +        */
17922 +       return probe_irq_off(mask);
17923 +}
17924 +
17925 +static int ucb1x00_probe(struct mcp *mcp)
17926 +{
17927 +       struct ucb1x00 *ucb;
17928 +       unsigned int id;
17929 +       int ret = -ENODEV;
17930 +
17931 +       mcp_enable(mcp);
17932 +       id = mcp_reg_read(mcp, UCB_ID);
17933 +
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;
17937 +       }
17938 +
17939 +       ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
17940 +       ret = -ENOMEM;
17941 +       if (!ucb)
17942 +               goto err_disable;
17943 +
17944 +       memset(ucb, 0, sizeof(struct ucb1x00));
17945 +
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));
17949 +
17950 +       spin_lock_init(&ucb->lock);
17951 +       spin_lock_init(&ucb->io_lock);
17952 +       sema_init(&ucb->adc_sem, 1);
17953 +
17954 +       ucb->id  = id;
17955 +       ucb->mcp = mcp;
17956 +       ucb->irq = ucb1x00_detect_irq(ucb);
17957 +       if (ucb->irq == NO_IRQ) {
17958 +               printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
17959 +               ret = -ENODEV;
17960 +               goto err_free;
17961 +       }
17962 +
17963 +       ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb);
17964 +       if (ret) {
17965 +               printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
17966 +                       ucb->irq, ret);
17967 +               goto err_free;
17968 +       }
17969 +
17970 +       set_irq_type(ucb->irq, IRQT_RISING);
17971 +       mcp_set_drvdata(mcp, ucb);
17972 +
17973 +       ret = class_device_register(&ucb->cdev);
17974 +       if (ret) {
17975 +               free_irq(ucb->irq, ucb);
17976 + err_free:
17977 +               kfree(ucb);
17978 +       }
17979 + err_disable:
17980 +       mcp_disable(mcp);
17981 +       return ret;
17982 +}
17983 +
17984 +static void ucb1x00_remove(struct mcp *mcp)
17985 +{
17986 +       struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
17987 +
17988 +       class_device_unregister(&ucb->cdev);
17989 +       free_irq(ucb->irq, ucb);
17990 +}
17991 +
17992 +static void ucb1x00_release(struct class_device *dev)
17993 +{
17994 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
17995 +       kfree(ucb);
17996 +}
17997 +
17998 +static struct class ucb1x00_class = {
17999 +       .name           = "ucb1x00",
18000 +       .release        = ucb1x00_release,
18001 +};
18002 +
18003 +int ucb1x00_register_interface(struct class_interface *intf)
18004 +{
18005 +       intf->class = &ucb1x00_class;
18006 +       return class_interface_register(intf);
18007 +}
18008 +
18009 +void ucb1x00_unregister_interface(struct class_interface *intf)
18010 +{
18011 +       class_interface_unregister(intf);
18012 +}
18013 +
18014 +static struct mcp_driver ucb1x00_driver = {
18015 +       .drv            = {
18016 +               .name   = "ucb1x00",
18017 +       },
18018 +       .probe          = ucb1x00_probe,
18019 +       .remove         = ucb1x00_remove,
18020 +};
18021 +
18022 +static int __init ucb1x00_init(void)
18023 +{
18024 +       int ret = class_register(&ucb1x00_class);
18025 +       if (ret == 0) {
18026 +               ret = mcp_driver_register(&ucb1x00_driver);
18027 +               if (ret)
18028 +                       class_unregister(&ucb1x00_class);
18029 +       }
18030 +       return ret;
18031 +}
18032 +
18033 +static void __exit ucb1x00_exit(void)
18034 +{
18035 +       mcp_driver_unregister(&ucb1x00_driver);
18036 +       class_unregister(&ucb1x00_class);
18037 +}
18038 +
18039 +module_init(ucb1x00_init);
18040 +module_exit(ucb1x00_exit);
18041 +
18042 +EXPORT_SYMBOL(ucb1x00_class);
18043 +
18044 +EXPORT_SYMBOL(ucb1x00_io_set_dir);
18045 +EXPORT_SYMBOL(ucb1x00_io_write);
18046 +EXPORT_SYMBOL(ucb1x00_io_read);
18047 +
18048 +EXPORT_SYMBOL(ucb1x00_adc_enable);
18049 +EXPORT_SYMBOL(ucb1x00_adc_read);
18050 +EXPORT_SYMBOL(ucb1x00_adc_disable);
18051 +
18052 +EXPORT_SYMBOL(ucb1x00_hook_irq);
18053 +EXPORT_SYMBOL(ucb1x00_free_irq);
18054 +EXPORT_SYMBOL(ucb1x00_enable_irq);
18055 +EXPORT_SYMBOL(ucb1x00_disable_irq);
18056 +
18057 +EXPORT_SYMBOL(ucb1x00_register_interface);
18058 +EXPORT_SYMBOL(ucb1x00_unregister_interface);
18059 +
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
18065 @@ -0,0 +1,214 @@
18066 +/*
18067 + *  linux/drivers/misc/switches-ucb1x00.c
18068 + *
18069 + *  Copyright (C) 2001 John Dorsey
18070 + *
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.
18074 + *
18075 + *  19 December 2001 - created from sa1100_switches.c.
18076 + */
18077 +
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>
18085 +
18086 +#include <asm/dma.h>
18087 +#include <asm/hardware.h>
18088 +#include <asm/irq.h>
18089 +#include <asm/mach-types.h>
18090 +
18091 +#ifdef CONFIG_SA1100_ASSABET
18092 +#include <asm/arch/assabet.h>
18093 +#endif
18094 +
18095 +#include "switches.h"
18096 +#include "ucb1x00.h"
18097 +
18098 +
18099 +static void switches_ucb1x00_handler(int irq, void *devid);
18100 +
18101 +
18102 +#ifdef CONFIG_SA1100_ASSABET
18103 +
18104 +/* Assabet
18105 + * ^^^^^^^
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().
18110 + */
18111 +
18112 +static int assabet_switches_ucb1x00_init(struct ucb1x00 *ucb)
18113 +{
18114 +       int i;
18115 +
18116 +       ucb1x00_enable(ucb);
18117 +
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);
18121 +
18122 +       for (i = 0; i < 6; ++i) {
18123 +               ucb1x00_enable_irq(ucb, i, UCB_RISING | UCB_FALLING);
18124 +
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);
18129 +
18130 +                       /* FIXME: BUGGY ERROR HANDLING */
18131 +                       return -EBUSY;
18132 +               }
18133 +
18134 +       }
18135 +
18136 +       ucb1x00_disable(ucb);
18137 +
18138 +       return 0;
18139 +
18140 +}
18141 +
18142 +static void assabet_switches_ucb1x00_shutdown(struct ucb1x00 *ucb)
18143 +{
18144 +       int i;
18145 +
18146 +       ucb1x00_enable(ucb);
18147 +
18148 +       for (i = 5; i >= 0; --i) {
18149 +               ucb1x00_disable_irq(ucb, i, UCB_RISING | UCB_FALLING);
18150 +
18151 +               /* Only error conditions are ENOENT and EINVAL; silently
18152 +                * ignore:
18153 +                */
18154 +               ucb1x00_free_irq(ucb, i, ucb);
18155 +       }
18156 +
18157 +       ucb1x00_disable(ucb);
18158 +}
18159 +
18160 +static void assabet_switches_ucb1x00_handler(struct ucb1x00 *ucb, int irq, switches_mask_t *mask)
18161 +{
18162 +       unsigned int last, this;
18163 +       static unsigned int states = 0;
18164 +
18165 +       last = ((states & (1 << irq)) != 0);
18166 +       this = ((ucb1x00_io_read(ucb) & (1 << irq)) != 0);
18167 +
18168 +       if (last == this) /* debounce */
18169 +               return;
18170 +
18171 +       /* Intel StrongARM SA-1110 Development Board
18172 +        * Schematics Figure 5, Sheet 5 of 12
18173 +        *
18174 +        * See switches S8 and S7. Notice their
18175 +        * relationship to signals SW7 and SW8. Hmmm.
18176 +        */
18177 +
18178 +       switch (irq) {
18179 +
18180 +       case 4:
18181 +
18182 +               SWITCHES_SET(mask, 8, this);
18183 +               break;
18184 +
18185 +       case 5:
18186 +
18187 +               SWITCHES_SET(mask, 7, this);
18188 +               break;
18189 +
18190 +       default:
18191 +
18192 +               SWITCHES_SET(mask, irq + 3, this);
18193 +
18194 +       }
18195 +
18196 +       states = this ? (states | (1 << irq)) : (states & ~(1 << irq));
18197 +
18198 +}
18199 +#endif  /* CONFIG_SA1100_ASSABET */
18200 +
18201 +
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().
18209 + */
18210 +static void switches_ucb1x00_handler(int irq, void *devid)
18211 +{
18212 +       struct ucb1x00 *ucb = devid;
18213 +       switches_mask_t mask;
18214 +
18215 +       SWITCHES_ZERO(&mask);
18216 +
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.
18221 +        */
18222 +
18223 +#ifdef CONFIG_SA1100_ASSABET
18224 +       if (machine_is_assabet()) {
18225 +               assabet_switches_ucb1x00_handler(ucb, irq, &mask);
18226 +       }
18227 +#endif
18228 +
18229 +       switches_event(&mask);
18230 +}
18231 +
18232 +static int switches_add(struct class_device *dev)
18233 +{
18234 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
18235 +       int ret = -ENODEV;
18236 +
18237 +#ifdef CONFIG_SA1100_ASSABET
18238 +       if (machine_is_assabet()) {
18239 +               ret = assabet_switches_ucb1x00_init(ucb);
18240 +       }
18241 +#endif
18242 +       /* Porting note: call a board-specific init routine here. */
18243 +
18244 +       return ret;
18245 +}
18246 +
18247 +static void switches_remove(struct class_device *dev)
18248 +{
18249 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
18250 +
18251 +       /* Porting note: call a board-specific shutdown routine here. */
18252 +
18253 +#ifdef CONFIG_SA1100_ASSABET
18254 +       if (machine_is_assabet()) {
18255 +               assabet_switches_ucb1x00_shutdown(ucb);
18256 +       }
18257 +#endif
18258 +}
18259 +
18260 +static struct class_interface ucb1x00_switches_interface = {
18261 +       .add    = switches_add,
18262 +       .remove = switches_remove,
18263 +};
18264 +
18265 +static int __init switches_ucb1x00_init(void)
18266 +{
18267 +       return ucb1x00_register_interface(&ucb1x00_switches_interface);
18268 +}
18269 +
18270 +static void __exit switches_ucb1x00_exit(void)
18271 +{
18272 +       ucb1x00_unregister_interface(&ucb1x00_switches_interface);
18273 +}
18274 +
18275 +module_init(switches_ucb1x00_init);
18276 +module_exit(switches_ucb1x00_exit);
18277 +
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
18282 @@ -0,0 +1,200 @@
18283 +/*
18284 + *  linux/drivers/misc/switches-core.c
18285 + *
18286 + *  Copyright (C) 2000-2001 John Dorsey
18287 + *
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.
18291 + *
18292 + *  5 October 2000 - created.
18293 + *
18294 + *  25 October 2000 - userland file interface added.
18295 + *
18296 + *  13 January 2001 - added support for Spot.
18297 + *
18298 + *  11 September 2001 - UCB1200 driver framework support added.
18299 + *
18300 + *  19 December 2001 - separated out SA-1100 and UCB1x00 code.
18301 + */
18302 +
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>
18314 +
18315 +#include <asm/uaccess.h>
18316 +
18317 +#include "switches.h"
18318 +
18319 +
18320 +MODULE_AUTHOR("John Dorsey");
18321 +MODULE_DESCRIPTION("Console switch support");
18322 +MODULE_LICENSE("GPL");
18323 +
18324 +
18325 +struct switches_action {
18326 +       struct list_head list;
18327 +       switches_mask_t  mask;
18328 +};
18329 +
18330 +
18331 +static int switches_users = 0;
18332 +
18333 +static spinlock_t switches_lock = SPIN_LOCK_UNLOCKED;
18334 +
18335 +DECLARE_WAIT_QUEUE_HEAD(switches_wait);
18336 +LIST_HEAD(switches_event_queue);
18337 +
18338 +
18339 +static ssize_t switches_read(struct file *file, char *buffer,
18340 +                            size_t count, loff_t *pos)
18341 +{
18342 +       unsigned long flags;
18343 +       struct list_head *event;
18344 +       struct switches_action *action;
18345 +
18346 +       if (count < sizeof(struct switches_mask_t))
18347 +               return -EINVAL;
18348 +
18349 +       while (list_empty(&switches_event_queue)) {
18350 +
18351 +               if (file->f_flags & O_NDELAY)
18352 +                       return -EAGAIN;
18353 +
18354 +               interruptible_sleep_on(&switches_wait);
18355 +
18356 +               if (signal_pending(current))
18357 +                       return -ERESTARTSYS;
18358 +
18359 +       }
18360 +
18361 +       if (verify_area(VERIFY_WRITE, buffer, sizeof(struct switches_mask_t)))
18362 +               return -EFAULT;
18363 +
18364 +       spin_lock_irqsave(&switches_lock, flags);
18365 +
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));
18369 +       list_del(event);
18370 +       kfree(action);
18371 +
18372 +       spin_unlock_irqrestore(&switches_lock, flags);
18373 +
18374 +       return 0;
18375 +
18376 +}
18377 +
18378 +static ssize_t switches_write(struct file *file, const char *buffer,
18379 +                             size_t count, loff_t *ppos)
18380 +{
18381 +       return -EINVAL;
18382 +}
18383 +
18384 +static unsigned int switches_poll(struct file *file, poll_table *wait)
18385 +{
18386 +
18387 +       poll_wait(file, &switches_wait, wait);
18388 +
18389 +       if (!list_empty(&switches_event_queue))
18390 +               return POLLIN | POLLRDNORM;
18391 +
18392 +       return 0;
18393 +
18394 +}
18395 +
18396 +static int switches_open(struct inode *inode, struct file *file)
18397 +{
18398 +
18399 +       if (switches_users > 0)
18400 +               return -EBUSY;
18401 +
18402 +       ++switches_users;
18403 +       return 0;
18404 +
18405 +}
18406 +
18407 +static int switches_release(struct inode *inode, struct file *file)
18408 +{
18409 +
18410 +       --switches_users;
18411 +       return 0;
18412 +
18413 +}
18414 +
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,
18422 +};
18423 +
18424 +static struct miscdevice switches_misc = {
18425 +       .minor          = MISC_DYNAMIC_MINOR,
18426 +       .name           = SWITCHES_NAME,
18427 +       .fops           = &switches_ops,
18428 +};
18429 +
18430 +int switches_event(switches_mask_t *mask)
18431 +{
18432 +       struct switches_action *action;
18433 +
18434 +       if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) {
18435 +
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);
18441 +                       return -1;
18442 +               }
18443 +
18444 +               action->mask = *mask;
18445 +
18446 +               spin_lock(&switches_lock);
18447 +               list_add_tail(&action->list, &switches_event_queue);
18448 +               spin_unlock(&switches_lock);
18449 +
18450 +               wake_up_interruptible(&switches_wait);
18451 +
18452 +       }
18453 +
18454 +       return 0;
18455 +
18456 +}
18457 +
18458 +EXPORT_SYMBOL(switches_event);
18459 +
18460 +
18461 +static int __init switches_init(void)
18462 +{
18463 +       if (misc_register(&switches_misc) < 0) {
18464 +               printk(KERN_ERR "%s: unable to register misc device\n",
18465 +                      SWITCHES_NAME);
18466 +               return -EIO;
18467 +       }
18468 +
18469 +       printk(KERN_INFO "Console switches initialized\n");
18470 +
18471 +       return 0;
18472 +}
18473 +
18474 +static void __exit switches_exit(void)
18475 +{
18476 +       if (misc_deregister(&switches_misc) < 0)
18477 +               printk(KERN_ERR "%s: unable to deregister misc device\n",
18478 +                      SWITCHES_NAME);
18479 +}
18480 +
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
18485 @@ -0,0 +1,439 @@
18486 +/*
18487 + *  linux/drivers/misc/ucb1x00-audio.c
18488 + *
18489 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
18490 + *
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.
18494 + */
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>
18504 +
18505 +#include <asm/dma.h>
18506 +#include <asm/hardware.h>
18507 +#include <asm/semaphore.h>
18508 +#include <asm/uaccess.h>
18509 +
18510 +#include "ucb1x00.h"
18511 +
18512 +#include "../sound/oss/sa1100-audio.h"
18513 +
18514 +#define MAGIC  0x41544154
18515 +
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;
18524 +       int                     dev_id;
18525 +       int                     mix_id;
18526 +       unsigned int            daa_oh_bit;
18527 +       unsigned int            telecom;
18528 +       unsigned int            magic;
18529 +       unsigned int            ctrl_a;
18530 +       unsigned int            ctrl_b;
18531 +
18532 +       /* mixer info */
18533 +       unsigned int            mod_cnt;
18534 +       unsigned short          output_level;
18535 +       unsigned short          input_level;
18536 +};
18537 +
18538 +#define REC_MASK       (SOUND_MASK_VOLUME | SOUND_MASK_MIC)
18539 +#define DEV_MASK       REC_MASK
18540 +
18541 +static int
18542 +ucb1x00_mixer_ioctl(struct inode *ino, struct file *filp, uint cmd, ulong arg)
18543 +{
18544 +       struct ucb1x00_audio *ucba;
18545 +       unsigned int val, gain;
18546 +       int ret = 0;
18547 +
18548 +       ucba = list_entry(filp->f_op, struct ucb1x00_audio, mops);
18549 +
18550 +       if (_IOC_TYPE(cmd) != 'M')
18551 +               return -EINVAL;
18552 +
18553 +       if (cmd == SOUND_MIXER_INFO) {
18554 +               struct mixer_info mi;
18555 +
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;
18560 +       }
18561 +
18562 +       if (_IOC_DIR(cmd) & _IOC_WRITE) {
18563 +               unsigned int left, right;
18564 +
18565 +               ret = get_user(val, (unsigned int *)arg);
18566 +               if (ret)
18567 +                       goto out;
18568 +
18569 +               left  = val & 255;
18570 +               right = val >> 8;
18571 +
18572 +               if (left > 100)
18573 +                       left = 100;
18574 +               if (right > 100)
18575 +                       right = 100;
18576 +
18577 +               gain = (left + right) / 2;
18578 +
18579 +               ret = -EINVAL;
18580 +               if (!ucba->telecom) {
18581 +                       switch(_IOC_NR(cmd)) {
18582 +                       case SOUND_MIXER_VOLUME:
18583 +                               ucba->output_level = gain | gain << 8;
18584 +                               ucba->mod_cnt++;
18585 +                               ucba->ctrl_b = (ucba->ctrl_b & 0xff00) |
18586 +                                              ((gain * 31) / 100);
18587 +                               ucb1x00_reg_write(ucba->ucb, UCB_AC_B,
18588 +                                                 ucba->ctrl_b);
18589 +                               ret = 0;
18590 +                               break;
18591 +
18592 +                       case SOUND_MIXER_MIC:
18593 +                               ucba->input_level = gain | gain << 8;
18594 +                               ucba->mod_cnt++;
18595 +                               ucba->ctrl_a = (ucba->ctrl_a & 0x7f) |
18596 +                                              (((gain * 31) / 100) << 7);
18597 +                               ucb1x00_reg_write(ucba->ucb, UCB_AC_A,
18598 +                                                 ucba->ctrl_a);
18599 +                               ret = 0;
18600 +                               break;
18601 +                       }
18602 +               }
18603 +       }
18604 +
18605 +       if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
18606 +               switch (_IOC_NR(cmd)) {
18607 +               case SOUND_MIXER_VOLUME:
18608 +                       val = ucba->output_level;
18609 +                       break;
18610 +
18611 +               case SOUND_MIXER_MIC:
18612 +                       val = ucba->input_level;
18613 +                       break;
18614 +
18615 +               case SOUND_MIXER_RECSRC:
18616 +               case SOUND_MIXER_RECMASK:
18617 +                       val = ucba->telecom ? 0 : REC_MASK;
18618 +                       break;
18619 +
18620 +               case SOUND_MIXER_DEVMASK:
18621 +                       val = ucba->telecom ? 0 : DEV_MASK;
18622 +                       break;
18623 +
18624 +               case SOUND_MIXER_CAPS:
18625 +               case SOUND_MIXER_STEREODEVS:
18626 +                       val = 0;
18627 +                       break;
18628 +
18629 +               default:
18630 +                       val = 0;
18631 +                       ret = -EINVAL;
18632 +                       break;
18633 +               }
18634 +
18635 +               if (ret == 0)
18636 +                       ret = put_user(val, (int *)arg);
18637 +       }
18638 + out:
18639 +       return ret;
18640 +}
18641 +
18642 +static int ucb1x00_audio_setrate(struct ucb1x00_audio *ucba, int rate)
18643 +{
18644 +       unsigned int div_rate = ucb1x00_clkrate(ucba->ucb) / 32;
18645 +       unsigned int div;
18646 +
18647 +       div = (div_rate + (rate / 2)) / rate;
18648 +       if (div < 6)
18649 +               div = 6;
18650 +       if (div > 127)
18651 +               div = 127;
18652 +
18653 +       ucba->ctrl_a = (ucba->ctrl_a & ~0x7f) | div;
18654 +
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);
18660 +       } else {
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);
18665 +       }
18666 +
18667 +       ucba->rate = div_rate / div;
18668 +
18669 +       return ucba->rate;
18670 +}
18671 +
18672 +static int ucb1x00_audio_getrate(struct ucb1x00_audio *ucba)
18673 +{
18674 +       return ucba->rate;
18675 +}
18676 +
18677 +static void ucb1x00_audio_startup(void *data)
18678 +{
18679 +       struct ucb1x00_audio *ucba = data;
18680 +
18681 +       ucb1x00_enable(ucba->ucb);
18682 +       ucb1x00_audio_setrate(ucba, ucba->rate);
18683 +
18684 +       ucb1x00_reg_write(ucba->ucb, UCB_MODE, UCB_MODE_DYN_VFLAG_ENA);
18685 +
18686 +       /*
18687 +        * Take off-hook
18688 +        */
18689 +       if (ucba->daa_oh_bit)
18690 +               ucb1x00_io_write(ucba->ucb, 0, ucba->daa_oh_bit);
18691 +}
18692 +
18693 +static void ucb1x00_audio_shutdown(void *data)
18694 +{
18695 +       struct ucb1x00_audio *ucba = data;
18696 +
18697 +       /*
18698 +        * Place on-hook
18699 +        */
18700 +       if (ucba->daa_oh_bit)
18701 +               ucb1x00_io_write(ucba->ucb, ucba->daa_oh_bit, 0);
18702 +
18703 +       ucb1x00_reg_write(ucba->ucb, ucba->telecom ? UCB_TC_B : UCB_AC_B, 0);
18704 +       ucb1x00_disable(ucba->ucb);
18705 +}
18706 +
18707 +static int
18708 +ucb1x00_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
18709 +{
18710 +       struct ucb1x00_audio *ucba;
18711 +       int val, ret = 0;
18712 +
18713 +       ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
18714 +
18715 +       /*
18716 +        * Make sure we have our magic number
18717 +        */
18718 +       if (ucba->magic != MAGIC)
18719 +               return -ENODEV;
18720 +
18721 +       switch (cmd) {
18722 +       case SNDCTL_DSP_STEREO:
18723 +               ret = get_user(val, (int *)arg);
18724 +               if (ret)
18725 +                       return ret;
18726 +               if (val != 0)
18727 +                       return -EINVAL;
18728 +               val = 0;
18729 +               break;
18730 +
18731 +       case SNDCTL_DSP_CHANNELS:
18732 +       case SOUND_PCM_READ_CHANNELS:
18733 +               val = 1;
18734 +               break;
18735 +
18736 +       case SNDCTL_DSP_SPEED:
18737 +               ret = get_user(val, (int *)arg);
18738 +               if (ret)
18739 +                       return ret;
18740 +               val = ucb1x00_audio_setrate(ucba, val);
18741 +               break;
18742 +
18743 +       case SOUND_PCM_READ_RATE:
18744 +               val = ucb1x00_audio_getrate(ucba);
18745 +               break;
18746 +
18747 +       case SNDCTL_DSP_SETFMT:
18748 +       case SNDCTL_DSP_GETFMTS:
18749 +               val = AFMT_S16_LE;
18750 +               break;
18751 +
18752 +       default:
18753 +               return ucb1x00_mixer_ioctl(inode, file, cmd, arg);
18754 +       }
18755 +
18756 +       return put_user(val, (int *)arg);
18757 +}
18758 +
18759 +static int ucb1x00_audio_open(struct inode *inode, struct file *file)
18760 +{
18761 +       struct ucb1x00_audio *ucba;
18762 +
18763 +       ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
18764 +
18765 +       return sa1100_audio_attach(inode, file, &ucba->state);
18766 +}
18767 +
18768 +static struct ucb1x00_audio *ucb1x00_audio_alloc(struct ucb1x00 *ucb)
18769 +{
18770 +       struct ucb1x00_audio *ucba;
18771 +
18772 +       ucba = kmalloc(sizeof(*ucba), GFP_KERNEL);
18773 +       if (ucba) {
18774 +               memset(ucba, 0, sizeof(*ucba));
18775 +
18776 +               ucba->magic = MAGIC;
18777 +               ucba->ucb = ucb;
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;
18788 +
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.
18793 +                */
18794 +               ucba->state.need_tx_for_rx = 1;
18795 +
18796 +               init_MUTEX(&ucba->state.sem);
18797 +               ucba->rate = 8000;
18798 +       }
18799 +       return ucba;
18800 +}
18801 +
18802 +static struct ucb1x00_audio *ucb1x00_audio_add_one(struct ucb1x00 *ucb, int telecom)
18803 +{
18804 +       struct ucb1x00_audio *a;
18805 +
18806 +       a = ucb1x00_audio_alloc(ucb);
18807 +       if (a) {
18808 +               a->telecom = telecom;
18809 +
18810 +               a->input_stream.dev = ucb->cdev.dev;
18811 +               a->output_stream.dev = ucb->cdev.dev;
18812 +               a->ctrl_a = 0;
18813 +
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;
18820 +#if 0
18821 +                       a->daa_oh_bit = UCB_IO_8;
18822 +
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);
18827 +#endif
18828 +               } else {
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;
18834 +               }
18835 +
18836 +               a->dev_id = register_sound_dsp(&a->fops, -1);
18837 +               a->mix_id = register_sound_mixer(&a->mops, -1);
18838 +
18839 +               printk("Sound: UCB1x00 %s: dsp id %d mixer id %d\n",
18840 +                       a->telecom ? "telecom" : "audio",
18841 +                       a->dev_id, a->mix_id);
18842 +       }
18843 +
18844 +       return a;
18845 +}
18846 +
18847 +static void ucb1x00_audio_remove_one(struct ucb1x00_audio *a)
18848 +{
18849 +       unregister_sound_dsp(a->dev_id);
18850 +       unregister_sound_mixer(a->mix_id);
18851 +       kfree(a);
18852 +}
18853 +
18854 +static int ucb1x00_audio_add(struct class_device *cdev)
18855 +{
18856 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev);
18857 +
18858 +       if (ucb->cdev.dev == NULL || ucb->cdev.dev->dma_mask == NULL)
18859 +               return -ENXIO;
18860 +
18861 +       ucb->audio_data = ucb1x00_audio_add_one(ucb, 0);
18862 +       ucb->telecom_data = ucb1x00_audio_add_one(ucb, 1);
18863 +
18864 +       return 0;
18865 +}
18866 +
18867 +static void ucb1x00_audio_remove(struct class_device *cdev)
18868 +{
18869 +       struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev);
18870 +
18871 +       ucb1x00_audio_remove_one(ucb->audio_data);
18872 +       ucb1x00_audio_remove_one(ucb->telecom_data);
18873 +}
18874 +
18875 +#if 0 //def CONFIG_PM
18876 +static int ucb1x00_audio_suspend(struct ucb1x00 *ucb, u32 state)
18877 +{
18878 +       struct ucb1x00_audio *a;
18879 +
18880 +       a = ucb->audio_data;
18881 +       sa1100_audio_suspend(&a->state, state);
18882 +       a = ucb->telecom_data;
18883 +       sa1100_audio_suspend(&a->state, state);
18884 +
18885 +       return 0;
18886 +}
18887 +
18888 +static int ucb1x00_audio_resume(struct ucb1x00 *ucb)
18889 +{
18890 +       struct ucb1x00_audio *a;
18891 +
18892 +       a = ucb->audio_data;
18893 +       sa1100_audio_resume(&a->state);
18894 +       a = ucb->telecom_data;
18895 +       sa1100_audio_resume(&a->state);
18896 +
18897 +       return 0;
18898 +}
18899 +#else
18900 +#define ucb1x00_audio_suspend  NULL
18901 +#define ucb1x00_audio_resume   NULL
18902 +#endif
18903 +
18904 +static struct class_interface ucb1x00_audio_interface = {
18905 +       .add            = ucb1x00_audio_add,
18906 +       .remove         = ucb1x00_audio_remove,
18907 +};
18908 +
18909 +static int __init ucb1x00_audio_init(void)
18910 +{
18911 +       return ucb1x00_register_interface(&ucb1x00_audio_interface);
18912 +}
18913 +
18914 +static void __exit ucb1x00_audio_exit(void)
18915 +{
18916 +       ucb1x00_unregister_interface(&ucb1x00_audio_interface);
18917 +}
18918 +
18919 +module_init(ucb1x00_audio_init);
18920 +module_exit(ucb1x00_audio_exit);
18921 +
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
18927 @@ -0,0 +1,275 @@
18928 +/*
18929 + *  linux/drivers/misc/mcp-sa1100.c
18930 + *
18931 + *  Copyright (C) 2001 Russell King
18932 + *
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.
18936 + *
18937 + *  SA1100 MCP (Multimedia Communications Port) driver.
18938 + *
18939 + *  MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
18940 + */
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>
18949 +
18950 +#include <asm/dma.h>
18951 +#include <asm/hardware.h>
18952 +#include <asm/mach-types.h>
18953 +#include <asm/system.h>
18954 +
18955 +#include <asm/arch/assabet.h>
18956 +
18957 +#include "mcp.h"
18958 +
18959 +static void
18960 +mcp_sa1100_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
18961 +{
18962 +       unsigned int mccr0;
18963 +
18964 +       divisor /= 32;
18965 +
18966 +       mccr0 = Ser4MCCR0 & ~0x00007f00;
18967 +       mccr0 |= divisor << 8;
18968 +       Ser4MCCR0 = mccr0;
18969 +}
18970 +
18971 +static void
18972 +mcp_sa1100_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
18973 +{
18974 +       unsigned int mccr0;
18975 +
18976 +       divisor /= 32;
18977 +
18978 +       mccr0 = Ser4MCCR0 & ~0x0000007f;
18979 +       mccr0 |= divisor;
18980 +       Ser4MCCR0 = mccr0;
18981 +}
18982 +
18983 +/*
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
18987 + * wait.
18988 + */
18989 +static void
18990 +mcp_sa1100_write(struct mcp *mcp, unsigned int reg, unsigned int val)
18991 +{
18992 +       int ret = -ETIME;
18993 +       int i;
18994 +
18995 +       Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
18996 +
18997 +       for (i = 0; i < 2; i++) {
18998 +               udelay(mcp->rw_timeout);
18999 +               if (Ser4MCSR & MCSR_CWC) {
19000 +                       ret = 0;
19001 +                       break;
19002 +               }
19003 +       }
19004 +
19005 +       if (ret < 0)
19006 +               printk(KERN_WARNING "mcp: write timed out\n");
19007 +}
19008 +
19009 +/*
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
19013 + * wait.
19014 + */
19015 +static unsigned int
19016 +mcp_sa1100_read(struct mcp *mcp, unsigned int reg)
19017 +{
19018 +       int ret = -ETIME;
19019 +       int i;
19020 +
19021 +       Ser4MCDR2 = reg << 17 | MCDR2_Rd;
19022 +
19023 +       for (i = 0; i < 2; i++) {
19024 +               udelay(mcp->rw_timeout);
19025 +               if (Ser4MCSR & MCSR_CRC) {
19026 +                       ret = Ser4MCDR2 & 0xffff;
19027 +                       break;
19028 +               }
19029 +       }
19030 +
19031 +       if (ret < 0)
19032 +               printk(KERN_WARNING "mcp: read timed out\n");
19033 +
19034 +       return ret;
19035 +}
19036 +
19037 +static void mcp_sa1100_enable(struct mcp *mcp)
19038 +{
19039 +       Ser4MCSR = -1;
19040 +       Ser4MCCR0 |= MCCR0_MCE;
19041 +}
19042 +
19043 +static void mcp_sa1100_disable(struct mcp *mcp)
19044 +{
19045 +       Ser4MCCR0 &= ~MCCR0_MCE;
19046 +}
19047 +
19048 +/*
19049 + * Our methods.
19050 + */
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,
19065 +};
19066 +
19067 +static int mcp_sa1100_probe(struct device *dev)
19068 +{
19069 +       struct platform_device *pdev = to_platform_device(dev);
19070 +       struct mcp *mcp = &mcp_sa1100;
19071 +       int ret;
19072 +
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())
19080 +               return -ENODEV;
19081 +
19082 +       if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
19083 +               return -EBUSY;
19084 +
19085 +       mcp->me = dev;
19086 +       dev_set_drvdata(dev, mcp);
19087 +
19088 +       if (machine_is_assabet()) {
19089 +               ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
19090 +       }
19091 +
19092 +       /*
19093 +        * Setup the PPC unit correctly.
19094 +        */
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);
19100 +
19101 +       Ser4MCSR = -1;
19102 +       Ser4MCCR1 = 0;
19103 +       Ser4MCCR0 = 0x00007f7f | MCCR0_ADM;
19104 +
19105 +       /*
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.
19109 +        */
19110 +       mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
19111 +                         mcp->sclk_rate;
19112 +
19113 +       ret = mcp_host_register(mcp, &pdev->dev);
19114 +       if (ret != 0) {
19115 +               release_mem_region(0x80060000, 0x60);
19116 +               dev_set_drvdata(dev, NULL);
19117 +       }
19118 +
19119 +       return ret;
19120 +}
19121 +
19122 +static int mcp_sa1100_remove(struct device *dev)
19123 +{
19124 +       struct mcp *mcp = dev_get_drvdata(dev);
19125 +
19126 +       dev_set_drvdata(dev, NULL);
19127 +
19128 +       mcp_host_unregister(mcp);
19129 +       release_mem_region(0x80060000, 0x60);
19130 +
19131 +       return 0;
19132 +}
19133 +
19134 +struct mcp_sa1100_state {
19135 +       u32     mccr0;
19136 +       u32     mccr1;
19137 +};
19138 +
19139 +static int mcp_sa1100_suspend(struct device *dev, u32 state, u32 level)
19140 +{
19141 +       struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state;
19142 +
19143 +       if (!s) {
19144 +               s = kmalloc(sizeof(struct mcp_sa1100_state), GFP_KERNEL);
19145 +               dev->saved_state = (unsigned char *)s;
19146 +       }
19147 +
19148 +       if (s) {
19149 +               s->mccr0 = Ser4MCCR0;
19150 +               s->mccr1 = Ser4MCCR1;
19151 +       }
19152 +
19153 +       if (level == SUSPEND_DISABLE)
19154 +               Ser4MCCR0 &= ~MCCR0_MCE;
19155 +       return 0;
19156 +}
19157 +
19158 +static int mcp_sa1100_resume(struct device *dev, u32 level)
19159 +{
19160 +       struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state;
19161 +
19162 +       if (s && level == RESUME_RESTORE_STATE) {
19163 +               Ser4MCCR1 = s->mccr1;
19164 +               Ser4MCCR0 = s->mccr0;
19165 +
19166 +               dev->saved_state = NULL;
19167 +               kfree(s);
19168 +       }
19169 +       return 0;
19170 +}
19171 +
19172 +/*
19173 + * The driver for the SA11x0 MCP port.
19174 + */
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,
19182 +};
19183 +
19184 +/*
19185 + * This needs re-working
19186 + */
19187 +static int __init mcp_sa1100_init(void)
19188 +{
19189 +       return driver_register(&mcp_sa1100_driver);
19190 +}
19191 +
19192 +static void __exit mcp_sa1100_exit(void)
19193 +{
19194 +       driver_unregister(&mcp_sa1100_driver);
19195 +}
19196 +
19197 +module_init(mcp_sa1100_init);
19198 +module_exit(mcp_sa1100_exit);
19199 +
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
19205 @@ -0,0 +1,58 @@
19206 +/*
19207 + *  linux/drivers/misc/mcp.h
19208 + *
19209 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
19210 + *
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.
19214 + */
19215 +#ifndef MCP_H
19216 +#define MCP_H
19217 +
19218 +struct mcp {
19219 +       struct module   *owner;
19220 +       struct device   *me;
19221 +       spinlock_t      lock;
19222 +       int             use_count;
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;
19236 +};
19237 +
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)
19245 +
19246 +int mcp_host_register(struct mcp *, struct device *);
19247 +void mcp_host_unregister(struct mcp *);
19248 +
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 *);
19255 +};
19256 +
19257 +int mcp_driver_register(struct mcp_driver *);
19258 +void mcp_driver_unregister(struct mcp_driver *);
19259 +
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)
19262 +
19263 +#endif
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
19266 @@ -0,0 +1,233 @@
19267 +/*
19268 + *  linux/drivers/misc/ucb1x00.h
19269 + *
19270 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
19271 + *
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.
19275 + */
19276 +#ifndef UCB1200_H
19277 +#define UCB1200_H
19278 +
19279 +#define UCB_IO_DATA    0x00
19280 +#define UCB_IO_DIR     0x01
19281 +
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)
19292 +
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)
19302 +
19303 +#define UCB_IRQ_TSPX           12
19304 +
19305 +#define UCB_TC_A       0x05
19306 +#define UCB_TC_A_LOOP          (1 << 7)        /* UCB1200 */
19307 +#define UCB_TC_A_AMPL          (1 << 7)        /* UCB1300 */
19308 +
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)
19317 +
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)
19324 +
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)
19340 +
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)
19355 +
19356 +#define UCB_ADC_DATA   0x0b
19357 +#define UCB_ADC_DAT_VAL                (1 << 15)
19358 +#define UCB_ADC_DAT(x)         (((x) & 0x7fe0) >> 5)
19359 +
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 */
19365 +
19366 +#define UCB_MODE       0x0d
19367 +#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
19368 +#define UCB_MODE_AUD_OFF_CAN   (1 << 13)
19369 +
19370 +#include "mcp.h"
19371 +
19372 +struct ucb1x00;
19373 +
19374 +struct ucb1x00_irq {
19375 +       void *devid;
19376 +       void (*fn)(int, void *);
19377 +};
19378 +
19379 +struct ucb1x00 {
19380 +       spinlock_t              lock;
19381 +       struct mcp              *mcp;
19382 +       unsigned int            irq;
19383 +       struct semaphore        adc_sem;
19384 +       spinlock_t              io_lock;
19385 +       u16                     id;
19386 +       u16                     io_dir;
19387 +       u16                     io_out;
19388 +       u16                     adc_cr;
19389 +       u16                     irq_fal_enbl;
19390 +       u16                     irq_ris_enbl;
19391 +       struct ucb1x00_irq      irq_handler[16];
19392 +};
19393 +
19394 +/**
19395 + *     ucb1x00_clkrate - return the UCB1x00 SIB clock rate
19396 + *     @ucb: UCB1x00 structure describing chip
19397 + *
19398 + *     Return the SIB clock rate in Hz.
19399 + */
19400 +static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
19401 +{
19402 +       return mcp_get_sclk_rate(ucb->mcp);
19403 +}
19404 +
19405 +/**
19406 + *     ucb1x00_enable - enable the UCB1x00 SIB clock
19407 + *     @ucb: UCB1x00 structure describing chip
19408 + *
19409 + *     Enable the SIB clock.  This can be called multiple times.
19410 + */
19411 +static inline void ucb1x00_enable(struct ucb1x00 *ucb)
19412 +{
19413 +       mcp_enable(ucb->mcp);
19414 +}
19415 +
19416 +/**
19417 + *     ucb1x00_disable - disable the UCB1x00 SIB clock
19418 + *     @ucb: UCB1x00 structure describing chip
19419 + *
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.
19423 + */
19424 +static inline void ucb1x00_disable(struct ucb1x00 *ucb)
19425 +{
19426 +       mcp_disable(ucb->mcp);
19427 +}
19428 +
19429 +/**
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
19434 + *
19435 + *     Write the UCB1x00 register @reg with value @val.  The SIB
19436 + *     clock must be running for this function to return.
19437 + */
19438 +static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
19439 +{
19440 +       mcp_reg_write(ucb->mcp, reg, val);
19441 +}
19442 +
19443 +/**
19444 + *     ucb1x00_reg_read - read a UCB1x00 register
19445 + *     @ucb: UCB1x00 structure describing chip
19446 + *     @reg: UCB1x00 4-bit register index to write
19447 + *
19448 + *     Read the UCB1x00 register @reg and return its value.  The SIB
19449 + *     clock must be running for this function to return.
19450 + */
19451 +static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
19452 +{
19453 +       return mcp_reg_read(ucb->mcp, reg);
19454 +}
19455 +/**
19456 + *     ucb1x00_set_audio_divisor - 
19457 + *     @ucb: UCB1x00 structure describing chip
19458 + *     @div: SIB clock divisor
19459 + */
19460 +static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
19461 +{
19462 +       mcp_set_audio_divisor(ucb->mcp, div);
19463 +}
19464 +
19465 +/**
19466 + *     ucb1x00_set_telecom_divisor -
19467 + *     @ucb: UCB1x00 structure describing chip
19468 + *     @div: SIB clock divisor
19469 + */
19470 +static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
19471 +{
19472 +       mcp_set_telecom_divisor(ucb->mcp, div);
19473 +}
19474 +
19475 +struct ucb1x00 *ucb1x00_get(void);
19476 +
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);
19480 +
19481 +#define UCB_NOSYNC     (0)
19482 +#define UCB_SYNC       (1)
19483 +
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);
19487 +
19488 +/*
19489 + * Which edges of the IRQ do you want to control today?
19490 + */
19491 +#define UCB_RISING     (1 << 0)
19492 +#define UCB_FALLING    (1 << 1)
19493 +
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);
19498 +
19499 +#endif
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
19502 @@ -0,0 +1,271 @@
19503 +/*
19504 + *  linux/drivers/misc/ucb1x00.h
19505 + *
19506 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
19507 + *
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.
19511 + */
19512 +#ifndef UCB1200_H
19513 +#define UCB1200_H
19514 +
19515 +#ifdef CONFIG_ARCH_PXA
19516 +
19517 +/* ucb1400 aclink register mappings: */
19518 +
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) */
19529 +
19530 +#define UCB_ADC_DAT(x)         ((x) & 0x3ff)
19531 +
19532 +#else
19533 +
19534 +/* ucb1x00 SIB register mappings: */
19535 +
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
19551 +
19552 +#define UCB_ADC_DAT(x)         (((x) & 0x7fe0) >> 5)
19553 +
19554 +#endif
19555 +
19556 +
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)
19567 +
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)
19573 +
19574 +#define UCB_IRQ_TSPX           12
19575 +
19576 +#define UCB_TC_A_LOOP          (1 << 7)        /* UCB1200 */
19577 +#define UCB_TC_A_AMPL          (1 << 7)        /* UCB1300 */
19578 +
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)
19586 +
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)
19591 +
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)
19606 +
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)
19620 +
19621 +#define UCB_ADC_DAT_VAL                (1 << 15)
19622 +
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 */
19627 +
19628 +#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
19629 +#define UCB_MODE_AUD_OFF_CAN   (1 << 13)
19630 +
19631 +#include <linux/completion.h>
19632 +#include "mcp.h"
19633 +
19634 +struct ucb1x00_irq {
19635 +       void *devid;
19636 +       void (*fn)(int, void *);
19637 +};
19638 +
19639 +extern struct class ucb1x00_class;
19640 +
19641 +struct ucb1x00 {
19642 +       spinlock_t              lock;
19643 +       struct mcp              *mcp;
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;
19650 +       u16                     id;
19651 +       u16                     io_dir;
19652 +       u16                     io_out;
19653 +       u16                     adc_cr;
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;
19660 +       void                    *ts_data;
19661 +};
19662 +
19663 +#define classdev_to_ucb1x00(cd)        container_of(cd, struct ucb1x00, cdev)
19664 +
19665 +int ucb1x00_register_interface(struct class_interface *intf);
19666 +void ucb1x00_unregister_interface(struct class_interface *intf);
19667 +
19668 +/**
19669 + *     ucb1x00_clkrate - return the UCB1x00 SIB clock rate
19670 + *     @ucb: UCB1x00 structure describing chip
19671 + *
19672 + *     Return the SIB clock rate in Hz.
19673 + */
19674 +static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
19675 +{
19676 +       return mcp_get_sclk_rate(ucb->mcp);
19677 +}
19678 +
19679 +/**
19680 + *     ucb1x00_enable - enable the UCB1x00 SIB clock
19681 + *     @ucb: UCB1x00 structure describing chip
19682 + *
19683 + *     Enable the SIB clock.  This can be called multiple times.
19684 + */
19685 +static inline void ucb1x00_enable(struct ucb1x00 *ucb)
19686 +{
19687 +       mcp_enable(ucb->mcp);
19688 +}
19689 +
19690 +/**
19691 + *     ucb1x00_disable - disable the UCB1x00 SIB clock
19692 + *     @ucb: UCB1x00 structure describing chip
19693 + *
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.
19697 + */
19698 +static inline void ucb1x00_disable(struct ucb1x00 *ucb)
19699 +{
19700 +       mcp_disable(ucb->mcp);
19701 +}
19702 +
19703 +/**
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
19708 + *
19709 + *     Write the UCB1x00 register @reg with value @val.  The SIB
19710 + *     clock must be running for this function to return.
19711 + */
19712 +static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
19713 +{
19714 +       mcp_reg_write(ucb->mcp, reg, val);
19715 +}
19716 +
19717 +/**
19718 + *     ucb1x00_reg_read - read a UCB1x00 register
19719 + *     @ucb: UCB1x00 structure describing chip
19720 + *     @reg: UCB1x00 4-bit register index to write
19721 + *
19722 + *     Read the UCB1x00 register @reg and return its value.  The SIB
19723 + *     clock must be running for this function to return.
19724 + */
19725 +static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
19726 +{
19727 +       return mcp_reg_read(ucb->mcp, reg);
19728 +}
19729 +/**
19730 + *     ucb1x00_set_audio_divisor - 
19731 + *     @ucb: UCB1x00 structure describing chip
19732 + *     @div: SIB clock divisor
19733 + */
19734 +static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
19735 +{
19736 +       mcp_set_audio_divisor(ucb->mcp, div);
19737 +}
19738 +
19739 +/**
19740 + *     ucb1x00_set_telecom_divisor -
19741 + *     @ucb: UCB1x00 structure describing chip
19742 + *     @div: SIB clock divisor
19743 + */
19744 +static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
19745 +{
19746 +       mcp_set_telecom_divisor(ucb->mcp, div);
19747 +}
19748 +
19749 +#define ucb1x00_get()  NULL
19750 +
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);
19754 +
19755 +#define UCB_NOSYNC     (0)
19756 +#define UCB_SYNC       (1)
19757 +
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);
19761 +
19762 +/*
19763 + * Which edges of the IRQ do you want to control today?
19764 + */
19765 +#define UCB_RISING     (1 << 0)
19766 +#define UCB_FALLING    (1 << 1)
19767 +
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);
19772 +
19773 +#endif
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
19776 @@ -0,0 +1,323 @@
19777 +/*
19778 + *  linux/drivers/misc/switches-sa1100.c
19779 + *
19780 + *  Copyright (C) 2001 John Dorsey
19781 + *
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.
19785 + *
19786 + *  19 December 2001 - created from sa1100_switches.c.
19787 + */
19788 +
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>
19796 +
19797 +#include <asm/hardware.h>
19798 +#include <asm/mach-types.h>
19799 +#include <asm/irq.h>
19800 +
19801 +#include <asm/arch/assabet.h>
19802 +#include <asm/arch/neponset.h>
19803 +#include <asm/arch/badge4.h>
19804 +
19805 +#include "switches.h"
19806 +
19807 +
19808 +static irqreturn_t switches_sa1100_handler(int irq, void *dev_id,
19809 +                                          struct pt_regs *regs);
19810 +
19811 +
19812 +#ifdef CONFIG_SA1100_ASSABET
19813 +
19814 +/* Assabet
19815 + * ^^^^^^^
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.
19819 + */
19820 +
19821 +static int assabet_switches_sa1100_init(void)
19822 +{
19823 +
19824 +       if (machine_has_neponset())
19825 +               NCR_0 |= NCR_GP01_OFF;
19826 +
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",
19830 +                      SWITCHES_NAME);
19831 +               return -EIO;
19832 +       }
19833 +
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",
19837 +                      SWITCHES_NAME);
19838 +               free_irq(IRQ_GPIO0, NULL);
19839 +               return -EIO;
19840 +       }
19841 +
19842 +       set_irq_type(IRQ_GPIO0, IRQT_BOTHEDGE);
19843 +       set_irq_type(IRQ_GPIO1, IRQT_BOTHEDGE);
19844 +
19845 +       return 0;
19846 +
19847 +}
19848 +
19849 +static void assabet_switches_sa1100_shutdown(void)
19850 +{
19851 +
19852 +       free_irq(IRQ_GPIO1, NULL);
19853 +       free_irq(IRQ_GPIO0, NULL);
19854 +
19855 +}
19856 +
19857 +static irqreturn_t assabet_switches_sa1100_handler(int irq, switches_mask_t *mask)
19858 +{
19859 +       unsigned int s, last, this;
19860 +       static unsigned int states = 0;
19861 +
19862 +       switch (irq) {
19863 +
19864 +       case IRQ_GPIO0: s = 0; break;
19865 +
19866 +       case IRQ_GPIO1: s = 1; break;
19867 +
19868 +       default:        return IRQ_NONE;
19869 +
19870 +       }
19871 +
19872 +       last = ((states & (1 << s)) != 0);
19873 +       this = ((GPLR & GPIO_GPIO(s)) != 0);
19874 +
19875 +       if (last == this) /* debounce */
19876 +               return IRQ_HANDLED;
19877 +
19878 +       SWITCHES_SET(mask, s + 1, this);
19879 +
19880 +       states = this ? (states | (1 << s)) : (states & ~(1 << s));
19881 +
19882 +       return IRQ_HANDLED;
19883 +}
19884 +#endif  /* CONFIG_SA1100_ASSABET */
19885 +
19886 +#ifdef CONFIG_SA1100_BADGE4
19887 +
19888 +/* BadgePAD 4
19889 + * ^^^^^^^^^^
19890 + *
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.
19893 + */
19894 +
19895 +#define BADGE4_SW0_GPIO GPIO_GPIO23    /* aka BADGE4_GPIO_TESTPT_J6  */
19896 +#define BADGE4_SW0_IRQ  IRQ_GPIO23
19897 +
19898 +static int badge4_switches_sa1100_init(void)
19899 +{
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",
19903 +                      SWITCHES_NAME);
19904 +               return -EIO;
19905 +       }
19906 +
19907 +       set_irq_type(BADGE4_SW0_IRQ, IRQT_BOTHEDGE);
19908 +
19909 +       return 0;
19910 +}
19911 +
19912 +static void badge4_switches_sa1100_shutdown(void)
19913 +{
19914 +       free_irq(BADGE4_SW0_IRQ, NULL);
19915 +}
19916 +
19917 +static irqreturn_t badge4_switches_sa1100_handler(int irq, switches_mask_t *mask)
19918 +{
19919 +       unsigned int swno, last, this, gpio;
19920 +       static unsigned int states = 0;
19921 +
19922 +       switch (irq) {
19923 +       case BADGE4_SW0_IRQ:
19924 +               swno = 0;
19925 +               gpio = BADGE4_SW0_GPIO;
19926 +               break;
19927 +       default:
19928 +               return IRQ_NONE;
19929 +       }
19930 +
19931 +       last = ((states & gpio) != 0);
19932 +       this = ((GPLR & gpio) != 0);
19933 +
19934 +       if (last == this) /* debounce */
19935 +               return IRQ_HANDLED;
19936 +
19937 +       SWITCHES_SET(mask, swno, this);
19938 +
19939 +       states = this ? (states | gpio) : (states & ~gpio);
19940 +
19941 +       return IRQ_HANDLED;
19942 +}
19943 +#endif /* CONFIG_SA1100_BADGE4 */
19944 +
19945 +
19946 +#ifdef CONFIG_SA1100_SPOT
19947 +
19948 +/* Spot
19949 + * ^^^^
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
19952 + * userland.
19953 + */
19954 +
19955 +static int spot_switches_sa1100_init(void)
19956 +{
19957 +
19958 +       set_GPIO_IRQ_edge(GPIO_SW1, GPIO_BOTH_EDGES);
19959 +
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",
19963 +                      SWITCHES_NAME);
19964 +               return -EIO;
19965 +       }
19966 +
19967 +       return 0;
19968 +
19969 +}
19970 +
19971 +static void spot_switches_sa1100_shutdown(void)
19972 +{
19973 +
19974 +       free_irq(IRQ_GPIO_SW1, NULL);
19975 +
19976 +}
19977 +
19978 +static irqreturn_t spot_switches_sa1100_handler(int irq, switches_mask_t *mask)
19979 +{
19980 +       unsigned int s, last, this;
19981 +       static unsigned int states = 0;
19982 +
19983 +       switch (irq) {
19984 +
19985 +       case IRQ_GPIO_SW1:      s = 0; break;
19986 +
19987 +       default:                return IRQ_NONE;
19988 +
19989 +       }
19990 +
19991 +       last = ((states & (1 << s)) != 0);
19992 +       this = ((GPLR & GPIO_GPIO(s)) != 0);
19993 +
19994 +       if (last == this) /* debounce */
19995 +               return IRQ_HANDLED;
19996 +
19997 +       SWITCHES_SET(mask, s + 1, this);
19998 +
19999 +       states = this ? (states | (1 << s)) : (states & ~(1 << s));
20000 +
20001 +       return IRQ_HANDLED;
20002 +
20003 +}
20004 +#endif  /* CONFIG_SA1100_SPOT */
20005 +
20006 +
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().
20014 + */
20015 +static irqreturn_t switches_sa1100_handler(int irq, void *dev_id,
20016 +                                          struct pt_regs *regs)
20017 +{
20018 +       switches_mask_t mask;
20019 +       irqreturn_t ret = IRQ_NONE;
20020 +
20021 +       SWITCHES_ZERO(&mask);
20022 +
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.
20027 +        */
20028 +
20029 +       if (machine_is_assabet()) {
20030 +#ifdef CONFIG_SA1100_ASSABET
20031 +               ret = assabet_switches_sa1100_handler(irq, &mask);
20032 +#endif
20033 +       } else if (machine_is_badge4()) {
20034 +#ifdef CONFIG_SA1100_BADGE4
20035 +               ret = badge4_switches_sa1100_handler(irq, &mask);
20036 +#endif
20037 +       } else if (machine_is_spot()) {
20038 +#ifdef CONFIG_SA1100_SPOT
20039 +               ret = spot_switches_sa1100_handler(irq, &mask);
20040 +#endif
20041 +       }
20042 +
20043 +       switches_event(&mask);
20044 +
20045 +       return ret;
20046 +}
20047 +
20048 +int __init switches_sa1100_init(void)
20049 +{
20050 +
20051 +       /* Porting note: call a board-specific init routine here. */
20052 +
20053 +       if (machine_is_assabet()) {
20054 +#ifdef CONFIG_SA1100_ASSABET
20055 +               if (assabet_switches_sa1100_init() < 0)
20056 +                       return -EIO;
20057 +#endif
20058 +       } else if (machine_is_badge4()) {
20059 +#ifdef CONFIG_SA1100_BADGE4
20060 +               if (badge4_switches_sa1100_init() < 0)
20061 +                       return -EIO;
20062 +#endif
20063 +       } else if (machine_is_spot()) {
20064 +#ifdef CONFIG_SA1100_SPOT
20065 +               if (spot_switches_sa1100_init() < 0)
20066 +                       return -EIO;
20067 +#endif
20068 +       }
20069 +
20070 +       return 0;
20071 +
20072 +}
20073 +
20074 +void __exit switches_sa1100_exit(void)
20075 +{
20076 +
20077 +       /* Porting note: call a board-specific shutdown routine here. */
20078 +
20079 +       if (machine_is_assabet()) {
20080 +#ifdef CONFIG_SA1100_ASSABET
20081 +               assabet_switches_sa1100_shutdown();
20082 +#endif
20083 +       } else if (machine_is_badge4()) {
20084 +#ifdef CONFIG_SA1100_BADGE4
20085 +               badge4_switches_sa1100_shutdown();
20086 +#endif
20087 +       } else if (machine_is_spot()) {
20088 +#ifdef CONFIG_SA1100_SPOT
20089 +               spot_switches_sa1100_shutdown();
20090 +#endif
20091 +       }
20092 +
20093 +}
20094 +
20095 +module_init(switches_sa1100_init);
20096 +module_exit(switches_sa1100_exit);
20097 +
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
20102 @@ -4,3 +4,21 @@
20103  obj- := misc.o # Dummy rule to force built-in.o to be made
20104  
20105  obj-$(CONFIG_IBM_ASM)  += ibmasm/
20106 +
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
20111 +
20112 +ifeq ($(CONFIG_SA1100_ASSABET),y)
20113 +obj-$(CONFIG_MCP_UCB1200)      += ucb1x00-assabet.o
20114 +endif
20115 +
20116 +obj-$(CONFIG_SWITCHES)         += switches-core.o
20117 +obj-$(CONFIG_SWITCHES_SA1100)  += switches-sa1100.o
20118 +obj-$(CONFIG_SWITCHES_UCB1X00) += switches-ucb1x00.o
20119 +
20120 +obj-$(CONFIG_MCP_SA1100)       += mcp-sa1100.o
20121 +
20122 +obj-$(CONFIG_UCB1400_TS)       += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o
20123 +
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
20126 @@ -70,6 +70,16 @@
20127           This support is also available as a module.  If so, the module
20128           will be called i2c-hydra.
20129  
20130 +config I2C_BIT_SA1100_GPIO
20131 +       bool "SA1100 I2C GPIO adapter"
20132 +       depends on ARCH_SA1100 && I2C_ALGOBIT
20133 +       help
20134 +         This supports I2C on the SA11x0 processor GPIO pins.  This
20135 +         shares support with the L3 driver.
20136 +
20137 +         This support is also available as a module.  If so, the module
20138 +         will be called l3-bit-sa1100.
20139 +
20140  config I2C_I801
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.
20146  
20147 +config I2C_PXA2XX
20148 +       tristate "PXA I2C Interface"
20149 +       depends on I2C && ARCH_PXA
20150 +       select I2C_ALGOPXA
20151 +       help
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. 
20154 +
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.
20158 +
20159  config I2C_RPXLITE
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
20164 @@ -0,0 +1,388 @@
20165 +/*
20166 + *  i2c_adap_pxa.c
20167 + *
20168 + *  I2C adapter for the PXA I2C bus access.
20169 + *
20170 + *  Copyright (C) 2002 Intrinsyc Software Inc.
20171 + *
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.
20175 + *
20176 + *  History:
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]
20182 + */
20183 +
20184 +#include <linux/kernel.h>
20185 +#include <linux/module.h>
20186 +
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>
20195 +
20196 +#include <asm/hardware.h>
20197 +#include <asm/irq.h>
20198 +#include <asm/arch/irqs.h>              /* for IRQ_I2C */
20199 +
20200 +#include <linux/i2c-pxa.h>
20201 +
20202 +/*
20203 + * Set this to zero to remove all debug statements via dead code elimination.
20204 + */
20205 +//#define DEBUG       1
20206 +
20207 +#if DEBUG
20208 +static unsigned int i2c_debug = DEBUG;
20209 +#else
20210 +#define i2c_debug      0
20211 +#endif
20212 +
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;
20218 +
20219 +static wait_queue_head_t i2c_wait;
20220 +static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte);
20221 +
20222 +/* place a byte in the transmit register */
20223 +static void i2c_pxa_write_byte(u8 value)
20224 +{
20225 +       IDBR = value;
20226 +}
20227 +
20228 +/* read byte in the receive register */
20229 +static u8 i2c_pxa_read_byte(void)
20230 +{
20231 +       return (u8) (0xff & IDBR);
20232 +}
20233 +
20234 +static void i2c_pxa_start(void)
20235 +{
20236 +       unsigned long icr = ICR;
20237 +       icr |= ICR_START;
20238 +       icr &= ~(ICR_STOP | ICR_ALDIE | ICR_ACKNAK);
20239 +       ICR = icr;
20240 +
20241 +       bus_error=0;            /* clear any bus_error from previous txfers */
20242 +       tx_finished=0;          /* clear rx and tx interrupts from previous txfers */
20243 +       rx_finished=0;
20244 +       i2c_pending = 0;
20245 +}
20246 +
20247 +static void i2c_pxa_repeat_start(void)
20248 +{
20249 +       unsigned long icr = ICR;
20250 +       icr |= ICR_START;
20251 +       icr &= ~(ICR_STOP | ICR_ALDIE);
20252 +       ICR = icr;
20253 +
20254 +       bus_error=0;            /* clear any bus_error from previous txfers */
20255 +       tx_finished=0;          /* clear rx and tx interrupts from previous txfers */
20256 +       rx_finished=0;
20257 +       i2c_pending = 0;
20258 +}
20259 +
20260 +static void i2c_pxa_stop(void)
20261 +{
20262 +       unsigned long icr = ICR;
20263 +       icr |= ICR_STOP;
20264 +       icr &= ~(ICR_START);
20265 +       ICR = icr;
20266 +}
20267 +
20268 +static void i2c_pxa_midbyte(void)
20269 +{
20270 +       unsigned long icr = ICR;
20271 +       icr &= ~(ICR_START | ICR_STOP);
20272 +       ICR = icr;
20273 +}
20274 +
20275 +static void i2c_pxa_abort(void)
20276 +{
20277 +       unsigned long timeout = jiffies + HZ/4;
20278 +
20279 +#ifdef PXA_ABORT_MA
20280 +       while ((long)(timeout - jiffies) > 0 && (ICR & ICR_TB)) {
20281 +               set_current_state(TASK_INTERRUPTIBLE);
20282 +               schedule_timeout(1);
20283 +       }
20284 +
20285 +       ICR |= ICR_MA;
20286 +       udelay(100);
20287 +#else
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);
20292 +       }
20293 +#endif
20294 +       ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
20295 +}
20296 +
20297 +static int i2c_pxa_wait_bus_not_busy( void)
20298 +{
20299 +       int timeout = DEF_TIMEOUT;
20300 +
20301 +       while (timeout-- && (ISR & ISR_IBB)) {
20302 +               udelay(100); /* wait for 100 us */
20303 +       }
20304 +
20305 +       return (timeout<=0);
20306 +}
20307 +
20308 +spinlock_t i2c_pxa_irqlock = SPIN_LOCK_UNLOCKED;
20309 +
20310 +static void i2c_pxa_wait_for_ite(void){
20311 +       unsigned long flags;
20312 +       if (irq > 0) {
20313 +           spin_lock_irqsave(&i2c_pxa_irqlock, flags);
20314 +               if (i2c_pending == 0) {
20315 +                       interruptible_sleep_on_timeout(&i2c_wait, I2C_SLEEP_TIMEOUT );
20316 +               }
20317 +               i2c_pending = 0;
20318 +               spin_unlock_irqrestore(&i2c_pxa_irqlock, flags);
20319 +       } else {
20320 +               udelay(100);
20321 +       }
20322 +}
20323 +
20324 +static int i2c_pxa_wait_for_int( int wait_type)
20325 +{
20326 +       int timeout = DEF_TIMEOUT;
20327 +#ifdef DEBUG
20328 +       if (bus_error)
20329 +               printk(KERN_INFO"i2c_pxa_wait_for_int: Bus error on enter\n");
20330 +       if (rx_finished)
20331 +               printk(KERN_INFO"i2c_pxa_wait_for_int: Receive interrupt on enter\n");
20332 +       if (tx_finished)
20333 +               printk(KERN_INFO"i2c_pxa_wait_for_int: Transmit interrupt on enter\n");
20334 +#endif
20335 +
20336 +       if (wait_type == I2C_RECEIVE){         /* wait on receive */
20337 +
20338 +               do {
20339 +                       i2c_pxa_wait_for_ite();
20340 +               } while (!(rx_finished) && timeout-- && !signal_pending(current));
20341 +
20342 +#ifdef DEBUG
20343 +               if (timeout<0){
20344 +                       if (tx_finished)
20345 +                               printk("Error: i2c-algo-pxa.o: received a tx"
20346 +                                               " interrupt while waiting on a rx in wait_for_int");
20347 +               }
20348 +#endif
20349 +       } else {                  /* wait on transmit */
20350 +
20351 +               do {
20352 +                       i2c_pxa_wait_for_ite();
20353 +               } while (!(tx_finished) && timeout-- && !signal_pending(current));
20354 +
20355 +#ifdef DEBUG
20356 +               if (timeout<0){
20357 +                       if (rx_finished)
20358 +                               printk("Error: i2c-algo-pxa.o: received a rx"
20359 +                                       " interrupt while waiting on a tx in wait_for_int");
20360 +               }
20361 +#endif
20362 +       }
20363 +
20364 +       udelay(ACK_DELAY);      /* this is needed for the bus error */
20365 +
20366 +       tx_finished=0;
20367 +       rx_finished=0;
20368 +
20369 +       if (bus_error){
20370 +               bus_error=0;
20371 +               if( i2c_debug > 2)printk("wait_for_int: error - no ack.\n");
20372 +               return BUS_ERROR;
20373 +       }
20374 +
20375 +       if (signal_pending(current)) {
20376 +               return (-ERESTARTSYS);
20377 +       } else if (timeout < 0) {
20378 +               if( i2c_debug > 2)printk("wait_for_int: timeout.\n");
20379 +               return(-EIO);
20380 +       } else
20381 +               return(0);
20382 +}
20383 +
20384 +static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte)
20385 +{
20386 +       if( lastbyte)
20387 +       {
20388 +               if( receive==I2C_RECEIVE) ICR |= ICR_ACKNAK;
20389 +               i2c_pxa_stop();
20390 +       }
20391 +       else if( midbyte)
20392 +       {
20393 +               i2c_pxa_midbyte();
20394 +       }
20395 +       ICR |= ICR_TB;
20396 +}
20397 +
20398 +static void i2c_pxa_reset( void)
20399 +{
20400 +#ifdef DEBUG
20401 +       printk("Resetting I2C Controller Unit\n");
20402 +#endif
20403 +
20404 +       /* abort any transfer currently under way */
20405 +       i2c_pxa_abort();
20406 +
20407 +       /* reset according to 9.8 */
20408 +       ICR = ICR_UR;
20409 +       ISR = I2C_ISR_INIT;
20410 +       ICR &= ~ICR_UR;
20411 +
20412 +       /* set the global I2C clock on */
20413 +       CKEN |= CKEN14_I2C;
20414 +
20415 +       /* set our slave address */
20416 +       ISAR = I2C_PXA_SLAVE_ADDR;
20417 +
20418 +       /* set control register values */
20419 +       ICR = I2C_ICR_INIT;
20420 +
20421 +       /* clear any leftover states from prior transmissions */
20422 +       i2c_pending = rx_finished = tx_finished = bus_error = 0;
20423 +
20424 +       /* enable unit */
20425 +       ICR |= ICR_IUE;
20426 +       udelay(100);
20427 +}
20428 +
20429 +static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
20430 +{
20431 +    unsigned long flags;
20432 +       int status, wakeup = 0;
20433 +       status = (ISR);
20434 +
20435 +       if (status & ISR_BED){
20436 +               (ISR) |= ISR_BED;
20437 +               bus_error=ISR_BED;
20438 +               wakeup = 1;
20439 +       }
20440 +       if (status & ISR_ITE){
20441 +               (ISR) |= ISR_ITE;
20442 +               tx_finished=ISR_ITE;
20443 +               wakeup = 1;
20444 +       }
20445 +       if (status & ISR_IRF){
20446 +               (ISR) |= ISR_IRF;
20447 +               rx_finished=ISR_IRF;
20448 +               wakeup = 1;
20449 +       }
20450 +       if (wakeup) {
20451 +           spin_lock_irqsave(&i2c_pxa_irqlock, flags);
20452 +               i2c_pending = 1;
20453 +               spin_unlock_irqrestore(&i2c_pxa_irqlock, flags);
20454 +               wake_up_interruptible(&i2c_wait);
20455 +       }
20456 +       return IRQ_HANDLED;
20457 +}
20458 +
20459 +static int i2c_pxa_resource_init( void)
20460 +{
20461 +       init_waitqueue_head(&i2c_wait);
20462 +
20463 +       if (request_irq(IRQ_I2C, &i2c_pxa_handler, SA_INTERRUPT, "I2C", 0) < 0) {
20464 +               irq = 0;
20465 +               if(i2c_debug)
20466 +                       printk(KERN_INFO "I2C: Failed to register I2C irq %i\n", IRQ_I2C);
20467 +               return -ENODEV;
20468 +       }
20469 +       return 0;
20470 +}
20471 +
20472 +static void i2c_pxa_resource_release( void)
20473 +{
20474 +       if( irq > 0)
20475 +       {
20476 +               disable_irq(irq);
20477 +               free_irq(irq,0);
20478 +               irq=0;
20479 +       }
20480 +}
20481 +
20482 +static int i2c_pxa_client_register(struct i2c_client *client)
20483 +{
20484 +       return 0;
20485 +}
20486 +
20487 +static int i2c_pxa_client_unregister(struct i2c_client *client)
20488 +{
20489 +       return 0;
20490 +}
20491 +
20492 +static struct i2c_algo_pxa_data i2c_pxa_data = {
20493 +       write_byte:             i2c_pxa_write_byte,
20494 +       read_byte:              i2c_pxa_read_byte,
20495 +
20496 +       start:                  i2c_pxa_start,
20497 +       repeat_start:           i2c_pxa_repeat_start,
20498 +       stop:                   i2c_pxa_stop,
20499 +       abort:                  i2c_pxa_abort,
20500 +
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,
20505 +
20506 +       udelay:                 10,
20507 +       timeout:                DEF_TIMEOUT,
20508 +};
20509 +
20510 +static struct i2c_adapter i2c_pxa_ops = {
20511 +       .owner      = THIS_MODULE,
20512 +    .id         = I2C_ALGO_PXA,
20513 +    .algo_data  = &i2c_pxa_data,
20514 +    .dev        = {
20515 +        .name   = "PXA I2C Adapter",
20516 +    },
20517 +       .client_register   = i2c_pxa_client_register,
20518 +       .client_unregister = i2c_pxa_client_unregister,
20519 +       .retries           = 2,
20520 +};
20521 +
20522 +extern int i2c_pxa_add_bus(struct i2c_adapter *);
20523 +extern int i2c_pxa_del_bus(struct i2c_adapter *);
20524 +
20525 +static int __init i2c_adap_pxa_init(void)
20526 +{
20527 +       if( i2c_pxa_resource_init() == 0) {
20528 +
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");
20532 +                       return -ENODEV;
20533 +               }
20534 +       } else {
20535 +               return -ENODEV;
20536 +       }
20537 +
20538 +       printk(KERN_INFO "I2C: Successfully added bus\n");
20539 +
20540 +       return 0;
20541 +}
20542 +
20543 +static void i2c_adap_pxa_exit(void)
20544 +{
20545 +       i2c_pxa_del_bus( &i2c_pxa_ops);
20546 +       i2c_pxa_resource_release();
20547 +
20548 +       printk(KERN_INFO "I2C: Successfully removed bus\n");
20549 +}
20550 +
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
20555 @@ -21,6 +21,7 @@
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
20565 @@ -38,6 +38,18 @@
20566           This support is also available as a module.  If so, the module 
20567           will be called i2c-algo-ite.
20568  
20569 +config I2C_ALGOPXA
20570 +       tristate "PXA I2C Algorithm"
20571 +       depends on ARCH_PXA && I2C
20572 +       help
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.
20576 +
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.
20580 +
20581  config I2C_ALGO8XX
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
20586 @@ -0,0 +1,384 @@
20587 +/*
20588 + *  i2c-algo-pxa.c
20589 + *
20590 + *  I2C algorithm for the PXA I2C bus access.
20591 + *  Byte driven algorithm similar to pcf.
20592 + *
20593 + *  Copyright (C) 2002 Intrinsyc Software Inc.
20594 + *
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.
20598 + *
20599 + *  History:
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]
20605 + *
20606 + */
20607 +#include <linux/kernel.h>
20608 +#include <linux/module.h>
20609 +
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>
20615 +
20616 +#include <linux/i2c-pxa.h>
20617 +
20618 +/*
20619 + * Set this to zero to remove all the debug statements via dead code elimination.
20620 + */
20621 +//#define DEBUG                1
20622 +
20623 +#if DEBUG
20624 +static unsigned int i2c_debug = DEBUG;
20625 +#else
20626 +#define i2c_debug      0
20627 +#endif
20628 +
20629 +static int pxa_scan = 1;
20630 +
20631 +static int i2c_pxa_valid_messages( struct i2c_msg msgs[], int num)
20632 +{
20633 +       int i;
20634 +       if (num < 1 || num > MAX_MESSAGES){
20635 +               if( i2c_debug)
20636 +                       printk(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n",
20637 +                               MAX_MESSAGES, num);
20638 +               return -EINVAL;
20639 +       }
20640 +
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");
20645 +                       return -EINVAL;
20646 +               } else {
20647 +                       if (msgs[i].buf == NULL){
20648 +                               if( i2c_debug)printk(KERN_INFO "Length is less than zero");
20649 +                               return -EINVAL;
20650 +                       }
20651 +               }
20652 +       }
20653 +
20654 +       return 1;
20655 +}
20656 +
20657 +static int i2c_pxa_readbytes(struct i2c_adapter *i2c_adap, char *buf,
20658 +                       int count, int last)
20659 +{
20660 +
20661 +       int i, timeout=0;
20662 +       struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
20663 +
20664 +       /* increment number of bytes to read by one -- read dummy byte */
20665 +       for (i = 0; i <= count; i++) {
20666 +               if (i!=0){
20667 +                       /* set ACK to NAK for last received byte ICR[ACKNAK] = 1
20668 +                          only if not a repeated start */
20669 +
20670 +                       if ((i == count) && last) {
20671 +                               adap->transfer( last, I2C_RECEIVE, 0);
20672 +                       }else{
20673 +                               adap->transfer( 0, I2C_RECEIVE, 1);
20674 +                       }
20675 +
20676 +                       timeout = adap->wait_for_interrupt(I2C_RECEIVE);
20677 +
20678 +#ifdef DEBUG
20679 +                       if (timeout==BUS_ERROR){
20680 +                               printk(KERN_INFO "i2c_pxa_readbytes: bus error -> forcing reset\n");
20681 +                               adap->reset();
20682 +                               return I2C_RETRY;
20683 +                       } else
20684 +#endif
20685 +                       if (timeout == -ERESTARTSYS) {
20686 +                               adap->abort();
20687 +                               return timeout;
20688 +                       } else
20689 +                       if (timeout){
20690 +#ifdef DEBUG
20691 +                               printk(KERN_INFO "i2c_pxa_readbytes: timeout -> forcing reset\n");
20692 +#endif
20693 +                               adap->reset();
20694 +                               return I2C_RETRY;
20695 +                       }
20696 +
20697 +               }
20698 +
20699 +               if (i) {
20700 +                       buf[i - 1] = adap->read_byte();
20701 +               } else {
20702 +                       adap->read_byte(); /* dummy read */
20703 +               }
20704 +       }
20705 +       return (i - 1);
20706 +}
20707 +
20708 +static int i2c_pxa_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
20709 +                         int count, int last)
20710 +{
20711 +
20712 +       struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
20713 +       int wrcount, timeout;
20714 +
20715 +       for (wrcount=0; wrcount<count; ++wrcount) {
20716 +
20717 +               adap->write_byte(buf[wrcount]);
20718 +               if ((wrcount==(count-1)) && last) {
20719 +                       adap->transfer( last, I2C_TRANSMIT, 0);
20720 +               }else{
20721 +                       adap->transfer( 0, I2C_TRANSMIT, 1);
20722 +               }
20723 +
20724 +               timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
20725 +
20726 +#ifdef DEBUG
20727 +               if (timeout==BUS_ERROR) {
20728 +                       printk(KERN_INFO "i2c_pxa_sendbytes: bus error -> forcing reset.\n");
20729 +                       adap->reset();
20730 +                       return I2C_RETRY;
20731 +               } else
20732 +#endif
20733 +               if (timeout == -ERESTARTSYS) {
20734 +                       adap->abort();
20735 +                       return timeout;
20736 +               } else
20737 +               if (timeout) {
20738 +#ifdef DEBUG
20739 +                       printk(KERN_INFO "i2c_pxa_sendbytes: timeout -> forcing reset\n");
20740 +#endif
20741 +                       adap->reset();
20742 +                       return I2C_RETRY;
20743 +               }
20744 +       }
20745 +       return (wrcount);
20746 +}
20747 +
20748 +
20749 +static inline int i2c_pxa_set_ctrl_byte(struct i2c_algo_pxa_data * adap, struct i2c_msg *msg)
20750 +{
20751 +       u16 flags = msg->flags;
20752 +       u8 addr;
20753 +       addr = (u8) ( (0x7f & msg->addr) << 1 );
20754 +       if (flags & I2C_M_RD )
20755 +               addr |= 1;
20756 +       if (flags & I2C_M_REV_DIR_ADDR )
20757 +               addr ^= 1;
20758 +       adap->write_byte(addr);
20759 +       return 0;
20760 +}
20761 +
20762 +static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
20763 +{
20764 +       struct i2c_algo_pxa_data * adap;
20765 +       struct i2c_msg *pmsg=NULL;
20766 +       int i;
20767 +       int ret=0, timeout;
20768 +
20769 +       adap = i2c_adap->algo_data;
20770 +
20771 +       timeout = adap->wait_bus_not_busy();
20772 +
20773 +       if (timeout) {
20774 +               return I2C_RETRY;
20775 +       }
20776 +
20777 +       for (i = 0;ret >= 0 && i < num; i++) {
20778 +               int last = i + 1 == num;
20779 +               pmsg = &msgs[i];
20780 +
20781 +               ret = i2c_pxa_set_ctrl_byte(adap,pmsg);
20782 +
20783 +               /* Send START */
20784 +               if (i == 0) {
20785 +                       adap->start();
20786 +               }else{
20787 +                       adap->repeat_start();
20788 +               }
20789 +
20790 +               adap->transfer(0, I2C_TRANSMIT, 0);
20791 +
20792 +               /* Wait for ITE (transmit empty) */
20793 +               timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
20794 +
20795 +#ifdef DEBUG
20796 +               /* Check for ACK (bus error) */
20797 +               if (timeout==BUS_ERROR){
20798 +                       printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n");
20799 +                       adap->reset();
20800 +                       return I2C_RETRY;
20801 +               } else
20802 +#endif
20803 +               if (timeout == -ERESTARTSYS) {
20804 +                       adap->abort();
20805 +                       return timeout;
20806 +               } else
20807 +               if (timeout) {
20808 +#ifdef DEBUG
20809 +                       printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n");
20810 +#endif
20811 +                       adap->reset();
20812 +                       return I2C_RETRY;
20813 +               }
20814 +/* FIXME: handle arbitration... */
20815 +#if 0
20816 +               /* Check for bus arbitration loss */
20817 +               if (adap->arbitration_loss()){
20818 +                       printk("Arbitration loss detected \n");
20819 +                       adap->reset();
20820 +                       return I2C_RETRY;
20821 +               }
20822 +#endif
20823 +
20824 +               /* Read */
20825 +               if (pmsg->flags & I2C_M_RD) {
20826 +                       /* read bytes into buffer*/
20827 +                       ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last);
20828 +#if DEBUG > 2
20829 +                       if (ret != pmsg->len) {
20830 +                               printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n",
20831 +                                       ret, pmsg->len);
20832 +                       } else {
20833 +                               printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret);
20834 +                       }
20835 +#endif
20836 +               } else { /* Write */
20837 +                       ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last);
20838 +#if DEBUG > 2
20839 +                       if (ret != pmsg->len) {
20840 +                               printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n",
20841 +                                       ret, pmsg->len);
20842 +                       } else {
20843 +                               printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret);
20844 +                       }
20845 +#endif
20846 +               }
20847 +       }
20848 +
20849 +       if (ret<0){
20850 +               return ret;
20851 +       }else{
20852 +               return i;
20853 +       }
20854 +}
20855 +
20856 +static int i2c_pxa_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
20857 +{
20858 +       int retval = i2c_pxa_valid_messages( msgs, num);
20859 +       if( retval > 0)
20860 +       {
20861 +               int i;
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){
20865 +                               return retval;
20866 +                       }
20867 +                       if( i2c_debug)printk(KERN_INFO"Retrying transmission \n");
20868 +                       udelay(100);
20869 +               }
20870 +               if( i2c_debug)printk(KERN_INFO"Retried %i times\n",i2c_adap->retries);
20871 +               return -EREMOTEIO;
20872 +
20873 +       }
20874 +       return retval;
20875 +}
20876 +
20877 +static u32 i2c_pxa_functionality(struct i2c_adapter * adapter)
20878 +{
20879 +    /* Emulate the SMBUS functions */
20880 +       return I2C_FUNC_SMBUS_EMUL;
20881 +}
20882 +
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,
20892 +};
20893 +
20894 +/*
20895 + * registering functions to load algorithms at runtime
20896 + */
20897 +int i2c_pxa_add_bus(struct i2c_adapter *i2c_adap)
20898 +{
20899 +       struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
20900 +
20901 +       printk(KERN_INFO"I2C: Adding %s.\n", i2c_adap->dev.name);
20902 +
20903 +       i2c_adap->algo = &i2c_pxa_algorithm;
20904 +
20905 +       MOD_INC_USE_COUNT;
20906 +
20907 +       /* register new adapter to i2c module... */
20908 +       i2c_add_adapter(i2c_adap);
20909 +
20910 +       adap->reset();
20911 +
20912 +       /* scan bus */
20913 +       if (pxa_scan) {
20914 +               int i;
20915 +               printk(KERN_INFO "I2C: Scanning bus ");
20916 +               for (i = 0x02; i < 0xff; i+=2) {
20917 +                       if( i==(I2C_PXA_SLAVE_ADDR<<1)) continue;
20918 +
20919 +                       if (adap->wait_bus_not_busy()) {
20920 +                               printk(KERN_INFO "I2C: scanning bus %s - TIMEOUT.\n",
20921 +                                               i2c_adap->dev.name);
20922 +                               return -EIO;
20923 +                       }
20924 +                       adap->write_byte(i);
20925 +                       adap->start();
20926 +                       adap->transfer(0, I2C_TRANSMIT, 0);
20927 +
20928 +                       if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) {
20929 +                               printk("(%02x)",i>>1);
20930 +                               adap->abort();
20931 +                       } else {
20932 +//                             printk(".");
20933 +                               adap->stop();
20934 +                       }
20935 +                       udelay(adap->udelay);
20936 +               }
20937 +               printk("\n");
20938 +       }
20939 +       return 0;
20940 +}
20941 +
20942 +int i2c_pxa_del_bus(struct i2c_adapter *i2c_adap)
20943 +{
20944 +       int res;
20945 +       if ((res = i2c_del_adapter(i2c_adap)) < 0)
20946 +               return res;
20947 +
20948 +       MOD_DEC_USE_COUNT;
20949 +
20950 +       printk(KERN_INFO "I2C: Removing %s.\n", i2c_adap->dev.name);
20951 +
20952 +       return 0;
20953 +}
20954 +
20955 +static int __init i2c_algo_pxa_init (void)
20956 +{
20957 +       printk(KERN_INFO "I2C: PXA algorithm module loaded.\n");
20958 +       return 0;
20959 +}
20960 +
20961 +EXPORT_SYMBOL(i2c_pxa_add_bus);
20962 +EXPORT_SYMBOL(i2c_pxa_del_bus);
20963 +
20964 +MODULE_PARM(pxa_scan, "i");
20965 +MODULE_PARM_DESC(pxa_scan, "Scan for active chips on the bus");
20966 +
20967 +MODULE_AUTHOR("Intrinsyc Software Inc.");
20968 +MODULE_LICENSE("GPL");
20969 +
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
20973 @@ -4,6 +4,7 @@
20974  
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
20979  
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
20983 @@ -1,7 +1,7 @@
20984  VERSION = 2
20985  PATCHLEVEL = 6
20986  SUBLEVEL = 5
20987 -EXTRAVERSION =
20988 +EXTRAVERSION = -gnalm1
20989  NAME=Zonked Quokka
20990  
20991  # *DOCUMENTATION*