aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/dma/sh/shdma-base.c25
-rw-r--r--drivers/dma/sh/shdma.c12
-rw-r--r--include/linux/sh_dma.h8
-rw-r--r--include/linux/shdma-base.h8
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
287static void sh_dmae_setup_xfer(struct shdma_chan *schan, 287static 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
304static const struct sh_dmae_slave_config *dmae_find_slave( 304static 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
322static int sh_dmae_set_slave(struct shdma_chan *schan, 322static 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 */
29struct sh_dmae_slave_config { 29struct 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
36struct sh_dmae_channel { 36struct 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
45struct shdma_slave { 45struct shdma_slave {
46 unsigned int slave_id; 46 int slave_id;
47}; 47};
48 48
49struct shdma_desc { 49struct 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);