]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/spi/spi-coldfire-qspi.c
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
[karo-tx-linux.git] / drivers / spi / spi-coldfire-qspi.c
1 /*
2  * Freescale/Motorola Coldfire Queued SPI driver
3  *
4  * Copyright 2010 Steven King <sfking@fdwdc.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA
19  *
20 */
21
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/interrupt.h>
25 #include <linux/errno.h>
26 #include <linux/platform_device.h>
27 #include <linux/sched.h>
28 #include <linux/delay.h>
29 #include <linux/io.h>
30 #include <linux/clk.h>
31 #include <linux/err.h>
32 #include <linux/spi/spi.h>
33 #include <linux/pm_runtime.h>
34
35 #include <asm/coldfire.h>
36 #include <asm/mcfsim.h>
37 #include <asm/mcfqspi.h>
38
39 #define DRIVER_NAME "mcfqspi"
40
41 #define MCFQSPI_BUSCLK                  (MCF_BUSCLK / 2)
42
43 #define MCFQSPI_QMR                     0x00
44 #define         MCFQSPI_QMR_MSTR        0x8000
45 #define         MCFQSPI_QMR_CPOL        0x0200
46 #define         MCFQSPI_QMR_CPHA        0x0100
47 #define MCFQSPI_QDLYR                   0x04
48 #define         MCFQSPI_QDLYR_SPE       0x8000
49 #define MCFQSPI_QWR                     0x08
50 #define         MCFQSPI_QWR_HALT        0x8000
51 #define         MCFQSPI_QWR_WREN        0x4000
52 #define         MCFQSPI_QWR_CSIV        0x1000
53 #define MCFQSPI_QIR                     0x0C
54 #define         MCFQSPI_QIR_WCEFB       0x8000
55 #define         MCFQSPI_QIR_ABRTB       0x4000
56 #define         MCFQSPI_QIR_ABRTL       0x1000
57 #define         MCFQSPI_QIR_WCEFE       0x0800
58 #define         MCFQSPI_QIR_ABRTE       0x0400
59 #define         MCFQSPI_QIR_SPIFE       0x0100
60 #define         MCFQSPI_QIR_WCEF        0x0008
61 #define         MCFQSPI_QIR_ABRT        0x0004
62 #define         MCFQSPI_QIR_SPIF        0x0001
63 #define MCFQSPI_QAR                     0x010
64 #define         MCFQSPI_QAR_TXBUF       0x00
65 #define         MCFQSPI_QAR_RXBUF       0x10
66 #define         MCFQSPI_QAR_CMDBUF      0x20
67 #define MCFQSPI_QDR                     0x014
68 #define MCFQSPI_QCR                     0x014
69 #define         MCFQSPI_QCR_CONT        0x8000
70 #define         MCFQSPI_QCR_BITSE       0x4000
71 #define         MCFQSPI_QCR_DT          0x2000
72
73 struct mcfqspi {
74         void __iomem *iobase;
75         int irq;
76         struct clk *clk;
77         struct mcfqspi_cs_control *cs_control;
78
79         wait_queue_head_t waitq;
80
81         struct device *dev;
82 };
83
84 static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
85 {
86         writew(val, mcfqspi->iobase + MCFQSPI_QMR);
87 }
88
89 static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val)
90 {
91         writew(val, mcfqspi->iobase + MCFQSPI_QDLYR);
92 }
93
94 static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi)
95 {
96         return readw(mcfqspi->iobase + MCFQSPI_QDLYR);
97 }
98
99 static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val)
100 {
101         writew(val, mcfqspi->iobase + MCFQSPI_QWR);
102 }
103
104 static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val)
105 {
106         writew(val, mcfqspi->iobase + MCFQSPI_QIR);
107 }
108
109 static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val)
110 {
111         writew(val, mcfqspi->iobase + MCFQSPI_QAR);
112 }
113
114 static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val)
115 {
116         writew(val, mcfqspi->iobase + MCFQSPI_QDR);
117 }
118
119 static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi)
120 {
121         return readw(mcfqspi->iobase + MCFQSPI_QDR);
122 }
123
124 static void mcfqspi_cs_select(struct mcfqspi *mcfqspi, u8 chip_select,
125                             bool cs_high)
126 {
127         mcfqspi->cs_control->select(mcfqspi->cs_control, chip_select, cs_high);
128 }
129
130 static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select,
131                                 bool cs_high)
132 {
133         mcfqspi->cs_control->deselect(mcfqspi->cs_control, chip_select, cs_high);
134 }
135
136 static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi)
137 {
138         return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ?
139                 mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0;
140 }
141
142 static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)
143 {
144         if (mcfqspi->cs_control && mcfqspi->cs_control->teardown)
145                 mcfqspi->cs_control->teardown(mcfqspi->cs_control);
146 }
147
148 static u8 mcfqspi_qmr_baud(u32 speed_hz)
149 {
150         return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u);
151 }
152
153 static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi)
154 {
155         return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE;
156 }
157
158 static irqreturn_t mcfqspi_irq_handler(int this_irq, void *dev_id)
159 {
160         struct mcfqspi *mcfqspi = dev_id;
161
162         /* clear interrupt */
163         mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE | MCFQSPI_QIR_SPIF);
164         wake_up(&mcfqspi->waitq);
165
166         return IRQ_HANDLED;
167 }
168
169 static void mcfqspi_transfer_msg8(struct mcfqspi *mcfqspi, unsigned count,
170                                   const u8 *txbuf, u8 *rxbuf)
171 {
172         unsigned i, n, offset = 0;
173
174         n = min(count, 16u);
175
176         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
177         for (i = 0; i < n; ++i)
178                 mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
179
180         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
181         if (txbuf)
182                 for (i = 0; i < n; ++i)
183                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
184         else
185                 for (i = 0; i < count; ++i)
186                         mcfqspi_wr_qdr(mcfqspi, 0);
187
188         count -= n;
189         if (count) {
190                 u16 qwr = 0xf08;
191                 mcfqspi_wr_qwr(mcfqspi, 0x700);
192                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
193
194                 do {
195                         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
196                         mcfqspi_wr_qwr(mcfqspi, qwr);
197                         mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
198                         if (rxbuf) {
199                                 mcfqspi_wr_qar(mcfqspi,
200                                                MCFQSPI_QAR_RXBUF + offset);
201                                 for (i = 0; i < 8; ++i)
202                                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
203                         }
204                         n = min(count, 8u);
205                         if (txbuf) {
206                                 mcfqspi_wr_qar(mcfqspi,
207                                                MCFQSPI_QAR_TXBUF + offset);
208                                 for (i = 0; i < n; ++i)
209                                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
210                         }
211                         qwr = (offset ? 0x808 : 0) + ((n - 1) << 8);
212                         offset ^= 8;
213                         count -= n;
214                 } while (count);
215                 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
216                 mcfqspi_wr_qwr(mcfqspi, qwr);
217                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
218                 if (rxbuf) {
219                         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
220                         for (i = 0; i < 8; ++i)
221                                 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
222                         offset ^= 8;
223                 }
224         } else {
225                 mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
226                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
227         }
228         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
229         if (rxbuf) {
230                 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
231                 for (i = 0; i < n; ++i)
232                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
233         }
234 }
235
236 static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
237                                    const u16 *txbuf, u16 *rxbuf)
238 {
239         unsigned i, n, offset = 0;
240
241         n = min(count, 16u);
242
243         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
244         for (i = 0; i < n; ++i)
245                 mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
246
247         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
248         if (txbuf)
249                 for (i = 0; i < n; ++i)
250                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
251         else
252                 for (i = 0; i < count; ++i)
253                         mcfqspi_wr_qdr(mcfqspi, 0);
254
255         count -= n;
256         if (count) {
257                 u16 qwr = 0xf08;
258                 mcfqspi_wr_qwr(mcfqspi, 0x700);
259                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
260
261                 do {
262                         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
263                         mcfqspi_wr_qwr(mcfqspi, qwr);
264                         mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
265                         if (rxbuf) {
266                                 mcfqspi_wr_qar(mcfqspi,
267                                                MCFQSPI_QAR_RXBUF + offset);
268                                 for (i = 0; i < 8; ++i)
269                                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
270                         }
271                         n = min(count, 8u);
272                         if (txbuf) {
273                                 mcfqspi_wr_qar(mcfqspi,
274                                                MCFQSPI_QAR_TXBUF + offset);
275                                 for (i = 0; i < n; ++i)
276                                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
277                         }
278                         qwr = (offset ? 0x808 : 0x000) + ((n - 1) << 8);
279                         offset ^= 8;
280                         count -= n;
281                 } while (count);
282                 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
283                 mcfqspi_wr_qwr(mcfqspi, qwr);
284                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
285                 if (rxbuf) {
286                         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
287                         for (i = 0; i < 8; ++i)
288                                 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
289                         offset ^= 8;
290                 }
291         } else {
292                 mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
293                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
294         }
295         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
296         if (rxbuf) {
297                 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
298                 for (i = 0; i < n; ++i)
299                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
300         }
301 }
302
303 static int mcfqspi_transfer_one_message(struct spi_master *master,
304                                          struct spi_message *msg)
305 {
306         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
307         struct spi_device *spi = msg->spi;
308         struct spi_transfer *t;
309         int status = 0;
310
311         list_for_each_entry(t, &msg->transfers, transfer_list) {
312                 bool cs_high = spi->mode & SPI_CS_HIGH;
313                 u16 qmr = MCFQSPI_QMR_MSTR;
314
315                 if (t->bits_per_word)
316                         qmr |= t->bits_per_word << 10;
317                 else
318                         qmr |= spi->bits_per_word << 10;
319                 if (spi->mode & SPI_CPHA)
320                         qmr |= MCFQSPI_QMR_CPHA;
321                 if (spi->mode & SPI_CPOL)
322                         qmr |= MCFQSPI_QMR_CPOL;
323                 if (t->speed_hz)
324                         qmr |= mcfqspi_qmr_baud(t->speed_hz);
325                 else
326                         qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
327                 mcfqspi_wr_qmr(mcfqspi, qmr);
328
329                 mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
330
331                 mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
332                 if ((t->bits_per_word ? t->bits_per_word :
333                                         spi->bits_per_word) == 8)
334                         mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf,
335                                         t->rx_buf);
336                 else
337                         mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf,
338                                         t->rx_buf);
339                 mcfqspi_wr_qir(mcfqspi, 0);
340
341                 if (t->delay_usecs)
342                         udelay(t->delay_usecs);
343                 if (t->cs_change) {
344                         if (!list_is_last(&t->transfer_list, &msg->transfers))
345                                 mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
346                                                 cs_high);
347                 } else {
348                         if (list_is_last(&t->transfer_list, &msg->transfers))
349                                 mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
350                                                 cs_high);
351                 }
352                 msg->actual_length += t->len;
353         }
354         msg->status = status;
355         spi_finalize_current_message(master);
356
357         return status;
358
359 }
360
361 static int mcfqspi_prepare_transfer_hw(struct spi_master *master)
362 {
363         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
364
365         pm_runtime_get_sync(mcfqspi->dev);
366
367         return 0;
368 }
369
370 static int mcfqspi_unprepare_transfer_hw(struct spi_master *master)
371 {
372         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
373
374         pm_runtime_put_sync(mcfqspi->dev);
375
376         return 0;
377 }
378
379 static int mcfqspi_setup(struct spi_device *spi)
380 {
381         if ((spi->bits_per_word < 8) || (spi->bits_per_word > 16)) {
382                 dev_dbg(&spi->dev, "%d bits per word is not supported\n",
383                         spi->bits_per_word);
384                 return -EINVAL;
385         }
386         if (spi->chip_select >= spi->master->num_chipselect) {
387                 dev_dbg(&spi->dev, "%d chip select is out of range\n",
388                         spi->chip_select);
389                 return -EINVAL;
390         }
391
392         mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),
393                             spi->chip_select, spi->mode & SPI_CS_HIGH);
394
395         dev_dbg(&spi->dev,
396                         "bits per word %d, chip select %d, speed %d KHz\n",
397                         spi->bits_per_word, spi->chip_select,
398                         (MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz))
399                         / 1000);
400
401         return 0;
402 }
403
404 static int __devinit mcfqspi_probe(struct platform_device *pdev)
405 {
406         struct spi_master *master;
407         struct mcfqspi *mcfqspi;
408         struct resource *res;
409         struct mcfqspi_platform_data *pdata;
410         int status;
411
412         master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
413         if (master == NULL) {
414                 dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
415                 return -ENOMEM;
416         }
417
418         mcfqspi = spi_master_get_devdata(master);
419
420         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
421         if (!res) {
422                 dev_dbg(&pdev->dev, "platform_get_resource failed\n");
423                 status = -ENXIO;
424                 goto fail0;
425         }
426
427         if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
428                 dev_dbg(&pdev->dev, "request_mem_region failed\n");
429                 status = -EBUSY;
430                 goto fail0;
431         }
432
433         mcfqspi->iobase = ioremap(res->start, resource_size(res));
434         if (!mcfqspi->iobase) {
435                 dev_dbg(&pdev->dev, "ioremap failed\n");
436                 status = -ENOMEM;
437                 goto fail1;
438         }
439
440         mcfqspi->irq = platform_get_irq(pdev, 0);
441         if (mcfqspi->irq < 0) {
442                 dev_dbg(&pdev->dev, "platform_get_irq failed\n");
443                 status = -ENXIO;
444                 goto fail2;
445         }
446
447         status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, 0,
448                              pdev->name, mcfqspi);
449         if (status) {
450                 dev_dbg(&pdev->dev, "request_irq failed\n");
451                 goto fail2;
452         }
453
454         mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk");
455         if (IS_ERR(mcfqspi->clk)) {
456                 dev_dbg(&pdev->dev, "clk_get failed\n");
457                 status = PTR_ERR(mcfqspi->clk);
458                 goto fail3;
459         }
460         clk_enable(mcfqspi->clk);
461
462         pdata = pdev->dev.platform_data;
463         if (!pdata) {
464                 dev_dbg(&pdev->dev, "platform data is missing\n");
465                 goto fail4;
466         }
467         master->bus_num = pdata->bus_num;
468         master->num_chipselect = pdata->num_chipselect;
469
470         mcfqspi->cs_control = pdata->cs_control;
471         status = mcfqspi_cs_setup(mcfqspi);
472         if (status) {
473                 dev_dbg(&pdev->dev, "error initializing cs_control\n");
474                 goto fail4;
475         }
476
477         init_waitqueue_head(&mcfqspi->waitq);
478         mcfqspi->dev = &pdev->dev;
479
480         master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
481         master->setup = mcfqspi_setup;
482         master->transfer_one_message = mcfqspi_transfer_one_message;
483         master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw;
484         master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw;
485
486         platform_set_drvdata(pdev, master);
487
488         status = spi_register_master(master);
489         if (status) {
490                 dev_dbg(&pdev->dev, "spi_register_master failed\n");
491                 goto fail5;
492         }
493         pm_runtime_enable(mcfqspi->dev);
494
495         dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
496
497         return 0;
498
499 fail5:
500         mcfqspi_cs_teardown(mcfqspi);
501 fail4:
502         clk_disable(mcfqspi->clk);
503         clk_put(mcfqspi->clk);
504 fail3:
505         free_irq(mcfqspi->irq, mcfqspi);
506 fail2:
507         iounmap(mcfqspi->iobase);
508 fail1:
509         release_mem_region(res->start, resource_size(res));
510 fail0:
511         spi_master_put(master);
512
513         dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
514
515         return status;
516 }
517
518 static int __devexit mcfqspi_remove(struct platform_device *pdev)
519 {
520         struct spi_master *master = platform_get_drvdata(pdev);
521         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
522         struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
523
524         pm_runtime_disable(mcfqspi->dev);
525         /* disable the hardware (set the baud rate to 0) */
526         mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
527
528         platform_set_drvdata(pdev, NULL);
529         mcfqspi_cs_teardown(mcfqspi);
530         clk_disable(mcfqspi->clk);
531         clk_put(mcfqspi->clk);
532         free_irq(mcfqspi->irq, mcfqspi);
533         iounmap(mcfqspi->iobase);
534         release_mem_region(res->start, resource_size(res));
535         spi_unregister_master(master);
536         spi_master_put(master);
537
538         return 0;
539 }
540
541 #ifdef CONFIG_PM_SLEEP
542 static int mcfqspi_suspend(struct device *dev)
543 {
544         struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
545         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
546
547         spi_master_suspend(master);
548
549         clk_disable(mcfqspi->clk);
550
551         return 0;
552 }
553
554 static int mcfqspi_resume(struct device *dev)
555 {
556         struct spi_master *master = spi_master_get(dev_get_drvdata(dev));
557         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
558
559         spi_master_resume(master);
560
561         clk_enable(mcfqspi->clk);
562
563         return 0;
564 }
565 #endif
566
567 #ifdef CONFIG_PM_RUNTIME
568 static int mcfqspi_runtime_suspend(struct device *dev)
569 {
570         struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
571
572         clk_disable(mcfqspi->clk);
573
574         return 0;
575 }
576
577 static int mcfqspi_runtime_resume(struct device *dev)
578 {
579         struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
580
581         clk_enable(mcfqspi->clk);
582
583         return 0;
584 }
585 #endif
586
587 static const struct dev_pm_ops mcfqspi_pm = {
588         SET_SYSTEM_SLEEP_PM_OPS(mcfqspi_suspend, mcfqspi_resume)
589         SET_RUNTIME_PM_OPS(mcfqspi_runtime_suspend, mcfqspi_runtime_resume,
590                         NULL)
591 };
592
593 static struct platform_driver mcfqspi_driver = {
594         .driver.name    = DRIVER_NAME,
595         .driver.owner   = THIS_MODULE,
596         .driver.pm      = &mcfqspi_pm,
597         .probe          = mcfqspi_probe,
598         .remove         = __devexit_p(mcfqspi_remove),
599 };
600 module_platform_driver(mcfqspi_driver);
601
602 MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
603 MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
604 MODULE_LICENSE("GPL");
605 MODULE_ALIAS("platform:" DRIVER_NAME);