sunxi: driver refresh for 3.13
[openwrt.git] / target / linux / sunxi / patches-3.13 / 262-spi-add-a10-spi-driver.patch
1 From 67e7ba38902a28679bf6ee8fd82952ae6795f5f5 Mon Sep 17 00:00:00 2001
2 From: Maxime Ripard <maxime.ripard@free-electrons.com>
3 Date: Sat, 22 Feb 2014 22:35:53 +0100
4 Subject: [PATCH] spi: sunxi: Add Allwinner A10 SPI controller driver
5
6 The older Allwinner SoCs (A10, A13, A10s and A20) all have the same SPI
7 controller.
8
9 Unfortunately, this SPI controller, even though quite similar, is significantly
10 different from the recently supported A31 SPI controller (different registers
11 offset, split/merged registers, etc.). Supporting both controllers in a single
12 driver would be unreasonable, hence the addition of a new driver.
13
14 Like its more recent counterpart, it supports DMA, but the driver only does PIO
15 until we have a dmaengine driver for this platform.
16
17 Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
18 ---
19  .../devicetree/bindings/spi/spi-sun4i.txt          |  24 ++
20  drivers/spi/Kconfig                                |   6 +
21  drivers/spi/Makefile                               |   1 +
22  drivers/spi/spi-sun4i.c                            | 477 +++++++++++++++++++++
23  4 files changed, 508 insertions(+)
24  create mode 100644 Documentation/devicetree/bindings/spi/spi-sun4i.txt
25  create mode 100644 drivers/spi/spi-sun4i.c
26
27 diff --git a/Documentation/devicetree/bindings/spi/spi-sun4i.txt b/Documentation/devicetree/bindings/spi/spi-sun4i.txt
28 new file mode 100644
29 index 0000000..de827f5
30 --- /dev/null
31 +++ b/Documentation/devicetree/bindings/spi/spi-sun4i.txt
32 @@ -0,0 +1,24 @@
33 +Allwinner A10 SPI controller
34 +
35 +Required properties:
36 +- compatible: Should be "allwinner,sun4-a10-spi".
37 +- reg: Should contain register location and length.
38 +- interrupts: Should contain interrupt.
39 +- clocks: phandle to the clocks feeding the SPI controller. Two are
40 +          needed:
41 +  - "ahb": the gated AHB parent clock
42 +  - "mod": the parent module clock
43 +- clock-names: Must contain the clock names described just above
44 +
45 +Example:
46 +
47 +spi1: spi@01c06000 {
48 +       compatible = "allwinner,sun4i-a10-spi";
49 +       reg = <0x01c06000 0x1000>;
50 +       interrupts = <11>;
51 +       clocks = <&ahb_gates 21>, <&spi1_clk>;
52 +       clock-names = "ahb", "mod";
53 +       status = "disabled";
54 +       #address-cells = <1>;
55 +       #size-cells = <0>;
56 +};
57 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
58 index 58530d3..78adfae 100644
59 --- a/drivers/spi/Kconfig
60 +++ b/drivers/spi/Kconfig
61 @@ -446,6 +446,12 @@ config SPI_SIRF
62         help
63           SPI driver for CSR SiRFprimaII SoCs
64  
65 +config SPI_SUN4I
66 +       tristate "Allwinner A10 SoCs SPI controller"
67 +       depends on ARCH_SUNXI || COMPILE_TEST
68 +       help
69 +         SPI driver for Allwinner sun4i, sun5i and sun7i SoCs
70 +
71  config SPI_SUN6I
72         tristate "Allwinner A31 SPI controller"
73         depends on ARCH_SUNXI || COMPILE_TEST
74 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
75 index 13b6ccf..65f4993 100644
76 --- a/drivers/spi/Makefile
77 +++ b/drivers/spi/Makefile
78 @@ -70,6 +70,7 @@ obj-$(CONFIG_SPI_SH_HSPI)             += spi-sh-hspi.o
79  obj-$(CONFIG_SPI_SH_MSIOF)             += spi-sh-msiof.o
80  obj-$(CONFIG_SPI_SH_SCI)               += spi-sh-sci.o
81  obj-$(CONFIG_SPI_SIRF)         += spi-sirf.o
82 +obj-$(CONFIG_SPI_SUN4I)                        += spi-sun4i.o
83  obj-$(CONFIG_SPI_SUN6I)                        += spi-sun6i.o
84  obj-$(CONFIG_SPI_TEGRA114)             += spi-tegra114.o
85  obj-$(CONFIG_SPI_TEGRA20_SFLASH)       += spi-tegra20-sflash.o
86 diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
87 new file mode 100644
88 index 0000000..3f82705
89 --- /dev/null
90 +++ b/drivers/spi/spi-sun4i.c
91 @@ -0,0 +1,477 @@
92 +/*
93 + * Copyright (C) 2012 - 2014 Allwinner Tech
94 + * Pan Nan <pannan@allwinnertech.com>
95 + *
96 + * Copyright (C) 2014 Maxime Ripard
97 + * Maxime Ripard <maxime.ripard@free-electrons.com>
98 + *
99 + * This program is free software; you can redistribute it and/or
100 + * modify it under the terms of the GNU General Public License as
101 + * published by the Free Software Foundation; either version 2 of
102 + * the License, or (at your option) any later version.
103 + */
104 +
105 +#include <linux/clk.h>
106 +#include <linux/delay.h>
107 +#include <linux/device.h>
108 +#include <linux/interrupt.h>
109 +#include <linux/io.h>
110 +#include <linux/module.h>
111 +#include <linux/platform_device.h>
112 +#include <linux/pm_runtime.h>
113 +#include <linux/workqueue.h>
114 +
115 +#include <linux/spi/spi.h>
116 +
117 +#define SUN4I_FIFO_DEPTH               64
118 +
119 +#define SUN4I_RXDATA_REG               0x00
120 +
121 +#define SUN4I_TXDATA_REG               0x04
122 +
123 +#define SUN4I_CTL_REG                  0x08
124 +#define SUN4I_CTL_ENABLE                       BIT(0)
125 +#define SUN4I_CTL_MASTER                       BIT(1)
126 +#define SUN4I_CTL_CPHA                         BIT(2)
127 +#define SUN4I_CTL_CPOL                         BIT(3)
128 +#define SUN4I_CTL_CS_ACTIVE_LOW                        BIT(4)
129 +#define SUN4I_CTL_LMTF                         BIT(6)
130 +#define SUN4I_CTL_TF_RST                       BIT(8)
131 +#define SUN4I_CTL_RF_RST                       BIT(9)
132 +#define SUN4I_CTL_XCH                          BIT(10)
133 +#define SUN4I_CTL_CS_MASK                      0x3000
134 +#define SUN4I_CTL_CS(cs)                       (((cs) << 12) & SUN4I_CTL_CS_MASK)
135 +#define SUN4I_CTL_DHB                          BIT(15)
136 +#define SUN4I_CTL_CS_MANUAL                    BIT(16)
137 +#define SUN4I_CTL_CS_LEVEL                     BIT(17)
138 +#define SUN4I_CTL_TP                           BIT(18)
139 +
140 +#define SUN4I_INT_CTL_REG              0x0c
141 +#define SUN4I_INT_CTL_TC                       BIT(16)
142 +
143 +#define SUN4I_INT_STA_REG              0x10
144 +
145 +#define SUN4I_DMA_CTL_REG              0x14
146 +
147 +#define SUN4I_WAIT_REG                 0x18
148 +
149 +#define SUN4I_CLK_CTL_REG              0x1c
150 +#define SUN4I_CLK_CTL_CDR2_MASK                        0xff
151 +#define SUN4I_CLK_CTL_CDR2(div)                        ((div) & SUN4I_CLK_CTL_CDR2_MASK)
152 +#define SUN4I_CLK_CTL_CDR1_MASK                        0xf
153 +#define SUN4I_CLK_CTL_CDR1(div)                        (((div) & SUN4I_CLK_CTL_CDR1_MASK) << 8)
154 +#define SUN4I_CLK_CTL_DRS                      BIT(12)
155 +
156 +#define SUN4I_BURST_CNT_REG            0x20
157 +#define SUN4I_BURST_CNT(cnt)                   ((cnt) & 0xffffff)
158 +
159 +#define SUN4I_XMIT_CNT_REG             0x24
160 +#define SUN4I_XMIT_CNT(cnt)                    ((cnt) & 0xffffff)
161 +
162 +#define SUN4I_FIFO_STA_REG             0x28
163 +#define SUN4I_FIFO_STA_RF_CNT_MASK             0x7f
164 +#define SUN4I_FIFO_STA_RF_CNT_BITS             0
165 +#define SUN4I_FIFO_STA_TF_CNT_MASK             0x7f
166 +#define SUN4I_FIFO_STA_TF_CNT_BITS             16
167 +
168 +struct sun4i_spi {
169 +       struct spi_master       *master;
170 +       void __iomem            *base_addr;
171 +       struct clk              *hclk;
172 +       struct clk              *mclk;
173 +
174 +       struct completion       done;
175 +
176 +       const u8                *tx_buf;
177 +       u8                      *rx_buf;
178 +       int                     len;
179 +};
180 +
181 +static inline u32 sun4i_spi_read(struct sun4i_spi *sspi, u32 reg)
182 +{
183 +       return readl(sspi->base_addr + reg);
184 +}
185 +
186 +static inline void sun4i_spi_write(struct sun4i_spi *sspi, u32 reg, u32 value)
187 +{
188 +       writel(value, sspi->base_addr + reg);
189 +}
190 +
191 +static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len)
192 +{
193 +       u32 reg, cnt;
194 +       u8 byte;
195 +
196 +       /* See how much data is available */
197 +       reg = sun4i_spi_read(sspi, SUN4I_FIFO_STA_REG);
198 +       reg &= SUN4I_FIFO_STA_RF_CNT_MASK;
199 +       cnt = reg >> SUN4I_FIFO_STA_RF_CNT_BITS;
200 +
201 +       if (len > cnt)
202 +               len = cnt;
203 +
204 +       while (len--) {
205 +               byte = readb(sspi->base_addr + SUN4I_RXDATA_REG);
206 +               if (sspi->rx_buf)
207 +                       *sspi->rx_buf++ = byte;
208 +       }
209 +}
210 +
211 +static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len)
212 +{
213 +       u8 byte;
214 +
215 +       if (len > sspi->len)
216 +               len = sspi->len;
217 +
218 +       while (len--) {
219 +               byte = sspi->tx_buf ? *sspi->tx_buf++ : 0;
220 +               writeb(byte, sspi->base_addr + SUN4I_TXDATA_REG);
221 +               sspi->len--;
222 +       }
223 +}
224 +
225 +static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
226 +{
227 +       struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
228 +       u32 reg;
229 +
230 +       reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
231 +
232 +       reg &= ~SUN4I_CTL_CS_MASK;
233 +       reg |= SUN4I_CTL_CS(spi->chip_select);
234 +
235 +       if (enable)
236 +               reg |= SUN4I_CTL_CS_LEVEL;
237 +       else
238 +               reg &= ~SUN4I_CTL_CS_LEVEL;
239 +
240 +       /*
241 +        * Even though this looks irrelevant since we are supposed to
242 +        * be controlling the chip select manually, this bit also
243 +        * controls the levels of the chip select for inactive
244 +        * devices.
245 +        *
246 +        * If we don't set it, the chip select level will go low by
247 +        * default when the device is idle, which is not really
248 +        * expected in the common case where the chip select is active
249 +        * low.
250 +        */
251 +       if (spi->mode & SPI_CS_HIGH)
252 +               reg &= ~SUN4I_CTL_CS_ACTIVE_LOW;
253 +       else
254 +               reg |= SUN4I_CTL_CS_ACTIVE_LOW;
255 +
256 +       sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
257 +}
258 +
259 +static int sun4i_spi_transfer_one(struct spi_master *master,
260 +                                 struct spi_device *spi,
261 +                                 struct spi_transfer *tfr)
262 +{
263 +       struct sun4i_spi *sspi = spi_master_get_devdata(master);
264 +       unsigned int mclk_rate, div, timeout;
265 +       unsigned int tx_len = 0;
266 +       int ret = 0;
267 +       u32 reg;
268 +
269 +       /* We don't support transfer larger than the FIFO */
270 +       if (tfr->len > SUN4I_FIFO_DEPTH)
271 +               return -EINVAL;
272 +
273 +       reinit_completion(&sspi->done);
274 +       sspi->tx_buf = tfr->tx_buf;
275 +       sspi->rx_buf = tfr->rx_buf;
276 +       sspi->len = tfr->len;
277 +
278 +       /* Clear pending interrupts */
279 +       sun4i_spi_write(sspi, SUN4I_INT_STA_REG, ~0);
280 +
281 +
282 +       reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
283 +
284 +       /* Reset FIFOs */
285 +       sun4i_spi_write(sspi, SUN4I_CTL_REG,
286 +                       reg | SUN4I_CTL_RF_RST | SUN4I_CTL_TF_RST);
287 +
288 +       /*
289 +        * Setup the transfer control register: Chip Select,
290 +        * polarities, etc.
291 +        */
292 +       if (spi->mode & SPI_CPOL)
293 +               reg |= SUN4I_CTL_CPOL;
294 +       else
295 +               reg &= ~SUN4I_CTL_CPOL;
296 +
297 +       if (spi->mode & SPI_CPHA)
298 +               reg |= SUN4I_CTL_CPHA;
299 +       else
300 +               reg &= ~SUN4I_CTL_CPHA;
301 +
302 +       if (spi->mode & SPI_LSB_FIRST)
303 +               reg |= SUN4I_CTL_LMTF;
304 +       else
305 +               reg &= ~SUN4I_CTL_LMTF;
306 +
307 +
308 +       /*
309 +        * If it's a TX only transfer, we don't want to fill the RX
310 +        * FIFO with bogus data
311 +        */
312 +       if (sspi->rx_buf)
313 +               reg &= ~SUN4I_CTL_DHB;
314 +       else
315 +               reg |= SUN4I_CTL_DHB;
316 +
317 +       /* We want to control the chip select manually */
318 +       reg |= SUN4I_CTL_CS_MANUAL;
319 +
320 +       sun4i_spi_write(sspi, SUN4I_CTL_REG, reg);
321 +
322 +       /* Ensure that we have a parent clock fast enough */
323 +       mclk_rate = clk_get_rate(sspi->mclk);
324 +       if (mclk_rate < (2 * spi->max_speed_hz)) {
325 +               clk_set_rate(sspi->mclk, 2 * spi->max_speed_hz);
326 +               mclk_rate = clk_get_rate(sspi->mclk);
327 +       }
328 +
329 +       /*
330 +        * Setup clock divider.
331 +        *
332 +        * We have two choices there. Either we can use the clock
333 +        * divide rate 1, which is calculated thanks to this formula:
334 +        * SPI_CLK = MOD_CLK / (2 ^ (cdr + 1))
335 +        * Or we can use CDR2, which is calculated with the formula:
336 +        * SPI_CLK = MOD_CLK / (2 * (cdr + 1))
337 +        * Wether we use the former or the latter is set through the
338 +        * DRS bit.
339 +        *
340 +        * First try CDR2, and if we can't reach the expected
341 +        * frequency, fall back to CDR1.
342 +        */
343 +       div = mclk_rate / (2 * spi->max_speed_hz);
344 +       if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) {
345 +               if (div > 0)
346 +                       div--;
347 +
348 +               reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS;
349 +       } else {
350 +               div = ilog2(mclk_rate) - ilog2(spi->max_speed_hz);
351 +               reg = SUN4I_CLK_CTL_CDR1(div);
352 +       }
353 +
354 +       sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg);
355 +
356 +       /* Setup the transfer now... */
357 +       if (sspi->tx_buf)
358 +               tx_len = tfr->len;
359 +
360 +       /* Setup the counters */
361 +       sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
362 +       sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
363 +
364 +       /* Fill the TX FIFO */
365 +       sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
366 +
367 +       /* Enable the interrupts */
368 +       sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
369 +
370 +       /* Start the transfer */
371 +       reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
372 +       sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
373 +
374 +       timeout = wait_for_completion_timeout(&sspi->done,
375 +                                             msecs_to_jiffies(1000));
376 +       if (!timeout) {
377 +               ret = -ETIMEDOUT;
378 +               goto out;
379 +       }
380 +
381 +       sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH);
382 +
383 +out:
384 +       sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0);
385 +
386 +       return ret;
387 +}
388 +
389 +static irqreturn_t sun4i_spi_handler(int irq, void *dev_id)
390 +{
391 +       struct sun4i_spi *sspi = dev_id;
392 +       u32 status = sun4i_spi_read(sspi, SUN4I_INT_STA_REG);
393 +
394 +       /* Transfer complete */
395 +       if (status & SUN4I_INT_CTL_TC) {
396 +               sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC);
397 +               complete(&sspi->done);
398 +               return IRQ_HANDLED;
399 +       }
400 +
401 +       return IRQ_NONE;
402 +}
403 +
404 +static int sun4i_spi_runtime_resume(struct device *dev)
405 +{
406 +       struct spi_master *master = dev_get_drvdata(dev);
407 +       struct sun4i_spi *sspi = spi_master_get_devdata(master);
408 +       int ret;
409 +
410 +       ret = clk_prepare_enable(sspi->hclk);
411 +       if (ret) {
412 +               dev_err(dev, "Couldn't enable AHB clock\n");
413 +               goto out;
414 +       }
415 +
416 +       ret = clk_prepare_enable(sspi->mclk);
417 +       if (ret) {
418 +               dev_err(dev, "Couldn't enable module clock\n");
419 +               goto err;
420 +       }
421 +
422 +       sun4i_spi_write(sspi, SUN4I_CTL_REG,
423 +                       SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP);
424 +
425 +       return 0;
426 +
427 +err:
428 +       clk_disable_unprepare(sspi->hclk);
429 +out:
430 +       return ret;
431 +}
432 +
433 +static int sun4i_spi_runtime_suspend(struct device *dev)
434 +{
435 +       struct spi_master *master = dev_get_drvdata(dev);
436 +       struct sun4i_spi *sspi = spi_master_get_devdata(master);
437 +
438 +       clk_disable_unprepare(sspi->mclk);
439 +       clk_disable_unprepare(sspi->hclk);
440 +
441 +       return 0;
442 +}
443 +
444 +static int sun4i_spi_probe(struct platform_device *pdev)
445 +{
446 +       struct spi_master *master;
447 +       struct sun4i_spi *sspi;
448 +       struct resource *res;
449 +       int ret = 0, irq;
450 +
451 +       master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi));
452 +       if (!master) {
453 +               dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
454 +               return -ENOMEM;
455 +       }
456 +
457 +       platform_set_drvdata(pdev, master);
458 +       sspi = spi_master_get_devdata(master);
459 +
460 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
461 +       sspi->base_addr = devm_ioremap_resource(&pdev->dev, res);
462 +       if (IS_ERR(sspi->base_addr)) {
463 +               ret = PTR_ERR(sspi->base_addr);
464 +               goto err_free_master;
465 +       }
466 +
467 +       irq = platform_get_irq(pdev, 0);
468 +       if (irq < 0) {
469 +               dev_err(&pdev->dev, "No spi IRQ specified\n");
470 +               ret = -ENXIO;
471 +               goto err_free_master;
472 +       }
473 +
474 +       ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler,
475 +                              0, "sun4i-spi", sspi);
476 +       if (ret) {
477 +               dev_err(&pdev->dev, "Cannot request IRQ\n");
478 +               goto err_free_master;
479 +       }
480 +
481 +       sspi->master = master;
482 +       master->set_cs = sun4i_spi_set_cs;
483 +       master->transfer_one = sun4i_spi_transfer_one;
484 +       master->num_chipselect = 4;
485 +       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
486 +       master->dev.of_node = pdev->dev.of_node;
487 +       master->auto_runtime_pm = true;
488 +
489 +       sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
490 +       if (IS_ERR(sspi->hclk)) {
491 +               dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
492 +               ret = PTR_ERR(sspi->hclk);
493 +               goto err_free_master;
494 +       }
495 +
496 +       sspi->mclk = devm_clk_get(&pdev->dev, "mod");
497 +       if (IS_ERR(sspi->mclk)) {
498 +               dev_err(&pdev->dev, "Unable to acquire module clock\n");
499 +               ret = PTR_ERR(sspi->mclk);
500 +               goto err_free_master;
501 +       }
502 +
503 +       init_completion(&sspi->done);
504 +
505 +       /*
506 +        * This wake-up/shutdown pattern is to be able to have the
507 +        * device woken up, even if runtime_pm is disabled
508 +        */
509 +       ret = sun4i_spi_runtime_resume(&pdev->dev);
510 +       if (ret) {
511 +               dev_err(&pdev->dev, "Couldn't resume the device\n");
512 +               goto err_free_master;
513 +       }
514 +
515 +       pm_runtime_set_active(&pdev->dev);
516 +       pm_runtime_enable(&pdev->dev);
517 +       pm_runtime_idle(&pdev->dev);
518 +
519 +       ret = devm_spi_register_master(&pdev->dev, master);
520 +       if (ret) {
521 +               dev_err(&pdev->dev, "cannot register SPI master\n");
522 +               goto err_pm_disable;
523 +       }
524 +
525 +       return 0;
526 +
527 +err_pm_disable:
528 +       pm_runtime_disable(&pdev->dev);
529 +       sun4i_spi_runtime_suspend(&pdev->dev);
530 +err_free_master:
531 +       spi_master_put(master);
532 +       return ret;
533 +}
534 +
535 +static int sun4i_spi_remove(struct platform_device *pdev)
536 +{
537 +       pm_runtime_disable(&pdev->dev);
538 +
539 +       return 0;
540 +}
541 +
542 +static const struct of_device_id sun4i_spi_match[] = {
543 +       { .compatible = "allwinner,sun4i-a10-spi", },
544 +       {}
545 +};
546 +MODULE_DEVICE_TABLE(of, sun4i_spi_match);
547 +
548 +static const struct dev_pm_ops sun4i_spi_pm_ops = {
549 +       .runtime_resume         = sun4i_spi_runtime_resume,
550 +       .runtime_suspend        = sun4i_spi_runtime_suspend,
551 +};
552 +
553 +static struct platform_driver sun4i_spi_driver = {
554 +       .probe  = sun4i_spi_probe,
555 +       .remove = sun4i_spi_remove,
556 +       .driver = {
557 +               .name           = "sun4i-spi",
558 +               .owner          = THIS_MODULE,
559 +               .of_match_table = sun4i_spi_match,
560 +               .pm             = &sun4i_spi_pm_ops,
561 +       },
562 +};
563 +module_platform_driver(sun4i_spi_driver);
564 +
565 +MODULE_AUTHOR("Pan Nan <pannan@allwinnertech.com>");
566 +MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
567 +MODULE_DESCRIPTION("Allwinner A1X/A20 SPI controller driver");
568 +MODULE_LICENSE("GPL");
569 -- 
570 1.8.5.5
571