diff options
-rw-r--r-- | drivers/dma/sh/shdma-base.c | 25 | ||||
-rw-r--r-- | drivers/dma/sh/shdma.c | 12 | ||||
-rw-r--r-- | include/linux/sh_dma.h | 8 | ||||
-rw-r--r-- | include/linux/shdma-base.h | 8 |
4 files changed, 27 insertions, 26 deletions
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index f75ebfa735c0..73db282a1436 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c | |||
@@ -76,7 +76,6 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
76 | container_of(tx, struct shdma_desc, async_tx), | 76 | container_of(tx, struct shdma_desc, async_tx), |
77 | *last = desc; | 77 | *last = desc; |
78 | struct shdma_chan *schan = to_shdma_chan(tx->chan); | 78 | struct shdma_chan *schan = to_shdma_chan(tx->chan); |
79 | struct shdma_slave *slave = schan->slave; | ||
80 | dma_async_tx_callback callback = tx->callback; | 79 | dma_async_tx_callback callback = tx->callback; |
81 | dma_cookie_t cookie; | 80 | dma_cookie_t cookie; |
82 | bool power_up; | 81 | bool power_up; |
@@ -138,7 +137,7 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
138 | * Make it int then, on error remove chunks from the | 137 | * Make it int then, on error remove chunks from the |
139 | * queue again | 138 | * queue again |
140 | */ | 139 | */ |
141 | ops->setup_xfer(schan, slave); | 140 | ops->setup_xfer(schan, schan->slave_id); |
142 | 141 | ||
143 | if (schan->pm_state == SHDMA_PM_PENDING) | 142 | if (schan->pm_state == SHDMA_PM_PENDING) |
144 | shdma_chan_xfer_ld_queue(schan); | 143 | shdma_chan_xfer_ld_queue(schan); |
@@ -186,7 +185,7 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan) | |||
186 | * never runs concurrently with itself or free_chan_resources. | 185 | * never runs concurrently with itself or free_chan_resources. |
187 | */ | 186 | */ |
188 | if (slave) { | 187 | if (slave) { |
189 | if (slave->slave_id >= slave_num) { | 188 | if (slave->slave_id < 0 || slave->slave_id >= slave_num) { |
190 | ret = -EINVAL; | 189 | ret = -EINVAL; |
191 | goto evalid; | 190 | goto evalid; |
192 | } | 191 | } |
@@ -196,9 +195,13 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan) | |||
196 | goto etestused; | 195 | goto etestused; |
197 | } | 196 | } |
198 | 197 | ||
199 | ret = ops->set_slave(schan, slave); | 198 | ret = ops->set_slave(schan, slave->slave_id); |
200 | if (ret < 0) | 199 | if (ret < 0) |
201 | goto esetslave; | 200 | goto esetslave; |
201 | |||
202 | schan->slave_id = slave->slave_id; | ||
203 | } else { | ||
204 | schan->slave_id = -EINVAL; | ||
202 | } | 205 | } |
203 | 206 | ||
204 | schan->desc = kcalloc(NR_DESCS_PER_CHANNEL, | 207 | schan->desc = kcalloc(NR_DESCS_PER_CHANNEL, |
@@ -208,7 +211,6 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan) | |||
208 | goto edescalloc; | 211 | goto edescalloc; |
209 | } | 212 | } |
210 | schan->desc_num = NR_DESCS_PER_CHANNEL; | 213 | schan->desc_num = NR_DESCS_PER_CHANNEL; |
211 | schan->slave = slave; | ||
212 | 214 | ||
213 | for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) { | 215 | for (i = 0; i < NR_DESCS_PER_CHANNEL; i++) { |
214 | desc = ops->embedded_desc(schan->desc, i); | 216 | desc = ops->embedded_desc(schan->desc, i); |
@@ -366,10 +368,9 @@ static void shdma_free_chan_resources(struct dma_chan *chan) | |||
366 | if (!list_empty(&schan->ld_queue)) | 368 | if (!list_empty(&schan->ld_queue)) |
367 | shdma_chan_ld_cleanup(schan, true); | 369 | shdma_chan_ld_cleanup(schan, true); |
368 | 370 | ||
369 | if (schan->slave) { | 371 | if (schan->slave_id >= 0) { |
370 | /* The caller is holding dma_list_mutex */ | 372 | /* The caller is holding dma_list_mutex */ |
371 | struct shdma_slave *slave = schan->slave; | 373 | clear_bit(schan->slave_id, shdma_slave_used); |
372 | clear_bit(slave->slave_id, shdma_slave_used); | ||
373 | chan->private = NULL; | 374 | chan->private = NULL; |
374 | } | 375 | } |
375 | 376 | ||
@@ -559,7 +560,7 @@ static struct dma_async_tx_descriptor *shdma_prep_slave_sg( | |||
559 | struct shdma_chan *schan = to_shdma_chan(chan); | 560 | struct shdma_chan *schan = to_shdma_chan(chan); |
560 | struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); | 561 | struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); |
561 | const struct shdma_ops *ops = sdev->ops; | 562 | const struct shdma_ops *ops = sdev->ops; |
562 | struct shdma_slave *slave = schan->slave; | 563 | int slave_id = schan->slave_id; |
563 | dma_addr_t slave_addr; | 564 | dma_addr_t slave_addr; |
564 | 565 | ||
565 | if (!chan) | 566 | if (!chan) |
@@ -568,9 +569,9 @@ static struct dma_async_tx_descriptor *shdma_prep_slave_sg( | |||
568 | BUG_ON(!schan->desc_num); | 569 | BUG_ON(!schan->desc_num); |
569 | 570 | ||
570 | /* Someone calling slave DMA on a generic channel? */ | 571 | /* Someone calling slave DMA on a generic channel? */ |
571 | if (!slave || !sg_len) { | 572 | if (slave_id < 0 || !sg_len) { |
572 | dev_warn(schan->dev, "%s: bad parameter: %p, %d, %d\n", | 573 | dev_warn(schan->dev, "%s: bad parameter: len=%d, id=%d\n", |
573 | __func__, slave, sg_len, slave ? slave->slave_id : -1); | 574 | __func__, sg_len, slave_id); |
574 | return NULL; | 575 | return NULL; |
575 | } | 576 | } |
576 | 577 | ||
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c index 9f0a2e507ac3..9a10d8bbdef2 100644 --- a/drivers/dma/sh/shdma.c +++ b/drivers/dma/sh/shdma.c | |||
@@ -285,12 +285,12 @@ static bool sh_dmae_channel_busy(struct shdma_chan *schan) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | static void sh_dmae_setup_xfer(struct shdma_chan *schan, | 287 | static void sh_dmae_setup_xfer(struct shdma_chan *schan, |
288 | struct shdma_slave *sslave) | 288 | int slave_id) |
289 | { | 289 | { |
290 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, | 290 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, |
291 | shdma_chan); | 291 | shdma_chan); |
292 | 292 | ||
293 | if (sslave) { | 293 | if (slave_id >= 0) { |
294 | const struct sh_dmae_slave_config *cfg = | 294 | const struct sh_dmae_slave_config *cfg = |
295 | sh_chan->config; | 295 | sh_chan->config; |
296 | 296 | ||
@@ -302,7 +302,7 @@ static void sh_dmae_setup_xfer(struct shdma_chan *schan, | |||
302 | } | 302 | } |
303 | 303 | ||
304 | static const struct sh_dmae_slave_config *dmae_find_slave( | 304 | static const struct sh_dmae_slave_config *dmae_find_slave( |
305 | struct sh_dmae_chan *sh_chan, unsigned int slave_id) | 305 | struct sh_dmae_chan *sh_chan, int slave_id) |
306 | { | 306 | { |
307 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); | 307 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
308 | struct sh_dmae_pdata *pdata = shdev->pdata; | 308 | struct sh_dmae_pdata *pdata = shdev->pdata; |
@@ -320,11 +320,11 @@ static const struct sh_dmae_slave_config *dmae_find_slave( | |||
320 | } | 320 | } |
321 | 321 | ||
322 | static int sh_dmae_set_slave(struct shdma_chan *schan, | 322 | static int sh_dmae_set_slave(struct shdma_chan *schan, |
323 | struct shdma_slave *sslave) | 323 | int slave_id) |
324 | { | 324 | { |
325 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, | 325 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, |
326 | shdma_chan); | 326 | shdma_chan); |
327 | const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, sslave->slave_id); | 327 | const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave_id); |
328 | if (!cfg) | 328 | if (!cfg) |
329 | return -ENODEV; | 329 | return -ENODEV; |
330 | 330 | ||
@@ -579,7 +579,7 @@ static int sh_dmae_resume(struct device *dev) | |||
579 | if (!sh_chan->shdma_chan.desc_num) | 579 | if (!sh_chan->shdma_chan.desc_num) |
580 | continue; | 580 | continue; |
581 | 581 | ||
582 | if (sh_chan->shdma_chan.slave) { | 582 | if (sh_chan->shdma_chan.slave_id >= 0) { |
583 | const struct sh_dmae_slave_config *cfg = sh_chan->config; | 583 | const struct sh_dmae_slave_config *cfg = sh_chan->config; |
584 | dmae_set_dmars(sh_chan, cfg->mid_rid); | 584 | dmae_set_dmars(sh_chan, cfg->mid_rid); |
585 | dmae_set_chcr(sh_chan, cfg->chcr); | 585 | dmae_set_chcr(sh_chan, cfg->chcr); |
diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h index a79f10a32243..4e83f3e034f3 100644 --- a/include/linux/sh_dma.h +++ b/include/linux/sh_dma.h | |||
@@ -27,10 +27,10 @@ struct sh_dmae_slave { | |||
27 | * a certain peripheral | 27 | * a certain peripheral |
28 | */ | 28 | */ |
29 | struct sh_dmae_slave_config { | 29 | struct sh_dmae_slave_config { |
30 | unsigned int slave_id; | 30 | int slave_id; |
31 | dma_addr_t addr; | 31 | dma_addr_t addr; |
32 | u32 chcr; | 32 | u32 chcr; |
33 | char mid_rid; | 33 | char mid_rid; |
34 | }; | 34 | }; |
35 | 35 | ||
36 | struct sh_dmae_channel { | 36 | struct sh_dmae_channel { |
diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index c3a19e9c20c4..6263ad2e7426 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h | |||
@@ -43,7 +43,7 @@ struct device; | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | struct shdma_slave { | 45 | struct shdma_slave { |
46 | unsigned int slave_id; | 46 | int slave_id; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | struct shdma_desc { | 49 | struct shdma_desc { |
@@ -66,7 +66,7 @@ struct shdma_chan { | |||
66 | size_t max_xfer_len; /* max transfer length */ | 66 | size_t max_xfer_len; /* max transfer length */ |
67 | int id; /* Raw id of this channel */ | 67 | int id; /* Raw id of this channel */ |
68 | int irq; /* Channel IRQ */ | 68 | int irq; /* Channel IRQ */ |
69 | struct shdma_slave *slave; /* Client data for slave DMA */ | 69 | int slave_id; /* Client ID for slave DMA */ |
70 | enum shdma_pm_state pm_state; | 70 | enum shdma_pm_state pm_state; |
71 | }; | 71 | }; |
72 | 72 | ||
@@ -93,8 +93,8 @@ struct shdma_ops { | |||
93 | dma_addr_t (*slave_addr)(struct shdma_chan *); | 93 | dma_addr_t (*slave_addr)(struct shdma_chan *); |
94 | int (*desc_setup)(struct shdma_chan *, struct shdma_desc *, | 94 | int (*desc_setup)(struct shdma_chan *, struct shdma_desc *, |
95 | dma_addr_t, dma_addr_t, size_t *); | 95 | dma_addr_t, dma_addr_t, size_t *); |
96 | int (*set_slave)(struct shdma_chan *, struct shdma_slave *); | 96 | int (*set_slave)(struct shdma_chan *, int); |
97 | void (*setup_xfer)(struct shdma_chan *, struct shdma_slave *); | 97 | void (*setup_xfer)(struct shdma_chan *, int); |
98 | void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); | 98 | void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); |
99 | struct shdma_desc *(*embedded_desc)(void *, int); | 99 | struct shdma_desc *(*embedded_desc)(void *, int); |
100 | bool (*chan_irq)(struct shdma_chan *, int); | 100 | bool (*chan_irq)(struct shdma_chan *, int); |