classpath-native: Fix typo in depends.
[vuplus_openembedded] / packages / linux / linux-rp-2.6.26 / collie.patch
1 diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
2 index c7ad324..daa2e0a 100644
3 --- a/arch/arm/Kconfig
4 +++ b/arch/arm/Kconfig
5 @@ -998,7 +998,7 @@ config CPU_FREQ_SA1100
6  
7  config CPU_FREQ_SA1110
8         bool
9 -       depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3)
10 +       depends on CPU_FREQ && (SA1100_ASSABET || SA1100_CERF || SA1100_PT_SYSTEM3 || SA1100_COLLIE)
11         default y
12  
13  config CPU_FREQ_INTEGRATOR
14 diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c
15 index e508028..36f726c 100644
16 --- a/arch/arm/mach-sa1100/dma.c
17 +++ b/arch/arm/mach-sa1100/dma.c
18 @@ -39,7 +39,7 @@ typedef struct {
19  
20  static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];
21  
22 -static spinlock_t dma_list_lock;
23 +static  DEFINE_SPINLOCK(dma_list_lock);
24  
25  
26  static irqreturn_t dma_irq_handler(int irq, void *dev_id)
27 diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
28 index 9caed30..79e19bf 100644
29 --- a/drivers/input/keyboard/locomokbd.c
30 +++ b/drivers/input/keyboard/locomokbd.c
31 @@ -265,6 +265,7 @@ static int __devinit locomokbd_probe(struct locomo_dev *dev)
32         for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
33                 set_bit(locomokbd->keycode[i], input_dev->keybit);
34         clear_bit(0, input_dev->keybit);
35 +       locomo_writel(0, locomokbd->base + LOCOMO_KSC);
36  
37         /* attempt to get the interrupt */
38         err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
39 diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
40 index 9f93c29..33fc5d6 100644
41 --- a/drivers/mfd/Kconfig
42 +++ b/drivers/mfd/Kconfig
43 @@ -72,4 +72,10 @@ config MCP_UCB1200_TS
44         tristate "Touchscreen interface support"
45         depends on MCP_UCB1200 && INPUT
46  
47 +config MCP_COLLIE_TS
48 +       tristate "Touchscreen collie support"
49 +       depends on MCP_UCB1200 && INPUT && !MCP_UCB1200_TS
50 +        ---help---
51 +         Driver for touchscreen on collie - sharp sl-5500.
52 +
53  endmenu
54 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
55 index 33daa2f..0885ccd 100644
56 --- a/drivers/mfd/Makefile
57 +++ b/drivers/mfd/Makefile
58 @@ -16,7 +16,7 @@ obj-$(CONFIG_MCP)             += mcp-core.o
59  obj-$(CONFIG_MCP_SA11X0)       += mcp-sa11x0.o
60  obj-$(CONFIG_MCP_UCB1200)      += ucb1x00-core.o
61  obj-$(CONFIG_MCP_UCB1200_TS)   += ucb1x00-ts.o
62 -
63 +obj-$(CONFIG_MCP_COLLIE_TS)     += collie-ts.o
64  ifeq ($(CONFIG_SA1100_ASSABET),y)
65  obj-$(CONFIG_MCP_UCB1200)      += ucb1x00-assabet.o
66  endif
67 diff --git a/drivers/mfd/collie-ts.c b/drivers/mfd/collie-ts.c
68 new file mode 100644
69 index 0000000..ddde5fc
70 --- /dev/null
71 +++ b/drivers/mfd/collie-ts.c
72 @@ -0,0 +1,449 @@
73 +/*
74 + *  Touchscreen driver for UCB1x00-based touchscreens
75 + *
76 + *  Copyright (C) 2001 Russell King, All Rights Reserved.
77 + *  Copyright (C) 2005 Pavel Machek
78 + *
79 + * This program is free software; you can redistribute it and/or modify
80 + * it under the terms of the GNU General Public License version 2 as
81 + * published by the Free Software Foundation.
82 + *
83 + * 21-Jan-2002 <jco@ict.es> :
84 + *
85 + * Added support for synchronous A/D mode. This mode is useful to
86 + * avoid noise induced in the touchpanel by the LCD, provided that
87 + * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
88 + * It is important to note that the signal connected to the ADCSYNC
89 + * pin should provide pulses even when the LCD is blanked, otherwise
90 + * a pen touch needed to unblank the LCD will never be read.
91 + */
92 +#include <linux/module.h>
93 +#include <linux/moduleparam.h>
94 +#include <linux/init.h>
95 +#include <linux/smp.h>
96 +#include <linux/smp_lock.h>
97 +#include <linux/sched.h>
98 +#include <linux/completion.h>
99 +#include <linux/delay.h>
100 +#include <linux/string.h>
101 +#include <linux/input.h>
102 +#include <linux/device.h>
103 +#include <linux/freezer.h>
104 +#include <linux/slab.h>
105 +#include <linux/kthread.h>
106 +
107 +#include <asm/dma.h>
108 +#include <asm/semaphore.h>
109 +#include <asm/arch/collie.h>
110 +#include <asm/mach-types.h>
111 +
112 +#include "ucb1x00.h"
113 +
114 +struct ucb1x00_ts {
115 +       struct input_dev        *idev;
116 +       struct ucb1x00          *ucb;
117 +
118 +       wait_queue_head_t       irq_wait;
119 +       struct task_struct      *rtask;
120 +       u16                     x_res;
121 +       u16                     y_res;
122 +
123 +       unsigned int            adcsync:1;
124 +};
125 +
126 +static int adcsync;
127 +
128 +/**********************************
129 +
130 +     ................
131 +     .              . = 340
132 +     .              .
133 +     .             ^.
134 +     .             ^.
135 +     .             ^.
136 +     .             ^.
137 +     .              .
138 +     .             X. = 10
139 +     .  <<<<<<<<  Y .
140 +     ................
141 +     .   Sharp    =200
142 +     .              .
143 +     .  -   O    -  .
144 +     .              .
145 +     ................
146 +
147 +**********************************/
148 +
149 +
150 +static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
151 +{
152 +       struct input_dev *idev = ts->idev;
153 +
154 +       input_report_abs(idev, ABS_X, x);
155 +       input_report_abs(idev, ABS_Y, y);
156 +       input_report_abs(idev, ABS_PRESSURE, pressure);
157 +        input_report_key(idev, BTN_TOUCH, 1);
158 +       input_sync(idev);
159 +}
160 +
161 +static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
162 +{
163 +       struct input_dev *idev = ts->idev;
164 +
165 +       input_report_abs(idev, ABS_PRESSURE, 0);
166 +        input_report_key(idev, BTN_TOUCH, 0);
167 +       input_sync(idev);
168 +}
169 +
170 +/*
171 + * Switch to interrupt mode. This set touchscreen to interrupt 
172 + * mode, so that chip is able to send interrupt.
173 + */
174 +static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
175 +{
176 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
177 +                       UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
178 +                       UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
179 +                       UCB_TS_CR_MODE_INT);
180 +}
181 +
182 +/*
183 + * Switch to pressure mode, and read pressure.  We don't need to wait
184 + * here, since both plates are being driven.
185 + *
186 + * set_read_pressure() in sharp code
187 + */
188 +static inline void ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
189 +{
190 +       ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
191 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
192 +                         UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
193 +                         UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
194 +
195 +       ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr | 
196 +                         UCB_ADC_INP_AD2 | 
197 +                         UCB_ADC_SYNC_ENA);
198 +       udelay(100);
199 +       ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr | 
200 +                         UCB_ADC_INP_AD2 | 
201 +                         UCB_ADC_SYNC_ENA | UCB_ADC_START);
202 +}
203 +
204 +/*
205 + * Switch to X position mode and measure Y plate.  We switch the plate
206 + * configuration in pressure mode, then switch to position mode.  This
207 + * gives a faster response time.  Even so, we need to wait about 55us
208 + * for things to stabilise.
209 + */
210 +static inline void ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
211 +{
212 +       ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
213 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
214 +                       UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
215 +                       UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
216 +
217 +
218 +       ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr | 
219 +                         UCB_ADC_INP_TSPY | UCB_ADC_SYNC_ENA);
220 +       udelay(100);
221 +       ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr | 
222 +                         UCB_ADC_INP_TSPY | UCB_ADC_SYNC_ENA | 
223 +                         UCB_ADC_START);
224 +}
225 +
226 +/*
227 + * Switch to Y position mode and measure X plate.  We switch the plate
228 + * configuration in pressure mode, then switch to position mode.  This
229 + * gives a faster response time.  Even so, we need to wait about 55us
230 + * for things to stabilise.
231 + */
232 +static inline void ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
233 +{
234 +       ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
235 +
236 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
237 +                       UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
238 +                       UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
239 +
240 +
241 +       ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr | 
242 +                         UCB_ADC_INP_TSPX | UCB_ADC_SYNC_ENA);
243 +       udelay(100);
244 +       ucb1x00_reg_write(ts->ucb, UCB_ADC_CR, ts->ucb->adc_cr |
245 +                         UCB_ADC_INP_TSPX | UCB_ADC_SYNC_ENA | 
246 +                         UCB_ADC_START);
247 +}
248 +
249 +/*
250 + * Switch to X plate resistance mode.  Set MX to ground, PX to
251 + * supply.  Measure current.
252 + */
253 +static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
254 +{
255 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
256 +                       UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
257 +                       UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
258 +       return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
259 +}
260 +
261 +/*
262 + * Switch to Y plate resistance mode.  Set MY to ground, PY to
263 + * supply.  Measure current.
264 + */
265 +static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
266 +{
267 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
268 +                       UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
269 +                       UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
270 +       return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
271 +}
272 +
273 +/*
274 + * This is a RT kernel thread that handles the ADC accesses
275 + * (mainly so we can use semaphores in the UCB1200 core code
276 + * to serialise accesses to the ADC).
277 + */
278 +static int ucb1x00_thread(void *_ts)
279 +{
280 +       struct ucb1x00_ts *ts = _ts;
281 +       struct task_struct *tsk = current;
282 +       DECLARE_WAITQUEUE(wait, tsk);
283 +       int state;
284 +
285 +       /*
286 +        * We could run as a real-time thread.  However, thus far
287 +        * this doesn't seem to be necessary.
288 +        */
289 +
290 +       add_wait_queue(&ts->irq_wait, &wait);   
291 +
292 +       while (!kthread_should_stop()) {
293 +               unsigned int data[3];
294 +                       
295 +               for (state=0; state<3; state++) {
296 +                       
297 +                       ucb1x00_adc_enable(ts->ucb);
298 +                       ucb1x00_enable_irq(ts->ucb, UCB_IRQ_ADC, UCB_FALLING);
299 +                       switch (state) {
300 +                       /* Order matters here; last measurement seems to be more noisy then the
301 +                          rest, and we care about pressure least */
302 +                               case 2: ucb1x00_ts_read_pressure(ts);
303 +                                       break;
304 +                               case 0: ucb1x00_ts_read_ypos(ts);
305 +                                       break;
306 +                               case 1: ucb1x00_ts_read_xpos(ts);
307 +                                       break;
308 +                       }
309 +                       /* wait for adc */
310 +                       try_to_freeze();
311 +                       schedule_timeout(1000 * HZ);
312 +                       ucb1x00_disable_irq(ts->ucb, UCB_IRQ_ADC, UCB_FALLING);
313 +                       data[state] = UCB_ADC_DAT(ucb1x00_reg_read(ts->ucb, UCB_ADC_DATA));
314 +                       ucb1x00_adc_disable(ts->ucb);
315 +               }       
316 +               
317 +               /* If not pressed any more, try to sleep! */
318 +               if (data[2] < 300) {
319 +                       set_task_state(tsk, TASK_INTERRUPTIBLE);
320 +                       ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_RISING);
321 +                       ucb1x00_ts_mode_int(ts);
322 +                       ucb1x00_disable(ts->ucb);
323 +                       ucb1x00_ts_event_release(ts);
324 +                       try_to_freeze();
325 +                       schedule_timeout(1000 * HZ);
326 +                       ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_RISING);
327 +                       ucb1x00_enable(ts->ucb);
328 +               } else {        
329 +                       ucb1x00_ts_evt_add(ts, data[2], data[1], data[0]);
330 +               }
331 +               ucb1x00_disable(ts->ucb);
332 +               msleep(20);
333 +               ucb1x00_enable(ts->ucb);
334 +       }
335 +
336 +       remove_wait_queue(&ts->irq_wait, &wait);
337 +
338 +       ts->rtask = NULL;
339 +       return 0;
340 +}
341 +
342 +/*
343 + * We only detect touch screen _touches_ with this interrupt
344 + * handler, and even then we just schedule our task.
345 + */
346 +static void ucb1x00_ts_irq(int idx, void *id)
347 +{
348 +       struct ucb1x00_ts *ts = id;
349 +       wake_up(&ts->irq_wait);
350 +}
351 +
352 +static void ucb1x00_adc_irq(int idx, void *id)
353 +{
354 +       struct ucb1x00_ts *ts = id;
355 +       wake_up(&ts->irq_wait);
356 +}
357 +
358 +static int ucb1x00_ts_open(struct input_dev *idev)
359 +{
360 +       struct ucb1x00_ts *ts = input_get_drvdata(idev);
361 +       int ret = 0;
362 +
363 +       BUG_ON(ts->rtask);
364 +
365 +       init_waitqueue_head(&ts->irq_wait);
366 +       
367 +       ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
368 +       if (ret < 0)
369 +               return ret;
370 +       
371 +       ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_ADC, ucb1x00_adc_irq, ts);
372 +       if (ret < 0) {
373 +               ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
374 +               return ret;
375 +       }
376 +
377 +       ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_RISING);
378 +       
379 +       /*
380 +        * If we do this at all, we should allow the user to
381 +        * measure and read the X and Y resistance at any time.
382 +        */
383 +       ucb1x00_adc_enable(ts->ucb);
384 +       ts->x_res = ucb1x00_ts_read_xres(ts);
385 +       ts->y_res = ucb1x00_ts_read_yres(ts);
386 +       ucb1x00_adc_disable(ts->ucb);
387 +
388 +       if (machine_is_collie()) {
389 +               ucb1x00_io_set_dir(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
390 +       }
391 +
392 +       ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd");
393 +       if (!IS_ERR(ts->rtask)) {
394 +               ret = 0;
395 +       } else {
396 +               ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
397 +               ts->rtask = NULL;
398 +               ret = -EFAULT;
399 +       }
400 +       
401 +       return ret;
402 +}
403 +
404 +/*
405 + * Release touchscreen resources.  Disable IRQs.
406 + */
407 +static void ucb1x00_ts_close(struct input_dev *idev)
408 +{
409 +       struct ucb1x00_ts *ts = input_get_drvdata(idev);
410 +
411 +       if (ts->rtask)
412 +               kthread_stop(ts->rtask);
413 +
414 +       ucb1x00_enable(ts->ucb);
415 +       ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
416 +       ucb1x00_free_irq(ts->ucb, UCB_IRQ_ADC, ts);
417 +       ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
418 +       ucb1x00_disable(ts->ucb);
419 +}
420 +
421 +#ifdef CONFIG_PM
422 +static int ucb1x00_ts_resume(struct ucb1x00_dev *dev)
423 +{
424 +       struct ucb1x00_ts *ts = dev->priv;
425 +
426 +       if (ts->rtask != NULL) {
427 +               /*
428 +                * Restart the TS thread to ensure the
429 +                * TS interrupt mode is set up again
430 +                * after sleep.
431 +                */
432 +               wake_up(&ts->irq_wait);
433 +       }
434 +       return 0;
435 +}
436 +#else
437 +#define ucb1x00_ts_resume NULL
438 +#endif
439 +
440 +
441 +/*
442 + * Initialisation.
443 + */
444 +static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
445 +{
446 +       struct ucb1x00_ts *ts;
447 +       struct input_dev *idev;
448 +       int err;
449 +
450 +       ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
451 +       idev = input_allocate_device();
452 +       if (!ts || !idev) {
453 +               err = -ENOMEM;
454 +               goto fail;
455 +       }
456 +
457 +       ts->ucb = dev->ucb;
458 +       ts->idev = idev;
459 +       ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
460 +
461 +       input_set_drvdata(idev, ts);
462 +       idev->name       = "Touchscreen panel";
463 +       idev->id.product = ts->ucb->id;
464 +       idev->open       = ucb1x00_ts_open;
465 +       idev->close      = ucb1x00_ts_close;
466 +
467 +       __set_bit(EV_ABS, idev->evbit);
468 +       __set_bit(ABS_X, idev->absbit);
469 +       __set_bit(ABS_Y, idev->absbit);
470 +       __set_bit(ABS_PRESSURE, idev->absbit);
471 +
472 +        input_set_abs_params(ts->idev, ABS_X, 0, 450, 0, 0);
473 +        input_set_abs_params(ts->idev, ABS_Y, 200, 800, 0, 0);
474 +        input_set_abs_params(ts->idev, ABS_PRESSURE, 400, 800, 0, 0);
475 +
476 +
477 +       err = input_register_device(idev);
478 +       if (err)
479 +               goto fail;
480 +
481 +       dev->priv = ts;
482 +
483 +       return 0;
484 +
485 + fail:
486 +       input_free_device(idev);
487 +       kfree(ts);
488 +       return err;
489 +}
490 +
491 +static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
492 +{
493 +       struct ucb1x00_ts *ts = dev->priv;
494 +
495 +       input_unregister_device(ts->idev);
496 +       kfree(ts);
497 +}
498 +
499 +static struct ucb1x00_driver ucb1x00_ts_driver = {
500 +       .add            = ucb1x00_ts_add,
501 +       .remove         = ucb1x00_ts_remove,
502 +       .resume         = ucb1x00_ts_resume,
503 +};
504 +
505 +static int __init ucb1x00_ts_init(void)
506 +{
507 +       return ucb1x00_register_driver(&ucb1x00_ts_driver);
508 +}
509 +
510 +static void __exit ucb1x00_ts_exit(void)
511 +{
512 +       ucb1x00_unregister_driver(&ucb1x00_ts_driver);
513 +}
514 +
515 +module_param(adcsync, int, 0444);
516 +module_init(ucb1x00_ts_init);
517 +module_exit(ucb1x00_ts_exit);
518 +
519 +MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
520 +MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
521 +MODULE_LICENSE("GPL");
522 diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h
523 index a8ad8a0..137b043 100644
524 --- a/drivers/mfd/ucb1x00.h
525 +++ b/drivers/mfd/ucb1x00.h
526 @@ -34,7 +34,10 @@
527  #define UCB_IE_TCLIP           (1 << 14)
528  #define UCB_IE_ACLIP           (1 << 15)
529  
530 +/* UCB1200 irqs */
531 +#define UCB_IRQ_ADC            11
532  #define UCB_IRQ_TSPX           12
533 +#define UCB_IRQ_TSMX           13
534  
535  #define UCB_TC_A       0x05
536  #define UCB_TC_A_LOOP          (1 << 7)        /* UCB1200 */
537 diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
538 index 3b4e55c..0ae741d 100644
539 --- a/drivers/net/wireless/hostap/hostap_cs.c
540 +++ b/drivers/net/wireless/hostap/hostap_cs.c
541 @@ -35,7 +35,7 @@ static int ignore_cis_vcc;
542  module_param(ignore_cis_vcc, int, 0444);
543  MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
544  
545 -
546 +int activar=0;
547  /* struct local_info::hw_priv */
548  struct hostap_cs_priv {
549         dev_node_t node;
550 @@ -499,11 +499,13 @@ static int hostap_cs_probe(struct pcmcia_device *p_dev)
551  
552         PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
553         p_dev->conf.IntType = INT_MEMORY_AND_IO;
554 -
555 +       
556 +       activar=0;
557         ret = prism2_config(p_dev);
558         if (ret) {
559                 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
560         }
561 +       activar=1;
562  
563         return ret;
564  }
565 diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
566 index 13d5882..6f24d66 100644
567 --- a/drivers/net/wireless/hostap/hostap_hw.c
568 +++ b/drivers/net/wireless/hostap/hostap_hw.c
569 @@ -54,6 +54,7 @@
570  #include "hostap.h"
571  #include "hostap_ap.h"
572  
573 +extern int activar;
574  
575  /* #define final_version */
576  
577 @@ -1497,6 +1498,8 @@ static int prism2_hw_config(struct net_device *dev, int initial)
578         if (local->hw_downloading)
579                 return 1;
580  
581 +       activar=1;
582 +
583         if (prism2_hw_init(dev, initial)) {
584                 return local->no_pri ? 0 : 1;
585         }
586 @@ -2628,8 +2631,15 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id)
587         int events = 0;
588         u16 ev;
589  
590 -       iface = netdev_priv(dev);
591 -       local = iface->local;
592 +
593 +       // Todos los parametros de entrada son correctos (no son nulos). De momento esta es la unica forma que conozco de detectar el problema.
594 +       if (!activar) {
595 +               printk("hostap_hw.c: INTERRUPT BEFORE DEVICE INIT!\n");
596 +               return IRQ_HANDLED;
597 +       }
598 +
599 +       iface = netdev_priv(dev);
600 +       local = iface->local;
601  
602         prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0);
603  
604 diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
605 index 3a874fc..df58aa3 100644
606 --- a/drivers/net/wireless/hostap/hostap_pci.c
607 +++ b/drivers/net/wireless/hostap/hostap_pci.c
608 @@ -19,6 +19,7 @@
609  
610  #include "hostap_wlan.h"
611  
612 +int activar=1;
613  
614  static char *dev_info = "hostap_pci";
615  
616 diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
617 index cbf15d7..4475174 100644
618 --- a/drivers/net/wireless/hostap/hostap_plx.c
619 +++ b/drivers/net/wireless/hostap/hostap_plx.c
620 @@ -21,7 +21,7 @@
621  #include <asm/io.h>
622  
623  #include "hostap_wlan.h"
624 -
625 +int activar=1;
626  
627  static char *dev_info = "hostap_plx";
628  
629 diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
630 index c5b2a44..eecbe8c 100644
631 --- a/drivers/pcmcia/sa1100_generic.c
632 +++ b/drivers/pcmcia/sa1100_generic.c
633 @@ -81,13 +81,14 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
634         return ret;
635  }
636  
637 -static struct device_driver sa11x0_pcmcia_driver = {
638 -       .probe          = sa11x0_drv_pcmcia_probe,
639 -       .remove         = soc_common_drv_pcmcia_remove,
640 -       .name           = "sa11x0-pcmcia",
641 -       .bus            = &platform_bus_type,
642 -       .suspend        = pcmcia_socket_dev_suspend,
643 -       .resume         = pcmcia_socket_dev_resume,
644 +static struct platform_driver sa11x0_pcmcia_driver = {
645 +       .driver         = {
646 +               .name   = "sa11x0-pcmcia",
647 +               .probe  = sa11x0_drv_pcmcia_probe,
648 +               .remove = soc_common_drv_pcmcia_remove,
649 +               .suspend= pcmcia_socket_dev_suspend,
650 +               .resume = pcmcia_socket_dev_resume,
651 +       },
652  };
653  
654  /* sa11x0_pcmcia_init()
655 @@ -100,7 +101,7 @@ static struct device_driver sa11x0_pcmcia_driver = {
656   */
657  static int __init sa11x0_pcmcia_init(void)
658  {
659 -       return driver_register(&sa11x0_pcmcia_driver);
660 +       return platform_driver_register(&sa11x0_pcmcia_driver);
661  }
662  
663  /* sa11x0_pcmcia_exit()
664 @@ -110,7 +111,7 @@ static int __init sa11x0_pcmcia_init(void)
665   */
666  static void __exit sa11x0_pcmcia_exit(void)
667  {
668 -       driver_unregister(&sa11x0_pcmcia_driver);
669 +       platform_driver_unregister(&sa11x0_pcmcia_driver);
670  }
671  
672  MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
673 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
674 index 66ec5d8..aba38d7 100644
675 --- a/drivers/spi/Kconfig
676 +++ b/drivers/spi/Kconfig
677 @@ -123,6 +123,10 @@ config SPI_MPC52xx_PSC
678           This enables using the Freescale MPC52xx Programmable Serial
679           Controller in master SPI mode.
680  
681 +config SPI_LOCOMO
682 +       tristate "Locomo SPI master"
683 +       depends on SPI_MASTER && SHARP_LOCOMO && EXPERIMENTAL
684 +
685  config SPI_MPC83xx
686         tristate "Freescale MPC83xx/QUICC Engine SPI controller"
687         depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
688 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
689 index 7fca043..b89992b 100644
690 --- a/drivers/spi/Makefile
691 +++ b/drivers/spi/Makefile
692 @@ -28,6 +28,7 @@ obj-$(CONFIG_SPI_S3C24XX)             += spi_s3c24xx.o
693  obj-$(CONFIG_SPI_TXX9)                 += spi_txx9.o
694  obj-$(CONFIG_SPI_XILINX)               += xilinx_spi.o
695  obj-$(CONFIG_SPI_SH_SCI)               += spi_sh_sci.o
696 +obj-$(CONFIG_SPI_LOCOMO)                += locomo_spi.o
697  #      ... add above this line ...
698  
699  # SPI protocol drivers (device/link on bus)
700 diff --git a/drivers/spi/locomo_spi.c b/drivers/spi/locomo_spi.c
701 new file mode 100644
702 index 0000000..d3a4bd9
703 --- /dev/null
704 +++ b/drivers/spi/locomo_spi.c
705 @@ -0,0 +1,1097 @@
706 +#include <asm/io.h>
707 +#include <asm/irq.h>
708 +#include <linux/module.h>
709 +#include <linux/init.h>
710 +#include <linux/device.h>
711 +#include <linux/stat.h>
712 +#include <linux/delay.h>
713 +#include <linux/wait.h>
714 +#include <linux/interrupt.h>
715 +#include <asm/hardware/locomo.h>
716 +#include <asm/errno.h>
717 +#include <linux/mmc/host.h>
718 +#include <linux/spi/spi.h>
719 +#include <linux/spi/mmc_spi.h>
720 +#include <linux/workqueue.h>
721 +#include <linux/spinlock.h>
722 +#include <linux/list.h>
723 +#include "locomo_spi.h"
724 +static struct locomospi_dev * spidev;
725 +static struct work_struct transfer_wq;
726 +int  delay;
727 +
728 +char* transtxbuf=(char*)NULL;
729 +char* transrxbuf=(char*)NULL;
730 +int transfercount=0, transfersize=0;
731 +static DECLARE_WAIT_QUEUE_HEAD(transferqueue);
732 +/* MMC_SPI functions *********************************************************/
733 +
734 +static int locomommcspi_init(struct device *dev, irqreturn_t (*isr)(int, void*), void *mmc)
735 +{
736 +       int result;
737 +       result=request_irq(IRQ_LOCOMO_CARDDETECT, isr, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "locomo-spi",  mmc);
738 +       return result;
739 +}
740 +
741 +static void locomommcspi_exit(struct device *dev, void* mmc)
742 +{
743 +       free_irq(IRQ_LOCOMO_CARDDETECT, mmc);
744 +}
745 +
746 +static int locomommcspi_getro(struct device *dev)
747 +{
748 +       return locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_WRITE_PROT) > 0 ? 1 : 0;
749 +}
750 +
751 +static void locomommcspi_setpower(struct device *dev, unsigned int mask)
752 +{
753 +       if(!mask && spidev->card_power)
754 +               locomospi_power(0);
755 +       else if( !spidev->card_power )
756 +               locomospi_power(1);
757 +
758 +}
759 +
760 +
761 +static struct mmc_spi_platform_data colliemmc ={
762 +       .init           = locomommcspi_init,
763 +       .exit           = locomommcspi_exit,
764 +       .detect_delay   = 200,
765 +       .get_ro         = locomommcspi_getro,
766 +       .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
767 +       .setpower       = locomommcspi_setpower,
768 +       .powerup_msecs  = 200,
769 +};
770 +
771 +/* Utility function **********************************************************/
772 +
773 +static void locomospi_power(int on)
774 +{
775 +       locomo_gpio_write(spidev->ldev->dev.parent, LOCOMO_GPIO_CARD_POWER, on);
776 +       spidev->card_power=on;
777 +       printk(KERN_DEBUG "locomospi: power %d\n",on);
778 +}
779 +
780 +static void locomospi_setclock(unsigned int div, unsigned int clock)
781 +{
782 +       u16 r = ioread16(spidev->base+LOCOMO_SPIMD);
783 +       div &= 0x7;
784 +       clock &= 0x3;
785 +       if(clock != spidev->clock_base || div != spidev->clock_div){
786 +               r &= ~(LOCOMO_SPI_XSEL  | LOCOMO_SPI_CLKSEL | LOCOMO_SPI_XEN);
787 +               iowrite16(r,spidev->base+LOCOMO_SPIMD);
788 +               r |=  (div | (clock <<3) | LOCOMO_SPI_XEN);
789 +               iowrite16(r,spidev->base+LOCOMO_SPIMD);
790 +               spidev->clock_div = div;
791 +               spidev->clock_base = clock;
792 +               udelay(300);
793 +       }
794 +
795 +}
796 +// returns 1 if card ist present, 0 otherwise
797 +static int locomospi_carddetect()
798 +{
799 +       return (locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_CARD_DETECT)>0)?0:1;
800 +}
801 +
802 +static void locomospi_setcs(int high)
803 +{
804 +       u16 r;
805 +       printk(KERN_DEBUG "locomospi: cs %d\n",high);
806 +       r = ioread16(spidev->base + LOCOMO_SPICT);
807 +       if(high)
808 +               r |= LOCOMO_SPI_CS;
809 +       else
810 +               r &= ~LOCOMO_SPI_CS;
811 +       iowrite16(r, spidev->base + LOCOMO_SPICT);
812 +}
813 +
814 +static void locomospi_reg_open()
815 +{
816 +       u16 r;
817 +       spidev->clock_div = DIV_64;
818 +       spidev->clock_base = CLOCK_18MHZ;
819 +       locomospi_power(1);
820 +       msleep(100);
821 +//     iowrite16( 0xec00 | (CLOCK_18MHZ <<3)|DIV_64, spidev->base+LOCOMO_SPIMD);
822 +       iowrite16( LOCOMO_SPI_MSB1ST | LOCOMO_SPI_DOSTAT | LOCOMO_SPI_RCPOL | LOCOMO_SPI_TCPOL 
823 +                       |(CLOCK_18MHZ <<3) | DIV_64, spidev->base+LOCOMO_SPIMD);
824 +//     if(locomospi_carddetect()){
825 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
826 +               r |= LOCOMO_SPI_XON;
827 +               iowrite16( r, spidev->base+LOCOMO_SPIMD);
828 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
829 +               r |= LOCOMO_SPI_XEN;
830 +               iowrite16( r, spidev->base+LOCOMO_SPIMD);
831 +//     }
832 +       iowrite16( LOCOMO_SPI_CS, spidev->base+LOCOMO_SPICT);
833 +       r = ioread16(spidev->base+LOCOMO_SPICT);
834 +       r |= (LOCOMO_SPI_CEN | LOCOMO_SPI_RXUEN | LOCOMO_SPI_ALIGNEN);
835 +       iowrite16( r, spidev->base+LOCOMO_SPICT);
836 +       udelay(200);
837 +       r = ioread16(spidev->base+LOCOMO_SPICT);
838 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
839 +       r = ioread16(spidev->base+LOCOMO_SPICT);
840 +       r &= ~LOCOMO_SPI_CS;
841 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
842 +}
843 +
844 +static void locomospi_reg_release()
845 +{
846 +       u16 r;
847 +       r = ioread16(spidev->base+LOCOMO_SPICT);
848 +       r &= ~LOCOMO_SPI_CEN;
849 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
850 +       r = ioread16(spidev->base+LOCOMO_SPIMD);
851 +       r &= ~LOCOMO_SPI_XEN;
852 +       iowrite16(r, spidev->base+LOCOMO_SPIMD);
853 +       r = ioread16(spidev->base+LOCOMO_SPIMD);
854 +       r &= ~LOCOMO_SPI_XON;
855 +       iowrite16(r, spidev->base+LOCOMO_SPIMD);
856 +       r = ioread16(spidev->base+LOCOMO_SPICT);
857 +       r |= LOCOMO_SPI_XEN;
858 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
859 +       locomospi_power(0);
860 +}
861 +#if 0
862 +static int txrx(const char* txbuffer, char* rxbuffer, int size)
863 +{
864 +       u16 r = ioread16(spidev->base+LOCOMO_SPICT);
865 +       r |= LOCOMO_SPI_ALIGNEN;
866 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
867 +       printk(KERN_DEBUG "locomospi: %d bytes to prozess\n",size);
868 +       /* initialize global vars for isr */
869 +       transfercount=0; transfersize=size; 
870 +       transtxbuf=txbuffer; transrxbuf=rxbuffer;
871 +
872 +       /* start transmit and go sleep  isr will wake us*/
873 +       enable_irq(IRQ_LOCOMO_SPI_TEND);
874 +       iowrite8(txbuffer[0], spidev->base+LOCOMO_SPITD);
875 +       wait_event(transferqueue, transfercount >= transfersize);
876 +       disable_irq(IRQ_LOCOMO_SPI_TEND);
877 +       transrxbuf=NULL; transtxbuf=NULL;
878 +       
879 +       r = ioread16(spidev->base+LOCOMO_SPICT);
880 +       r &= ~LOCOMO_SPI_ALIGNEN;
881 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
882 +       int i;
883 +       for(i=0; i< size; i++)
884 +               printk(KERN_DEBUG "locomospi: sent: %x  received: %x \n",txbuffer[i], rxbuffer[i]);
885 +       
886 +       
887 +       return size;
888 +}
889 +
890 +
891 +static int tx(const char* txbuffer, int size)
892 +{
893 +       printk(KERN_DEBUG "locomospi: %d bytes to send\n",size);
894 +       /* initialize global vars for isr */
895 +       transfercount=0; transfersize=size; 
896 +       transtxbuf=txbuffer; 
897 +
898 +       /* start transmit and go sleep  isr will wake us*/
899 +       enable_irq(IRQ_LOCOMO_SPI_RFW);
900 +       iowrite8(txbuffer[0], spidev->base+LOCOMO_SPITD);
901 +       wait_event(transferqueue, transfercount >= transfersize);
902 +       disable_irq(IRQ_LOCOMO_SPI_RFW);
903 +       transtxbuf=NULL;
904 +       
905 +       int i;
906 +       for(i=0; i< size; i++)
907 +               printk(KERN_DEBUG "locomospi: sent: %x\n",txbuffer[i]);
908 +       
909 +       
910 +       return size;
911 +}
912 +
913 +static int rx(char* rxbuffer, int size)
914 +{
915 +       printk(KERN_DEBUG "locomospi: %d bytes to read\n",size);
916 +       /* initialize global vars for isr */
917 +       transfercount=0; transfersize=size; 
918 +       transrxbuf=rxbuffer;
919 +
920 +       /* start transmit and go sleep  isr will wake us*/
921 +       enable_irq(IRQ_LOCOMO_SPI_RFR);
922 +       rxbuffer[0]=ioread8(spidev->base+LOCOMO_SPIRD);
923 +       wait_event(transferqueue, transfercount >= transfersize);
924 +       disable_irq(IRQ_LOCOMO_SPI_RFR);
925 +       transrxbuf=NULL;
926 +       
927 +       int i;
928 +       for(i=0; i< size; i++)
929 +               printk(KERN_DEBUG "locomospi: received: %x \n", rxbuffer[i]);
930 +       
931 +       
932 +       return size;
933 +}
934 +
935 +#else
936 +static int txrx(const char* txbuffer, char* rxbuffer, int size)
937 +{
938 +       int i=0,j=0;
939 +       int wait;
940 +       u16 r;
941 +/*     char * txback = kmalloc(size * sizeof(char), GFP_KERNEL);
942 +       memcpy(txback, txbuffer, size); 
943 +*/     
944 +       if(spidev->clock_div == 4)
945 +               wait = 0x10000;
946 +       else
947 +               wait = 8;
948 +       
949 +//     printk(KERN_DEBUG "locomospi: txrx %d bytes to prozess\n",size);
950 +       
951 +//     r = ioread16(spidev->base+LOCOMO_SPICT);
952 +//     r |= LOCOMO_SPI_ALIGNEN;
953 +//     iowrite16(r, spidev->base+LOCOMO_SPICT);
954 +       //discard first bogus byte
955 +
956 +       ioread8(spidev->base+LOCOMO_SPIRD);
957 +       for(i=0; i<size; i++){
958 +               for(j=0; j <= wait; j++){
959 +                       if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFW)
960 +                               break;
961 +               }
962 +               iowrite8(txbuffer[i], spidev->base+LOCOMO_SPITD);
963 +               ndelay(delay);
964 +               
965 +               for(j=0; j <= wait; j++){
966 +                       if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFR)
967 +                               break;
968 +               }
969 +               rxbuffer[i] = ioread8(spidev->base+LOCOMO_SPIRD);
970 +               ndelay(delay);
971 +       }
972 +//     r = ioread16(spidev->base+LOCOMO_SPICT);
973 +//     r &= ~LOCOMO_SPI_ALIGNEN;
974 +//     iowrite16(r, spidev->base+LOCOMO_SPICT);
975 +       
976 +/*     for(j=0; j< size; j++)
977 +               printk(KERN_DEBUG "locomospi: sent: %x  received: %x \n",txback[j], rxbuffer[j]);
978 +       
979 +       kfree(txback);  
980 +*/     return i;
981 +}
982 +
983 +static int tx(const char* buffer, int size)
984 +{
985 +       int i=0,j=0;
986 +       int wait;
987 +       u16 r;
988 +       if(spidev->clock_div == 4)
989 +               wait = 0x10000;
990 +       else
991 +               wait = 8;
992 +       r = ioread16(spidev->base+LOCOMO_SPICT);
993 +       r &= ~LOCOMO_SPI_ALIGNEN;
994 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
995 +
996 +//     printk(KERN_DEBUG "locomospi: tx %d bytes to transmit\n",size);
997 +       for(i=0; i<size; i++){
998 +               for(j=0; j <= wait; j++){
999 +                       if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFW)
1000 +                               break;
1001 +               }
1002 +               iowrite8(buffer[i], spidev->base+LOCOMO_SPITD);
1003 +               ndelay(delay);
1004 +       }
1005 +
1006 +       for(j=0; j <= wait; j++){
1007 +               if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_TEND)
1008 +                       break;
1009 +       }
1010 +       
1011 +       r = ioread16(spidev->base+LOCOMO_SPICT);
1012 +       r |= LOCOMO_SPI_ALIGNEN;
1013 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
1014 +       
1015 +//     for(j=0; j< size; j++)
1016 +//             printk(KERN_DEBUG "locomospi: sent: %x \n", buffer[j]);
1017 +//     printk(KERN_DEBUG "locomospi: tx %d bytes transmitted\n",i);
1018 +       return i;
1019 +}
1020 +
1021 +static int rx(char* buffer, int size)
1022 +{
1023 +       int i,j;
1024 +       int wait;
1025 +       u16 r;  
1026 +       printk(KERN_DEBUG "locomospi: rx %d bytes to receive\n",size);
1027 +       if(spidev->clock_div == 4)
1028 +               wait = 0x10000;
1029 +       else
1030 +               wait = 8;
1031 +       r = ioread16(spidev->base+LOCOMO_SPICT);
1032 +       r &= ~LOCOMO_SPI_ALIGNEN;
1033 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
1034 +
1035 +       for(i=0; i<size; i++){
1036 +
1037 +               for(j=0; j <= wait; j++){
1038 +                       if(ioread16(spidev->base+LOCOMO_SPIST) & LOCOMO_SPI_RFR)
1039 +                               break;
1040 +               }
1041 +               buffer[i]= ioread8(spidev->base+LOCOMO_SPIRD);
1042 +               ndelay(delay);
1043 +       }
1044 +       
1045 +       r = ioread16(spidev->base+LOCOMO_SPICT);
1046 +       r |= LOCOMO_SPI_ALIGNEN;
1047 +       iowrite16(r, spidev->base+LOCOMO_SPICT);
1048 +       
1049 +       for(j=0; j< size; j++)
1050 +               printk(KERN_DEBUG "locomospi: received: %x \n", buffer[j]);
1051 +       printk(KERN_DEBUG "locomospi: rx %d bytes received\n",i);
1052 +       return i;
1053 +}
1054 +#endif
1055 +/*
1056 +static irqreturn_t locomospi_rwready(int irq, void *dev_id)
1057 +{
1058 +       struct locomospi_dev* dev=(struct locomospi_dev*) dev_id;
1059 +//     dev_dbg(&spidev->sdev->dev, "IRQ: %d\n", irq);
1060 +//     printk(KERN_DEBUG "locomospi: IRQ: %d\n", irq);
1061 +       wake_up_interruptible(&dev->waitqueue);
1062 +       return IRQ_HANDLED;
1063 +}
1064 +*/
1065 +static irqreturn_t locomospi_testisr(int irq, void *dev_id)
1066 +{
1067 +       char *buf="";
1068 +       switch(irq){
1069 +               case IRQ_LOCOMO_SPI_RFR: buf="RFR";
1070 +                                        break;
1071 +               case IRQ_LOCOMO_SPI_RFW: buf="RFW";
1072 +                                        break;
1073 +               case IRQ_LOCOMO_SPI_REND:buf="REND";
1074 +                                        break;
1075 +               case IRQ_LOCOMO_SPI_TEND:buf="TEND";
1076 +                                        break;
1077 +               case IRQ_LOCOMO_CARDDETECT:
1078 +                                        buf="CARD_DETECT";
1079 +                                        break;
1080 +               default:                return IRQ_NONE;
1081 +       }
1082 +       printk(KERN_DEBUG "locomospi: IRQ: %s\n",buf);
1083 +//     dev_dbg(&spidev->sdev->dev, "IRQ: %s\n",buf);
1084 +       return IRQ_HANDLED;
1085 +}
1086 +static irqreturn_t locomospi_txrxisr(int irq, void *dev_id)
1087 +{
1088 +       if(transfercount < transfersize){
1089 +               transrxbuf[transfercount++] = ioread8(spidev->base+LOCOMO_SPIRD);
1090 +               iowrite8(transtxbuf[transfercount], spidev->base+LOCOMO_SPITD);                 
1091 +       }
1092 +       else{
1093 +               /* transfer complete. wake up txrx */
1094 +               wake_up(&transferqueue);
1095 +       }
1096 +       return IRQ_HANDLED;     
1097 +}      
1098 +
1099 +static irqreturn_t locomospi_txisr(int irq, void *dev_id)
1100 +{
1101 +       if(transfercount < transfersize){
1102 +               iowrite8(transtxbuf[transfercount++], spidev->base+LOCOMO_SPITD);               
1103 +       }
1104 +       else{
1105 +               /* transfer complete. wake up txrx */
1106 +               wake_up(&transferqueue);
1107 +       }
1108 +       return IRQ_HANDLED;     
1109 +}      
1110 +
1111 +static irqreturn_t locomospi_rxisr(int irq, void *dev_id)
1112 +{
1113 +       if(transfercount < transfersize){
1114 +               transrxbuf[transfercount++] = ioread8(spidev->base+LOCOMO_SPIRD);
1115 +       }
1116 +       else{
1117 +               /* transfer complete. wake up txrx */
1118 +               wake_up(&transferqueue);
1119 +       }
1120 +       return IRQ_HANDLED;     
1121 +}      
1122 +
1123 +static void locomospi_clock(unsigned int Hz)
1124 +{
1125 +       u16 r;
1126 +       printk(KERN_DEBUG "locomospi: changing clock to: %d\n", Hz);
1127 +       if(Hz == 0){
1128 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1129 +               r &= ~LOCOMO_SPI_XON;
1130 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1131 +       }
1132 +       else if(Hz >= 24576000){
1133 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1134 +               r |= LOCOMO_SPI_XON;
1135 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1136 +               locomospi_setclock(DIV_1, CLOCK_25MHZ);
1137 +               delay=41;
1138 +       }
1139 +       else if(Hz >= 22579200){
1140 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1141 +               r |= LOCOMO_SPI_XON;
1142 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1143 +               locomospi_setclock(DIV_1, CLOCK_22MHZ);
1144 +               delay=45;
1145 +       }
1146 +       else if(Hz >= 18432000){
1147 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1148 +               r |= LOCOMO_SPI_XON;
1149 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1150 +               locomospi_setclock(DIV_1, CLOCK_18MHZ);
1151 +               delay=55;
1152 +       }
1153 +       else if(Hz >= 12288000){
1154 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1155 +               r |= LOCOMO_SPI_XON;
1156 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1157 +               locomospi_setclock(DIV_2, CLOCK_25MHZ);
1158 +               delay=82;
1159 +       }
1160 +       else if(Hz >= 11289600){
1161 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1162 +               r |= LOCOMO_SPI_XON;
1163 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1164 +               locomospi_setclock(DIV_2, CLOCK_22MHZ);
1165 +               delay=89;
1166 +       }
1167 +       else if(Hz >= 9216000){
1168 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1169 +               r |= LOCOMO_SPI_XON;
1170 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1171 +               locomospi_setclock(DIV_2, CLOCK_18MHZ);
1172 +               delay=110;
1173 +       }
1174 +       else if(Hz >= 6144000){
1175 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1176 +               r |= LOCOMO_SPI_XON;
1177 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1178 +               locomospi_setclock(DIV_4, CLOCK_25MHZ);
1179 +               delay=164;
1180 +       }
1181 +       else if(Hz >= 5644800){
1182 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1183 +               r |= LOCOMO_SPI_XON;
1184 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1185 +               locomospi_setclock(DIV_4, CLOCK_22MHZ);
1186 +               delay=178;
1187 +       }
1188 +       else if(Hz >= 4608000){
1189 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1190 +               r |= LOCOMO_SPI_XON;
1191 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1192 +               locomospi_setclock(DIV_4, CLOCK_18MHZ);
1193 +               delay=218;
1194 +       }
1195 +       else if(Hz >= 3072000){
1196 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1197 +               r |= LOCOMO_SPI_XON;
1198 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1199 +               locomospi_setclock(DIV_8, CLOCK_25MHZ);
1200 +               delay=327;
1201 +       }
1202 +       else if(Hz >= 2822400){
1203 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1204 +               r |= LOCOMO_SPI_XON;
1205 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1206 +               locomospi_setclock(DIV_8, CLOCK_22MHZ);
1207 +               delay=355;
1208 +       }
1209 +       else if(Hz >= 2304000){
1210 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1211 +               r |= LOCOMO_SPI_XON;
1212 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1213 +               locomospi_setclock(DIV_8, CLOCK_18MHZ);
1214 +               delay=435;
1215 +       }
1216 +       else if(Hz >= 384000){
1217 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1218 +               r |= LOCOMO_SPI_XON;
1219 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1220 +               locomospi_setclock(DIV_64, CLOCK_25MHZ);
1221 +               delay=2605;
1222 +       }
1223 +       else if(Hz >= 352800){
1224 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1225 +               r |= LOCOMO_SPI_XON;
1226 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1227 +               locomospi_setclock(DIV_64, CLOCK_22MHZ);
1228 +               delay=2834;
1229 +       }
1230 +       else{ /* set to 288 KHz */
1231 +               r = ioread16(spidev->base+LOCOMO_SPIMD);
1232 +               r |= LOCOMO_SPI_XON;
1233 +               iowrite16(r, spidev->base+LOCOMO_SPIMD);
1234 +               locomospi_setclock(DIV_64, CLOCK_18MHZ);
1235 +               delay=3473;
1236 +       }
1237 +       spidev->clock = Hz;
1238 +}
1239 +
1240 +/* sysfs attributes used for debug *******************************************/
1241 +
1242 +/* SPI registers */
1243 +ssize_t locomospi_showspimd(struct device_driver *drv, char *buf)
1244 +{
1245 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIMD));
1246 +}
1247 +
1248 +ssize_t locomospi_storespimd(struct device_driver *drv, const char *buf, size_t count)
1249 +{
1250 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIMD);
1251 +       return count;
1252 +}
1253 +static DRIVER_ATTR(spimd, S_IWUSR | S_IRUGO, locomospi_showspimd, locomospi_storespimd);
1254 +
1255 +ssize_t locomospi_showspict(struct device_driver *drv, char *buf)
1256 +{
1257 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPICT));
1258 +}
1259 +
1260 +ssize_t locomospi_storespict(struct device_driver *drv, const char *buf, size_t count)
1261 +{
1262 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPICT);
1263 +       return count;
1264 +}
1265 +static DRIVER_ATTR(spict, S_IWUSR | S_IRUGO, locomospi_showspict, locomospi_storespict);
1266 +
1267 +ssize_t locomospi_showspist(struct device_driver *drv, char *buf)
1268 +{
1269 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIST));
1270 +}
1271 +
1272 +ssize_t locomospi_storespist(struct device_driver *drv, const char *buf, size_t count)
1273 +{
1274 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIST);
1275 +       return count;
1276 +}
1277 +static DRIVER_ATTR(spist, S_IWUSR | S_IRUGO, locomospi_showspist, locomospi_storespist);
1278 +
1279 +ssize_t locomospi_showspitd(struct device_driver *drv, char *buf)
1280 +{
1281 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPITD));
1282 +}
1283 +
1284 +ssize_t locomospi_storespitd(struct device_driver *drv, const char *buf, size_t count)
1285 +{
1286 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPITD);
1287 +       return count;
1288 +}
1289 +static DRIVER_ATTR(spitd, S_IWUSR | S_IRUGO, locomospi_showspitd, locomospi_storespitd);
1290 +
1291 +ssize_t locomospi_showspird(struct device_driver *drv, char *buf)
1292 +{
1293 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIRD));
1294 +}
1295 +
1296 +ssize_t locomospi_storespird(struct device_driver *drv, const char *buf, size_t count)
1297 +{
1298 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIRD);
1299 +       return count;
1300 +}
1301 +static DRIVER_ATTR(spird, S_IWUSR | S_IRUGO, locomospi_showspird, locomospi_storespird);
1302 +
1303 +ssize_t locomospi_showspits(struct device_driver *drv, char *buf)
1304 +{
1305 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPITS));
1306 +}
1307 +
1308 +ssize_t locomospi_storespits(struct device_driver *drv, const char *buf, size_t count)
1309 +{
1310 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPITS);
1311 +       return count;
1312 +}
1313 +static DRIVER_ATTR(spits, S_IWUSR | S_IRUGO, locomospi_showspits, locomospi_storespits);
1314 +
1315 +ssize_t locomospi_showspirs(struct device_driver *drv, char *buf)
1316 +{
1317 +       return sprintf(buf, "0x%x\n", ioread16(spidev->base+LOCOMO_SPIRS));
1318 +}
1319 +
1320 +ssize_t locomospi_storespirs(struct device_driver *drv, const char *buf, size_t count)
1321 +{
1322 +       iowrite16(simple_strtoul(buf, NULL, 16), spidev->base+LOCOMO_SPIRS);
1323 +       return count;
1324 +}
1325 +static DRIVER_ATTR(spirs, S_IWUSR | S_IRUGO, locomospi_showspirs, locomospi_storespirs);
1326 +
1327 +/* MMC Card status */
1328 +
1329 +ssize_t locomospi_showpower(struct device_driver *drv, char *buf)
1330 +{
1331 +       return sprintf(buf, "%d\n", spidev->card_power);
1332 +}
1333 +
1334 +ssize_t locomospi_storepower(struct device_driver *drv, const char *buf, size_t count)
1335 +{
1336 +       locomospi_power(simple_strtoul(buf, NULL, 10));
1337 +       return count;
1338 +}
1339 +static DRIVER_ATTR(cardpower, S_IWUSR | S_IRUGO, locomospi_showpower, locomospi_storepower);
1340 +
1341 +ssize_t locomospi_detectcard(struct device_driver *drv, char *buf)
1342 +{
1343 +       return sprintf(buf, "%d\n",(locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_CARD_DETECT)>0)?0:1);
1344 +}
1345 +static DRIVER_ATTR(carddetect, S_IRUGO, locomospi_detectcard, NULL);
1346 +
1347 +ssize_t locomospi_writeprotect(struct device_driver *drv, char *buf)
1348 +{
1349 +       return sprintf(buf, "%d\n",(locomo_gpio_read_level(spidev->ldev->dev.parent,LOCOMO_GPIO_WRITE_PROT)>0)?1:0);
1350 +}
1351 +static DRIVER_ATTR(cardwriteprotect, S_IRUGO, locomospi_writeprotect, NULL);
1352 +
1353 +
1354 +ssize_t locomospi_showclock(struct device_driver *drv, char *buf)
1355 +{
1356 +       return sprintf(buf, "%d\n", spidev->clock);
1357 +}
1358 +
1359 +ssize_t locomospi_storeclock(struct device_driver *drv, const char *buf, size_t count)
1360 +{
1361 +       locomospi_clock(simple_strtoul(buf, NULL, 10));
1362 +       return count;
1363 +}
1364 +static DRIVER_ATTR(clock, S_IWUSR | S_IRUGO, locomospi_showclock, locomospi_storeclock);
1365 +
1366 +/* debug */
1367 +ssize_t locomospi_showdelay(struct device_driver *drv, char *buf)
1368 +{
1369 +       return sprintf(buf, "%d\n", delay);
1370 +}
1371 +
1372 +ssize_t locomospi_storedelay(struct device_driver *drv, const char *buf, size_t count)
1373 +{
1374 +       delay=simple_strtoul(buf,NULL,10);
1375 +       return count;
1376 +}
1377 +static DRIVER_ATTR(delay, S_IWUSR | S_IRUGO, locomospi_showdelay, locomospi_storedelay);
1378 +
1379 +ssize_t locomospi_reset(struct device_driver *drv, const char *buf, size_t count)
1380 +{
1381 +       int choice = simple_strtoul(buf, NULL, 10);
1382 +       char   buff[100];
1383 +       u16 r; 
1384 +       switch(choice){
1385 +               case 0: locomospi_reg_release();
1386 +                       schedule_timeout(2*HZ);
1387 +                       locomospi_reg_open();
1388 +                       break;
1389 +               case 1: {
1390 +                               char b1[] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
1391 +                               char b2[] = "\xff\x40\x00\x00\x00\x00\x95\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
1392 +                               locomospi_setcs(1);
1393 +                               txrx(b1,b1,17);
1394 +                               locomospi_setcs(0);
1395 +                               txrx(b2,b2,18);
1396 +
1397 +                       }
1398 +                       break;
1399 +               case 2: locomospi_setcs(1);
1400 +                       txrx("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",buff,18);
1401 +                       locomospi_setcs(0);
1402 +                       txrx("\xff\x40\x00\x00\x00\x00\x95\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff",buff,17);
1403 +                       break;
1404 +               case 3: 
1405 +                       r = ioread16(spidev->base+LOCOMO_SPIMD);
1406 +                       r |= LOCOMO_SPI_LOOPBACK;
1407 +                       iowrite16(r, spidev->base+LOCOMO_SPIMD);
1408 +                       txrx("X",buff,1);
1409 +                       txrx("abcdefghijklmnopqrstuvwxyz1234567890",buff,36);
1410 +                       txrx("Y",buff,1);
1411 +                       udelay(100);
1412 +                       txrx("Z",buff,1);
1413 +                       schedule_timeout(HZ);   
1414 +                       txrx("abcdefghijklmnopqrstuvwxyz1234567890",buff,36);
1415 +                       
1416 +                       r = ioread16(spidev->base+LOCOMO_SPIMD);
1417 +                       r &= ~LOCOMO_SPI_LOOPBACK;
1418 +                       iowrite16(r, spidev->base+LOCOMO_SPIMD);
1419 +                       break;
1420 +               default: /* do nothing */;
1421 +       }
1422 +       return count;
1423 +}
1424 +static DRIVER_ATTR(reset, S_IWUSR, NULL, locomospi_reset);
1425 +
1426 +typedef struct locomo_reg_entry {
1427 +        u32 addr;
1428 +        char* name;
1429 +} locomo_reg_entry_t;
1430 +#define LCM     (sizeof(locomo_regs)/sizeof(locomo_reg_entry_t))
1431 +static locomo_reg_entry_t locomo_regs[] =
1432 +{
1433 +/*      { addr,    name,     description } */
1434 +        { 0x00, "VER" },
1435 +        { 0x04, "ST" },
1436 +        { 0x08, "C32K" },
1437 +        { 0x0C, "ICR" },
1438 +        { 0x10, "MCSX0" },
1439 +        { 0x14, "MCSX1" },
1440 +        { 0x18, "MCSX2" },
1441 +        { 0x1C, "MCSX3" },
1442 +        { 0x20, "ASD" },
1443 +        { 0x28, "HSD" },
1444 +        { 0x2C, "HSC" },
1445 +        { 0x30, "TADC" },
1446 +        { 0x38, "TC" },
1447 +        { 0x3C, "CPSD" },
1448 +        { 0x40, "KIB" },
1449 +        { 0x44, "KSC" },
1450 +        { 0x48, "KCMD" },
1451 +        { 0x4C, "KIC" },
1452 +        { 0x54, "ACC" },
1453 +        { 0x60, "SPIMD" },
1454 +        { 0x64, "SPICT" },
1455 +        { 0x68, "SPIST" },
1456 +        { 0x70, "SPIIS" },
1457 +        { 0x74, "SPIWE" },
1458 +        { 0x78, "SPIIE" },
1459 +        { 0x7C, "SPIIR" },
1460 +        { 0x80, "SPITD" },
1461 +        { 0x84, "SPIRD" },
1462 +        { 0x88, "SPITS" },
1463 +        { 0x8C, "SPIRS" },
1464 +        { 0x90, "GPD" },
1465 +        { 0x94, "GPE" },
1466 +        { 0x98, "GPL" },
1467 +        { 0x9C, "GPO" },
1468 +        { 0xa0, "GRIE" },
1469 +        { 0xa4, "GFIE" },
1470 +        { 0xa8, "GIS" },
1471 +        { 0xac, "GWE" },
1472 +        { 0xb0, "GIE" },
1473 +        { 0xb4, "GIR" },
1474 +        { 0xc8, "ALC" },
1475 +        { 0xcc, "ALR" },
1476 +        { 0xd0, "PAIF" },
1477 +        { 0xd8, "LTC" },
1478 +        { 0xdc, "LTINT" },
1479 +        { 0xe0, "DAC" },
1480 +        { 0xe8, "LPT0" },
1481 +        { 0xec, "LPT1" },
1482 +        { 0xfc, "TCR" },
1483 +};
1484 +
1485 +static ssize_t lcm_show(struct device *dev, struct device_attribute *attr, char *buf)
1486 +{
1487 +       int base = spidev->base - LOCOMO_SPI; 
1488 +       char b[4000]="";
1489 +       char c[30];
1490 +       int i;
1491 +       for(i=0; i<LCM; i++){
1492 +               sprintf(c,"%s:\t\t 0x%x\n",locomo_regs[i].name, ioread16(base + locomo_regs[i].addr));
1493 +               strcat(b,c);
1494 +       }
1495 +       return sprintf(buf,"%s",b);
1496 +}
1497 +
1498 +static DRIVER_ATTR(regs, 0444, lcm_show, NULL);
1499 +
1500 +
1501 +/* SPI functions *************************************************************/
1502 +
1503 +static void locomospi_do_transfer(struct work_struct *wrk)
1504 +{
1505 +       struct list_head *mptr, *tptr, *mptr2;
1506 +       struct spi_transfer *entry;
1507 +       struct spi_message *msg;
1508 +
1509 +       list_for_each_safe(mptr, mptr2, &spidev->message_list){
1510 +               msg = list_entry(mptr, struct spi_message, queue);
1511 +
1512 +               msg->status = 0;
1513 +               msg->actual_length = 0;
1514 +               list_for_each(tptr, &msg->transfers){
1515 +                       entry = list_entry(tptr, struct spi_transfer, transfer_list);
1516 +                       if(entry->tx_buf && entry->rx_buf){ //duplex
1517 +                               txrx((char*) entry->tx_buf, (char*) entry->rx_buf, entry->len);                         
1518 +                               msg->actual_length += entry->len;
1519 +                       } else if(entry->tx_buf && !entry->rx_buf){ //write
1520 +                               tx((char*) entry->tx_buf, entry->len);
1521 +                               msg->actual_length += entry->len;
1522 +                       } else if(!entry->tx_buf && entry->rx_buf){ //read
1523 +                               rx((char*) entry->rx_buf, entry->len);
1524 +                               msg->actual_length += entry->len;
1525 +                       } else if(!entry->tx_buf && !entry->rx_buf){ //error
1526 +                               dev_err(&spidev->sdev->dev, "do_transfer: no buffers allocated\n");
1527 +                               msg->status = -EFAULT;
1528 +                       }
1529 +               }
1530 +               spin_lock(&spidev->message_lock);
1531 +               list_del(mptr);
1532 +               spin_unlock(&spidev->message_lock);
1533 +               msg->complete(msg->context);
1534 +       }
1535 +}
1536 +
1537 +static int locomospi_setup(struct spi_device *spi)
1538 +{
1539 +       if((spi->mode & SPI_CS_HIGH) != (spidev->spimode & SPI_CS_HIGH)) 
1540 +               locomospi_setcs(spi->mode & SPI_CS_HIGH ? 1 : 0 );
1541 +       if(spidev->clock != spi->max_speed_hz){
1542 +               locomospi_clock(spi->max_speed_hz);
1543 +       }
1544 +       spidev->spimode = spi->mode;
1545 +
1546 +       return 0;
1547 +}
1548 +
1549 +static int locomospi_transfer(struct spi_device *spi, struct spi_message *msg)
1550 +{
1551 +
1552 +       spin_lock(&spidev->message_lock);
1553 +       list_add_tail(&msg->queue, &spidev->message_list);
1554 +       spin_unlock(&spidev->message_lock);
1555 +       schedule_work(&transfer_wq);
1556 +       return 0;
1557 +}
1558 +
1559 +static struct locomo_driver locomo_spi_driver = {
1560 +       .drv = {
1561 +               .name = "locomo-spi",
1562 +       },
1563 +       .devid  = LOCOMO_DEVID_SPI,
1564 +       .probe  = locomospi_probe,
1565 +       .remove = locomospi_remove,
1566 +#ifdef CONFIG_PM
1567 +       .suspend = locomospi_suspend,
1568 +       .resume = locomospi_resume,
1569 +#endif
1570 +};
1571 +
1572 +static struct spi_board_info board = {
1573 +       .modalias       = "mmc_spi",
1574 +       .platform_data  = (void*) &colliemmc,
1575 +       .controller_data= NULL,
1576 +       .irq            = 0,
1577 +       .max_speed_hz   = 25000000,
1578 +       .bus_num        = 0,
1579 +       .chip_select    = 0,
1580 +       .mode           = 0,
1581 +};
1582 +
1583 +#ifdef CONFIG_PM
1584 +static int locomospi_suspend(struct locomo_dev *dev, pm_message_t state)
1585 +{
1586 +       disable_irq(IRQ_LOCOMO_CARDDETECT);
1587 +       return 0;
1588 +}
1589 +
1590 +static int locomospi_resume(struct locomo_dev *dev)
1591 +{
1592 +       enable_irq(IRQ_LOCOMO_CARDDETECT);
1593 +       return 0;
1594 +}
1595 +#endif
1596 +
1597 +static int locomospi_probe(struct locomo_dev *dev)
1598 +{
1599 +       int result=0;
1600 +       printk(KERN_DEBUG "Collie MMC over SPI Driver\n");
1601 +       spidev=kmalloc(sizeof(struct locomospi_dev),GFP_KERNEL);
1602 +       if(!spidev){
1603 +               return -ENOMEM;
1604 +       }
1605 +       spidev->ldev = dev;
1606 +       spidev->card_power = 1;
1607 +       spidev->spimode = 0;
1608 +
1609 +       if(!request_mem_region((unsigned long) dev->mapbase, dev->length, LOCOMO_DRIVER_NAME(dev))) {
1610 +               dev_err(&dev->dev, " Can't aquire access to io memory\n");
1611 +               return -EBUSY;
1612 +       }
1613 +       spidev->base=(unsigned long) dev->mapbase;
1614 +       locomospi_reg_open();
1615 +
1616 +       locomo_gpio_set_dir(dev->dev.parent, LOCOMO_GPIO_CARD_POWER, 0);
1617 +       locomo_gpio_set_dir(dev->dev.parent, LOCOMO_GPIO_CARD_DETECT, 1);
1618 +       locomo_gpio_set_dir(dev->dev.parent, LOCOMO_GPIO_WRITE_PROT, 1);
1619 +
1620 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_cardpower);
1621 +       if(result){
1622 +               dev_err(&dev->dev, "error creating driver attribute\n");
1623 +               goto region;
1624 +       }
1625 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_carddetect);
1626 +       if(result){
1627 +               dev_err(&dev->dev,"error creating driver attribute\n");
1628 +               goto region;
1629 +       }
1630 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_cardwriteprotect);
1631 +       if(result){
1632 +               dev_err(&dev->dev, "error creating driver attribute\n");
1633 +               goto region;
1634 +       }
1635 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spimd);
1636 +       if(result){
1637 +               dev_err(&dev->dev, "error creating driver attribute\n");
1638 +               goto region;
1639 +       }
1640 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spict);
1641 +       if(result){
1642 +               dev_err(&dev->dev, "error creating driver attribute\n");
1643 +               goto region;
1644 +       }
1645 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spist);
1646 +       if(result){
1647 +               dev_err(&dev->dev, "error creating driver attribute\n");
1648 +               goto region;
1649 +       }
1650 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spitd);
1651 +       if(result){
1652 +               dev_err(&dev->dev, "error creating driver attribute\n");
1653 +               goto region;
1654 +       }
1655 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spird);
1656 +       if(result){
1657 +               dev_err(&dev->dev, "error creating driver attribute\n");
1658 +               goto region;
1659 +       }
1660 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spits);
1661 +       if(result){
1662 +               dev_err(&dev->dev, "error creating driver attribute\n");
1663 +               goto region;
1664 +       }
1665 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_spirs);
1666 +       if(result){
1667 +               dev_err(&dev->dev, "error creating driver attribute\n");
1668 +               goto region;
1669 +       }
1670 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_clock);
1671 +       if(result){
1672 +               dev_err(&dev->dev, "error creating driver attribute\n");
1673 +               goto region;
1674 +       }
1675 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_delay);
1676 +       if(result){
1677 +               dev_err(&dev->dev, "error creating driver attribute\n");
1678 +               goto region;
1679 +       }
1680 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_reset);
1681 +       if(result){
1682 +               dev_err(&dev->dev, "error creating driver attribute\n");
1683 +               goto region;
1684 +       }
1685 +       result=driver_create_file(&locomo_spi_driver.drv, &driver_attr_regs);
1686 +        if(result){
1687 +                dev_err(&dev->dev, "error creating driver attribute\n");
1688 +                goto region;
1689 +        }
1690 +       INIT_WORK(&transfer_wq, locomospi_do_transfer);
1691 +       INIT_LIST_HEAD(&spidev->message_list);
1692 +       spin_lock_init(&spidev->message_lock);
1693 +       init_waitqueue_head(&spidev->waitqueue);
1694 +       spidev->master=spi_alloc_master(&dev->dev,0);
1695 +       if(!spidev->master){
1696 +               result=-ENOMEM;
1697 +               goto region;
1698 +       }
1699 +       spidev->master->bus_num = 0;
1700 +       spidev->master->num_chipselect = 1;
1701 +       spidev->master->setup = locomospi_setup;
1702 +       spidev->master->transfer = locomospi_transfer;
1703 +       spidev->sdev = spi_new_device(spidev->master, &board);
1704 +       if(!spidev->sdev){
1705 +               dev_err(&dev->dev, "failed to register spi device\n");
1706 +               result = -EINVAL;
1707 +               goto master;
1708 +       }
1709 +/*     result=request_irq(IRQ_LOCOMO_SPI_RFR, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1710 +       if(result) {
1711 +               dev_err(&dev->dev, "Could not get IRQ: RFR\n");
1712 +               goto regdev;
1713 +       }
1714 +       //disable_irq(IRQ_LOCOMO_SPI_RFR);
1715 +*//*   result=request_irq(IRQ_LOCOMO_SPI_RFW, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1716 +       if(result) {
1717 +               dev_err(&dev->dev, "Could not get IRQ: RFW\n");
1718 +               goto irq1;
1719 +       }
1720 +       //disable_irq(IRQ_LOCOMO_SPI_RFW);
1721 +*//*   result=request_irq(IRQ_LOCOMO_SPI_REND, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1722 +       if(result) {
1723 +               dev_err(&dev->dev, "Could not get IRQ: REND\n");
1724 +               goto irq2;
1725 +       }
1726 +*//*   result=request_irq(IRQ_LOCOMO_SPI_TEND, locomospi_testisr, IRQF_SHARED, "locomo-spi", (void*) spidev);
1727 +       if(result) {
1728 +               dev_err(&dev->dev, "Could not get IRQ: TEND\n");
1729 +               goto irq3;
1730 +       }
1731 +       //disable_irq(IRQ_LOCOMO_SPI_TEND);     
1732 +*/     spidev->workqueue = create_singlethread_workqueue("locomo-spi");
1733 +       if(!spidev->workqueue){
1734 +               dev_err(&dev->dev, "failed to create workqueue\n");
1735 +               goto irq4;
1736 +       }
1737 +       result=spi_register_master(spidev->master);
1738 +       if(result){
1739 +               dev_err(&dev->dev, "failed to register spimaster\n");
1740 +               goto wq;
1741 +       }
1742 +       return 0;
1743 +wq:
1744 +       destroy_workqueue(spidev->workqueue);
1745 +irq4:
1746 +//     free_irq(IRQ_LOCOMO_SPI_TEND, (void*) spidev);
1747 +irq3:
1748 +//     free_irq(IRQ_LOCOMO_SPI_REND, (void*) spidev);
1749 +irq2:
1750 +//     free_irq(IRQ_LOCOMO_SPI_RFW, (void*) spidev);
1751 +irq1:
1752 +//     free_irq(IRQ_LOCOMO_SPI_RFR, (void*) spidev);
1753 +regdev:
1754 +       spi_unregister_device(spidev->sdev);
1755 +master:
1756 +       spi_master_put(spidev->master);
1757 +region:
1758 +       release_mem_region((unsigned long) dev->mapbase, dev->length);
1759 +       kfree(spidev);
1760 +       return result;
1761 +
1762 +}
1763 +
1764 +static int locomospi_remove(struct locomo_dev *dev)
1765 +{
1766 +       spi_unregister_device(spidev->sdev);
1767 +       spi_unregister_master(spidev->master);
1768 +       destroy_workqueue(spidev->workqueue);
1769 +       locomospi_reg_release();
1770 +//     free_irq(IRQ_LOCOMO_SPI_TEND, (void*) spidev);
1771 +//     free_irq(IRQ_LOCOMO_SPI_REND, (void*) spidev);
1772 +//     free_irq(IRQ_LOCOMO_SPI_RFW, (void*) spidev);
1773 +//     free_irq(IRQ_LOCOMO_SPI_RFR, (void*) spidev);
1774 +       spi_master_put(spidev->master);
1775 +       release_mem_region((unsigned long) dev->mapbase, dev->length);
1776 +       kfree(spidev);
1777 +       return 0;
1778 +}
1779 +
1780 +
1781 +
1782 +static int __init locomospi_init(void)
1783 +{
1784 +       int ret = locomo_driver_register(&locomo_spi_driver);
1785 +       if (ret)
1786 +               return ret;
1787 +
1788 +
1789 +       return 0;
1790 +}
1791 +
1792 +static void __exit locomospi_exit(void)
1793 +{
1794 +       locomo_driver_unregister(&locomo_spi_driver);
1795 +}
1796 +
1797 +module_init(locomospi_init);
1798 +module_exit(locomospi_exit);
1799 +
1800 +MODULE_AUTHOR("Thomas Kunze thommy@tabao.de");
1801 +MODULE_DESCRIPTION("Collie mmc driver");
1802 +MODULE_LICENSE("GPL");
1803 diff --git a/drivers/spi/locomo_spi.h b/drivers/spi/locomo_spi.h
1804 new file mode 100644
1805 index 0000000..7e1c0ce
1806 --- /dev/null
1807 +++ b/drivers/spi/locomo_spi.h
1808 @@ -0,0 +1,75 @@
1809 +#include <asm/hardware/locomo.h>
1810 +#ifndef __LOCOMO_SPI_H__
1811 +#define __LOCOMO_SPI_H__
1812 +
1813 +/* locomo-spi status register LOCOMO_SPIST */
1814 +#define LOCOMO_SPI_TEND (1 << 3)        /* Transfer end bit */
1815 +#define LOCOMO_SPI_REND (1 << 2)        /* Receive end bit */
1816 +#define LOCOMO_SPI_RFW  (1 << 1)        /* write buffer bit */
1817 +#define LOCOMO_SPI_RFR  (1)             /* read buffer bit */
1818 +
1819 +/* locomo-spi mode register LOCOMO_SPIMD */
1820 +#define LOCOMO_SPI_LOOPBACK (1 << 15)  /* loopback tx to rx    */
1821 +#define LOCOMO_SPI_MSB1ST   (1 << 14)  /* send MSB first       */
1822 +#define LOCOMO_SPI_DOSTAT   (1 << 13)  /* transmit line is idle high */
1823 +#define LOCOMO_SPI_TCPOL    (1 << 11)  /* transmit CPOL (maybe affects CPHA too) */
1824 +#define LOCOMO_SPI_RCPOL    (1 << 10)  /* receive CPOL (maybe affects CPHA too) */
1825 +#define        LOCOMO_SPI_TDINV    (1 << 9)    /* invert transmit line */
1826 +#define LOCOMO_SPI_RDINV    (1 << 8)   /* invert receive line */
1827 +#define LOCOMO_SPI_XON     (1 << 7)    /* enable spi controller clock */
1828 +#define LOCOMO_SPI_XEN     (1 << 6)    /* clock bit write enable xon must be off, wait 300 us before xon->1 */ 
1829 +#define LOCOMO_SPI_XSEL            0x0018      /* clock select                 */
1830 +#define CLOCK_18MHZ        0           /* 18,432 MHz clock     */
1831 +#define CLOCK_22MHZ        1           /* 22,5792 MHz clock    */
1832 +#define CLOCK_25MHZ        2           /* 24,576 MHz clock     */
1833 +#define LOCOMO_SPI_CLKSEL   0x7        
1834 +#define DIV_1              0           /* don't divide clock   */
1835 +#define DIV_2              1           /* divide clock by two  */
1836 +#define DIV_4              2           /* divide clock by four */
1837 +#define DIV_8              3           /* divide clock by eight*/
1838 +#define DIV_64             4           /* divide clock by 64 */
1839 +
1840 +/* locomo-spi control register LOCOMO_SPICT */
1841 +#define LOCOMO_SPI_CRC16_7_B   (1 << 15)       /* 0: crc16 1: crc7 */
1842 +#define LOCOMO_SPI_CRCRX_TX_B  (1 << 14)
1843 +#define LOCOMO_SPI_CRCRESET_B  (1 << 13)
1844 +#define LOCOMO_SPI_CEN         (1 << 7)        /* ?? enable */
1845 +#define LOCOMO_SPI_CS          (1 << 6)        /* chip select */
1846 +#define LOCOMO_SPI_UNIT16      (1 << 5)        /* 0: 8 bit units, 1: 16 bit unit */
1847 +#define LOCOMO_SPI_ALIGNEN     (1 << 2)        /* align transfer enable */
1848 +#define LOCOMO_SPI_RXWEN       (1 << 1)        /* continous receive */
1849 +#define LOCOMO_SPI_RXUEN       (1 << 0)        /* aligned receive */
1850 +
1851 +#define IRQ_LOCOMO_CARDDETECT  IRQ_LOCOMO_GPIO13
1852 +
1853 +
1854 +struct locomospi_dev {
1855 +       struct locomo_dev *ldev;
1856 +       struct spi_master *master;
1857 +       struct spi_device *sdev;
1858 +       int card_power;
1859 +       int clock_base;
1860 +       int clock_div;
1861 +       int clock;
1862 +       unsigned long base;
1863 +       u8 spimode;
1864 +       wait_queue_head_t waitqueue;
1865 +       struct workqueue_struct *workqueue;
1866 +       struct list_head message_list;
1867 +       spinlock_t message_lock;
1868 +};
1869 +
1870 +
1871 +static irqreturn_t     locomospi_cardisr(int, void*);
1872 +static int     locomospi_probe(struct locomo_dev*);
1873 +static int     locomospi_remove(struct locomo_dev*);
1874 +static int     locomospi_carddetect(void);
1875 +static void    locomospi_reg_open(void);
1876 +static void    locomospi_reg_release(void);
1877 +static int     tx(const char*, int);
1878 +static int     rx(char *, int);
1879 +static void    locomospi_power(int on);
1880 +static int locomospi_suspend(struct locomo_dev *dev, pm_message_t state);
1881 +static int locomospi_resume(struct locomo_dev *dev);
1882 +static void locomospi_setcs(int high);
1883 +#endif