aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/dts-bindings/fsl/dma.txt8
-rw-r--r--drivers/dma/fsldma.c173
2 files changed, 137 insertions, 44 deletions
diff --git a/Documentation/powerpc/dts-bindings/fsl/dma.txt b/Documentation/powerpc/dts-bindings/fsl/dma.txt
index 0732cdd05ba1..2a4b4bce6110 100644
--- a/Documentation/powerpc/dts-bindings/fsl/dma.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/dma.txt
@@ -44,21 +44,29 @@ Example:
44 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; 44 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
45 cell-index = <0>; 45 cell-index = <0>;
46 reg = <0 0x80>; 46 reg = <0 0x80>;
47 interrupt-parent = <&ipic>;
48 interrupts = <71 8>;
47 }; 49 };
48 dma-channel@80 { 50 dma-channel@80 {
49 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; 51 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
50 cell-index = <1>; 52 cell-index = <1>;
51 reg = <0x80 0x80>; 53 reg = <0x80 0x80>;
54 interrupt-parent = <&ipic>;
55 interrupts = <71 8>;
52 }; 56 };
53 dma-channel@100 { 57 dma-channel@100 {
54 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; 58 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
55 cell-index = <2>; 59 cell-index = <2>;
56 reg = <0x100 0x80>; 60 reg = <0x100 0x80>;
61 interrupt-parent = <&ipic>;
62 interrupts = <71 8>;
57 }; 63 };
58 dma-channel@180 { 64 dma-channel@180 {
59 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel"; 65 compatible = "fsl,mpc8349-dma-channel", "fsl,elo-dma-channel";
60 cell-index = <3>; 66 cell-index = <3>;
61 reg = <0x180 0x80>; 67 reg = <0x180 0x80>;
68 interrupt-parent = <&ipic>;
69 interrupts = <71 8>;
62 }; 70 };
63 }; 71 };
64 72
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 507b29716bbd..6a905929ef01 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -967,6 +967,10 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *chan,
967 return dma_async_is_complete(cookie, last_complete, last_used); 967 return dma_async_is_complete(cookie, last_complete, last_used);
968} 968}
969 969
970/*----------------------------------------------------------------------------*/
971/* Interrupt Handling */
972/*----------------------------------------------------------------------------*/
973
970static irqreturn_t fsldma_chan_irq(int irq, void *data) 974static irqreturn_t fsldma_chan_irq(int irq, void *data)
971{ 975{
972 struct fsldma_chan *fsl_chan = data; 976 struct fsldma_chan *fsl_chan = data;
@@ -1048,24 +1052,116 @@ static irqreturn_t fsldma_chan_irq(int irq, void *data)
1048 return IRQ_HANDLED; 1052 return IRQ_HANDLED;
1049} 1053}
1050 1054
1051static irqreturn_t fsldma_irq(int irq, void *data) 1055static void dma_do_tasklet(unsigned long data)
1056{
1057 struct fsldma_chan *fsl_chan = (struct fsldma_chan *)data;
1058 fsl_chan_ld_cleanup(fsl_chan);
1059}
1060
1061static irqreturn_t fsldma_ctrl_irq(int irq, void *data)
1052{ 1062{
1053 struct fsldma_device *fdev = data; 1063 struct fsldma_device *fdev = data;
1054 int ch_nr; 1064 struct fsldma_chan *chan;
1055 u32 gsr; 1065 unsigned int handled = 0;
1066 u32 gsr, mask;
1067 int i;
1056 1068
1057 gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->regs) 1069 gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->regs)
1058 : in_le32(fdev->regs); 1070 : in_le32(fdev->regs);
1059 ch_nr = (32 - ffs(gsr)) / 8; 1071 mask = 0xff000000;
1072 dev_dbg(fdev->dev, "IRQ: gsr 0x%.8x\n", gsr);
1060 1073
1061 return fdev->chan[ch_nr] ? fsldma_chan_irq(irq, 1074 for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
1062 fdev->chan[ch_nr]) : IRQ_NONE; 1075 chan = fdev->chan[i];
1076 if (!chan)
1077 continue;
1078
1079 if (gsr & mask) {
1080 dev_dbg(fdev->dev, "IRQ: chan %d\n", chan->id);
1081 fsldma_chan_irq(irq, chan);
1082 handled++;
1083 }
1084
1085 gsr &= ~mask;
1086 mask >>= 8;
1087 }
1088
1089 return IRQ_RETVAL(handled);
1063} 1090}
1064 1091
1065static void dma_do_tasklet(unsigned long data) 1092static void fsldma_free_irqs(struct fsldma_device *fdev)
1066{ 1093{
1067 struct fsldma_chan *fsl_chan = (struct fsldma_chan *)data; 1094 struct fsldma_chan *chan;
1068 fsl_chan_ld_cleanup(fsl_chan); 1095 int i;
1096
1097 if (fdev->irq != NO_IRQ) {
1098 dev_dbg(fdev->dev, "free per-controller IRQ\n");
1099 free_irq(fdev->irq, fdev);
1100 return;
1101 }
1102
1103 for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
1104 chan = fdev->chan[i];
1105 if (chan && chan->irq != NO_IRQ) {
1106 dev_dbg(fdev->dev, "free channel %d IRQ\n", chan->id);
1107 free_irq(chan->irq, chan);
1108 }
1109 }
1110}
1111
1112static int fsldma_request_irqs(struct fsldma_device *fdev)
1113{
1114 struct fsldma_chan *chan;
1115 int ret;
1116 int i;
1117
1118 /* if we have a per-controller IRQ, use that */
1119 if (fdev->irq != NO_IRQ) {
1120 dev_dbg(fdev->dev, "request per-controller IRQ\n");
1121 ret = request_irq(fdev->irq, fsldma_ctrl_irq, IRQF_SHARED,
1122 "fsldma-controller", fdev);
1123 return ret;
1124 }
1125
1126 /* no per-controller IRQ, use the per-channel IRQs */
1127 for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
1128 chan = fdev->chan[i];
1129 if (!chan)
1130 continue;
1131
1132 if (chan->irq == NO_IRQ) {
1133 dev_err(fdev->dev, "no interrupts property defined for "
1134 "DMA channel %d. Please fix your "
1135 "device tree\n", chan->id);
1136 ret = -ENODEV;
1137 goto out_unwind;
1138 }
1139
1140 dev_dbg(fdev->dev, "request channel %d IRQ\n", chan->id);
1141 ret = request_irq(chan->irq, fsldma_chan_irq, IRQF_SHARED,
1142 "fsldma-chan", chan);
1143 if (ret) {
1144 dev_err(fdev->dev, "unable to request IRQ for DMA "
1145 "channel %d\n", chan->id);
1146 goto out_unwind;
1147 }
1148 }
1149
1150 return 0;
1151
1152out_unwind:
1153 for (/* none */; i >= 0; i--) {
1154 chan = fdev->chan[i];
1155 if (!chan)
1156 continue;
1157
1158 if (chan->irq == NO_IRQ)
1159 continue;
1160
1161 free_irq(chan->irq, chan);
1162 }
1163
1164 return ret;
1069} 1165}
1070 1166
1071/*----------------------------------------------------------------------------*/ 1167/*----------------------------------------------------------------------------*/
@@ -1143,29 +1239,18 @@ static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev,
1143 1239
1144 fchan->common.device = &fdev->common; 1240 fchan->common.device = &fdev->common;
1145 1241
1242 /* find the IRQ line, if it exists in the device tree */
1243 fchan->irq = irq_of_parse_and_map(node, 0);
1244
1146 /* Add the channel to DMA device channel list */ 1245 /* Add the channel to DMA device channel list */
1147 list_add_tail(&fchan->common.device_node, &fdev->common.channels); 1246 list_add_tail(&fchan->common.device_node, &fdev->common.channels);
1148 fdev->common.chancnt++; 1247 fdev->common.chancnt++;
1149 1248
1150 fchan->irq = irq_of_parse_and_map(node, 0);
1151 if (fchan->irq != NO_IRQ) {
1152 err = request_irq(fchan->irq, &fsldma_chan_irq,
1153 IRQF_SHARED, "fsldma-channel", fchan);
1154 if (err) {
1155 dev_err(fdev->dev, "unable to request IRQ "
1156 "for channel %d\n", fchan->id);
1157 goto out_list_del;
1158 }
1159 }
1160
1161 dev_info(fdev->dev, "#%d (%s), irq %d\n", fchan->id, compatible, 1249 dev_info(fdev->dev, "#%d (%s), irq %d\n", fchan->id, compatible,
1162 fchan->irq != NO_IRQ ? fchan->irq : fdev->irq); 1250 fchan->irq != NO_IRQ ? fchan->irq : fdev->irq);
1163 1251
1164 return 0; 1252 return 0;
1165 1253
1166out_list_del:
1167 irq_dispose_mapping(fchan->irq);
1168 list_del_init(&fchan->common.device_node);
1169out_iounmap_regs: 1254out_iounmap_regs:
1170 iounmap(fchan->regs); 1255 iounmap(fchan->regs);
1171out_free_fchan: 1256out_free_fchan:
@@ -1176,11 +1261,7 @@ out_return:
1176 1261
1177static void fsl_dma_chan_remove(struct fsldma_chan *fchan) 1262static void fsl_dma_chan_remove(struct fsldma_chan *fchan)
1178{ 1263{
1179 if (fchan->irq != NO_IRQ) { 1264 irq_dispose_mapping(fchan->irq);
1180 free_irq(fchan->irq, fchan);
1181 irq_dispose_mapping(fchan->irq);
1182 }
1183
1184 list_del(&fchan->common.device_node); 1265 list_del(&fchan->common.device_node);
1185 iounmap(fchan->regs); 1266 iounmap(fchan->regs);
1186 kfree(fchan); 1267 kfree(fchan);
@@ -1211,6 +1292,9 @@ static int __devinit fsldma_of_probe(struct of_device *op,
1211 goto out_free_fdev; 1292 goto out_free_fdev;
1212 } 1293 }
1213 1294
1295 /* map the channel IRQ if it exists, but don't hookup the handler yet */
1296 fdev->irq = irq_of_parse_and_map(op->node, 0);
1297
1214 dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); 1298 dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
1215 dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); 1299 dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
1216 dma_cap_set(DMA_SLAVE, fdev->common.cap_mask); 1300 dma_cap_set(DMA_SLAVE, fdev->common.cap_mask);
@@ -1224,16 +1308,6 @@ static int __devinit fsldma_of_probe(struct of_device *op,
1224 fdev->common.device_terminate_all = fsl_dma_device_terminate_all; 1308 fdev->common.device_terminate_all = fsl_dma_device_terminate_all;
1225 fdev->common.dev = &op->dev; 1309 fdev->common.dev = &op->dev;
1226 1310
1227 fdev->irq = irq_of_parse_and_map(op->node, 0);
1228 if (fdev->irq != NO_IRQ) {
1229 err = request_irq(fdev->irq, &fsldma_irq, IRQF_SHARED,
1230 "fsldma-device", fdev);
1231 if (err) {
1232 dev_err(&op->dev, "unable to request IRQ\n");
1233 goto out_iounmap_regs;
1234 }
1235 }
1236
1237 dev_set_drvdata(&op->dev, fdev); 1311 dev_set_drvdata(&op->dev, fdev);
1238 1312
1239 /* 1313 /*
@@ -1255,12 +1329,24 @@ static int __devinit fsldma_of_probe(struct of_device *op,
1255 } 1329 }
1256 } 1330 }
1257 1331
1332 /*
1333 * Hookup the IRQ handler(s)
1334 *
1335 * If we have a per-controller interrupt, we prefer that to the
1336 * per-channel interrupts to reduce the number of shared interrupt
1337 * handlers on the same IRQ line
1338 */
1339 err = fsldma_request_irqs(fdev);
1340 if (err) {
1341 dev_err(fdev->dev, "unable to request IRQs\n");
1342 goto out_free_fdev;
1343 }
1344
1258 dma_async_device_register(&fdev->common); 1345 dma_async_device_register(&fdev->common);
1259 return 0; 1346 return 0;
1260 1347
1261out_iounmap_regs:
1262 iounmap(fdev->regs);
1263out_free_fdev: 1348out_free_fdev:
1349 irq_dispose_mapping(fdev->irq);
1264 kfree(fdev); 1350 kfree(fdev);
1265out_return: 1351out_return:
1266 return err; 1352 return err;
@@ -1274,14 +1360,13 @@ static int fsldma_of_remove(struct of_device *op)
1274 fdev = dev_get_drvdata(&op->dev); 1360 fdev = dev_get_drvdata(&op->dev);
1275 dma_async_device_unregister(&fdev->common); 1361 dma_async_device_unregister(&fdev->common);
1276 1362
1363 fsldma_free_irqs(fdev);
1364
1277 for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) { 1365 for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
1278 if (fdev->chan[i]) 1366 if (fdev->chan[i])
1279 fsl_dma_chan_remove(fdev->chan[i]); 1367 fsl_dma_chan_remove(fdev->chan[i]);
1280 } 1368 }
1281 1369
1282 if (fdev->irq != NO_IRQ)
1283 free_irq(fdev->irq, fdev);
1284
1285 iounmap(fdev->regs); 1370 iounmap(fdev->regs);
1286 dev_set_drvdata(&op->dev, NULL); 1371 dev_set_drvdata(&op->dev, NULL);
1287 kfree(fdev); 1372 kfree(fdev);