diff options
-rw-r--r-- | drivers/spi/Kconfig | 4 | ||||
-rw-r--r-- | drivers/spi/Makefile | 3 | ||||
-rw-r--r-- | drivers/spi/dw_spi.c | 33 | ||||
-rw-r--r-- | drivers/spi/dw_spi_mid.c | 223 | ||||
-rw-r--r-- | drivers/spi/dw_spi_pci.c | 20 | ||||
-rw-r--r-- | include/linux/spi/dw_spi.h | 24 |
6 files changed, 283 insertions, 24 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 665d03d4e022..caa2e84cc0a6 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -382,6 +382,10 @@ config SPI_DW_PCI | |||
382 | tristate "PCI interface driver for DW SPI core" | 382 | tristate "PCI interface driver for DW SPI core" |
383 | depends on SPI_DESIGNWARE && PCI | 383 | depends on SPI_DESIGNWARE && PCI |
384 | 384 | ||
385 | config SPI_DW_MID_DMA | ||
386 | bool "DMA support for DW SPI controller on Intel Moorestown platform" | ||
387 | depends on SPI_DW_PCI && INTEL_MID_DMAC | ||
388 | |||
385 | config SPI_DW_MMIO | 389 | config SPI_DW_MMIO |
386 | tristate "Memory-mapped io interface driver for DW SPI core" | 390 | tristate "Memory-mapped io interface driver for DW SPI core" |
387 | depends on SPI_DESIGNWARE && HAVE_CLK | 391 | depends on SPI_DESIGNWARE && HAVE_CLK |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 02dad4ae412d..7ec375b6c0c3 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -17,7 +17,8 @@ obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o | |||
17 | obj-$(CONFIG_SPI_COLDFIRE_QSPI) += coldfire_qspi.o | 17 | obj-$(CONFIG_SPI_COLDFIRE_QSPI) += coldfire_qspi.o |
18 | obj-$(CONFIG_SPI_DAVINCI) += davinci_spi.o | 18 | obj-$(CONFIG_SPI_DAVINCI) += davinci_spi.o |
19 | obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o | 19 | obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o |
20 | obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o | 20 | obj-$(CONFIG_SPI_DW_PCI) += dw_spi_midpci.o |
21 | dw_spi_midpci-objs := dw_spi_pci.o dw_spi_mid.o | ||
21 | obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o | 22 | obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o |
22 | obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o | 23 | obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o |
23 | obj-$(CONFIG_SPI_GPIO) += spi_gpio.o | 24 | obj-$(CONFIG_SPI_GPIO) += spi_gpio.o |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index b50bf5ba873f..497ecb3ab83f 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -288,8 +288,10 @@ static void *next_transfer(struct dw_spi *dws) | |||
288 | */ | 288 | */ |
289 | static int map_dma_buffers(struct dw_spi *dws) | 289 | static int map_dma_buffers(struct dw_spi *dws) |
290 | { | 290 | { |
291 | if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited | 291 | if (!dws->cur_msg->is_dma_mapped |
292 | || !dws->cur_chip->enable_dma) | 292 | || !dws->dma_inited |
293 | || !dws->cur_chip->enable_dma | ||
294 | || !dws->dma_ops) | ||
293 | return 0; | 295 | return 0; |
294 | 296 | ||
295 | if (dws->cur_transfer->tx_dma) | 297 | if (dws->cur_transfer->tx_dma) |
@@ -341,7 +343,7 @@ static void int_error_stop(struct dw_spi *dws, const char *msg) | |||
341 | tasklet_schedule(&dws->pump_transfers); | 343 | tasklet_schedule(&dws->pump_transfers); |
342 | } | 344 | } |
343 | 345 | ||
344 | static void transfer_complete(struct dw_spi *dws) | 346 | void dw_spi_xfer_done(struct dw_spi *dws) |
345 | { | 347 | { |
346 | /* Update total byte transfered return count actual bytes read */ | 348 | /* Update total byte transfered return count actual bytes read */ |
347 | dws->cur_msg->actual_length += dws->len; | 349 | dws->cur_msg->actual_length += dws->len; |
@@ -356,6 +358,7 @@ static void transfer_complete(struct dw_spi *dws) | |||
356 | } else | 358 | } else |
357 | tasklet_schedule(&dws->pump_transfers); | 359 | tasklet_schedule(&dws->pump_transfers); |
358 | } | 360 | } |
361 | EXPORT_SYMBOL_GPL(dw_spi_xfer_done); | ||
359 | 362 | ||
360 | static irqreturn_t interrupt_transfer(struct dw_spi *dws) | 363 | static irqreturn_t interrupt_transfer(struct dw_spi *dws) |
361 | { | 364 | { |
@@ -387,7 +390,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) | |||
387 | if (dws->tx_end > dws->tx) | 390 | if (dws->tx_end > dws->tx) |
388 | spi_umask_intr(dws, SPI_INT_TXEI); | 391 | spi_umask_intr(dws, SPI_INT_TXEI); |
389 | else | 392 | else |
390 | transfer_complete(dws); | 393 | dw_spi_xfer_done(dws); |
391 | } | 394 | } |
392 | 395 | ||
393 | return IRQ_HANDLED; | 396 | return IRQ_HANDLED; |
@@ -422,11 +425,7 @@ static void poll_transfer(struct dw_spi *dws) | |||
422 | */ | 425 | */ |
423 | dws->read(dws); | 426 | dws->read(dws); |
424 | 427 | ||
425 | transfer_complete(dws); | 428 | dw_spi_xfer_done(dws); |
426 | } | ||
427 | |||
428 | static void dma_transfer(struct dw_spi *dws, int cs_change) | ||
429 | { | ||
430 | } | 429 | } |
431 | 430 | ||
432 | static void pump_transfers(unsigned long data) | 431 | static void pump_transfers(unsigned long data) |
@@ -608,7 +607,7 @@ static void pump_transfers(unsigned long data) | |||
608 | } | 607 | } |
609 | 608 | ||
610 | if (dws->dma_mapped) | 609 | if (dws->dma_mapped) |
611 | dma_transfer(dws, cs_change); | 610 | dws->dma_ops->dma_transfer(dws, cs_change); |
612 | 611 | ||
613 | if (chip->poll_mode) | 612 | if (chip->poll_mode) |
614 | poll_transfer(dws); | 613 | poll_transfer(dws); |
@@ -904,11 +903,17 @@ int __devinit dw_spi_add_host(struct dw_spi *dws) | |||
904 | master->setup = dw_spi_setup; | 903 | master->setup = dw_spi_setup; |
905 | master->transfer = dw_spi_transfer; | 904 | master->transfer = dw_spi_transfer; |
906 | 905 | ||
907 | dws->dma_inited = 0; | ||
908 | |||
909 | /* Basic HW init */ | 906 | /* Basic HW init */ |
910 | spi_hw_init(dws); | 907 | spi_hw_init(dws); |
911 | 908 | ||
909 | if (dws->dma_ops && dws->dma_ops->dma_init) { | ||
910 | ret = dws->dma_ops->dma_init(dws); | ||
911 | if (ret) { | ||
912 | dev_warn(&master->dev, "DMA init failed\n"); | ||
913 | dws->dma_inited = 0; | ||
914 | } | ||
915 | } | ||
916 | |||
912 | /* Initial and start queue */ | 917 | /* Initial and start queue */ |
913 | ret = init_queue(dws); | 918 | ret = init_queue(dws); |
914 | if (ret) { | 919 | if (ret) { |
@@ -933,6 +938,8 @@ int __devinit dw_spi_add_host(struct dw_spi *dws) | |||
933 | 938 | ||
934 | err_queue_alloc: | 939 | err_queue_alloc: |
935 | destroy_queue(dws); | 940 | destroy_queue(dws); |
941 | if (dws->dma_ops && dws->dma_ops->dma_exit) | ||
942 | dws->dma_ops->dma_exit(dws); | ||
936 | err_diable_hw: | 943 | err_diable_hw: |
937 | spi_enable_chip(dws, 0); | 944 | spi_enable_chip(dws, 0); |
938 | free_irq(dws->irq, dws); | 945 | free_irq(dws->irq, dws); |
@@ -957,6 +964,8 @@ void __devexit dw_spi_remove_host(struct dw_spi *dws) | |||
957 | dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " | 964 | dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " |
958 | "complete, message memory not freed\n"); | 965 | "complete, message memory not freed\n"); |
959 | 966 | ||
967 | if (dws->dma_ops && dws->dma_ops->dma_exit) | ||
968 | dws->dma_ops->dma_exit(dws); | ||
960 | spi_enable_chip(dws, 0); | 969 | spi_enable_chip(dws, 0); |
961 | /* Disable clk */ | 970 | /* Disable clk */ |
962 | spi_set_clk(dws, 0); | 971 | spi_set_clk(dws, 0); |
diff --git a/drivers/spi/dw_spi_mid.c b/drivers/spi/dw_spi_mid.c new file mode 100644 index 000000000000..c91c966e0717 --- /dev/null +++ b/drivers/spi/dw_spi_mid.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * dw_spi_mid.c - special handling for DW core on Intel MID platform | ||
3 | * | ||
4 | * Copyright (c) 2009, Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along | ||
16 | * with this program; if not, write to the Free Software Foundation, | ||
17 | * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/dma-mapping.h> | ||
21 | #include <linux/dmaengine.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | #include <linux/spi/dw_spi.h> | ||
26 | |||
27 | #ifdef CONFIG_SPI_DW_MID_DMA | ||
28 | #include <linux/intel_mid_dma.h> | ||
29 | #include <linux/pci.h> | ||
30 | |||
31 | struct mid_dma { | ||
32 | struct intel_mid_dma_slave dmas_tx; | ||
33 | struct intel_mid_dma_slave dmas_rx; | ||
34 | }; | ||
35 | |||
36 | static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param) | ||
37 | { | ||
38 | struct dw_spi *dws = param; | ||
39 | |||
40 | return dws->dmac && (&dws->dmac->dev == chan->device->dev); | ||
41 | } | ||
42 | |||
43 | static int mid_spi_dma_init(struct dw_spi *dws) | ||
44 | { | ||
45 | struct mid_dma *dw_dma = dws->dma_priv; | ||
46 | struct intel_mid_dma_slave *rxs, *txs; | ||
47 | dma_cap_mask_t mask; | ||
48 | |||
49 | /* | ||
50 | * Get pci device for DMA controller, currently it could only | ||
51 | * be the DMA controller of either Moorestown or Medfield | ||
52 | */ | ||
53 | dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0813, NULL); | ||
54 | if (!dws->dmac) | ||
55 | dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL); | ||
56 | |||
57 | dma_cap_zero(mask); | ||
58 | dma_cap_set(DMA_SLAVE, mask); | ||
59 | |||
60 | /* 1. Init rx channel */ | ||
61 | dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws); | ||
62 | if (!dws->rxchan) | ||
63 | goto err_exit; | ||
64 | rxs = &dw_dma->dmas_rx; | ||
65 | rxs->hs_mode = LNW_DMA_HW_HS; | ||
66 | rxs->cfg_mode = LNW_DMA_PER_TO_MEM; | ||
67 | dws->rxchan->private = rxs; | ||
68 | |||
69 | /* 2. Init tx channel */ | ||
70 | dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, dws); | ||
71 | if (!dws->txchan) | ||
72 | goto free_rxchan; | ||
73 | txs = &dw_dma->dmas_tx; | ||
74 | txs->hs_mode = LNW_DMA_HW_HS; | ||
75 | txs->cfg_mode = LNW_DMA_MEM_TO_PER; | ||
76 | dws->txchan->private = txs; | ||
77 | |||
78 | dws->dma_inited = 1; | ||
79 | return 0; | ||
80 | |||
81 | free_rxchan: | ||
82 | dma_release_channel(dws->rxchan); | ||
83 | err_exit: | ||
84 | return -1; | ||
85 | |||
86 | } | ||
87 | |||
88 | static void mid_spi_dma_exit(struct dw_spi *dws) | ||
89 | { | ||
90 | dma_release_channel(dws->txchan); | ||
91 | dma_release_channel(dws->rxchan); | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * dws->dma_chan_done is cleared before the dma transfer starts, | ||
96 | * callback for rx/tx channel will each increment it by 1. | ||
97 | * Reaching 2 means the whole spi transaction is done. | ||
98 | */ | ||
99 | static void dw_spi_dma_done(void *arg) | ||
100 | { | ||
101 | struct dw_spi *dws = arg; | ||
102 | |||
103 | if (++dws->dma_chan_done != 2) | ||
104 | return; | ||
105 | dw_spi_xfer_done(dws); | ||
106 | } | ||
107 | |||
108 | static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) | ||
109 | { | ||
110 | struct dma_async_tx_descriptor *txdesc = NULL, *rxdesc = NULL; | ||
111 | struct dma_chan *txchan, *rxchan; | ||
112 | struct dma_slave_config txconf, rxconf; | ||
113 | u16 dma_ctrl = 0; | ||
114 | |||
115 | /* 1. setup DMA related registers */ | ||
116 | if (cs_change) { | ||
117 | spi_enable_chip(dws, 0); | ||
118 | dw_writew(dws, dmardlr, 0xf); | ||
119 | dw_writew(dws, dmatdlr, 0x10); | ||
120 | if (dws->tx_dma) | ||
121 | dma_ctrl |= 0x2; | ||
122 | if (dws->rx_dma) | ||
123 | dma_ctrl |= 0x1; | ||
124 | dw_writew(dws, dmacr, dma_ctrl); | ||
125 | spi_enable_chip(dws, 1); | ||
126 | } | ||
127 | |||
128 | dws->dma_chan_done = 0; | ||
129 | txchan = dws->txchan; | ||
130 | rxchan = dws->rxchan; | ||
131 | |||
132 | /* 2. Prepare the TX dma transfer */ | ||
133 | txconf.direction = DMA_TO_DEVICE; | ||
134 | txconf.dst_addr = dws->dma_addr; | ||
135 | txconf.dst_maxburst = LNW_DMA_MSIZE_16; | ||
136 | txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
137 | txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
138 | |||
139 | txchan->device->device_control(txchan, DMA_SLAVE_CONFIG, | ||
140 | (unsigned long) &txconf); | ||
141 | |||
142 | memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl)); | ||
143 | dws->tx_sgl.dma_address = dws->tx_dma; | ||
144 | dws->tx_sgl.length = dws->len; | ||
145 | |||
146 | txdesc = txchan->device->device_prep_slave_sg(txchan, | ||
147 | &dws->tx_sgl, | ||
148 | 1, | ||
149 | DMA_TO_DEVICE, | ||
150 | DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP); | ||
151 | txdesc->callback = dw_spi_dma_done; | ||
152 | txdesc->callback_param = dws; | ||
153 | |||
154 | /* 3. Prepare the RX dma transfer */ | ||
155 | rxconf.direction = DMA_FROM_DEVICE; | ||
156 | rxconf.src_addr = dws->dma_addr; | ||
157 | rxconf.src_maxburst = LNW_DMA_MSIZE_16; | ||
158 | rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
159 | rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
160 | |||
161 | rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG, | ||
162 | (unsigned long) &rxconf); | ||
163 | |||
164 | memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl)); | ||
165 | dws->rx_sgl.dma_address = dws->rx_dma; | ||
166 | dws->rx_sgl.length = dws->len; | ||
167 | |||
168 | rxdesc = rxchan->device->device_prep_slave_sg(rxchan, | ||
169 | &dws->rx_sgl, | ||
170 | 1, | ||
171 | DMA_FROM_DEVICE, | ||
172 | DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP); | ||
173 | rxdesc->callback = dw_spi_dma_done; | ||
174 | rxdesc->callback_param = dws; | ||
175 | |||
176 | /* rx must be started before tx due to spi instinct */ | ||
177 | rxdesc->tx_submit(rxdesc); | ||
178 | txdesc->tx_submit(txdesc); | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct dw_spi_dma_ops mid_dma_ops = { | ||
183 | .dma_init = mid_spi_dma_init, | ||
184 | .dma_exit = mid_spi_dma_exit, | ||
185 | .dma_transfer = mid_spi_dma_transfer, | ||
186 | }; | ||
187 | #endif | ||
188 | |||
189 | /* Some specific info for SPI0 controller on Moorestown */ | ||
190 | |||
191 | /* HW info for MRST CLk Control Unit, one 32b reg */ | ||
192 | #define MRST_SPI_CLK_BASE 100000000 /* 100m */ | ||
193 | #define MRST_CLK_SPI0_REG 0xff11d86c | ||
194 | #define CLK_SPI_BDIV_OFFSET 0 | ||
195 | #define CLK_SPI_BDIV_MASK 0x00000007 | ||
196 | #define CLK_SPI_CDIV_OFFSET 9 | ||
197 | #define CLK_SPI_CDIV_MASK 0x00000e00 | ||
198 | #define CLK_SPI_DISABLE_OFFSET 8 | ||
199 | |||
200 | int dw_spi_mid_init(struct dw_spi *dws) | ||
201 | { | ||
202 | u32 *clk_reg, clk_cdiv; | ||
203 | |||
204 | clk_reg = ioremap_nocache(MRST_CLK_SPI0_REG, 16); | ||
205 | if (!clk_reg) | ||
206 | return -ENOMEM; | ||
207 | |||
208 | /* get SPI controller operating freq info */ | ||
209 | clk_cdiv = (readl(clk_reg) & CLK_SPI_CDIV_MASK) >> CLK_SPI_CDIV_OFFSET; | ||
210 | dws->max_freq = MRST_SPI_CLK_BASE / (clk_cdiv + 1); | ||
211 | iounmap(clk_reg); | ||
212 | |||
213 | dws->num_cs = 16; | ||
214 | dws->fifo_len = 40; /* FIFO has 40 words buffer */ | ||
215 | |||
216 | #ifdef CONFIG_SPI_DW_MID_DMA | ||
217 | dws->dma_priv = kzalloc(sizeof(struct mid_dma), GFP_KERNEL); | ||
218 | if (!dws->dma_priv) | ||
219 | return -ENOMEM; | ||
220 | dws->dma_ops = &mid_dma_ops; | ||
221 | #endif | ||
222 | return 0; | ||
223 | } | ||
diff --git a/drivers/spi/dw_spi_pci.c b/drivers/spi/dw_spi_pci.c index 1f52755dc878..49ec3aa1219f 100644 --- a/drivers/spi/dw_spi_pci.c +++ b/drivers/spi/dw_spi_pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * mrst_spi_pci.c - PCI interface driver for DW SPI Core | 2 | * dw_spi_pci.c - PCI interface driver for DW SPI Core |
3 | * | 3 | * |
4 | * Copyright (c) 2009, Intel Corporation. | 4 | * Copyright (c) 2009, Intel Corporation. |
5 | * | 5 | * |
@@ -26,8 +26,8 @@ | |||
26 | #define DRIVER_NAME "dw_spi_pci" | 26 | #define DRIVER_NAME "dw_spi_pci" |
27 | 27 | ||
28 | struct dw_spi_pci { | 28 | struct dw_spi_pci { |
29 | struct pci_dev *pdev; | 29 | struct pci_dev *pdev; |
30 | struct dw_spi dws; | 30 | struct dw_spi dws; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | static int __devinit spi_pci_probe(struct pci_dev *pdev, | 33 | static int __devinit spi_pci_probe(struct pci_dev *pdev, |
@@ -72,9 +72,17 @@ static int __devinit spi_pci_probe(struct pci_dev *pdev, | |||
72 | dws->parent_dev = &pdev->dev; | 72 | dws->parent_dev = &pdev->dev; |
73 | dws->bus_num = 0; | 73 | dws->bus_num = 0; |
74 | dws->num_cs = 4; | 74 | dws->num_cs = 4; |
75 | dws->max_freq = 25000000; /* for Moorestwon */ | ||
76 | dws->irq = pdev->irq; | 75 | dws->irq = pdev->irq; |
77 | dws->fifo_len = 40; /* FIFO has 40 words buffer */ | 76 | |
77 | /* | ||
78 | * Specific handling for Intel MID paltforms, like dma setup, | ||
79 | * clock rate, FIFO depth. | ||
80 | */ | ||
81 | if (pdev->device == 0x0800) { | ||
82 | ret = dw_spi_mid_init(dws); | ||
83 | if (ret) | ||
84 | goto err_unmap; | ||
85 | } | ||
78 | 86 | ||
79 | ret = dw_spi_add_host(dws); | 87 | ret = dw_spi_add_host(dws); |
80 | if (ret) | 88 | if (ret) |
@@ -140,7 +148,7 @@ static int spi_resume(struct pci_dev *pdev) | |||
140 | #endif | 148 | #endif |
141 | 149 | ||
142 | static const struct pci_device_id pci_ids[] __devinitdata = { | 150 | static const struct pci_device_id pci_ids[] __devinitdata = { |
143 | /* Intel Moorestown platform SPI controller 0 */ | 151 | /* Intel MID platform SPI controller 0 */ |
144 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) }, | 152 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) }, |
145 | {}, | 153 | {}, |
146 | }; | 154 | }; |
diff --git a/include/linux/spi/dw_spi.h b/include/linux/spi/dw_spi.h index c91302f3a257..6cd10f6ad472 100644 --- a/include/linux/spi/dw_spi.h +++ b/include/linux/spi/dw_spi.h | |||
@@ -1,5 +1,6 @@ | |||
1 | #ifndef DW_SPI_HEADER_H | 1 | #ifndef DW_SPI_HEADER_H |
2 | #define DW_SPI_HEADER_H | 2 | #define DW_SPI_HEADER_H |
3 | |||
3 | #include <linux/io.h> | 4 | #include <linux/io.h> |
4 | 5 | ||
5 | /* Bit fields in CTRLR0 */ | 6 | /* Bit fields in CTRLR0 */ |
@@ -82,6 +83,13 @@ struct dw_spi_reg { | |||
82 | though only low 16 bits matters */ | 83 | though only low 16 bits matters */ |
83 | } __packed; | 84 | } __packed; |
84 | 85 | ||
86 | struct dw_spi; | ||
87 | struct dw_spi_dma_ops { | ||
88 | int (*dma_init)(struct dw_spi *dws); | ||
89 | void (*dma_exit)(struct dw_spi *dws); | ||
90 | int (*dma_transfer)(struct dw_spi *dws, int cs_change); | ||
91 | }; | ||
92 | |||
85 | struct dw_spi { | 93 | struct dw_spi { |
86 | struct spi_master *master; | 94 | struct spi_master *master; |
87 | struct spi_device *cur_dev; | 95 | struct spi_device *cur_dev; |
@@ -136,13 +144,15 @@ struct dw_spi { | |||
136 | /* Dma info */ | 144 | /* Dma info */ |
137 | int dma_inited; | 145 | int dma_inited; |
138 | struct dma_chan *txchan; | 146 | struct dma_chan *txchan; |
147 | struct scatterlist tx_sgl; | ||
139 | struct dma_chan *rxchan; | 148 | struct dma_chan *rxchan; |
140 | int txdma_done; | 149 | struct scatterlist rx_sgl; |
141 | int rxdma_done; | 150 | int dma_chan_done; |
142 | u64 tx_param; | ||
143 | u64 rx_param; | ||
144 | struct device *dma_dev; | 151 | struct device *dma_dev; |
145 | dma_addr_t dma_addr; | 152 | dma_addr_t dma_addr; /* phy address of the Data register */ |
153 | struct dw_spi_dma_ops *dma_ops; | ||
154 | void *dma_priv; /* platform relate info */ | ||
155 | struct pci_dev *dmac; | ||
146 | 156 | ||
147 | /* Bus interface info */ | 157 | /* Bus interface info */ |
148 | void *priv; | 158 | void *priv; |
@@ -216,4 +226,8 @@ extern int dw_spi_add_host(struct dw_spi *dws); | |||
216 | extern void dw_spi_remove_host(struct dw_spi *dws); | 226 | extern void dw_spi_remove_host(struct dw_spi *dws); |
217 | extern int dw_spi_suspend_host(struct dw_spi *dws); | 227 | extern int dw_spi_suspend_host(struct dw_spi *dws); |
218 | extern int dw_spi_resume_host(struct dw_spi *dws); | 228 | extern int dw_spi_resume_host(struct dw_spi *dws); |
229 | extern void dw_spi_xfer_done(struct dw_spi *dws); | ||
230 | |||
231 | /* platform related setup */ | ||
232 | extern int dw_spi_mid_init(struct dw_spi *dws); /* Intel MID platforms */ | ||
219 | #endif /* DW_SPI_HEADER_H */ | 233 | #endif /* DW_SPI_HEADER_H */ |