diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-01-13 06:48:13 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-03-07 06:46:17 -0500 |
commit | bf95154ff6c84e04afd9ba7f2b54a4628beefdb9 (patch) | |
tree | e39edaec6829ba8323d0ce5101796b347137945f /drivers | |
parent | bb8c95055aef340e05ff0ba5cfb9063c51534376 (diff) |
NET: sa11x0-ir: convert sa11x0-ir driver to use DMA engine API
Convert the sa11x0 IrDA driver to use the sa11x0 DMA engine driver
rather than our own platform specific DMA API.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/irda/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/irda/sa1100_ir.c | 120 |
2 files changed, 92 insertions, 30 deletions
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index e535137eb2d0..468047866c8c 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -356,7 +356,7 @@ config VLSI_FIR | |||
356 | 356 | ||
357 | config SA1100_FIR | 357 | config SA1100_FIR |
358 | tristate "SA1100 Internal IR" | 358 | tristate "SA1100 Internal IR" |
359 | depends on ARCH_SA1100 && IRDA | 359 | depends on ARCH_SA1100 && IRDA && DMA_SA11X0 |
360 | 360 | ||
361 | config VIA_FIR | 361 | config VIA_FIR |
362 | tristate "VIA VT8231/VT1211 SIR/MIR/FIR" | 362 | tristate "VIA VT8231/VT1211 SIR/MIR/FIR" |
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c index 9c748f38b9d5..620a48d00e2b 100644 --- a/drivers/net/irda/sa1100_ir.c +++ b/drivers/net/irda/sa1100_ir.c | |||
@@ -30,12 +30,13 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
33 | #include <linux/dmaengine.h> | ||
34 | #include <linux/sa11x0-dma.h> | ||
33 | 35 | ||
34 | #include <net/irda/irda.h> | 36 | #include <net/irda/irda.h> |
35 | #include <net/irda/wrapper.h> | 37 | #include <net/irda/wrapper.h> |
36 | #include <net/irda/irda_device.h> | 38 | #include <net/irda/irda_device.h> |
37 | 39 | ||
38 | #include <mach/dma.h> | ||
39 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
40 | #include <asm/mach/irda.h> | 41 | #include <asm/mach/irda.h> |
41 | 42 | ||
@@ -47,7 +48,8 @@ struct sa1100_buf { | |||
47 | struct device *dev; | 48 | struct device *dev; |
48 | struct sk_buff *skb; | 49 | struct sk_buff *skb; |
49 | struct scatterlist sg; | 50 | struct scatterlist sg; |
50 | dma_regs_t *regs; | 51 | struct dma_chan *chan; |
52 | dma_cookie_t cookie; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | struct sa1100_irda { | 55 | struct sa1100_irda { |
@@ -79,6 +81,75 @@ static int sa1100_irda_set_speed(struct sa1100_irda *, int); | |||
79 | 81 | ||
80 | #define HPSIR_MAX_RXLEN 2047 | 82 | #define HPSIR_MAX_RXLEN 2047 |
81 | 83 | ||
84 | static struct dma_slave_config sa1100_irda_fir_rx = { | ||
85 | .direction = DMA_FROM_DEVICE, | ||
86 | .src_addr = __PREG(Ser2HSDR), | ||
87 | .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
88 | .src_maxburst = 8, | ||
89 | }; | ||
90 | |||
91 | static struct dma_slave_config sa1100_irda_fir_tx = { | ||
92 | .direction = DMA_TO_DEVICE, | ||
93 | .dst_addr = __PREG(Ser2HSDR), | ||
94 | .dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | ||
95 | .dst_maxburst = 8, | ||
96 | }; | ||
97 | |||
98 | static unsigned sa1100_irda_dma_xferred(struct sa1100_buf *buf) | ||
99 | { | ||
100 | struct dma_chan *chan = buf->chan; | ||
101 | struct dma_tx_state state; | ||
102 | enum dma_status status; | ||
103 | |||
104 | status = chan->device->device_tx_status(chan, buf->cookie, &state); | ||
105 | if (status != DMA_PAUSED) | ||
106 | return 0; | ||
107 | |||
108 | return sg_dma_len(&buf->sg) - state.residue; | ||
109 | } | ||
110 | |||
111 | static int sa1100_irda_dma_request(struct device *dev, struct sa1100_buf *buf, | ||
112 | const char *name, struct dma_slave_config *cfg) | ||
113 | { | ||
114 | dma_cap_mask_t m; | ||
115 | int ret; | ||
116 | |||
117 | dma_cap_zero(m); | ||
118 | dma_cap_set(DMA_SLAVE, m); | ||
119 | |||
120 | buf->chan = dma_request_channel(m, sa11x0_dma_filter_fn, (void *)name); | ||
121 | if (!buf->chan) { | ||
122 | dev_err(dev, "unable to request DMA channel for %s\n", | ||
123 | name); | ||
124 | return -ENOENT; | ||
125 | } | ||
126 | |||
127 | ret = dmaengine_slave_config(buf->chan, cfg); | ||
128 | if (ret) | ||
129 | dev_warn(dev, "DMA slave_config for %s returned %d\n", | ||
130 | name, ret); | ||
131 | |||
132 | buf->dev = buf->chan->device->dev; | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static void sa1100_irda_dma_start(struct sa1100_buf *buf, | ||
138 | enum dma_transfer_direction dir, dma_async_tx_callback cb, void *cb_p) | ||
139 | { | ||
140 | struct dma_async_tx_descriptor *desc; | ||
141 | struct dma_chan *chan = buf->chan; | ||
142 | |||
143 | desc = chan->device->device_prep_slave_sg(chan, &buf->sg, 1, dir, | ||
144 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
145 | if (desc) { | ||
146 | desc->callback = cb; | ||
147 | desc->callback_param = cb_p; | ||
148 | buf->cookie = dmaengine_submit(desc); | ||
149 | dma_async_issue_pending(chan); | ||
150 | } | ||
151 | } | ||
152 | |||
82 | /* | 153 | /* |
83 | * Allocate and map the receive buffer, unless it is already allocated. | 154 | * Allocate and map the receive buffer, unless it is already allocated. |
84 | */ | 155 | */ |
@@ -127,9 +198,9 @@ static void sa1100_irda_rx_dma_start(struct sa1100_irda *si) | |||
127 | /* | 198 | /* |
128 | * Enable the DMA, receiver and receive interrupt. | 199 | * Enable the DMA, receiver and receive interrupt. |
129 | */ | 200 | */ |
130 | sa1100_clear_dma(si->dma_rx.regs); | 201 | dmaengine_terminate_all(si->dma_rx.chan); |
131 | sa1100_start_dma(si->dma_rx.regs, sg_dma_address(&si->dma_rx.sg), | 202 | sa1100_irda_dma_start(&si->dma_rx, DMA_DEV_TO_MEM, NULL, NULL); |
132 | sg_dma_len(&si->dma_rx.sg)); | 203 | |
133 | Ser2HSCR0 = HSCR0_HSSP | HSCR0_RXE; | 204 | Ser2HSCR0 = HSCR0_HSSP | HSCR0_RXE; |
134 | } | 205 | } |
135 | 206 | ||
@@ -326,8 +397,7 @@ static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev, | |||
326 | return NETDEV_TX_OK; | 397 | return NETDEV_TX_OK; |
327 | } | 398 | } |
328 | 399 | ||
329 | sa1100_start_dma(si->dma_tx.regs, sg_dma_address(&si->dma_tx.sg), | 400 | sa1100_irda_dma_start(&si->dma_tx, DMA_MEM_TO_DEV, sa1100_irda_firtxdma_irq, dev); |
330 | sg_dma_len(&si->dma_tx.sg)); | ||
331 | 401 | ||
332 | /* | 402 | /* |
333 | * If we have a mean turn-around time, impose the specified | 403 | * If we have a mean turn-around time, impose the specified |
@@ -345,7 +415,6 @@ static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev, | |||
345 | static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev) | 415 | static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev) |
346 | { | 416 | { |
347 | struct sk_buff *skb = si->dma_rx.skb; | 417 | struct sk_buff *skb = si->dma_rx.skb; |
348 | dma_addr_t dma_addr; | ||
349 | unsigned int len, stat, data; | 418 | unsigned int len, stat, data; |
350 | 419 | ||
351 | if (!skb) { | 420 | if (!skb) { |
@@ -356,8 +425,7 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev | |||
356 | /* | 425 | /* |
357 | * Get the current data position. | 426 | * Get the current data position. |
358 | */ | 427 | */ |
359 | dma_addr = sa1100_get_dma_pos(si->dma_rx.regs); | 428 | len = sa1100_irda_dma_xferred(&si->dma_rx); |
360 | len = dma_addr - sg_dma_address(&si->dma_rx.sg); | ||
361 | if (len > HPSIR_MAX_RXLEN) | 429 | if (len > HPSIR_MAX_RXLEN) |
362 | len = HPSIR_MAX_RXLEN; | 430 | len = HPSIR_MAX_RXLEN; |
363 | dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE); | 431 | dma_unmap_sg(si->dma_rx.dev, &si->dma_rx.sg, 1, DMA_FROM_DEVICE); |
@@ -421,7 +489,7 @@ static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_ird | |||
421 | /* | 489 | /* |
422 | * Stop RX DMA | 490 | * Stop RX DMA |
423 | */ | 491 | */ |
424 | sa1100_stop_dma(si->dma_rx.regs); | 492 | dmaengine_pause(si->dma_rx.chan); |
425 | 493 | ||
426 | /* | 494 | /* |
427 | * Framing error - we throw away the packet completely. | 495 | * Framing error - we throw away the packet completely. |
@@ -476,11 +544,9 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed) | |||
476 | case 57600: case 115200: | 544 | case 57600: case 115200: |
477 | brd = 3686400 / (16 * speed) - 1; | 545 | brd = 3686400 / (16 * speed) - 1; |
478 | 546 | ||
479 | /* | 547 | /* Stop the receive DMA, and configure transmit. */ |
480 | * Stop the receive DMA. | ||
481 | */ | ||
482 | if (IS_FIR(si)) | 548 | if (IS_FIR(si)) |
483 | sa1100_stop_dma(si->dma_rx.regs); | 549 | dmaengine_terminate_all(si->dma_rx.chan); |
484 | 550 | ||
485 | local_irq_save(flags); | 551 | local_irq_save(flags); |
486 | 552 | ||
@@ -698,8 +764,8 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si) | |||
698 | /* | 764 | /* |
699 | * Stop all DMA activity. | 765 | * Stop all DMA activity. |
700 | */ | 766 | */ |
701 | sa1100_stop_dma(si->dma_rx.regs); | 767 | dmaengine_terminate_all(si->dma_rx.chan); |
702 | sa1100_stop_dma(si->dma_tx.regs); | 768 | dmaengine_terminate_all(si->dma_tx.chan); |
703 | 769 | ||
704 | /* Disable the port. */ | 770 | /* Disable the port. */ |
705 | Ser2UTCR3 = 0; | 771 | Ser2UTCR3 = 0; |
@@ -716,20 +782,16 @@ static int sa1100_irda_start(struct net_device *dev) | |||
716 | 782 | ||
717 | si->speed = 9600; | 783 | si->speed = 9600; |
718 | 784 | ||
719 | err = sa1100_request_dma(DMA_Ser2HSSPRd, "IrDA receive", | 785 | err = sa1100_irda_dma_request(si->dev, &si->dma_rx, "Ser2ICPRc", |
720 | NULL, NULL, &si->dma_rx.regs); | 786 | &sa1100_irda_fir_rx); |
721 | if (err) | 787 | if (err) |
722 | goto err_rx_dma; | 788 | goto err_rx_dma; |
723 | 789 | ||
724 | err = sa1100_request_dma(DMA_Ser2HSSPWr, "IrDA transmit", | 790 | err = sa1100_irda_dma_request(si->dev, &si->dma_tx, "Ser2ICPTr", |
725 | sa1100_irda_firtxdma_irq, dev, | 791 | &sa1100_irda_sir_tx); |
726 | &si->dma_tx.regs); | ||
727 | if (err) | 792 | if (err) |
728 | goto err_tx_dma; | 793 | goto err_tx_dma; |
729 | 794 | ||
730 | si->dma_rx.dev = si->dev; | ||
731 | si->dma_tx.dev = si->dev; | ||
732 | |||
733 | /* | 795 | /* |
734 | * Setup the serial port for the specified speed. | 796 | * Setup the serial port for the specified speed. |
735 | */ | 797 | */ |
@@ -764,9 +826,9 @@ err_irlap: | |||
764 | si->open = 0; | 826 | si->open = 0; |
765 | sa1100_irda_shutdown(si); | 827 | sa1100_irda_shutdown(si); |
766 | err_startup: | 828 | err_startup: |
767 | sa1100_free_dma(si->dma_tx.regs); | 829 | dma_release_channel(si->dma_tx.chan); |
768 | err_tx_dma: | 830 | err_tx_dma: |
769 | sa1100_free_dma(si->dma_rx.regs); | 831 | dma_release_channel(si->dma_rx.chan); |
770 | err_rx_dma: | 832 | err_rx_dma: |
771 | return err; | 833 | return err; |
772 | } | 834 | } |
@@ -810,8 +872,8 @@ static int sa1100_irda_stop(struct net_device *dev) | |||
810 | /* | 872 | /* |
811 | * Free resources | 873 | * Free resources |
812 | */ | 874 | */ |
813 | sa1100_free_dma(si->dma_tx.regs); | 875 | dma_release_channel(si->dma_tx.chan); |
814 | sa1100_free_dma(si->dma_rx.regs); | 876 | dma_release_channel(si->dma_rx.chan); |
815 | free_irq(dev->irq, dev); | 877 | free_irq(dev->irq, dev); |
816 | 878 | ||
817 | sa1100_set_power(si, 0); | 879 | sa1100_set_power(si, 0); |