[lantiq] update 3.2 patches
[openwrt.git] / target / linux / lantiq / patches-3.2 / 0038-SPI-MIPS-lantiq-add-FALC-ON-spi-driver.patch
1 From addbb26930d41b35e329d0ad6413cc8d087aa4cc Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Sat, 27 Aug 2011 18:12:26 +0200
4 Subject: [PATCH 38/73] SPI: MIPS: lantiq: add FALC-ON spi driver
5
6 The external bus unit (EBU) found on the FALC-ON SoC has spi emulation that is
7 designed for serial flash access. This driver has only been tested with m25p80
8 type chips. The hardware has no support for other types of spi peripherals.
9
10 Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
11 Signed-off-by: John Crispin <blogic@openwrt.org>
12 Cc: spi-devel-general@lists.sourceforge.net
13 ---
14  arch/mips/lantiq/falcon/devices.c        |   13 +
15  arch/mips/lantiq/falcon/devices.h        |    4 +
16  arch/mips/lantiq/falcon/mach-easy98000.c |   27 ++
17  drivers/spi/Kconfig                      |    4 +
18  drivers/spi/Makefile                     |    1 +
19  drivers/spi/spi-falcon.c                 |  483 ++++++++++++++++++++++++++++++
20  6 files changed, 532 insertions(+), 0 deletions(-)
21  create mode 100644 drivers/spi/spi-falcon.c
22
23 diff --git a/arch/mips/lantiq/falcon/devices.c b/arch/mips/lantiq/falcon/devices.c
24 index 6cd7a88..92ec571 100644
25 --- a/arch/mips/lantiq/falcon/devices.c
26 +++ b/arch/mips/lantiq/falcon/devices.c
27 @@ -121,3 +121,16 @@ falcon_register_gpio_extra(void)
28         platform_device_register_simple("falcon_gpio", 4,
29                 falcon_gpio4_res, ARRAY_SIZE(falcon_gpio4_res));
30  }
31 +
32 +/* spi flash */
33 +static struct platform_device ltq_spi = {
34 +       .name                   = "falcon_spi",
35 +       .num_resources          = 0,
36 +};
37 +
38 +void __init
39 +falcon_register_spi_flash(struct spi_board_info *data)
40 +{
41 +       spi_register_board_info(data, 1);
42 +       platform_device_register(&ltq_spi);
43 +}
44 diff --git a/arch/mips/lantiq/falcon/devices.h b/arch/mips/lantiq/falcon/devices.h
45 index 18be8b6..5e6f720 100644
46 --- a/arch/mips/lantiq/falcon/devices.h
47 +++ b/arch/mips/lantiq/falcon/devices.h
48 @@ -11,10 +11,14 @@
49  #ifndef _FALCON_DEVICES_H__
50  #define _FALCON_DEVICES_H__
51  
52 +#include <linux/spi/spi.h>
53 +#include <linux/spi/flash.h>
54 +
55  #include "../devices.h"
56  
57  extern void falcon_register_nand(void);
58  extern void falcon_register_gpio(void);
59  extern void falcon_register_gpio_extra(void);
60 +extern void falcon_register_spi_flash(struct spi_board_info *data);
61  
62  #endif
63 diff --git a/arch/mips/lantiq/falcon/mach-easy98000.c b/arch/mips/lantiq/falcon/mach-easy98000.c
64 index 361b8f0..1a7caad 100644
65 --- a/arch/mips/lantiq/falcon/mach-easy98000.c
66 +++ b/arch/mips/lantiq/falcon/mach-easy98000.c
67 @@ -40,6 +40,21 @@ struct physmap_flash_data easy98000_nor_flash_data = {
68         .parts          = easy98000_nor_partitions,
69  };
70  
71 +static struct flash_platform_data easy98000_spi_flash_platform_data = {
72 +       .name = "sflash",
73 +       .parts = easy98000_nor_partitions,
74 +       .nr_parts = ARRAY_SIZE(easy98000_nor_partitions)
75 +};
76 +
77 +static struct spi_board_info easy98000_spi_flash_data __initdata = {
78 +       .modalias               = "m25p80",
79 +       .bus_num                = 0,
80 +       .chip_select            = 0,
81 +       .max_speed_hz           = 10 * 1000 * 1000,
82 +       .mode                   = SPI_MODE_3,
83 +       .platform_data          = &easy98000_spi_flash_platform_data
84 +};
85 +
86  /* setup gpio based spi bus/device for access to the eeprom on the board */
87  #define SPI_GPIO_MRST          102
88  #define SPI_GPIO_MTSR          103
89 @@ -93,6 +108,13 @@ easy98000_init(void)
90  }
91  
92  static void __init
93 +easy98000sf_init(void)
94 +{
95 +       easy98000_init_common();
96 +       falcon_register_spi_flash(&easy98000_spi_flash_data);
97 +}
98 +
99 +static void __init
100  easy98000nand_init(void)
101  {
102         easy98000_init_common();
103 @@ -104,6 +126,11 @@ MIPS_MACHINE(LANTIQ_MACH_EASY98000,
104                         "EASY98000 Eval Board",
105                         easy98000_init);
106  
107 +MIPS_MACHINE(LANTIQ_MACH_EASY98000SF,
108 +                       "EASY98000SF",
109 +                       "EASY98000 Eval Board (Serial Flash)",
110 +                       easy98000sf_init);
111 +
112  MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND,
113                         "EASY98000NAND",
114                         "EASY98000 Eval Board (NAND Flash)",
115 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
116 index 8ba4510..b8424ba 100644
117 --- a/drivers/spi/Kconfig
118 +++ b/drivers/spi/Kconfig
119 @@ -180,6 +180,10 @@ config SPI_MPC52xx
120           This drivers supports the MPC52xx SPI controller in master SPI
121           mode.
122  
123 +config SPI_FALCON
124 +       tristate "Falcon SPI controller support"
125 +       depends on SOC_FALCON
126 +
127  config SPI_MPC52xx_PSC
128         tristate "Freescale MPC52xx PSC SPI controller"
129         depends on PPC_MPC52xx && EXPERIMENTAL
130 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
131 index 61c3261..570894c 100644
132 --- a/drivers/spi/Makefile
133 +++ b/drivers/spi/Makefile
134 @@ -25,6 +25,7 @@ obj-$(CONFIG_SPI_DW_MMIO)             += spi-dw-mmio.o
135  obj-$(CONFIG_SPI_DW_PCI)               += spi-dw-midpci.o
136  spi-dw-midpci-objs                     := spi-dw-pci.o spi-dw-mid.o
137  obj-$(CONFIG_SPI_EP93XX)               += spi-ep93xx.o
138 +obj-$(CONFIG_SPI_FALCON)               += spi-falcon.o
139  obj-$(CONFIG_SPI_FSL_LIB)              += spi-fsl-lib.o
140  obj-$(CONFIG_SPI_FSL_ESPI)             += spi-fsl-espi.o
141  obj-$(CONFIG_SPI_FSL_SPI)              += spi-fsl-spi.o
142 diff --git a/drivers/spi/spi-falcon.c b/drivers/spi/spi-falcon.c
143 new file mode 100644
144 index 0000000..447bbaa
145 --- /dev/null
146 +++ b/drivers/spi/spi-falcon.c
147 @@ -0,0 +1,483 @@
148 +/*
149 + *  This program is free software; you can redistribute it and/or modify it
150 + *  under the terms of the GNU General Public License version 2 as published
151 + *  by the Free Software Foundation.
152 + *
153 + *  Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
154 + */
155 +
156 +#include <linux/module.h>
157 +#include <linux/device.h>
158 +#include <linux/platform_device.h>
159 +#include <linux/spi/spi.h>
160 +#include <linux/delay.h>
161 +#include <linux/workqueue.h>
162 +
163 +#include <lantiq_soc.h>
164 +
165 +#define DRV_NAME                       "falcon_spi"
166 +
167 +#define FALCON_SPI_XFER_BEGIN          (1 << 0)
168 +#define FALCON_SPI_XFER_END            (1 << 1)
169 +
170 +/* Bus Read Configuration Register0 */
171 +#define LTQ_BUSRCON0   0x00000010
172 +/* Bus Write Configuration Register0 */
173 +#define LTQ_BUSWCON0   0x00000018
174 +/* Serial Flash Configuration Register */
175 +#define LTQ_SFCON      0x00000080
176 +/* Serial Flash Time Register */
177 +#define LTQ_SFTIME     0x00000084
178 +/* Serial Flash Status Register */
179 +#define LTQ_SFSTAT     0x00000088
180 +/* Serial Flash Command Register */
181 +#define LTQ_SFCMD      0x0000008C
182 +/* Serial Flash Address Register */
183 +#define LTQ_SFADDR     0x00000090
184 +/* Serial Flash Data Register */
185 +#define LTQ_SFDATA     0x00000094
186 +/* Serial Flash I/O Control Register */
187 +#define LTQ_SFIO       0x00000098
188 +/* EBU Clock Control Register */
189 +#define LTQ_EBUCC      0x000000C4
190 +
191 +/* Dummy Phase Length */
192 +#define SFCMD_DUMLEN_OFFSET    16
193 +#define SFCMD_DUMLEN_MASK      0x000F0000
194 +/* Chip Select */
195 +#define SFCMD_CS_OFFSET                24
196 +#define SFCMD_CS_MASK          0x07000000
197 +/* field offset */
198 +#define SFCMD_ALEN_OFFSET      20
199 +#define SFCMD_ALEN_MASK                0x00700000
200 +/* SCK Rise-edge Position */
201 +#define SFTIME_SCKR_POS_OFFSET 8
202 +#define SFTIME_SCKR_POS_MASK   0x00000F00
203 +/* SCK Period */
204 +#define SFTIME_SCK_PER_OFFSET  0
205 +#define SFTIME_SCK_PER_MASK    0x0000000F
206 +/* SCK Fall-edge Position */
207 +#define SFTIME_SCKF_POS_OFFSET 12
208 +#define SFTIME_SCKF_POS_MASK   0x0000F000
209 +/* Device Size */
210 +#define SFCON_DEV_SIZE_A23_0   0x03000000
211 +#define SFCON_DEV_SIZE_MASK    0x0F000000
212 +/* Read Data Position */
213 +#define SFTIME_RD_POS_MASK     0x000F0000
214 +/* Data Output */
215 +#define SFIO_UNUSED_WD_MASK    0x0000000F
216 +/* Command Opcode mask */
217 +#define SFCMD_OPC_MASK         0x000000FF
218 +/* dlen bytes of data to write */
219 +#define SFCMD_DIR_WRITE                0x00000100
220 +/* Data Length offset */
221 +#define SFCMD_DLEN_OFFSET      9
222 +/* Command Error */
223 +#define SFSTAT_CMD_ERR         0x20000000
224 +/* Access Command Pending */
225 +#define SFSTAT_CMD_PEND                0x00400000
226 +/* Frequency set to 100MHz. */
227 +#define EBUCC_EBUDIV_SELF100   0x00000001
228 +/* Serial Flash */
229 +#define BUSRCON0_AGEN_SERIAL_FLASH     0xF0000000
230 +/* 8-bit multiplexed */
231 +#define BUSRCON0_PORTW_8_BIT_MUX       0x00000000
232 +/* Serial Flash */
233 +#define BUSWCON0_AGEN_SERIAL_FLASH     0xF0000000
234 +/* Chip Select after opcode */
235 +#define SFCMD_KEEP_CS_KEEP_SELECTED    0x00008000
236 +
237 +struct falcon_spi {
238 +       u32 sfcmd; /* for caching of opcode, direction, ... */
239 +       struct spi_master *master;
240 +};
241 +
242 +int
243 +falcon_spi_xfer(struct spi_device *spi,
244 +                   struct spi_transfer *t,
245 +                   unsigned long flags)
246 +{
247 +       struct device *dev = &spi->dev;
248 +       struct falcon_spi *priv = spi_master_get_devdata(spi->master);
249 +       const u8 *txp = t->tx_buf;
250 +       u8 *rxp = t->rx_buf;
251 +       unsigned int bytelen = ((8 * t->len + 7) / 8);
252 +       unsigned int len, alen, dumlen;
253 +       u32 val;
254 +       enum {
255 +               state_init,
256 +               state_command_prepare,
257 +               state_write,
258 +               state_read,
259 +               state_disable_cs,
260 +               state_end
261 +       } state = state_init;
262 +
263 +       do {
264 +               switch (state) {
265 +               case state_init: /* detect phase of upper layer sequence */
266 +               {
267 +                       /* initial write ? */
268 +                       if (flags & FALCON_SPI_XFER_BEGIN) {
269 +                               if (!txp) {
270 +                                       dev_err(dev,
271 +                                               "BEGIN without tx data!\n");
272 +                                       return -1;
273 +                               }
274 +                               /*
275 +                                * Prepare the parts of the sfcmd register,
276 +                                * which should not
277 +                                * change during a sequence!
278 +                                * Only exception are the length fields,
279 +                                * especially alen and dumlen.
280 +                                */
281 +
282 +                               priv->sfcmd = ((spi->chip_select
283 +                                               << SFCMD_CS_OFFSET)
284 +                                              & SFCMD_CS_MASK);
285 +                               priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
286 +                               priv->sfcmd |= *txp;
287 +                               txp++;
288 +                               bytelen--;
289 +                               if (bytelen) {
290 +                                       /*
291 +                                        * more data:
292 +                                        * maybe address and/or dummy
293 +                                        */
294 +                                       state = state_command_prepare;
295 +                                       break;
296 +                               } else {
297 +                                       dev_dbg(dev, "write cmd %02X\n",
298 +                                               priv->sfcmd & SFCMD_OPC_MASK);
299 +                               }
300 +                       }
301 +                       /* continued write ? */
302 +                       if (txp && bytelen) {
303 +                               state = state_write;
304 +                               break;
305 +                       }
306 +                       /* read data? */
307 +                       if (rxp && bytelen) {
308 +                               state = state_read;
309 +                               break;
310 +                       }
311 +                       /* end of sequence? */
312 +                       if (flags & FALCON_SPI_XFER_END)
313 +                               state = state_disable_cs;
314 +                       else
315 +                               state = state_end;
316 +                       break;
317 +               }
318 +               /* collect tx data for address and dummy phase */
319 +               case state_command_prepare:
320 +               {
321 +                       /* txp is valid, already checked */
322 +                       val = 0;
323 +                       alen = 0;
324 +                       dumlen = 0;
325 +                       while (bytelen > 0) {
326 +                               if (alen < 3) {
327 +                                       val = (val<<8)|(*txp++);
328 +                                       alen++;
329 +                               } else if ((dumlen < 15) && (*txp == 0)) {
330 +                                       /*
331 +                                        * assume dummy bytes are set to 0
332 +                                        * from upper layer
333 +                                        */
334 +                                       dumlen++;
335 +                                       txp++;
336 +                               } else
337 +                                       break;
338 +                               bytelen--;
339 +                       }
340 +                       priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK);
341 +                       priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) |
342 +                                        (dumlen << SFCMD_DUMLEN_OFFSET);
343 +                       if (alen > 0)
344 +                               ltq_ebu_w32(val, LTQ_SFADDR);
345 +
346 +                       dev_dbg(dev, "write cmd %02X, alen=%d "
347 +                               "(addr=%06X) dumlen=%d\n",
348 +                               priv->sfcmd & SFCMD_OPC_MASK,
349 +                               alen, val, dumlen);
350 +
351 +                       if (bytelen > 0) {
352 +                               /* continue with write */
353 +                               state = state_write;
354 +                       } else if (flags & FALCON_SPI_XFER_END) {
355 +                               /* end of sequence? */
356 +                               state = state_disable_cs;
357 +                       } else {
358 +                               /*
359 +                                * go to end and expect another
360 +                                * call (read or write)
361 +                                */
362 +                               state = state_end;
363 +                       }
364 +                       break;
365 +               }
366 +               case state_write:
367 +               {
368 +                       /* txp still valid */
369 +                       priv->sfcmd |= SFCMD_DIR_WRITE;
370 +                       len = 0;
371 +                       val = 0;
372 +                       do {
373 +                               if (bytelen--)
374 +                                       val |= (*txp++) << (8 * len++);
375 +                               if ((flags & FALCON_SPI_XFER_END)
376 +                                   && (bytelen == 0)) {
377 +                                       priv->sfcmd &=
378 +                                               ~SFCMD_KEEP_CS_KEEP_SELECTED;
379 +                               }
380 +                               if ((len == 4) || (bytelen == 0)) {
381 +                                       ltq_ebu_w32(val, LTQ_SFDATA);
382 +                                       ltq_ebu_w32(priv->sfcmd
383 +                                               | (len<<SFCMD_DLEN_OFFSET),
384 +                                               LTQ_SFCMD);
385 +                                       len = 0;
386 +                                       val = 0;
387 +                                       priv->sfcmd &= ~(SFCMD_ALEN_MASK
388 +                                                        | SFCMD_DUMLEN_MASK);
389 +                               }
390 +                       } while (bytelen);
391 +                       state = state_end;
392 +                       break;
393 +               }
394 +               case state_read:
395 +               {
396 +                       /* read data */
397 +                       priv->sfcmd &= ~SFCMD_DIR_WRITE;
398 +                       do {
399 +                               if ((flags & FALCON_SPI_XFER_END)
400 +                                   && (bytelen <= 4)) {
401 +                                       priv->sfcmd &=
402 +                                               ~SFCMD_KEEP_CS_KEEP_SELECTED;
403 +                               }
404 +                               len = (bytelen > 4) ? 4 : bytelen;
405 +                               bytelen -= len;
406 +                               ltq_ebu_w32(priv->sfcmd
407 +                                       |(len<<SFCMD_DLEN_OFFSET), LTQ_SFCMD);
408 +                               priv->sfcmd &= ~(SFCMD_ALEN_MASK
409 +                                                | SFCMD_DUMLEN_MASK);
410 +                               do {
411 +                                       val = ltq_ebu_r32(LTQ_SFSTAT);
412 +                                       if (val & SFSTAT_CMD_ERR) {
413 +                                               /* reset error status */
414 +                                               dev_err(dev, "SFSTAT: CMD_ERR "
415 +                                                       "(%x)\n", val);
416 +                                               ltq_ebu_w32(SFSTAT_CMD_ERR,
417 +                                                       LTQ_SFSTAT);
418 +                                               return -1;
419 +                                       }
420 +                               } while (val & SFSTAT_CMD_PEND);
421 +                               val = ltq_ebu_r32(LTQ_SFDATA);
422 +                               do {
423 +                                       *rxp = (val & 0xFF);
424 +                                       rxp++;
425 +                                       val >>= 8;
426 +                                       len--;
427 +                               } while (len);
428 +                       } while (bytelen);
429 +                       state = state_end;
430 +                       break;
431 +               }
432 +               case state_disable_cs:
433 +               {
434 +                       priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED;
435 +                       ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET),
436 +                               LTQ_SFCMD);
437 +                       val = ltq_ebu_r32(LTQ_SFSTAT);
438 +                       if (val & SFSTAT_CMD_ERR) {
439 +                               /* reset error status */
440 +                               dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val);
441 +                               ltq_ebu_w32(SFSTAT_CMD_ERR, LTQ_SFSTAT);
442 +                               return -1;
443 +                       }
444 +                       state = state_end;
445 +                       break;
446 +               }
447 +               case state_end:
448 +                       break;
449 +               }
450 +       } while (state != state_end);
451 +
452 +       return 0;
453 +}
454 +
455 +static int
456 +falcon_spi_setup(struct spi_device *spi)
457 +{
458 +       struct device *dev = &spi->dev;
459 +       const u32 ebuclk = 100000000;
460 +       unsigned int i;
461 +       unsigned long flags;
462 +
463 +       dev_dbg(dev, "setup\n");
464 +
465 +       if (spi->master->bus_num > 0 || spi->chip_select > 0)
466 +               return -ENODEV;
467 +
468 +       spin_lock_irqsave(&ebu_lock, flags);
469 +
470 +       if (ebuclk < spi->max_speed_hz) {
471 +               /* set EBU clock to 100 MHz */
472 +               ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, LTQ_EBUCC);
473 +               i = 1; /* divider */
474 +       } else {
475 +               /* set EBU clock to 50 MHz */
476 +               ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, LTQ_EBUCC);
477 +
478 +               /* search for suitable divider */
479 +               for (i = 1; i < 7; i++) {
480 +                       if (ebuclk / i <= spi->max_speed_hz)
481 +                               break;
482 +               }
483 +       }
484 +
485 +       /* setup period of serial clock */
486 +       ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK
487 +                    | SFTIME_SCKR_POS_MASK
488 +                    | SFTIME_SCK_PER_MASK,
489 +                    (i << SFTIME_SCKR_POS_OFFSET)
490 +                    | (i << (SFTIME_SCK_PER_OFFSET + 1)),
491 +                    LTQ_SFTIME);
492 +
493 +       /*
494 +        * set some bits of unused_wd, to not trigger HOLD/WP
495 +        * signals on non QUAD flashes
496 +        */
497 +       ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), LTQ_SFIO);
498 +
499 +       ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX,
500 +               LTQ_BUSRCON0);
501 +       ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, LTQ_BUSWCON0);
502 +       /* set address wrap around to maximum for 24-bit addresses */
503 +       ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, LTQ_SFCON);
504 +
505 +       spin_unlock_irqrestore(&ebu_lock, flags);
506 +
507 +       return 0;
508 +}
509 +
510 +static int
511 +falcon_spi_transfer(struct spi_device *spi, struct spi_message *m)
512 +{
513 +       struct falcon_spi *priv = spi_master_get_devdata(spi->master);
514 +       struct spi_transfer *t;
515 +       unsigned long spi_flags;
516 +       unsigned long flags;
517 +       int ret = 0;
518 +
519 +       priv->sfcmd = 0;
520 +       m->actual_length = 0;
521 +
522 +       spi_flags = FALCON_SPI_XFER_BEGIN;
523 +       list_for_each_entry(t, &m->transfers, transfer_list) {
524 +               if (list_is_last(&t->transfer_list, &m->transfers))
525 +                       spi_flags |= FALCON_SPI_XFER_END;
526 +
527 +               spin_lock_irqsave(&ebu_lock, flags);
528 +               ret = falcon_spi_xfer(spi, t, spi_flags);
529 +               spin_unlock_irqrestore(&ebu_lock, flags);
530 +
531 +               if (ret)
532 +                       break;
533 +
534 +               m->actual_length += t->len;
535 +
536 +               if (t->delay_usecs || t->cs_change)
537 +                       BUG();
538 +
539 +               spi_flags = 0;
540 +       }
541 +
542 +       m->status = ret;
543 +       m->complete(m->context);
544 +
545 +       return 0;
546 +}
547 +
548 +static void
549 +falcon_spi_cleanup(struct spi_device *spi)
550 +{
551 +       struct device *dev = &spi->dev;
552 +
553 +       dev_dbg(dev, "cleanup\n");
554 +}
555 +
556 +static int __devinit
557 +falcon_spi_probe(struct platform_device *pdev)
558 +{
559 +       struct device *dev = &pdev->dev;
560 +       struct falcon_spi *priv;
561 +       struct spi_master *master;
562 +       int ret;
563 +
564 +       dev_dbg(dev, "probing\n");
565 +
566 +       master = spi_alloc_master(&pdev->dev, sizeof(*priv));
567 +       if (!master) {
568 +               dev_err(dev, "no memory for spi_master\n");
569 +               return -ENOMEM;
570 +       }
571 +
572 +       priv = spi_master_get_devdata(master);
573 +       priv->master = master;
574 +
575 +       master->mode_bits = SPI_MODE_3;
576 +       master->num_chipselect = 1;
577 +       master->bus_num = 0;
578 +
579 +       master->setup = falcon_spi_setup;
580 +       master->transfer = falcon_spi_transfer;
581 +       master->cleanup = falcon_spi_cleanup;
582 +
583 +       platform_set_drvdata(pdev, priv);
584 +
585 +       ret = spi_register_master(master);
586 +       if (ret)
587 +               spi_master_put(master);
588 +
589 +       return ret;
590 +}
591 +
592 +static int __devexit
593 +falcon_spi_remove(struct platform_device *pdev)
594 +{
595 +       struct device *dev = &pdev->dev;
596 +       struct falcon_spi *priv = platform_get_drvdata(pdev);
597 +
598 +       dev_dbg(dev, "removed\n");
599 +
600 +       spi_unregister_master(priv->master);
601 +
602 +       return 0;
603 +}
604 +
605 +static struct platform_driver falcon_spi_driver = {
606 +       .probe  = falcon_spi_probe,
607 +       .remove = __devexit_p(falcon_spi_remove),
608 +       .driver = {
609 +               .name   = DRV_NAME,
610 +               .owner  = THIS_MODULE
611 +       }
612 +};
613 +
614 +static int __init
615 +falcon_spi_init(void)
616 +{
617 +       return platform_driver_register(&falcon_spi_driver);
618 +}
619 +
620 +static void __exit
621 +falcon_spi_exit(void)
622 +{
623 +       platform_driver_unregister(&falcon_spi_driver);
624 +}
625 +
626 +module_init(falcon_spi_init);
627 +module_exit(falcon_spi_exit);
628 +
629 +MODULE_LICENSE("GPL");
630 +MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver");
631 -- 
632 1.7.9.1
633