• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/spi/
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/workqueue.h>
29#include <linux/delay.h>
30#include <linux/io.h>
31#include <linux/clk.h>
32#include <linux/err.h>
33#include <linux/spi/spi.h>
34
35#include <asm/coldfire.h>
36#include <asm/mcfqspi.h>
37
38#define	DRIVER_NAME "mcfqspi"
39
40#define	MCFQSPI_BUSCLK			(MCF_BUSCLK / 2)
41
42#define	MCFQSPI_QMR			0x00
43#define		MCFQSPI_QMR_MSTR	0x8000
44#define		MCFQSPI_QMR_CPOL	0x0200
45#define		MCFQSPI_QMR_CPHA	0x0100
46#define	MCFQSPI_QDLYR			0x04
47#define		MCFQSPI_QDLYR_SPE	0x8000
48#define	MCFQSPI_QWR			0x08
49#define		MCFQSPI_QWR_HALT	0x8000
50#define		MCFQSPI_QWR_WREN	0x4000
51#define		MCFQSPI_QWR_CSIV	0x1000
52#define	MCFQSPI_QIR			0x0C
53#define		MCFQSPI_QIR_WCEFB	0x8000
54#define		MCFQSPI_QIR_ABRTB	0x4000
55#define		MCFQSPI_QIR_ABRTL	0x1000
56#define		MCFQSPI_QIR_WCEFE	0x0800
57#define		MCFQSPI_QIR_ABRTE	0x0400
58#define		MCFQSPI_QIR_SPIFE	0x0100
59#define		MCFQSPI_QIR_WCEF	0x0008
60#define		MCFQSPI_QIR_ABRT	0x0004
61#define		MCFQSPI_QIR_SPIF	0x0001
62#define	MCFQSPI_QAR			0x010
63#define		MCFQSPI_QAR_TXBUF	0x00
64#define		MCFQSPI_QAR_RXBUF	0x10
65#define		MCFQSPI_QAR_CMDBUF	0x20
66#define	MCFQSPI_QDR			0x014
67#define	MCFQSPI_QCR			0x014
68#define		MCFQSPI_QCR_CONT	0x8000
69#define		MCFQSPI_QCR_BITSE	0x4000
70#define		MCFQSPI_QCR_DT		0x2000
71
72struct mcfqspi {
73	void __iomem *iobase;
74	int irq;
75	struct clk *clk;
76	struct mcfqspi_cs_control *cs_control;
77
78	wait_queue_head_t waitq;
79
80	struct work_struct work;
81	struct workqueue_struct *workq;
82	spinlock_t lock;
83	struct list_head msgq;
84};
85
86static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
87{
88	writew(val, mcfqspi->iobase + MCFQSPI_QMR);
89}
90
91static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val)
92{
93	writew(val, mcfqspi->iobase + MCFQSPI_QDLYR);
94}
95
96static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi)
97{
98	return readw(mcfqspi->iobase + MCFQSPI_QDLYR);
99}
100
101static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val)
102{
103	writew(val, mcfqspi->iobase + MCFQSPI_QWR);
104}
105
106static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val)
107{
108	writew(val, mcfqspi->iobase + MCFQSPI_QIR);
109}
110
111static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val)
112{
113	writew(val, mcfqspi->iobase + MCFQSPI_QAR);
114}
115
116static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val)
117{
118	writew(val, mcfqspi->iobase + MCFQSPI_QDR);
119}
120
121static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi)
122{
123	return readw(mcfqspi->iobase + MCFQSPI_QDR);
124}
125
126static void mcfqspi_cs_select(struct mcfqspi *mcfqspi, u8 chip_select,
127			    bool cs_high)
128{
129	mcfqspi->cs_control->select(mcfqspi->cs_control, chip_select, cs_high);
130}
131
132static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select,
133				bool cs_high)
134{
135	mcfqspi->cs_control->deselect(mcfqspi->cs_control, chip_select, cs_high);
136}
137
138static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi)
139{
140	return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ?
141		mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0;
142}
143
144static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)
145{
146	if (mcfqspi->cs_control && mcfqspi->cs_control->teardown)
147		mcfqspi->cs_control->teardown(mcfqspi->cs_control);
148}
149
150static u8 mcfqspi_qmr_baud(u32 speed_hz)
151{
152	return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u);
153}
154
155static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi)
156{
157	return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE;
158}
159
160static irqreturn_t mcfqspi_irq_handler(int this_irq, void *dev_id)
161{
162	struct mcfqspi *mcfqspi = dev_id;
163
164	/* clear interrupt */
165	mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE | MCFQSPI_QIR_SPIF);
166	wake_up(&mcfqspi->waitq);
167
168	return IRQ_HANDLED;
169}
170
171static void mcfqspi_transfer_msg8(struct mcfqspi *mcfqspi, unsigned count,
172				  const u8 *txbuf, u8 *rxbuf)
173{
174	unsigned i, n, offset = 0;
175
176	n = min(count, 16u);
177
178	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
179	for (i = 0; i < n; ++i)
180		mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
181
182	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
183	if (txbuf)
184		for (i = 0; i < n; ++i)
185			mcfqspi_wr_qdr(mcfqspi, *txbuf++);
186	else
187		for (i = 0; i < count; ++i)
188			mcfqspi_wr_qdr(mcfqspi, 0);
189
190	count -= n;
191	if (count) {
192		u16 qwr = 0xf08;
193		mcfqspi_wr_qwr(mcfqspi, 0x700);
194		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
195
196		do {
197			wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
198			mcfqspi_wr_qwr(mcfqspi, qwr);
199			mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
200			if (rxbuf) {
201				mcfqspi_wr_qar(mcfqspi,
202					       MCFQSPI_QAR_RXBUF + offset);
203				for (i = 0; i < 8; ++i)
204					*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
205			}
206			n = min(count, 8u);
207			if (txbuf) {
208				mcfqspi_wr_qar(mcfqspi,
209					       MCFQSPI_QAR_TXBUF + offset);
210				for (i = 0; i < n; ++i)
211					mcfqspi_wr_qdr(mcfqspi, *txbuf++);
212			}
213			qwr = (offset ? 0x808 : 0) + ((n - 1) << 8);
214			offset ^= 8;
215			count -= n;
216		} while (count);
217		wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
218		mcfqspi_wr_qwr(mcfqspi, qwr);
219		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
220		if (rxbuf) {
221			mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
222			for (i = 0; i < 8; ++i)
223				*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
224			offset ^= 8;
225		}
226	} else {
227		mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
228		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
229	}
230	wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
231	if (rxbuf) {
232		mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
233		for (i = 0; i < n; ++i)
234			*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
235	}
236}
237
238static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
239				   const u16 *txbuf, u16 *rxbuf)
240{
241	unsigned i, n, offset = 0;
242
243	n = min(count, 16u);
244
245	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
246	for (i = 0; i < n; ++i)
247		mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
248
249	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
250	if (txbuf)
251		for (i = 0; i < n; ++i)
252			mcfqspi_wr_qdr(mcfqspi, *txbuf++);
253	else
254		for (i = 0; i < count; ++i)
255			mcfqspi_wr_qdr(mcfqspi, 0);
256
257	count -= n;
258	if (count) {
259		u16 qwr = 0xf08;
260		mcfqspi_wr_qwr(mcfqspi, 0x700);
261		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
262
263		do {
264			wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
265			mcfqspi_wr_qwr(mcfqspi, qwr);
266			mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
267			if (rxbuf) {
268				mcfqspi_wr_qar(mcfqspi,
269					       MCFQSPI_QAR_RXBUF + offset);
270				for (i = 0; i < 8; ++i)
271					*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
272			}
273			n = min(count, 8u);
274			if (txbuf) {
275				mcfqspi_wr_qar(mcfqspi,
276					       MCFQSPI_QAR_TXBUF + offset);
277				for (i = 0; i < n; ++i)
278					mcfqspi_wr_qdr(mcfqspi, *txbuf++);
279			}
280			qwr = (offset ? 0x808 : 0x000) + ((n - 1) << 8);
281			offset ^= 8;
282			count -= n;
283		} while (count);
284		wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
285		mcfqspi_wr_qwr(mcfqspi, qwr);
286		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
287		if (rxbuf) {
288			mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
289			for (i = 0; i < 8; ++i)
290				*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
291			offset ^= 8;
292		}
293	} else {
294		mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
295		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
296	}
297	wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
298	if (rxbuf) {
299		mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
300		for (i = 0; i < n; ++i)
301			*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
302	}
303}
304
305static void mcfqspi_work(struct work_struct *work)
306{
307	struct mcfqspi *mcfqspi = container_of(work, struct mcfqspi, work);
308	unsigned long flags;
309
310	spin_lock_irqsave(&mcfqspi->lock, flags);
311	while (!list_empty(&mcfqspi->msgq)) {
312		struct spi_message *msg;
313		struct spi_device *spi;
314		struct spi_transfer *xfer;
315		int status = 0;
316
317		msg = container_of(mcfqspi->msgq.next, struct spi_message,
318				   queue);
319
320		list_del_init(&mcfqspi->msgq);
321		spin_unlock_irqrestore(&mcfqspi->lock, flags);
322
323		spi = msg->spi;
324
325		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
326			bool cs_high = spi->mode & SPI_CS_HIGH;
327			u16 qmr = MCFQSPI_QMR_MSTR;
328
329			if (xfer->bits_per_word)
330				qmr |= xfer->bits_per_word << 10;
331			else
332				qmr |= spi->bits_per_word << 10;
333			if (spi->mode & SPI_CPHA)
334				qmr |= MCFQSPI_QMR_CPHA;
335			if (spi->mode & SPI_CPOL)
336				qmr |= MCFQSPI_QMR_CPOL;
337			if (xfer->speed_hz)
338				qmr |= mcfqspi_qmr_baud(xfer->speed_hz);
339			else
340				qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
341			mcfqspi_wr_qmr(mcfqspi, qmr);
342
343			mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
344
345			mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
346			if ((xfer->bits_per_word ? xfer->bits_per_word :
347						spi->bits_per_word) == 8)
348				mcfqspi_transfer_msg8(mcfqspi, xfer->len,
349						      xfer->tx_buf,
350						      xfer->rx_buf);
351			else
352				mcfqspi_transfer_msg16(mcfqspi, xfer->len / 2,
353						       xfer->tx_buf,
354						       xfer->rx_buf);
355			mcfqspi_wr_qir(mcfqspi, 0);
356
357			if (xfer->delay_usecs)
358				udelay(xfer->delay_usecs);
359			if (xfer->cs_change) {
360				if (!list_is_last(&xfer->transfer_list,
361						  &msg->transfers))
362					mcfqspi_cs_deselect(mcfqspi,
363							    spi->chip_select,
364							    cs_high);
365			} else {
366				if (list_is_last(&xfer->transfer_list,
367						 &msg->transfers))
368					mcfqspi_cs_deselect(mcfqspi,
369							    spi->chip_select,
370							    cs_high);
371			}
372			msg->actual_length += xfer->len;
373		}
374		msg->status = status;
375		msg->complete(msg->context);
376
377		spin_lock_irqsave(&mcfqspi->lock, flags);
378	}
379	spin_unlock_irqrestore(&mcfqspi->lock, flags);
380}
381
382static int mcfqspi_transfer(struct spi_device *spi, struct spi_message *msg)
383{
384	struct mcfqspi *mcfqspi;
385	struct spi_transfer *xfer;
386	unsigned long flags;
387
388	mcfqspi = spi_master_get_devdata(spi->master);
389
390	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
391		if (xfer->bits_per_word && ((xfer->bits_per_word < 8)
392					|| (xfer->bits_per_word > 16))) {
393			dev_dbg(&spi->dev,
394				"%d bits per word is not supported\n",
395				xfer->bits_per_word);
396			goto fail;
397		}
398		if (xfer->speed_hz) {
399			u32 real_speed = MCFQSPI_BUSCLK /
400				mcfqspi_qmr_baud(xfer->speed_hz);
401			if (real_speed != xfer->speed_hz)
402				dev_dbg(&spi->dev,
403					"using speed %d instead of %d\n",
404					real_speed, xfer->speed_hz);
405		}
406	}
407	msg->status = -EINPROGRESS;
408	msg->actual_length = 0;
409
410	spin_lock_irqsave(&mcfqspi->lock, flags);
411	list_add_tail(&msg->queue, &mcfqspi->msgq);
412	queue_work(mcfqspi->workq, &mcfqspi->work);
413	spin_unlock_irqrestore(&mcfqspi->lock, flags);
414
415	return 0;
416fail:
417	msg->status = -EINVAL;
418	return -EINVAL;
419}
420
421static int mcfqspi_setup(struct spi_device *spi)
422{
423	if ((spi->bits_per_word < 8) || (spi->bits_per_word > 16)) {
424		dev_dbg(&spi->dev, "%d bits per word is not supported\n",
425			spi->bits_per_word);
426		return -EINVAL;
427	}
428	if (spi->chip_select >= spi->master->num_chipselect) {
429		dev_dbg(&spi->dev, "%d chip select is out of range\n",
430			spi->chip_select);
431		return -EINVAL;
432	}
433
434	mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),
435			    spi->chip_select, spi->mode & SPI_CS_HIGH);
436
437	dev_dbg(&spi->dev,
438			"bits per word %d, chip select %d, speed %d KHz\n",
439			spi->bits_per_word, spi->chip_select,
440			(MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz))
441			/ 1000);
442
443	return 0;
444}
445
446static int __devinit mcfqspi_probe(struct platform_device *pdev)
447{
448	struct spi_master *master;
449	struct mcfqspi *mcfqspi;
450	struct resource *res;
451	struct mcfqspi_platform_data *pdata;
452	int status;
453
454	master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
455	if (master == NULL) {
456		dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
457		return -ENOMEM;
458	}
459
460	mcfqspi = spi_master_get_devdata(master);
461
462	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
463	if (!res) {
464		dev_dbg(&pdev->dev, "platform_get_resource failed\n");
465		status = -ENXIO;
466		goto fail0;
467	}
468
469	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
470		dev_dbg(&pdev->dev, "request_mem_region failed\n");
471		status = -EBUSY;
472		goto fail0;
473	}
474
475	mcfqspi->iobase = ioremap(res->start, resource_size(res));
476	if (!mcfqspi->iobase) {
477		dev_dbg(&pdev->dev, "ioremap failed\n");
478		status = -ENOMEM;
479		goto fail1;
480	}
481
482	mcfqspi->irq = platform_get_irq(pdev, 0);
483	if (mcfqspi->irq < 0) {
484		dev_dbg(&pdev->dev, "platform_get_irq failed\n");
485		status = -ENXIO;
486		goto fail2;
487	}
488
489	status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, IRQF_DISABLED,
490			     pdev->name, mcfqspi);
491	if (status) {
492		dev_dbg(&pdev->dev, "request_irq failed\n");
493		goto fail2;
494	}
495
496	mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk");
497	if (IS_ERR(mcfqspi->clk)) {
498		dev_dbg(&pdev->dev, "clk_get failed\n");
499		status = PTR_ERR(mcfqspi->clk);
500		goto fail3;
501	}
502	clk_enable(mcfqspi->clk);
503
504	mcfqspi->workq = create_singlethread_workqueue(dev_name(master->dev.parent));
505	if (!mcfqspi->workq) {
506		dev_dbg(&pdev->dev, "create_workqueue failed\n");
507		status = -ENOMEM;
508		goto fail4;
509	}
510	INIT_WORK(&mcfqspi->work, mcfqspi_work);
511	spin_lock_init(&mcfqspi->lock);
512	INIT_LIST_HEAD(&mcfqspi->msgq);
513	init_waitqueue_head(&mcfqspi->waitq);
514
515	pdata = pdev->dev.platform_data;
516	if (!pdata) {
517		dev_dbg(&pdev->dev, "platform data is missing\n");
518		goto fail5;
519	}
520	master->bus_num = pdata->bus_num;
521	master->num_chipselect = pdata->num_chipselect;
522
523	mcfqspi->cs_control = pdata->cs_control;
524	status = mcfqspi_cs_setup(mcfqspi);
525	if (status) {
526		dev_dbg(&pdev->dev, "error initializing cs_control\n");
527		goto fail5;
528	}
529
530	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
531	master->setup = mcfqspi_setup;
532	master->transfer = mcfqspi_transfer;
533
534	platform_set_drvdata(pdev, master);
535
536	status = spi_register_master(master);
537	if (status) {
538		dev_dbg(&pdev->dev, "spi_register_master failed\n");
539		goto fail6;
540	}
541	dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
542
543	return 0;
544
545fail6:
546	mcfqspi_cs_teardown(mcfqspi);
547fail5:
548	destroy_workqueue(mcfqspi->workq);
549fail4:
550	clk_disable(mcfqspi->clk);
551	clk_put(mcfqspi->clk);
552fail3:
553	free_irq(mcfqspi->irq, mcfqspi);
554fail2:
555	iounmap(mcfqspi->iobase);
556fail1:
557	release_mem_region(res->start, resource_size(res));
558fail0:
559	spi_master_put(master);
560
561	dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
562
563	return status;
564}
565
566static int __devexit mcfqspi_remove(struct platform_device *pdev)
567{
568	struct spi_master *master = platform_get_drvdata(pdev);
569	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
570	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
571
572	/* disable the hardware (set the baud rate to 0) */
573	mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
574
575	platform_set_drvdata(pdev, NULL);
576	mcfqspi_cs_teardown(mcfqspi);
577	destroy_workqueue(mcfqspi->workq);
578	clk_disable(mcfqspi->clk);
579	clk_put(mcfqspi->clk);
580	free_irq(mcfqspi->irq, mcfqspi);
581	iounmap(mcfqspi->iobase);
582	release_mem_region(res->start, resource_size(res));
583	spi_unregister_master(master);
584	spi_master_put(master);
585
586	return 0;
587}
588
589#ifdef CONFIG_PM
590
591static int mcfqspi_suspend(struct device *dev)
592{
593	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
594
595	clk_disable(mcfqspi->clk);
596
597	return 0;
598}
599
600static int mcfqspi_resume(struct device *dev)
601{
602	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));
603
604	clk_enable(mcfqspi->clk);
605
606	return 0;
607}
608
609static struct dev_pm_ops mcfqspi_dev_pm_ops = {
610	.suspend	= mcfqspi_suspend,
611	.resume		= mcfqspi_resume,
612};
613
614#define	MCFQSPI_DEV_PM_OPS	(&mcfqspi_dev_pm_ops)
615#else
616#define	MCFQSPI_DEV_PM_OPS	NULL
617#endif
618
619static struct platform_driver mcfqspi_driver = {
620	.driver.name	= DRIVER_NAME,
621	.driver.owner	= THIS_MODULE,
622	.driver.pm	= MCFQSPI_DEV_PM_OPS,
623	.remove		= __devexit_p(mcfqspi_remove),
624};
625
626static int __init mcfqspi_init(void)
627{
628	return platform_driver_probe(&mcfqspi_driver, mcfqspi_probe);
629}
630module_init(mcfqspi_init);
631
632static void __exit mcfqspi_exit(void)
633{
634	platform_driver_unregister(&mcfqspi_driver);
635}
636module_exit(mcfqspi_exit);
637
638MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
639MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
640MODULE_LICENSE("GPL");
641MODULE_ALIAS("platform:" DRIVER_NAME);
642