diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2011-11-22 05:55:54 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@linux.intel.com> | 2011-11-28 05:25:36 -0500 |
commit | 02f88be9488a3d831f073c1161b1e5feacb9d3ec (patch) | |
tree | f4d9a53a2185a6e118ad64e2e27901a0ccb6e43a /drivers/dma/at_hdmac.c | |
parent | dcc817346d311bbd9dac6fc9d6bddb552134851c (diff) |
dmaengine: at_hdmac: simplify device selection from platform data or DT
Using a configuration structure simplify the finding of SoC
dependent parameters. Both platform data and device tree ids are
using these structures.
This will separate data from code and remove the need for an enum.
Idea from Grant Likely.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
Diffstat (limited to 'drivers/dma/at_hdmac.c')
-rw-r--r-- | drivers/dma/at_hdmac.c | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 30ec030456cf..97f87b29b9f3 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -1177,14 +1177,22 @@ static void atc_free_chan_resources(struct dma_chan *chan) | |||
1177 | 1177 | ||
1178 | /*-- Module Management -----------------------------------------------*/ | 1178 | /*-- Module Management -----------------------------------------------*/ |
1179 | 1179 | ||
1180 | /* cap_mask is a multi-u32 bitfield, fill it with proper C code. */ | ||
1181 | static struct at_dma_platform_data at91sam9rl_config = { | ||
1182 | .nr_channels = 2, | ||
1183 | }; | ||
1184 | static struct at_dma_platform_data at91sam9g45_config = { | ||
1185 | .nr_channels = 8, | ||
1186 | }; | ||
1187 | |||
1180 | #if defined(CONFIG_OF) | 1188 | #if defined(CONFIG_OF) |
1181 | static const struct of_device_id atmel_dma_dt_ids[] = { | 1189 | static const struct of_device_id atmel_dma_dt_ids[] = { |
1182 | { | 1190 | { |
1183 | .compatible = "atmel,at91sam9rl-dma", | 1191 | .compatible = "atmel,at91sam9rl-dma", |
1184 | .data = (void *)ATDMA_DEVTYPE_SAM9RL | 1192 | .data = &at91sam9rl_config, |
1185 | }, { | 1193 | }, { |
1186 | .compatible = "atmel,at91sam9g45-dma", | 1194 | .compatible = "atmel,at91sam9g45-dma", |
1187 | .data = (void *)ATDMA_DEVTYPE_SAM9G45 | 1195 | .data = &at91sam9g45_config, |
1188 | }, { | 1196 | }, { |
1189 | /* sentinel */ | 1197 | /* sentinel */ |
1190 | } | 1198 | } |
@@ -1196,26 +1204,27 @@ MODULE_DEVICE_TABLE(of, atmel_dma_dt_ids); | |||
1196 | static const struct platform_device_id atdma_devtypes[] = { | 1204 | static const struct platform_device_id atdma_devtypes[] = { |
1197 | { | 1205 | { |
1198 | .name = "at91sam9rl_dma", | 1206 | .name = "at91sam9rl_dma", |
1199 | .driver_data = ATDMA_DEVTYPE_SAM9RL, | 1207 | .driver_data = (unsigned long) &at91sam9rl_config, |
1200 | }, { | 1208 | }, { |
1201 | .name = "at91sam9g45_dma", | 1209 | .name = "at91sam9g45_dma", |
1202 | .driver_data = ATDMA_DEVTYPE_SAM9G45, | 1210 | .driver_data = (unsigned long) &at91sam9g45_config, |
1203 | }, { | 1211 | }, { |
1204 | /* sentinel */ | 1212 | /* sentinel */ |
1205 | } | 1213 | } |
1206 | }; | 1214 | }; |
1207 | 1215 | ||
1208 | static inline enum atdma_devtype __init at_dma_get_driver_data( | 1216 | static inline struct at_dma_platform_data * __init at_dma_get_driver_data( |
1209 | struct platform_device *pdev) | 1217 | struct platform_device *pdev) |
1210 | { | 1218 | { |
1211 | if (pdev->dev.of_node) { | 1219 | if (pdev->dev.of_node) { |
1212 | const struct of_device_id *match; | 1220 | const struct of_device_id *match; |
1213 | match = of_match_node(atmel_dma_dt_ids, pdev->dev.of_node); | 1221 | match = of_match_node(atmel_dma_dt_ids, pdev->dev.of_node); |
1214 | if (match == NULL) | 1222 | if (match == NULL) |
1215 | return ATDMA_DEVTYPE_UNDEFINED; | 1223 | return NULL; |
1216 | return (enum atdma_devtype)match->data; | 1224 | return match->data; |
1217 | } | 1225 | } |
1218 | return platform_get_device_id(pdev)->driver_data; | 1226 | return (struct at_dma_platform_data *) |
1227 | platform_get_device_id(pdev)->driver_data; | ||
1219 | } | 1228 | } |
1220 | 1229 | ||
1221 | /** | 1230 | /** |
@@ -1242,26 +1251,17 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1242 | int irq; | 1251 | int irq; |
1243 | int err; | 1252 | int err; |
1244 | int i; | 1253 | int i; |
1245 | u32 nr_channels; | 1254 | struct at_dma_platform_data *plat_dat; |
1246 | dma_cap_mask_t cap_mask = {}; | ||
1247 | enum atdma_devtype atdmatype; | ||
1248 | 1255 | ||
1249 | dma_cap_set(DMA_MEMCPY, cap_mask); | 1256 | /* setup platform data for each SoC */ |
1257 | dma_cap_set(DMA_MEMCPY, at91sam9rl_config.cap_mask); | ||
1258 | dma_cap_set(DMA_MEMCPY, at91sam9g45_config.cap_mask); | ||
1259 | dma_cap_set(DMA_SLAVE, at91sam9g45_config.cap_mask); | ||
1250 | 1260 | ||
1251 | /* get DMA parameters from controller type */ | 1261 | /* get DMA parameters from controller type */ |
1252 | atdmatype = at_dma_get_driver_data(pdev); | 1262 | plat_dat = at_dma_get_driver_data(pdev); |
1253 | 1263 | if (!plat_dat) | |
1254 | switch (atdmatype) { | 1264 | return -ENODEV; |
1255 | case ATDMA_DEVTYPE_SAM9RL: | ||
1256 | nr_channels = 2; | ||
1257 | break; | ||
1258 | case ATDMA_DEVTYPE_SAM9G45: | ||
1259 | nr_channels = 8; | ||
1260 | dma_cap_set(DMA_SLAVE, cap_mask); | ||
1261 | break; | ||
1262 | default: | ||
1263 | return -EINVAL; | ||
1264 | } | ||
1265 | 1265 | ||
1266 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1266 | io = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1267 | if (!io) | 1267 | if (!io) |
@@ -1272,15 +1272,14 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1272 | return irq; | 1272 | return irq; |
1273 | 1273 | ||
1274 | size = sizeof(struct at_dma); | 1274 | size = sizeof(struct at_dma); |
1275 | size += nr_channels * sizeof(struct at_dma_chan); | 1275 | size += plat_dat->nr_channels * sizeof(struct at_dma_chan); |
1276 | atdma = kzalloc(size, GFP_KERNEL); | 1276 | atdma = kzalloc(size, GFP_KERNEL); |
1277 | if (!atdma) | 1277 | if (!atdma) |
1278 | return -ENOMEM; | 1278 | return -ENOMEM; |
1279 | 1279 | ||
1280 | /* discover transaction capabilities */ | 1280 | /* discover transaction capabilities */ |
1281 | atdma->dma_common.cap_mask = cap_mask; | 1281 | atdma->dma_common.cap_mask = plat_dat->cap_mask; |
1282 | atdma->all_chan_mask = (1 << nr_channels) - 1; | 1282 | atdma->all_chan_mask = (1 << plat_dat->nr_channels) - 1; |
1283 | atdma->devtype = atdmatype; | ||
1284 | 1283 | ||
1285 | size = resource_size(io); | 1284 | size = resource_size(io); |
1286 | if (!request_mem_region(io->start, size, pdev->dev.driver->name)) { | 1285 | if (!request_mem_region(io->start, size, pdev->dev.driver->name)) { |
@@ -1326,7 +1325,7 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1326 | 1325 | ||
1327 | /* initialize channels related values */ | 1326 | /* initialize channels related values */ |
1328 | INIT_LIST_HEAD(&atdma->dma_common.channels); | 1327 | INIT_LIST_HEAD(&atdma->dma_common.channels); |
1329 | for (i = 0; i < nr_channels; i++) { | 1328 | for (i = 0; i < plat_dat->nr_channels; i++) { |
1330 | struct at_dma_chan *atchan = &atdma->chan[i]; | 1329 | struct at_dma_chan *atchan = &atdma->chan[i]; |
1331 | 1330 | ||
1332 | atchan->chan_common.device = &atdma->dma_common; | 1331 | atchan->chan_common.device = &atdma->dma_common; |
@@ -1371,7 +1370,7 @@ static int __init at_dma_probe(struct platform_device *pdev) | |||
1371 | dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n", | 1370 | dev_info(&pdev->dev, "Atmel AHB DMA Controller ( %s%s), %d channels\n", |
1372 | dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "", | 1371 | dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask) ? "cpy " : "", |
1373 | dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", | 1372 | dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", |
1374 | nr_channels); | 1373 | plat_dat->nr_channels); |
1375 | 1374 | ||
1376 | dma_async_device_register(&atdma->dma_common); | 1375 | dma_async_device_register(&atdma->dma_common); |
1377 | 1376 | ||