Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'samsung/dma' into next/dt

Required as a dependency for samsung/dt changes.

+108 -84
+46 -38
arch/arm/plat-samsung/dma-ops.c
··· 19 19 #include <mach/dma.h> 20 20 21 21 static unsigned samsung_dmadev_request(enum dma_ch dma_ch, 22 - struct samsung_dma_info *info) 22 + struct samsung_dma_req *param) 23 23 { 24 - struct dma_chan *chan; 25 24 dma_cap_mask_t mask; 26 - struct dma_slave_config slave_config; 27 25 void *filter_param; 28 26 29 27 dma_cap_zero(mask); 30 - dma_cap_set(info->cap, mask); 28 + dma_cap_set(param->cap, mask); 31 29 32 30 /* 33 31 * If a dma channel property of a device node from device tree is 34 32 * specified, use that as the fliter parameter. 35 33 */ 36 - filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop : 37 - (void *)dma_ch; 38 - chan = dma_request_channel(mask, pl330_filter, filter_param); 39 - 40 - if (info->direction == DMA_DEV_TO_MEM) { 41 - memset(&slave_config, 0, sizeof(struct dma_slave_config)); 42 - slave_config.direction = info->direction; 43 - slave_config.src_addr = info->fifo; 44 - slave_config.src_addr_width = info->width; 45 - slave_config.src_maxburst = 1; 46 - dmaengine_slave_config(chan, &slave_config); 47 - } else if (info->direction == DMA_MEM_TO_DEV) { 48 - memset(&slave_config, 0, sizeof(struct dma_slave_config)); 49 - slave_config.direction = info->direction; 50 - slave_config.dst_addr = info->fifo; 51 - slave_config.dst_addr_width = info->width; 52 - slave_config.dst_maxburst = 1; 53 - dmaengine_slave_config(chan, &slave_config); 54 - } 55 - 56 - return (unsigned)chan; 34 + filter_param = (dma_ch == DMACH_DT_PROP) ? 35 + (void *)param->dt_dmach_prop : (void *)dma_ch; 36 + return (unsigned)dma_request_channel(mask, pl330_filter, filter_param); 57 37 } 58 38 59 - static int samsung_dmadev_release(unsigned ch, 60 - struct s3c2410_dma_client *client) 39 + static int samsung_dmadev_release(unsigned ch, void *param) 61 40 { 62 41 dma_release_channel((struct dma_chan *)ch); 63 42 64 43 return 0; 65 44 } 66 45 46 + static int samsung_dmadev_config(unsigned ch, 47 + struct samsung_dma_config *param) 48 + { 49 + struct dma_chan *chan = (struct dma_chan *)ch; 50 + struct dma_slave_config slave_config; 51 + 52 + if (param->direction == DMA_DEV_TO_MEM) { 53 + memset(&slave_config, 0, sizeof(struct dma_slave_config)); 54 + slave_config.direction = param->direction; 55 + slave_config.src_addr = param->fifo; 56 + slave_config.src_addr_width = param->width; 57 + slave_config.src_maxburst = 1; 58 + dmaengine_slave_config(chan, &slave_config); 59 + } else if (param->direction == DMA_MEM_TO_DEV) { 60 + memset(&slave_config, 0, sizeof(struct dma_slave_config)); 61 + slave_config.direction = param->direction; 62 + slave_config.dst_addr = param->fifo; 63 + slave_config.dst_addr_width = param->width; 64 + slave_config.dst_maxburst = 1; 65 + dmaengine_slave_config(chan, &slave_config); 66 + } else { 67 + pr_warn("unsupported direction\n"); 68 + return -EINVAL; 69 + } 70 + 71 + return 0; 72 + } 73 + 67 74 static int samsung_dmadev_prepare(unsigned ch, 68 - struct samsung_dma_prep_info *info) 75 + struct samsung_dma_prep *param) 69 76 { 70 77 struct scatterlist sg; 71 78 struct dma_chan *chan = (struct dma_chan *)ch; 72 79 struct dma_async_tx_descriptor *desc; 73 80 74 - switch (info->cap) { 81 + switch (param->cap) { 75 82 case DMA_SLAVE: 76 83 sg_init_table(&sg, 1); 77 - sg_dma_len(&sg) = info->len; 78 - sg_set_page(&sg, pfn_to_page(PFN_DOWN(info->buf)), 79 - info->len, offset_in_page(info->buf)); 80 - sg_dma_address(&sg) = info->buf; 84 + sg_dma_len(&sg) = param->len; 85 + sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)), 86 + param->len, offset_in_page(param->buf)); 87 + sg_dma_address(&sg) = param->buf; 81 88 82 89 desc = dmaengine_prep_slave_sg(chan, 83 - &sg, 1, info->direction, DMA_PREP_INTERRUPT); 90 + &sg, 1, param->direction, DMA_PREP_INTERRUPT); 84 91 break; 85 92 case DMA_CYCLIC: 86 - desc = dmaengine_prep_dma_cyclic(chan, 87 - info->buf, info->len, info->period, info->direction); 93 + desc = dmaengine_prep_dma_cyclic(chan, param->buf, 94 + param->len, param->period, param->direction); 88 95 break; 89 96 default: 90 97 dev_err(&chan->dev->device, "unsupported format\n"); ··· 103 96 return -EFAULT; 104 97 } 105 98 106 - desc->callback = info->fp; 107 - desc->callback_param = info->fp_param; 99 + desc->callback = param->fp; 100 + desc->callback_param = param->fp_param; 108 101 109 102 dmaengine_submit((struct dma_async_tx_descriptor *)desc); 110 103 ··· 126 119 static struct samsung_dma_ops dmadev_ops = { 127 120 .request = samsung_dmadev_request, 128 121 .release = samsung_dmadev_release, 122 + .config = samsung_dmadev_config, 129 123 .prepare = samsung_dmadev_prepare, 130 124 .trigger = samsung_dmadev_trigger, 131 125 .started = NULL,
+12 -8
arch/arm/plat-samsung/include/plat/dma-ops.h
··· 16 16 #include <linux/dmaengine.h> 17 17 #include <mach/dma.h> 18 18 19 - struct samsung_dma_prep_info { 19 + struct samsung_dma_req { 20 + enum dma_transaction_type cap; 21 + struct property *dt_dmach_prop; 22 + struct s3c2410_dma_client *client; 23 + }; 24 + 25 + struct samsung_dma_prep { 20 26 enum dma_transaction_type cap; 21 27 enum dma_transfer_direction direction; 22 28 dma_addr_t buf; ··· 32 26 void *fp_param; 33 27 }; 34 28 35 - struct samsung_dma_info { 36 - enum dma_transaction_type cap; 29 + struct samsung_dma_config { 37 30 enum dma_transfer_direction direction; 38 31 enum dma_slave_buswidth width; 39 32 dma_addr_t fifo; 40 - struct s3c2410_dma_client *client; 41 - struct property *dt_dmach_prop; 42 33 }; 43 34 44 35 struct samsung_dma_ops { 45 - unsigned (*request)(enum dma_ch ch, struct samsung_dma_info *info); 46 - int (*release)(unsigned ch, struct s3c2410_dma_client *client); 47 - int (*prepare)(unsigned ch, struct samsung_dma_prep_info *info); 36 + unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param); 37 + int (*release)(unsigned ch, void *param); 38 + int (*config)(unsigned ch, struct samsung_dma_config *param); 39 + int (*prepare)(unsigned ch, struct samsung_dma_prep *param); 48 40 int (*trigger)(unsigned ch); 49 41 int (*started)(unsigned ch); 50 42 int (*flush)(unsigned ch);
+22 -17
arch/arm/plat-samsung/s3c-dma-ops.c
··· 36 36 } 37 37 38 38 static unsigned s3c_dma_request(enum dma_ch dma_ch, 39 - struct samsung_dma_info *info) 39 + struct samsung_dma_req *param) 40 40 { 41 41 struct cb_data *data; 42 42 43 - if (s3c2410_dma_request(dma_ch, info->client, NULL) < 0) { 44 - s3c2410_dma_free(dma_ch, info->client); 43 + if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) { 44 + s3c2410_dma_free(dma_ch, param->client); 45 45 return 0; 46 46 } 47 + 48 + if (param->cap == DMA_CYCLIC) 49 + s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR); 47 50 48 51 data = kzalloc(sizeof(struct cb_data), GFP_KERNEL); 49 52 data->ch = dma_ch; 50 53 list_add_tail(&data->node, &dma_list); 51 54 52 - s3c2410_dma_devconfig(dma_ch, info->direction, info->fifo); 53 - 54 - if (info->cap == DMA_CYCLIC) 55 - s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR); 56 - 57 - s3c2410_dma_config(dma_ch, info->width); 58 - 59 55 return (unsigned)dma_ch; 60 56 } 61 57 62 - static int s3c_dma_release(unsigned ch, struct s3c2410_dma_client *client) 58 + static int s3c_dma_release(unsigned ch, void *param) 63 59 { 64 60 struct cb_data *data; 65 61 ··· 64 68 break; 65 69 list_del(&data->node); 66 70 67 - s3c2410_dma_free(ch, client); 71 + s3c2410_dma_free(ch, param); 68 72 kfree(data); 69 73 70 74 return 0; 71 75 } 72 76 73 - static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep_info *info) 77 + static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param) 78 + { 79 + s3c2410_dma_devconfig(ch, param->direction, param->fifo); 80 + s3c2410_dma_config(ch, param->width); 81 + 82 + return 0; 83 + } 84 + 85 + static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) 74 86 { 75 87 struct cb_data *data; 76 - int len = (info->cap == DMA_CYCLIC) ? info->period : info->len; 88 + int len = (param->cap == DMA_CYCLIC) ? param->period : param->len; 77 89 78 90 list_for_each_entry(data, &dma_list, node) 79 91 if (data->ch == ch) ··· 89 85 90 86 if (!data->fp) { 91 87 s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb); 92 - data->fp = info->fp; 93 - data->fp_param = info->fp_param; 88 + data->fp = param->fp; 89 + data->fp_param = param->fp_param; 94 90 } 95 91 96 - s3c2410_dma_enqueue(ch, (void *)data, info->buf, len); 92 + s3c2410_dma_enqueue(ch, (void *)data, param->buf, len); 97 93 98 94 return 0; 99 95 } ··· 121 117 static struct samsung_dma_ops s3c_dma_ops = { 122 118 .request = s3c_dma_request, 123 119 .release = s3c_dma_release, 120 + .config = s3c_dma_config, 124 121 .prepare = s3c_dma_prepare, 125 122 .trigger = s3c_dma_trigger, 126 123 .started = s3c_dma_started,
+18 -13
drivers/spi/spi-s3c64xx.c
··· 262 262 unsigned len, dma_addr_t buf) 263 263 { 264 264 struct s3c64xx_spi_driver_data *sdd; 265 - struct samsung_dma_prep_info info; 265 + struct samsung_dma_prep info; 266 + struct samsung_dma_config config; 266 267 267 - if (dma->direction == DMA_DEV_TO_MEM) 268 + if (dma->direction == DMA_DEV_TO_MEM) { 268 269 sdd = container_of((void *)dma, 269 270 struct s3c64xx_spi_driver_data, rx_dma); 270 - else 271 + config.direction = sdd->rx_dma.direction; 272 + config.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; 273 + config.width = sdd->cur_bpw / 8; 274 + sdd->ops->config(sdd->rx_dma.ch, &config); 275 + } else { 271 276 sdd = container_of((void *)dma, 272 277 struct s3c64xx_spi_driver_data, tx_dma); 278 + config.direction = sdd->tx_dma.direction; 279 + config.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; 280 + config.width = sdd->cur_bpw / 8; 281 + sdd->ops->config(sdd->tx_dma.ch, &config); 282 + } 273 283 274 284 info.cap = DMA_SLAVE; 275 285 info.len = len; ··· 294 284 295 285 static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) 296 286 { 297 - struct samsung_dma_info info; 287 + struct samsung_dma_req req; 298 288 299 289 sdd->ops = samsung_dma_get_ops(); 300 290 301 - info.cap = DMA_SLAVE; 302 - info.client = &s3c64xx_spi_dma_client; 303 - info.width = sdd->cur_bpw / 8; 291 + req.cap = DMA_SLAVE; 292 + req.client = &s3c64xx_spi_dma_client; 304 293 305 - info.direction = sdd->rx_dma.direction; 306 - info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; 307 - sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info); 308 - info.direction = sdd->tx_dma.direction; 309 - info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; 310 - sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info); 294 + sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &req); 295 + sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &req); 311 296 312 297 return 1; 313 298 }
+10 -8
sound/soc/samsung/dma.c
··· 74 74 struct runtime_data *prtd = substream->runtime->private_data; 75 75 dma_addr_t pos = prtd->dma_pos; 76 76 unsigned int limit; 77 - struct samsung_dma_prep_info dma_info; 77 + struct samsung_dma_prep dma_info; 78 78 79 79 pr_debug("Entered %s\n", __func__); 80 80 ··· 146 146 unsigned long totbytes = params_buffer_bytes(params); 147 147 struct s3c_dma_params *dma = 148 148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 149 - struct samsung_dma_info dma_info; 149 + struct samsung_dma_req req; 150 + struct samsung_dma_config config; 150 151 151 152 pr_debug("Entered %s\n", __func__); 152 153 ··· 167 166 168 167 prtd->params->ops = samsung_dma_get_ops(); 169 168 170 - dma_info.cap = (samsung_dma_has_circular() ? 169 + req.cap = (samsung_dma_has_circular() ? 171 170 DMA_CYCLIC : DMA_SLAVE); 172 - dma_info.client = prtd->params->client; 173 - dma_info.direction = 171 + req.client = prtd->params->client; 172 + config.direction = 174 173 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK 175 174 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); 176 - dma_info.width = prtd->params->dma_size; 177 - dma_info.fifo = prtd->params->dma_addr; 175 + config.width = prtd->params->dma_size; 176 + config.fifo = prtd->params->dma_addr; 178 177 prtd->params->ch = prtd->params->ops->request( 179 - prtd->params->channel, &dma_info); 178 + prtd->params->channel, &req); 179 + prtd->params->ops->config(prtd->params->ch, &config); 180 180 } 181 181 182 182 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);