aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt42
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/spi-fsl-dspi.c557
4 files changed, 607 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
new file mode 100644
index 000000000000..a1fb3035a42b
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
@@ -0,0 +1,42 @@
1ARM Freescale DSPI controller
2
3Required properties:
4- compatible : "fsl,vf610-dspi"
5- reg : Offset and length of the register set for the device
6- interrupts : Should contain SPI controller interrupt
7- clocks: from common clock binding: handle to dspi clock.
8- clock-names: from common clock binding: Shall be "dspi".
9- pinctrl-0: pin control group to be used for this controller.
10- pinctrl-names: must contain a "default" entry.
11- spi-num-chipselects : the number of the chipselect signals.
12- bus-num : the slave chip chipselect signal number.
13Example:
14
15dspi0@4002c000 {
16 #address-cells = <1>;
17 #size-cells = <0>;
18 compatible = "fsl,vf610-dspi";
19 reg = <0x4002c000 0x1000>;
20 interrupts = <0 67 0x04>;
21 clocks = <&clks VF610_CLK_DSPI0>;
22 clock-names = "dspi";
23 spi-num-chipselects = <5>;
24 bus-num = <0>;
25 pinctrl-names = "default";
26 pinctrl-0 = <&pinctrl_dspi0_1>;
27 status = "okay";
28
29 sflash: at26df081a@0 {
30 #address-cells = <1>;
31 #size-cells = <1>;
32 compatible = "atmel,at26df081a";
33 spi-max-frequency = <16000000>;
34 spi-cpol;
35 spi-cpha;
36 reg = <0>;
37 linux,modalias = "m25p80";
38 modal = "at26df081a";
39 };
40};
41
42
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 2f6f42a4f805..718d08205bd3 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -255,6 +255,13 @@ config SPI_FSL_SPI
255 This also enables using the Aeroflex Gaisler GRLIB SPI controller in 255 This also enables using the Aeroflex Gaisler GRLIB SPI controller in
256 master mode. 256 master mode.
257 257
258config SPI_FSL_DSPI
259 tristate "Freescale DSPI controller"
260 select SPI_BITBANG
261 help
262 This enables support for the Freescale DSPI controller in master
263 mode. VF610 platform uses the controller.
264
258config SPI_FSL_ESPI 265config SPI_FSL_ESPI
259 bool "Freescale eSPI controller" 266 bool "Freescale eSPI controller"
260 depends on FSL_SOC 267 depends on FSL_SOC
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 7c4170263cd8..aaacc93c40f4 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o
31obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o 31obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o
32obj-$(CONFIG_SPI_FALCON) += spi-falcon.o 32obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
33obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o 33obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o
34obj-$(CONFIG_SPI_FSL_DSPI) += spi-fsl-dspi.o
34obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o 35obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o
35obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o 36obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o
36obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o 37obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
new file mode 100644
index 000000000000..6cd07d13ecab
--- /dev/null
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -0,0 +1,557 @@
1/*
2 * drivers/spi/spi-fsl-dspi.c
3 *
4 * Copyright 2013 Freescale Semiconductor, Inc.
5 *
6 * Freescale DSPI driver
7 * This file contains a driver for the Freescale DSPI
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19#include <linux/errno.h>
20#include <linux/platform_device.h>
21#include <linux/sched.h>
22#include <linux/delay.h>
23#include <linux/io.h>
24#include <linux/clk.h>
25#include <linux/err.h>
26#include <linux/spi/spi.h>
27#include <linux/spi/spi_bitbang.h>
28#include <linux/pm_runtime.h>
29#include <linux/of.h>
30#include <linux/of_device.h>
31
32#define DRIVER_NAME "fsl-dspi"
33
34#define TRAN_STATE_RX_VOID 0x01
35#define TRAN_STATE_TX_VOID 0x02
36#define TRAN_STATE_WORD_ODD_NUM 0x04
37
38#define DSPI_FIFO_SIZE 4
39
40#define SPI_MCR 0x00
41#define SPI_MCR_MASTER (1 << 31)
42#define SPI_MCR_PCSIS (0x3F << 16)
43#define SPI_MCR_CLR_TXF (1 << 11)
44#define SPI_MCR_CLR_RXF (1 << 10)
45
46#define SPI_TCR 0x08
47
48#define SPI_CTAR(x) (0x0c + (x * 4))
49#define SPI_CTAR_FMSZ(x) (((x) & 0x0000000f) << 27)
50#define SPI_CTAR_CPOL(x) ((x) << 26)
51#define SPI_CTAR_CPHA(x) ((x) << 25)
52#define SPI_CTAR_LSBFE(x) ((x) << 24)
53#define SPI_CTAR_PCSSCR(x) (((x) & 0x00000003) << 22)
54#define SPI_CTAR_PASC(x) (((x) & 0x00000003) << 20)
55#define SPI_CTAR_PDT(x) (((x) & 0x00000003) << 18)
56#define SPI_CTAR_PBR(x) (((x) & 0x00000003) << 16)
57#define SPI_CTAR_CSSCK(x) (((x) & 0x0000000f) << 12)
58#define SPI_CTAR_ASC(x) (((x) & 0x0000000f) << 8)
59#define SPI_CTAR_DT(x) (((x) & 0x0000000f) << 4)
60#define SPI_CTAR_BR(x) ((x) & 0x0000000f)
61
62#define SPI_CTAR0_SLAVE 0x0c
63
64#define SPI_SR 0x2c
65#define SPI_SR_EOQF 0x10000000
66
67#define SPI_RSER 0x30
68#define SPI_RSER_EOQFE 0x10000000
69
70#define SPI_PUSHR 0x34
71#define SPI_PUSHR_CONT (1 << 31)
72#define SPI_PUSHR_CTAS(x) (((x) & 0x00000007) << 28)
73#define SPI_PUSHR_EOQ (1 << 27)
74#define SPI_PUSHR_CTCNT (1 << 26)
75#define SPI_PUSHR_PCS(x) (((1 << x) & 0x0000003f) << 16)
76#define SPI_PUSHR_TXDATA(x) ((x) & 0x0000ffff)
77
78#define SPI_PUSHR_SLAVE 0x34
79
80#define SPI_POPR 0x38
81#define SPI_POPR_RXDATA(x) ((x) & 0x0000ffff)
82
83#define SPI_TXFR0 0x3c
84#define SPI_TXFR1 0x40
85#define SPI_TXFR2 0x44
86#define SPI_TXFR3 0x48
87#define SPI_RXFR0 0x7c
88#define SPI_RXFR1 0x80
89#define SPI_RXFR2 0x84
90#define SPI_RXFR3 0x88
91
92#define SPI_FRAME_BITS(bits) SPI_CTAR_FMSZ((bits) - 1)
93#define SPI_FRAME_BITS_MASK SPI_CTAR_FMSZ(0xf)
94#define SPI_FRAME_BITS_16 SPI_CTAR_FMSZ(0xf)
95#define SPI_FRAME_BITS_8 SPI_CTAR_FMSZ(0x7)
96
97#define SPI_CS_INIT 0x01
98#define SPI_CS_ASSERT 0x02
99#define SPI_CS_DROP 0x04
100
101struct chip_data {
102 u32 mcr_val;
103 u32 ctar_val;
104 u16 void_write_data;
105};
106
107struct fsl_dspi {
108 struct spi_bitbang bitbang;
109 struct platform_device *pdev;
110
111 void *base;
112 int irq;
113 struct clk *clk;
114
115 struct spi_transfer *cur_transfer;
116 struct chip_data *cur_chip;
117 size_t len;
118 void *tx;
119 void *tx_end;
120 void *rx;
121 void *rx_end;
122 char dataflags;
123 u8 cs;
124 u16 void_write_data;
125
126 wait_queue_head_t waitq;
127 u32 waitflags;
128};
129
130static inline int is_double_byte_mode(struct fsl_dspi *dspi)
131{
132 return ((readl(dspi->base + SPI_CTAR(dspi->cs)) & SPI_FRAME_BITS_MASK)
133 == SPI_FRAME_BITS(8)) ? 0 : 1;
134}
135
136static void set_bit_mode(struct fsl_dspi *dspi, unsigned char bits)
137{
138 u32 temp;
139
140 temp = readl(dspi->base + SPI_CTAR(dspi->cs));
141 temp &= ~SPI_FRAME_BITS_MASK;
142 temp |= SPI_FRAME_BITS(bits);
143 writel(temp, dspi->base + SPI_CTAR(dspi->cs));
144}
145
146static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
147 unsigned long clkrate)
148{
149 /* Valid baud rate pre-scaler values */
150 int pbr_tbl[4] = {2, 3, 5, 7};
151 int brs[16] = { 2, 4, 6, 8,
152 16, 32, 64, 128,
153 256, 512, 1024, 2048,
154 4096, 8192, 16384, 32768 };
155 int temp, i = 0, j = 0;
156
157 temp = clkrate / 2 / speed_hz;
158
159 for (i = 0; i < ARRAY_SIZE(pbr_tbl); i++)
160 for (j = 0; j < ARRAY_SIZE(brs); j++) {
161 if (pbr_tbl[i] * brs[j] >= temp) {
162 *pbr = i;
163 *br = j;
164 return;
165 }
166 }
167
168 pr_warn("Can not find valid buad rate,speed_hz is %d,clkrate is %ld\
169 ,we use the max prescaler value.\n", speed_hz, clkrate);
170 *pbr = ARRAY_SIZE(pbr_tbl) - 1;
171 *br = ARRAY_SIZE(brs) - 1;
172}
173
174static int dspi_transfer_write(struct fsl_dspi *dspi)
175{
176 int tx_count = 0;
177 int tx_word;
178 u16 d16;
179 u8 d8;
180 u32 dspi_pushr = 0;
181 int first = 1;
182
183 tx_word = is_double_byte_mode(dspi);
184
185 /* If we are in word mode, but only have a single byte to transfer
186 * then switch to byte mode temporarily. Will switch back at the
187 * end of the transfer.
188 */
189 if (tx_word && (dspi->len == 1)) {
190 dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
191 set_bit_mode(dspi, 8);
192 tx_word = 0;
193 }
194
195 while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) {
196 if (tx_word) {
197 if (dspi->len == 1)
198 break;
199
200 if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) {
201 d16 = *(u16 *)dspi->tx;
202 dspi->tx += 2;
203 } else {
204 d16 = dspi->void_write_data;
205 }
206
207 dspi_pushr = SPI_PUSHR_TXDATA(d16) |
208 SPI_PUSHR_PCS(dspi->cs) |
209 SPI_PUSHR_CTAS(dspi->cs) |
210 SPI_PUSHR_CONT;
211
212 dspi->len -= 2;
213 } else {
214 if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) {
215
216 d8 = *(u8 *)dspi->tx;
217 dspi->tx++;
218 } else {
219 d8 = (u8)dspi->void_write_data;
220 }
221
222 dspi_pushr = SPI_PUSHR_TXDATA(d8) |
223 SPI_PUSHR_PCS(dspi->cs) |
224 SPI_PUSHR_CTAS(dspi->cs) |
225 SPI_PUSHR_CONT;
226
227 dspi->len--;
228 }
229
230 if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) {
231 /* last transfer in the transfer */
232 dspi_pushr |= SPI_PUSHR_EOQ;
233 } else if (tx_word && (dspi->len == 1))
234 dspi_pushr |= SPI_PUSHR_EOQ;
235
236 if (first) {
237 first = 0;
238 dspi_pushr |= SPI_PUSHR_CTCNT; /* clear counter */
239 }
240
241 writel(dspi_pushr, dspi->base + SPI_PUSHR);
242 tx_count++;
243 }
244
245 return tx_count * (tx_word + 1);
246}
247
248static int dspi_transfer_read(struct fsl_dspi *dspi)
249{
250 int rx_count = 0;
251 int rx_word = is_double_byte_mode(dspi);
252 u16 d;
253 while ((dspi->rx < dspi->rx_end)
254 && (rx_count < DSPI_FIFO_SIZE)) {
255 if (rx_word) {
256 if ((dspi->rx_end - dspi->rx) == 1)
257 break;
258
259 d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR));
260
261 if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
262 *(u16 *)dspi->rx = d;
263 dspi->rx += 2;
264
265 } else {
266 d = SPI_POPR_RXDATA(readl(dspi->base + SPI_POPR));
267 if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
268 *(u8 *)dspi->rx = d;
269 dspi->rx++;
270 }
271 rx_count++;
272 }
273
274 return rx_count;
275}
276
277static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t)
278{
279 struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
280 dspi->cur_transfer = t;
281 dspi->cur_chip = spi_get_ctldata(spi);
282 dspi->cs = spi->chip_select;
283 dspi->void_write_data = dspi->cur_chip->void_write_data;
284
285 dspi->dataflags = 0;
286 dspi->tx = (void *)t->tx_buf;
287 dspi->tx_end = dspi->tx + t->len;
288 dspi->rx = t->rx_buf;
289 dspi->rx_end = dspi->rx + t->len;
290 dspi->len = t->len;
291
292 if (!dspi->rx)
293 dspi->dataflags |= TRAN_STATE_RX_VOID;
294
295 if (!dspi->tx)
296 dspi->dataflags |= TRAN_STATE_TX_VOID;
297
298 writel(dspi->cur_chip->mcr_val, dspi->base + SPI_MCR);
299 writel(dspi->cur_chip->ctar_val, dspi->base + SPI_CTAR(dspi->cs));
300 writel(SPI_RSER_EOQFE, dspi->base + SPI_RSER);
301
302 if (t->speed_hz)
303 writel(dspi->cur_chip->ctar_val,
304 dspi->base + SPI_CTAR(dspi->cs));
305
306 dspi_transfer_write(dspi);
307
308 if (wait_event_interruptible(dspi->waitq, dspi->waitflags))
309 dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n");
310 dspi->waitflags = 0;
311
312 return t->len - dspi->len;
313}
314
315static void dspi_chipselect(struct spi_device *spi, int value)
316{
317 struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
318 u32 pushr = readl(dspi->base + SPI_PUSHR);
319
320 switch (value) {
321 case BITBANG_CS_ACTIVE:
322 pushr |= SPI_PUSHR_CONT;
323 case BITBANG_CS_INACTIVE:
324 pushr &= ~SPI_PUSHR_CONT;
325 }
326
327 writel(pushr, dspi->base + SPI_PUSHR);
328}
329
330static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
331{
332 struct chip_data *chip;
333 struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
334 unsigned char br = 0, pbr = 0, fmsz = 0;
335
336 /* Only alloc on first setup */
337 chip = spi_get_ctldata(spi);
338 if (chip == NULL) {
339 chip = kcalloc(1, sizeof(struct chip_data), GFP_KERNEL);
340 if (!chip)
341 return -ENOMEM;
342 }
343
344 chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS |
345 SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF;
346 if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) {
347 fmsz = spi->bits_per_word - 1;
348 } else {
349 pr_err("Invalid wordsize\n");
350 kfree(chip);
351 return -ENODEV;
352 }
353
354 chip->void_write_data = 0;
355
356 hz_to_spi_baud(&pbr, &br,
357 spi->max_speed_hz, clk_get_rate(dspi->clk));
358
359 chip->ctar_val = SPI_CTAR_FMSZ(fmsz)
360 | SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0)
361 | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0)
362 | SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0)
363 | SPI_CTAR_PBR(pbr)
364 | SPI_CTAR_BR(br);
365
366 spi_set_ctldata(spi, chip);
367
368 return 0;
369}
370
371static int dspi_setup(struct spi_device *spi)
372{
373 if (!spi->max_speed_hz)
374 return -EINVAL;
375
376 if (!spi->bits_per_word)
377 spi->bits_per_word = 8;
378
379 return dspi_setup_transfer(spi, NULL);
380}
381
382static irqreturn_t dspi_interrupt(int irq, void *dev_id)
383{
384 struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;
385
386 writel(SPI_SR_EOQF, dspi->base + SPI_SR);
387
388 dspi_transfer_read(dspi);
389
390 if (!dspi->len) {
391 if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM)
392 set_bit_mode(dspi, 16);
393 dspi->waitflags = 1;
394 wake_up_interruptible(&dspi->waitq);
395 } else {
396 dspi_transfer_write(dspi);
397
398 return IRQ_HANDLED;
399 }
400
401 return IRQ_HANDLED;
402}
403
404static struct of_device_id fsl_dspi_dt_ids[] = {
405 { .compatible = "fsl,vf610-dspi", .data = NULL, },
406 { /* sentinel */ }
407};
408MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids);
409
410#ifdef CONFIG_PM_SLEEP
411static int dspi_suspend(struct device *dev)
412{
413 struct spi_master *master = dev_get_drvdata(dev);
414 struct fsl_dspi *dspi = spi_master_get_devdata(master);
415
416 spi_master_suspend(master);
417 clk_disable_unprepare(dspi->clk);
418
419 return 0;
420}
421
422static int dspi_resume(struct device *dev)
423{
424
425 struct spi_master *master = dev_get_drvdata(dev);
426 struct fsl_dspi *dspi = spi_master_get_devdata(master);
427
428 clk_prepare_enable(dspi->clk);
429 spi_master_resume(master);
430
431 return 0;
432}
433#endif /* CONFIG_PM_SLEEP */
434
435static const struct dev_pm_ops dspi_pm = {
436 SET_SYSTEM_SLEEP_PM_OPS(dspi_suspend, dspi_resume)
437};
438
439static int dspi_probe(struct platform_device *pdev)
440{
441 struct device_node *np = pdev->dev.of_node;
442 struct spi_master *master;
443 struct fsl_dspi *dspi;
444 struct resource *res;
445 int ret = 0, cs_num, bus_num;
446
447 master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
448 if (!master)
449 return -ENOMEM;
450
451 dspi = spi_master_get_devdata(master);
452 dspi->pdev = pdev;
453 dspi->bitbang.master = spi_master_get(master);
454 dspi->bitbang.chipselect = dspi_chipselect;
455 dspi->bitbang.setup_transfer = dspi_setup_transfer;
456 dspi->bitbang.txrx_bufs = dspi_txrx_transfer;
457 dspi->bitbang.master->setup = dspi_setup;
458 dspi->bitbang.master->dev.of_node = pdev->dev.of_node;
459
460 master->mode_bits = SPI_CPOL | SPI_CPHA;
461 master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) |
462 SPI_BPW_MASK(16);
463
464 ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num);
465 if (ret < 0) {
466 dev_err(&pdev->dev, "can't get spi-num-chipselects\n");
467 goto out_master_put;
468 }
469 master->num_chipselect = cs_num;
470
471 ret = of_property_read_u32(np, "bus-num", &bus_num);
472 if (ret < 0) {
473 dev_err(&pdev->dev, "can't get bus-num\n");
474 goto out_master_put;
475 }
476 master->bus_num = bus_num;
477
478 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
479 if (!res) {
480 dev_err(&pdev->dev, "can't get platform resource\n");
481 ret = -EINVAL;
482 goto out_master_put;
483 }
484
485 dspi->base = devm_ioremap_resource(&pdev->dev, res);
486 if (!dspi->base) {
487 ret = -EINVAL;
488 goto out_master_put;
489 }
490
491 dspi->irq = platform_get_irq(pdev, 0);
492 if (dspi->irq < 0) {
493 dev_err(&pdev->dev, "can't get platform irq\n");
494 ret = dspi->irq;
495 goto out_master_put;
496 }
497
498 ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, 0,
499 pdev->name, dspi);
500 if (ret < 0) {
501 dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n");
502 goto out_master_put;
503 }
504
505 dspi->clk = devm_clk_get(&pdev->dev, "dspi");
506 if (IS_ERR(dspi->clk)) {
507 ret = PTR_ERR(dspi->clk);
508 dev_err(&pdev->dev, "unable to get clock\n");
509 goto out_master_put;
510 }
511 clk_prepare_enable(dspi->clk);
512
513 init_waitqueue_head(&dspi->waitq);
514 platform_set_drvdata(pdev, dspi);
515
516 ret = spi_bitbang_start(&dspi->bitbang);
517 if (ret != 0) {
518 dev_err(&pdev->dev, "Problem registering DSPI master\n");
519 goto out_clk_put;
520 }
521
522 pr_info(KERN_INFO "Freescale DSPI master initialized\n");
523 return ret;
524
525out_clk_put:
526 clk_disable_unprepare(dspi->clk);
527out_master_put:
528 spi_master_put(master);
529 platform_set_drvdata(pdev, NULL);
530
531 return ret;
532}
533
534static int dspi_remove(struct platform_device *pdev)
535{
536 struct fsl_dspi *dspi = platform_get_drvdata(pdev);
537
538 /* Disconnect from the SPI framework */
539 spi_bitbang_stop(&dspi->bitbang);
540 spi_master_put(dspi->bitbang.master);
541
542 return 0;
543}
544
545static struct platform_driver fsl_dspi_driver = {
546 .driver.name = DRIVER_NAME,
547 .driver.of_match_table = fsl_dspi_dt_ids,
548 .driver.owner = THIS_MODULE,
549 .driver.pm = &dspi_pm,
550 .probe = dspi_probe,
551 .remove = dspi_remove,
552};
553module_platform_driver(fsl_dspi_driver);
554
555MODULE_DESCRIPTION("Freescale DSPI Controller Driver");
556MODULE_LICENSE("GPL v2");
557MODULE_ALIAS("platform:" DRIVER_NAME);