146-2-spi-add-a10-spi.patch 15 KB

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