aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2010-04-30 09:21:27 -0400
committerGrant Likely <grant.likely@secretlab.ca>2010-05-25 02:23:17 -0400
commit6e27388f1bd60b55e0b1a83d14233e6c7ad33700 (patch)
treeaab88490ac722b354e90d72a4d0d040acc02f127
parent2da8cb6af5fe0d9e16b8a49399c8b7c6cfa94d5a (diff)
spi/mpc5121: Add SPI master driver for MPC5121 PSC
Signed-off-by: John Rigby <jcrigby@gmail.com> Signed-off-by: Anatolij Gustschin <agust@denx.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--arch/powerpc/include/asm/mpc52xx_psc.h1
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/mpc512x_psc_spi.c576
4 files changed, 585 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h
index 42561f4f032d..ecc4fc69ac13 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -248,6 +248,7 @@ struct mpc52xx_psc_fifo {
248 u16 tflwfptr; /* PSC + 0x9e */ 248 u16 tflwfptr; /* PSC + 0x9e */
249}; 249};
250 250
251#define MPC512x_PSC_FIFO_EOF 0x100
251#define MPC512x_PSC_FIFO_RESET_SLICE 0x80 252#define MPC512x_PSC_FIFO_RESET_SLICE 0x80
252#define MPC512x_PSC_FIFO_ENABLE_SLICE 0x01 253#define MPC512x_PSC_FIFO_ENABLE_SLICE 0x01
253#define MPC512x_PSC_FIFO_ENABLE_DMA 0x04 254#define MPC512x_PSC_FIFO_ENABLE_DMA 0x04
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2b2f4c3b6b62..aacc0ed25ba4 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -175,6 +175,13 @@ config SPI_MPC52xx_PSC
175 This enables using the Freescale MPC52xx Programmable Serial 175 This enables using the Freescale MPC52xx Programmable Serial
176 Controller in master SPI mode. 176 Controller in master SPI mode.
177 177
178config SPI_MPC512x_PSC
179 tristate "Freescale MPC512x PSC SPI controller"
180 depends on SPI_MASTER && PPC_MPC512x
181 help
182 This enables using the Freescale MPC5121 Programmable Serial
183 Controller in SPI master mode.
184
178config SPI_MPC8xxx 185config SPI_MPC8xxx
179 tristate "Freescale MPC8xxx SPI controller" 186 tristate "Freescale MPC8xxx SPI controller"
180 depends on FSL_SOC 187 depends on FSL_SOC
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 377f8455208d..e9cbd18217a0 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o
31obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o 31obj-$(CONFIG_SPI_OMAP_100K) += omap_spi_100k.o
32obj-$(CONFIG_SPI_ORION) += orion_spi.o 32obj-$(CONFIG_SPI_ORION) += orion_spi.o
33obj-$(CONFIG_SPI_PL022) += amba-pl022.o 33obj-$(CONFIG_SPI_PL022) += amba-pl022.o
34obj-$(CONFIG_SPI_MPC512x_PSC) += mpc512x_psc_spi.o
34obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o 35obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o
35obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o 36obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o
36obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o 37obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o
diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c
new file mode 100644
index 000000000000..28a126d2742b
--- /dev/null
+++ b/drivers/spi/mpc512x_psc_spi.c
@@ -0,0 +1,576 @@
1/*
2 * MPC512x PSC in SPI mode driver.
3 *
4 * Copyright (C) 2007,2008 Freescale Semiconductor Inc.
5 * Original port from 52xx driver:
6 * Hongjun Chen <hong-jun.chen@freescale.com>
7 *
8 * Fork of mpc52xx_psc_spi.c:
9 * Copyright (C) 2006 TOPTICA Photonics AG., Dragos Carp
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/interrupt.h>
22#include <linux/of_platform.h>
23#include <linux/workqueue.h>
24#include <linux/completion.h>
25#include <linux/io.h>
26#include <linux/delay.h>
27#include <linux/clk.h>
28#include <linux/spi/spi.h>
29#include <linux/fsl_devices.h>
30#include <asm/mpc52xx_psc.h>
31
32struct mpc512x_psc_spi {
33 void (*cs_control)(struct spi_device *spi, bool on);
34 u32 sysclk;
35
36 /* driver internal data */
37 struct mpc52xx_psc __iomem *psc;
38 struct mpc512x_psc_fifo __iomem *fifo;
39 unsigned int irq;
40 u8 bits_per_word;
41 u8 busy;
42 u32 mclk;
43 u8 eofbyte;
44
45 struct workqueue_struct *workqueue;
46 struct work_struct work;
47
48 struct list_head queue;
49 spinlock_t lock; /* Message queue lock */
50
51 struct completion done;
52};
53
54/* controller state */
55struct mpc512x_psc_spi_cs {
56 int bits_per_word;
57 int speed_hz;
58};
59
60/* set clock freq, clock ramp, bits per work
61 * if t is NULL then reset the values to the default values
62 */
63static int mpc512x_psc_spi_transfer_setup(struct spi_device *spi,
64 struct spi_transfer *t)
65{
66 struct mpc512x_psc_spi_cs *cs = spi->controller_state;
67
68 cs->speed_hz = (t && t->speed_hz)
69 ? t->speed_hz : spi->max_speed_hz;
70 cs->bits_per_word = (t && t->bits_per_word)
71 ? t->bits_per_word : spi->bits_per_word;
72 cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8;
73 return 0;
74}
75
76static void mpc512x_psc_spi_activate_cs(struct spi_device *spi)
77{
78 struct mpc512x_psc_spi_cs *cs = spi->controller_state;
79 struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
80 struct mpc52xx_psc __iomem *psc = mps->psc;
81 u32 sicr;
82 u32 ccr;
83 u16 bclkdiv;
84
85 sicr = in_be32(&psc->sicr);
86
87 /* Set clock phase and polarity */
88 if (spi->mode & SPI_CPHA)
89 sicr |= 0x00001000;
90 else
91 sicr &= ~0x00001000;
92
93 if (spi->mode & SPI_CPOL)
94 sicr |= 0x00002000;
95 else
96 sicr &= ~0x00002000;
97
98 if (spi->mode & SPI_LSB_FIRST)
99 sicr |= 0x10000000;
100 else
101 sicr &= ~0x10000000;
102 out_be32(&psc->sicr, sicr);
103
104 ccr = in_be32(&psc->ccr);
105 ccr &= 0xFF000000;
106 if (cs->speed_hz)
107 bclkdiv = (mps->mclk / cs->speed_hz) - 1;
108 else
109 bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */
110
111 ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
112 out_be32(&psc->ccr, ccr);
113 mps->bits_per_word = cs->bits_per_word;
114
115 if (mps->cs_control)
116 mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
117}
118
119static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi)
120{
121 struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
122
123 if (mps->cs_control)
124 mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
125
126}
127
128/* extract and scale size field in txsz or rxsz */
129#define MPC512x_PSC_FIFO_SZ(sz) ((sz & 0x7ff) << 2);
130
131#define EOFBYTE 1
132
133static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi,
134 struct spi_transfer *t)
135{
136 struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
137 struct mpc52xx_psc __iomem *psc = mps->psc;
138 struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
139 size_t len = t->len;
140 u8 *tx_buf = (u8 *)t->tx_buf;
141 u8 *rx_buf = (u8 *)t->rx_buf;
142
143 if (!tx_buf && !rx_buf && t->len)
144 return -EINVAL;
145
146 /* Zero MR2 */
147 in_8(&psc->mode);
148 out_8(&psc->mode, 0x0);
149
150 while (len) {
151 int count;
152 int i;
153 u8 data;
154 size_t fifosz;
155 int rxcount;
156
157 /*
158 * The number of bytes that can be sent at a time
159 * depends on the fifo size.
160 */
161 fifosz = MPC512x_PSC_FIFO_SZ(in_be32(&fifo->txsz));
162 count = min(fifosz, len);
163
164 for (i = count; i > 0; i--) {
165 data = tx_buf ? *tx_buf++ : 0;
166 if (len == EOFBYTE)
167 setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF);
168 out_8(&fifo->txdata_8, data);
169 len--;
170 }
171
172 INIT_COMPLETION(mps->done);
173
174 /* interrupt on tx fifo empty */
175 out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
176 out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY);
177
178 /* enable transmiter/receiver */
179 out_8(&psc->command,
180 MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
181
182 wait_for_completion(&mps->done);
183
184 mdelay(1);
185
186 /* rx fifo should have count bytes in it */
187 rxcount = in_be32(&fifo->rxcnt);
188 if (rxcount != count)
189 mdelay(1);
190
191 rxcount = in_be32(&fifo->rxcnt);
192 if (rxcount != count) {
193 dev_warn(&spi->dev, "expected %d bytes in rx fifo "
194 "but got %d\n", count, rxcount);
195 }
196
197 rxcount = min(rxcount, count);
198 for (i = rxcount; i > 0; i--) {
199 data = in_8(&fifo->rxdata_8);
200 if (rx_buf)
201 *rx_buf++ = data;
202 }
203 while (in_be32(&fifo->rxcnt)) {
204 in_8(&fifo->rxdata_8);
205 }
206
207 out_8(&psc->command,
208 MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
209 }
210 /* disable transmiter/receiver and fifo interrupt */
211 out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
212 out_be32(&fifo->tximr, 0);
213 return 0;
214}
215
216static void mpc512x_psc_spi_work(struct work_struct *work)
217{
218 struct mpc512x_psc_spi *mps = container_of(work,
219 struct mpc512x_psc_spi,
220 work);
221
222 spin_lock_irq(&mps->lock);
223 mps->busy = 1;
224 while (!list_empty(&mps->queue)) {
225 struct spi_message *m;
226 struct spi_device *spi;
227 struct spi_transfer *t = NULL;
228 unsigned cs_change;
229 int status;
230
231 m = container_of(mps->queue.next, struct spi_message, queue);
232 list_del_init(&m->queue);
233 spin_unlock_irq(&mps->lock);
234
235 spi = m->spi;
236 cs_change = 1;
237 status = 0;
238 list_for_each_entry(t, &m->transfers, transfer_list) {
239 if (t->bits_per_word || t->speed_hz) {
240 status = mpc512x_psc_spi_transfer_setup(spi, t);
241 if (status < 0)
242 break;
243 }
244
245 if (cs_change)
246 mpc512x_psc_spi_activate_cs(spi);
247 cs_change = t->cs_change;
248
249 status = mpc512x_psc_spi_transfer_rxtx(spi, t);
250 if (status)
251 break;
252 m->actual_length += t->len;
253
254 if (t->delay_usecs)
255 udelay(t->delay_usecs);
256
257 if (cs_change)
258 mpc512x_psc_spi_deactivate_cs(spi);
259 }
260
261 m->status = status;
262 m->complete(m->context);
263
264 if (status || !cs_change)
265 mpc512x_psc_spi_deactivate_cs(spi);
266
267 mpc512x_psc_spi_transfer_setup(spi, NULL);
268
269 spin_lock_irq(&mps->lock);
270 }
271 mps->busy = 0;
272 spin_unlock_irq(&mps->lock);
273}
274
275static int mpc512x_psc_spi_setup(struct spi_device *spi)
276{
277 struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
278 struct mpc512x_psc_spi_cs *cs = spi->controller_state;
279 unsigned long flags;
280
281 if (spi->bits_per_word % 8)
282 return -EINVAL;
283
284 if (!cs) {
285 cs = kzalloc(sizeof *cs, GFP_KERNEL);
286 if (!cs)
287 return -ENOMEM;
288 spi->controller_state = cs;
289 }
290
291 cs->bits_per_word = spi->bits_per_word;
292 cs->speed_hz = spi->max_speed_hz;
293
294 spin_lock_irqsave(&mps->lock, flags);
295 if (!mps->busy)
296 mpc512x_psc_spi_deactivate_cs(spi);
297 spin_unlock_irqrestore(&mps->lock, flags);
298
299 return 0;
300}
301
302static int mpc512x_psc_spi_transfer(struct spi_device *spi,
303 struct spi_message *m)
304{
305 struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master);
306 unsigned long flags;
307
308 m->actual_length = 0;
309 m->status = -EINPROGRESS;
310
311 spin_lock_irqsave(&mps->lock, flags);
312 list_add_tail(&m->queue, &mps->queue);
313 queue_work(mps->workqueue, &mps->work);
314 spin_unlock_irqrestore(&mps->lock, flags);
315
316 return 0;
317}
318
319static void mpc512x_psc_spi_cleanup(struct spi_device *spi)
320{
321 kfree(spi->controller_state);
322}
323
324static int mpc512x_psc_spi_port_config(struct spi_master *master,
325 struct mpc512x_psc_spi *mps)
326{
327 struct mpc52xx_psc __iomem *psc = mps->psc;
328 struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
329 struct clk *spiclk;
330 int ret = 0;
331 char name[32];
332 u32 sicr;
333 u32 ccr;
334 u16 bclkdiv;
335
336 sprintf(name, "psc%d_mclk", master->bus_num);
337 spiclk = clk_get(&master->dev, name);
338 clk_enable(spiclk);
339 mps->mclk = clk_get_rate(spiclk);
340 clk_put(spiclk);
341
342 /* Reset the PSC into a known state */
343 out_8(&psc->command, MPC52xx_PSC_RST_RX);
344 out_8(&psc->command, MPC52xx_PSC_RST_TX);
345 out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);
346
347 /* Disable psc interrupts all useful interrupts are in fifo */
348 out_be16(&psc->isr_imr.imr, 0);
349
350 /* Disable fifo interrupts, will be enabled later */
351 out_be32(&fifo->tximr, 0);
352 out_be32(&fifo->rximr, 0);
353
354 /* Setup fifo slice address and size */
355 /*out_be32(&fifo->txsz, 0x0fe00004);*/
356 /*out_be32(&fifo->rxsz, 0x0ff00004);*/
357
358 sicr = 0x01000000 | /* SIM = 0001 -- 8 bit */
359 0x00800000 | /* GenClk = 1 -- internal clk */
360 0x00008000 | /* SPI = 1 */
361 0x00004000 | /* MSTR = 1 -- SPI master */
362 0x00000800; /* UseEOF = 1 -- SS low until EOF */
363
364 out_be32(&psc->sicr, sicr);
365
366 ccr = in_be32(&psc->ccr);
367 ccr &= 0xFF000000;
368 bclkdiv = (mps->mclk / 1000000) - 1; /* default 1MHz */
369 ccr |= (((bclkdiv & 0xff) << 16) | (((bclkdiv >> 8) & 0xff) << 8));
370 out_be32(&psc->ccr, ccr);
371
372 /* Set 2ms DTL delay */
373 out_8(&psc->ctur, 0x00);
374 out_8(&psc->ctlr, 0x82);
375
376 /* we don't use the alarms */
377 out_be32(&fifo->rxalarm, 0xfff);
378 out_be32(&fifo->txalarm, 0);
379
380 /* Enable FIFO slices for Rx/Tx */
381 out_be32(&fifo->rxcmd,
382 MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA);
383 out_be32(&fifo->txcmd,
384 MPC512x_PSC_FIFO_ENABLE_SLICE | MPC512x_PSC_FIFO_ENABLE_DMA);
385
386 mps->bits_per_word = 8;
387
388 return ret;
389}
390
391static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id)
392{
393 struct mpc512x_psc_spi *mps = (struct mpc512x_psc_spi *)dev_id;
394 struct mpc512x_psc_fifo __iomem *fifo = mps->fifo;
395
396 /* clear interrupt and wake up the work queue */
397 if (in_be32(&fifo->txisr) &
398 in_be32(&fifo->tximr) & MPC512x_PSC_FIFO_EMPTY) {
399 out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY);
400 out_be32(&fifo->tximr, 0);
401 complete(&mps->done);
402 return IRQ_HANDLED;
403 }
404 return IRQ_NONE;
405}
406
407/* bus_num is used only for the case dev->platform_data == NULL */
408static int __init mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr,
409 u32 size, unsigned int irq,
410 s16 bus_num)
411{
412 struct fsl_spi_platform_data *pdata = dev->platform_data;
413 struct mpc512x_psc_spi *mps;
414 struct spi_master *master;
415 int ret;
416 void *tempp;
417
418 master = spi_alloc_master(dev, sizeof *mps);
419 if (master == NULL)
420 return -ENOMEM;
421
422 dev_set_drvdata(dev, master);
423 mps = spi_master_get_devdata(master);
424 mps->irq = irq;
425
426 if (pdata == NULL) {
427 dev_err(dev, "probe called without platform data, no "
428 "cs_control function will be called\n");
429 mps->cs_control = NULL;
430 mps->sysclk = 0;
431 master->bus_num = bus_num;
432 master->num_chipselect = 255;
433 } else {
434 mps->cs_control = pdata->cs_control;
435 mps->sysclk = pdata->sysclk;
436 master->bus_num = pdata->bus_num;
437 master->num_chipselect = pdata->max_chipselect;
438 }
439
440 master->setup = mpc512x_psc_spi_setup;
441 master->transfer = mpc512x_psc_spi_transfer;
442 master->cleanup = mpc512x_psc_spi_cleanup;
443
444 tempp = ioremap(regaddr, size);
445 if (!tempp) {
446 dev_err(dev, "could not ioremap I/O port range\n");
447 ret = -EFAULT;
448 goto free_master;
449 }
450 mps->psc = tempp;
451 mps->fifo =
452 (struct mpc512x_psc_fifo *)(tempp + sizeof(struct mpc52xx_psc));
453
454 ret = request_irq(mps->irq, mpc512x_psc_spi_isr, IRQF_SHARED,
455 "mpc512x-psc-spi", mps);
456 if (ret)
457 goto free_master;
458
459 ret = mpc512x_psc_spi_port_config(master, mps);
460 if (ret < 0)
461 goto free_irq;
462
463 spin_lock_init(&mps->lock);
464 init_completion(&mps->done);
465 INIT_WORK(&mps->work, mpc512x_psc_spi_work);
466 INIT_LIST_HEAD(&mps->queue);
467
468 mps->workqueue =
469 create_singlethread_workqueue(dev_name(master->dev.parent));
470 if (mps->workqueue == NULL) {
471 ret = -EBUSY;
472 goto free_irq;
473 }
474
475 ret = spi_register_master(master);
476 if (ret < 0)
477 goto unreg_master;
478
479 return ret;
480
481unreg_master:
482 destroy_workqueue(mps->workqueue);
483free_irq:
484 free_irq(mps->irq, mps);
485free_master:
486 if (mps->psc)
487 iounmap(mps->psc);
488 spi_master_put(master);
489
490 return ret;
491}
492
493static int __exit mpc512x_psc_spi_do_remove(struct device *dev)
494{
495 struct spi_master *master = dev_get_drvdata(dev);
496 struct mpc512x_psc_spi *mps = spi_master_get_devdata(master);
497
498 flush_workqueue(mps->workqueue);
499 destroy_workqueue(mps->workqueue);
500 spi_unregister_master(master);
501 free_irq(mps->irq, mps);
502 if (mps->psc)
503 iounmap(mps->psc);
504
505 return 0;
506}
507
508static int __init mpc512x_psc_spi_of_probe(struct of_device *op,
509 const struct of_device_id *match)
510{
511 const u32 *regaddr_p;
512 u64 regaddr64, size64;
513 s16 id = -1;
514
515 regaddr_p = of_get_address(op->node, 0, &size64, NULL);
516 if (!regaddr_p) {
517 dev_err(&op->dev, "Invalid PSC address\n");
518 return -EINVAL;
519 }
520 regaddr64 = of_translate_address(op->node, regaddr_p);
521
522 /* get PSC id (0..11, used by port_config) */
523 if (op->dev.platform_data == NULL) {
524 const u32 *psc_nump;
525
526 psc_nump = of_get_property(op->node, "cell-index", NULL);
527 if (!psc_nump || *psc_nump > 11) {
528 dev_err(&op->dev, "mpc512x_psc_spi: Device node %s "
529 "has invalid cell-index property\n",
530 op->node->full_name);
531 return -EINVAL;
532 }
533 id = *psc_nump;
534 }
535
536 return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64,
537 irq_of_parse_and_map(op->node, 0), id);
538}
539
540static int __exit mpc512x_psc_spi_of_remove(struct of_device *op)
541{
542 return mpc512x_psc_spi_do_remove(&op->dev);
543}
544
545static struct of_device_id mpc512x_psc_spi_of_match[] = {
546 { .compatible = "fsl,mpc5121-psc-spi", },
547 {},
548};
549
550MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match);
551
552static struct of_platform_driver mpc512x_psc_spi_of_driver = {
553 .match_table = mpc512x_psc_spi_of_match,
554 .probe = mpc512x_psc_spi_of_probe,
555 .remove = __exit_p(mpc512x_psc_spi_of_remove),
556 .driver = {
557 .name = "mpc512x-psc-spi",
558 .owner = THIS_MODULE,
559 },
560};
561
562static int __init mpc512x_psc_spi_init(void)
563{
564 return of_register_platform_driver(&mpc512x_psc_spi_of_driver);
565}
566module_init(mpc512x_psc_spi_init);
567
568static void __exit mpc512x_psc_spi_exit(void)
569{
570 of_unregister_platform_driver(&mpc512x_psc_spi_of_driver);
571}
572module_exit(mpc512x_psc_spi_exit);
573
574MODULE_AUTHOR("John Rigby");
575MODULE_DESCRIPTION("MPC512x PSC SPI Driver");
576MODULE_LICENSE("GPL");