diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 19:43:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-14 19:43:47 -0500 |
commit | 6ae840e7cc4be0be3aa40d9f67c35c75cfc67d83 (patch) | |
tree | 9c83c87a8670ef678d95f8d6f76a07f24a09a49f /drivers/misc/carma/carma-fpga.c | |
parent | e6b5be2be4e30037eb551e0ed09dd97bd00d85d3 (diff) | |
parent | 91905b6f4afe51e23a3f58df93e4cdc5e49cf40c (diff) |
Merge tag 'char-misc-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here's the big char/misc driver update for 3.19-rc1
Lots of little things all over the place in different drivers, and a
new subsystem, "coresight" has been added. Full details are in the
shortlog"
* tag 'char-misc-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (73 commits)
parport: parport_pc, do not remove parent devices early
spmi: Remove shutdown/suspend/resume kernel-doc
carma-fpga-program: drop videobuf dependency
carma-fpga: drop videobuf dependency
carma-fpga-program.c: fix compile errors
i8k: Fix temperature bug handling in i8k_get_temp()
cxl: Name interrupts in /proc/interrupt
CXL: Return error to PSL if IRQ demultiplexing fails & print clearer warning
coresight-replicator: remove .owner field for driver
coresight: fixed comments in coresight.h
coresight: fix typo in comment in coresight-priv.h
coresight: bindings for coresight drivers
coresight: Adding ABI documentation
w1: support auto-load of w1_bq27000 module.
w1: avoid potential u16 overflow
cn: verify msg->len before making callback
mei: export fw status registers through sysfs
mei: read and print all six FW status registers
mei: txe: add cherrytrail device id
mei: kill cached host and me csr values
...
Diffstat (limited to 'drivers/misc/carma/carma-fpga.c')
-rw-r--r-- | drivers/misc/carma/carma-fpga.c | 98 |
1 files changed, 81 insertions, 17 deletions
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index cdf2d7b902bb..68cdfe151bdb 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c | |||
@@ -98,6 +98,7 @@ | |||
98 | #include <linux/seq_file.h> | 98 | #include <linux/seq_file.h> |
99 | #include <linux/highmem.h> | 99 | #include <linux/highmem.h> |
100 | #include <linux/debugfs.h> | 100 | #include <linux/debugfs.h> |
101 | #include <linux/vmalloc.h> | ||
101 | #include <linux/kernel.h> | 102 | #include <linux/kernel.h> |
102 | #include <linux/module.h> | 103 | #include <linux/module.h> |
103 | #include <linux/poll.h> | 104 | #include <linux/poll.h> |
@@ -105,8 +106,6 @@ | |||
105 | #include <linux/kref.h> | 106 | #include <linux/kref.h> |
106 | #include <linux/io.h> | 107 | #include <linux/io.h> |
107 | 108 | ||
108 | #include <media/videobuf-dma-sg.h> | ||
109 | |||
110 | /* system controller registers */ | 109 | /* system controller registers */ |
111 | #define SYS_IRQ_SOURCE_CTL 0x24 | 110 | #define SYS_IRQ_SOURCE_CTL 0x24 |
112 | #define SYS_IRQ_OUTPUT_EN 0x28 | 111 | #define SYS_IRQ_OUTPUT_EN 0x28 |
@@ -142,7 +141,10 @@ struct fpga_info { | |||
142 | 141 | ||
143 | struct data_buf { | 142 | struct data_buf { |
144 | struct list_head entry; | 143 | struct list_head entry; |
145 | struct videobuf_dmabuf vb; | 144 | void *vaddr; |
145 | struct scatterlist *sglist; | ||
146 | int sglen; | ||
147 | int nr_pages; | ||
146 | size_t size; | 148 | size_t size; |
147 | }; | 149 | }; |
148 | 150 | ||
@@ -207,6 +209,68 @@ static void fpga_device_release(struct kref *ref) | |||
207 | * Data Buffer Allocation Helpers | 209 | * Data Buffer Allocation Helpers |
208 | */ | 210 | */ |
209 | 211 | ||
212 | static int carma_dma_init(struct data_buf *buf, int nr_pages) | ||
213 | { | ||
214 | struct page *pg; | ||
215 | int i; | ||
216 | |||
217 | buf->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT); | ||
218 | if (NULL == buf->vaddr) { | ||
219 | pr_debug("vmalloc_32(%d pages) failed\n", nr_pages); | ||
220 | return -ENOMEM; | ||
221 | } | ||
222 | |||
223 | pr_debug("vmalloc is at addr 0x%08lx, size=%d\n", | ||
224 | (unsigned long)buf->vaddr, | ||
225 | nr_pages << PAGE_SHIFT); | ||
226 | |||
227 | memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT); | ||
228 | buf->nr_pages = nr_pages; | ||
229 | |||
230 | buf->sglist = vzalloc(buf->nr_pages * sizeof(*buf->sglist)); | ||
231 | if (NULL == buf->sglist) | ||
232 | goto vzalloc_err; | ||
233 | |||
234 | sg_init_table(buf->sglist, buf->nr_pages); | ||
235 | for (i = 0; i < buf->nr_pages; i++) { | ||
236 | pg = vmalloc_to_page(buf->vaddr + i * PAGE_SIZE); | ||
237 | if (NULL == pg) | ||
238 | goto vmalloc_to_page_err; | ||
239 | sg_set_page(&buf->sglist[i], pg, PAGE_SIZE, 0); | ||
240 | } | ||
241 | return 0; | ||
242 | |||
243 | vmalloc_to_page_err: | ||
244 | vfree(buf->sglist); | ||
245 | buf->sglist = NULL; | ||
246 | vzalloc_err: | ||
247 | vfree(buf->vaddr); | ||
248 | buf->vaddr = NULL; | ||
249 | return -ENOMEM; | ||
250 | } | ||
251 | |||
252 | static int carma_dma_map(struct device *dev, struct data_buf *buf) | ||
253 | { | ||
254 | buf->sglen = dma_map_sg(dev, buf->sglist, | ||
255 | buf->nr_pages, DMA_FROM_DEVICE); | ||
256 | |||
257 | if (0 == buf->sglen) { | ||
258 | pr_warn("%s: dma_map_sg failed\n", __func__); | ||
259 | return -ENOMEM; | ||
260 | } | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int carma_dma_unmap(struct device *dev, struct data_buf *buf) | ||
265 | { | ||
266 | if (!buf->sglen) | ||
267 | return 0; | ||
268 | |||
269 | dma_unmap_sg(dev, buf->sglist, buf->sglen, DMA_FROM_DEVICE); | ||
270 | buf->sglen = 0; | ||
271 | return 0; | ||
272 | } | ||
273 | |||
210 | /** | 274 | /** |
211 | * data_free_buffer() - free a single data buffer and all allocated memory | 275 | * data_free_buffer() - free a single data buffer and all allocated memory |
212 | * @buf: the buffer to free | 276 | * @buf: the buffer to free |
@@ -221,7 +285,8 @@ static void data_free_buffer(struct data_buf *buf) | |||
221 | return; | 285 | return; |
222 | 286 | ||
223 | /* free all memory */ | 287 | /* free all memory */ |
224 | videobuf_dma_free(&buf->vb); | 288 | vfree(buf->sglist); |
289 | vfree(buf->vaddr); | ||
225 | kfree(buf); | 290 | kfree(buf); |
226 | } | 291 | } |
227 | 292 | ||
@@ -230,7 +295,7 @@ static void data_free_buffer(struct data_buf *buf) | |||
230 | * @bytes: the number of bytes required | 295 | * @bytes: the number of bytes required |
231 | * | 296 | * |
232 | * This allocates all space needed for a data buffer. It must be mapped before | 297 | * This allocates all space needed for a data buffer. It must be mapped before |
233 | * use in a DMA transaction using videobuf_dma_map(). | 298 | * use in a DMA transaction using carma_dma_map(). |
234 | * | 299 | * |
235 | * Returns NULL on failure | 300 | * Returns NULL on failure |
236 | */ | 301 | */ |
@@ -252,9 +317,8 @@ static struct data_buf *data_alloc_buffer(const size_t bytes) | |||
252 | INIT_LIST_HEAD(&buf->entry); | 317 | INIT_LIST_HEAD(&buf->entry); |
253 | buf->size = bytes; | 318 | buf->size = bytes; |
254 | 319 | ||
255 | /* allocate the videobuf */ | 320 | /* allocate the buffer */ |
256 | videobuf_dma_init(&buf->vb); | 321 | ret = carma_dma_init(buf, nr_pages); |
257 | ret = videobuf_dma_init_kernel(&buf->vb, DMA_FROM_DEVICE, nr_pages); | ||
258 | if (ret) | 322 | if (ret) |
259 | goto out_free_buf; | 323 | goto out_free_buf; |
260 | 324 | ||
@@ -285,13 +349,13 @@ static void data_free_buffers(struct fpga_device *priv) | |||
285 | 349 | ||
286 | list_for_each_entry_safe(buf, tmp, &priv->free, entry) { | 350 | list_for_each_entry_safe(buf, tmp, &priv->free, entry) { |
287 | list_del_init(&buf->entry); | 351 | list_del_init(&buf->entry); |
288 | videobuf_dma_unmap(priv->dev, &buf->vb); | 352 | carma_dma_unmap(priv->dev, buf); |
289 | data_free_buffer(buf); | 353 | data_free_buffer(buf); |
290 | } | 354 | } |
291 | 355 | ||
292 | list_for_each_entry_safe(buf, tmp, &priv->used, entry) { | 356 | list_for_each_entry_safe(buf, tmp, &priv->used, entry) { |
293 | list_del_init(&buf->entry); | 357 | list_del_init(&buf->entry); |
294 | videobuf_dma_unmap(priv->dev, &buf->vb); | 358 | carma_dma_unmap(priv->dev, buf); |
295 | data_free_buffer(buf); | 359 | data_free_buffer(buf); |
296 | } | 360 | } |
297 | 361 | ||
@@ -330,7 +394,7 @@ static int data_alloc_buffers(struct fpga_device *priv) | |||
330 | break; | 394 | break; |
331 | 395 | ||
332 | /* map it for DMA */ | 396 | /* map it for DMA */ |
333 | ret = videobuf_dma_map(priv->dev, &buf->vb); | 397 | ret = carma_dma_map(priv->dev, buf); |
334 | if (ret) { | 398 | if (ret) { |
335 | data_free_buffer(buf); | 399 | data_free_buffer(buf); |
336 | break; | 400 | break; |
@@ -634,8 +698,8 @@ static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf) | |||
634 | dma_addr_t dst, src; | 698 | dma_addr_t dst, src; |
635 | unsigned long dma_flags = 0; | 699 | unsigned long dma_flags = 0; |
636 | 700 | ||
637 | dst_sg = buf->vb.sglist; | 701 | dst_sg = buf->sglist; |
638 | dst_nents = buf->vb.sglen; | 702 | dst_nents = buf->sglen; |
639 | 703 | ||
640 | src_sg = priv->corl_table.sgl; | 704 | src_sg = priv->corl_table.sgl; |
641 | src_nents = priv->corl_nents; | 705 | src_nents = priv->corl_nents; |
@@ -1134,7 +1198,7 @@ static ssize_t data_read(struct file *filp, char __user *ubuf, size_t count, | |||
1134 | spin_unlock_irq(&priv->lock); | 1198 | spin_unlock_irq(&priv->lock); |
1135 | 1199 | ||
1136 | /* Buffers are always mapped: unmap it */ | 1200 | /* Buffers are always mapped: unmap it */ |
1137 | videobuf_dma_unmap(priv->dev, &dbuf->vb); | 1201 | carma_dma_unmap(priv->dev, dbuf); |
1138 | 1202 | ||
1139 | /* save the buffer for later */ | 1203 | /* save the buffer for later */ |
1140 | reader->buf = dbuf; | 1204 | reader->buf = dbuf; |
@@ -1143,7 +1207,7 @@ static ssize_t data_read(struct file *filp, char __user *ubuf, size_t count, | |||
1143 | have_buffer: | 1207 | have_buffer: |
1144 | /* Get the number of bytes available */ | 1208 | /* Get the number of bytes available */ |
1145 | avail = dbuf->size - reader->buf_start; | 1209 | avail = dbuf->size - reader->buf_start; |
1146 | data = dbuf->vb.vaddr + reader->buf_start; | 1210 | data = dbuf->vaddr + reader->buf_start; |
1147 | 1211 | ||
1148 | /* Get the number of bytes we can transfer */ | 1212 | /* Get the number of bytes we can transfer */ |
1149 | count = min(count, avail); | 1213 | count = min(count, avail); |
@@ -1171,7 +1235,7 @@ have_buffer: | |||
1171 | * If it fails, we pretend that the read never happed and return | 1235 | * If it fails, we pretend that the read never happed and return |
1172 | * -EFAULT to userspace. The read will be retried. | 1236 | * -EFAULT to userspace. The read will be retried. |
1173 | */ | 1237 | */ |
1174 | ret = videobuf_dma_map(priv->dev, &dbuf->vb); | 1238 | ret = carma_dma_map(priv->dev, dbuf); |
1175 | if (ret) { | 1239 | if (ret) { |
1176 | dev_err(priv->dev, "unable to remap buffer for DMA\n"); | 1240 | dev_err(priv->dev, "unable to remap buffer for DMA\n"); |
1177 | return -EFAULT; | 1241 | return -EFAULT; |
@@ -1203,7 +1267,7 @@ out_unlock: | |||
1203 | spin_unlock_irq(&priv->lock); | 1267 | spin_unlock_irq(&priv->lock); |
1204 | 1268 | ||
1205 | if (drop_buffer) { | 1269 | if (drop_buffer) { |
1206 | videobuf_dma_unmap(priv->dev, &dbuf->vb); | 1270 | carma_dma_unmap(priv->dev, dbuf); |
1207 | data_free_buffer(dbuf); | 1271 | data_free_buffer(dbuf); |
1208 | } | 1272 | } |
1209 | 1273 | ||