diff options
| -rw-r--r-- | drivers/dma/fsldma.c | 259 | ||||
| -rw-r--r-- | drivers/dma/fsldma.h | 4 |
2 files changed, 134 insertions, 129 deletions
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index c2db7541c22b..507b29716bbd 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | static void dma_init(struct fsldma_chan *fsl_chan) | 40 | static void dma_init(struct fsldma_chan *fsl_chan) |
| 41 | { | 41 | { |
| 42 | /* Reset the channel */ | 42 | /* Reset the channel */ |
| 43 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, 0, 32); | 43 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, 0, 32); |
| 44 | 44 | ||
| 45 | switch (fsl_chan->feature & FSL_DMA_IP_MASK) { | 45 | switch (fsl_chan->feature & FSL_DMA_IP_MASK) { |
| 46 | case FSL_DMA_IP_85XX: | 46 | case FSL_DMA_IP_85XX: |
| @@ -49,7 +49,7 @@ static void dma_init(struct fsldma_chan *fsl_chan) | |||
| 49 | * EOSIE - End of segments interrupt enable (basic mode) | 49 | * EOSIE - End of segments interrupt enable (basic mode) |
| 50 | * EOLNIE - End of links interrupt enable | 50 | * EOLNIE - End of links interrupt enable |
| 51 | */ | 51 | */ |
| 52 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EIE | 52 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, FSL_DMA_MR_EIE |
| 53 | | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); | 53 | | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); |
| 54 | break; | 54 | break; |
| 55 | case FSL_DMA_IP_83XX: | 55 | case FSL_DMA_IP_83XX: |
| @@ -57,7 +57,7 @@ static void dma_init(struct fsldma_chan *fsl_chan) | |||
| 57 | * EOTIE - End-of-transfer interrupt enable | 57 | * EOTIE - End-of-transfer interrupt enable |
| 58 | * PRC_RM - PCI read multiple | 58 | * PRC_RM - PCI read multiple |
| 59 | */ | 59 | */ |
| 60 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, FSL_DMA_MR_EOTIE | 60 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, FSL_DMA_MR_EOTIE |
| 61 | | FSL_DMA_MR_PRC_RM, 32); | 61 | | FSL_DMA_MR_PRC_RM, 32); |
| 62 | break; | 62 | break; |
| 63 | } | 63 | } |
| @@ -66,12 +66,12 @@ static void dma_init(struct fsldma_chan *fsl_chan) | |||
| 66 | 66 | ||
| 67 | static void set_sr(struct fsldma_chan *fsl_chan, u32 val) | 67 | static void set_sr(struct fsldma_chan *fsl_chan, u32 val) |
| 68 | { | 68 | { |
| 69 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->sr, val, 32); | 69 | DMA_OUT(fsl_chan, &fsl_chan->regs->sr, val, 32); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | static u32 get_sr(struct fsldma_chan *fsl_chan) | 72 | static u32 get_sr(struct fsldma_chan *fsl_chan) |
| 73 | { | 73 | { |
| 74 | return DMA_IN(fsl_chan, &fsl_chan->reg_base->sr, 32); | 74 | return DMA_IN(fsl_chan, &fsl_chan->regs->sr, 32); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static void set_desc_cnt(struct fsldma_chan *fsl_chan, | 77 | static void set_desc_cnt(struct fsldma_chan *fsl_chan, |
| @@ -112,27 +112,27 @@ static void set_desc_next(struct fsldma_chan *fsl_chan, | |||
| 112 | 112 | ||
| 113 | static void set_cdar(struct fsldma_chan *fsl_chan, dma_addr_t addr) | 113 | static void set_cdar(struct fsldma_chan *fsl_chan, dma_addr_t addr) |
| 114 | { | 114 | { |
| 115 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->cdar, addr | FSL_DMA_SNEN, 64); | 115 | DMA_OUT(fsl_chan, &fsl_chan->regs->cdar, addr | FSL_DMA_SNEN, 64); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static dma_addr_t get_cdar(struct fsldma_chan *fsl_chan) | 118 | static dma_addr_t get_cdar(struct fsldma_chan *fsl_chan) |
| 119 | { | 119 | { |
| 120 | return DMA_IN(fsl_chan, &fsl_chan->reg_base->cdar, 64) & ~FSL_DMA_SNEN; | 120 | return DMA_IN(fsl_chan, &fsl_chan->regs->cdar, 64) & ~FSL_DMA_SNEN; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void set_ndar(struct fsldma_chan *fsl_chan, dma_addr_t addr) | 123 | static void set_ndar(struct fsldma_chan *fsl_chan, dma_addr_t addr) |
| 124 | { | 124 | { |
| 125 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->ndar, addr, 64); | 125 | DMA_OUT(fsl_chan, &fsl_chan->regs->ndar, addr, 64); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static dma_addr_t get_ndar(struct fsldma_chan *fsl_chan) | 128 | static dma_addr_t get_ndar(struct fsldma_chan *fsl_chan) |
| 129 | { | 129 | { |
| 130 | return DMA_IN(fsl_chan, &fsl_chan->reg_base->ndar, 64); | 130 | return DMA_IN(fsl_chan, &fsl_chan->regs->ndar, 64); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | static u32 get_bcr(struct fsldma_chan *fsl_chan) | 133 | static u32 get_bcr(struct fsldma_chan *fsl_chan) |
| 134 | { | 134 | { |
| 135 | return DMA_IN(fsl_chan, &fsl_chan->reg_base->bcr, 32); | 135 | return DMA_IN(fsl_chan, &fsl_chan->regs->bcr, 32); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int dma_is_idle(struct fsldma_chan *fsl_chan) | 138 | static int dma_is_idle(struct fsldma_chan *fsl_chan) |
| @@ -145,11 +145,11 @@ static void dma_start(struct fsldma_chan *fsl_chan) | |||
| 145 | { | 145 | { |
| 146 | u32 mode; | 146 | u32 mode; |
| 147 | 147 | ||
| 148 | mode = DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32); | 148 | mode = DMA_IN(fsl_chan, &fsl_chan->regs->mr, 32); |
| 149 | 149 | ||
| 150 | if ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) { | 150 | if ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) { |
| 151 | if (fsl_chan->feature & FSL_DMA_CHAN_PAUSE_EXT) { | 151 | if (fsl_chan->feature & FSL_DMA_CHAN_PAUSE_EXT) { |
| 152 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->bcr, 0, 32); | 152 | DMA_OUT(fsl_chan, &fsl_chan->regs->bcr, 0, 32); |
| 153 | mode |= FSL_DMA_MR_EMP_EN; | 153 | mode |= FSL_DMA_MR_EMP_EN; |
| 154 | } else { | 154 | } else { |
| 155 | mode &= ~FSL_DMA_MR_EMP_EN; | 155 | mode &= ~FSL_DMA_MR_EMP_EN; |
| @@ -161,7 +161,7 @@ static void dma_start(struct fsldma_chan *fsl_chan) | |||
| 161 | else | 161 | else |
| 162 | mode |= FSL_DMA_MR_CS; | 162 | mode |= FSL_DMA_MR_CS; |
| 163 | 163 | ||
| 164 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, mode, 32); | 164 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, mode, 32); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | static void dma_halt(struct fsldma_chan *fsl_chan) | 167 | static void dma_halt(struct fsldma_chan *fsl_chan) |
| @@ -169,12 +169,12 @@ static void dma_halt(struct fsldma_chan *fsl_chan) | |||
| 169 | u32 mode; | 169 | u32 mode; |
| 170 | int i; | 170 | int i; |
| 171 | 171 | ||
| 172 | mode = DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32); | 172 | mode = DMA_IN(fsl_chan, &fsl_chan->regs->mr, 32); |
| 173 | mode |= FSL_DMA_MR_CA; | 173 | mode |= FSL_DMA_MR_CA; |
| 174 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, mode, 32); | 174 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, mode, 32); |
| 175 | 175 | ||
| 176 | mode &= ~(FSL_DMA_MR_CS | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA); | 176 | mode &= ~(FSL_DMA_MR_CS | FSL_DMA_MR_EMS_EN | FSL_DMA_MR_CA); |
| 177 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, mode, 32); | 177 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, mode, 32); |
| 178 | 178 | ||
| 179 | for (i = 0; i < 100; i++) { | 179 | for (i = 0; i < 100; i++) { |
| 180 | if (dma_is_idle(fsl_chan)) | 180 | if (dma_is_idle(fsl_chan)) |
| @@ -235,7 +235,7 @@ static void fsl_chan_set_src_loop_size(struct fsldma_chan *fsl_chan, int size) | |||
| 235 | { | 235 | { |
| 236 | u32 mode; | 236 | u32 mode; |
| 237 | 237 | ||
| 238 | mode = DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32); | 238 | mode = DMA_IN(fsl_chan, &fsl_chan->regs->mr, 32); |
| 239 | 239 | ||
| 240 | switch (size) { | 240 | switch (size) { |
| 241 | case 0: | 241 | case 0: |
| @@ -249,7 +249,7 @@ static void fsl_chan_set_src_loop_size(struct fsldma_chan *fsl_chan, int size) | |||
| 249 | break; | 249 | break; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, mode, 32); | 252 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, mode, 32); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | /** | 255 | /** |
| @@ -267,7 +267,7 @@ static void fsl_chan_set_dst_loop_size(struct fsldma_chan *fsl_chan, int size) | |||
| 267 | { | 267 | { |
| 268 | u32 mode; | 268 | u32 mode; |
| 269 | 269 | ||
| 270 | mode = DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32); | 270 | mode = DMA_IN(fsl_chan, &fsl_chan->regs->mr, 32); |
| 271 | 271 | ||
| 272 | switch (size) { | 272 | switch (size) { |
| 273 | case 0: | 273 | case 0: |
| @@ -281,7 +281,7 @@ static void fsl_chan_set_dst_loop_size(struct fsldma_chan *fsl_chan, int size) | |||
| 281 | break; | 281 | break; |
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, mode, 32); | 284 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, mode, 32); |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | /** | 287 | /** |
| @@ -302,10 +302,10 @@ static void fsl_chan_set_request_count(struct fsldma_chan *fsl_chan, int size) | |||
| 302 | 302 | ||
| 303 | BUG_ON(size > 1024); | 303 | BUG_ON(size > 1024); |
| 304 | 304 | ||
| 305 | mode = DMA_IN(fsl_chan, &fsl_chan->reg_base->mr, 32); | 305 | mode = DMA_IN(fsl_chan, &fsl_chan->regs->mr, 32); |
| 306 | mode |= (__ilog2(size) << 24) & 0x0f000000; | 306 | mode |= (__ilog2(size) << 24) & 0x0f000000; |
| 307 | 307 | ||
| 308 | DMA_OUT(fsl_chan, &fsl_chan->reg_base->mr, mode, 32); | 308 | DMA_OUT(fsl_chan, &fsl_chan->regs->mr, mode, 32); |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | /** | 311 | /** |
| @@ -967,7 +967,7 @@ 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 | static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) | 970 | static irqreturn_t fsldma_chan_irq(int irq, void *data) |
| 971 | { | 971 | { |
| 972 | struct fsldma_chan *fsl_chan = data; | 972 | struct fsldma_chan *fsl_chan = data; |
| 973 | u32 stat; | 973 | u32 stat; |
| @@ -1048,17 +1048,17 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) | |||
| 1048 | return IRQ_HANDLED; | 1048 | return IRQ_HANDLED; |
| 1049 | } | 1049 | } |
| 1050 | 1050 | ||
| 1051 | static irqreturn_t fsl_dma_do_interrupt(int irq, void *data) | 1051 | static irqreturn_t fsldma_irq(int irq, void *data) |
| 1052 | { | 1052 | { |
| 1053 | struct fsldma_device *fdev = data; | 1053 | struct fsldma_device *fdev = data; |
| 1054 | int ch_nr; | 1054 | int ch_nr; |
| 1055 | u32 gsr; | 1055 | u32 gsr; |
| 1056 | 1056 | ||
| 1057 | gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->reg_base) | 1057 | gsr = (fdev->feature & FSL_DMA_BIG_ENDIAN) ? in_be32(fdev->regs) |
| 1058 | : in_le32(fdev->reg_base); | 1058 | : in_le32(fdev->regs); |
| 1059 | ch_nr = (32 - ffs(gsr)) / 8; | 1059 | ch_nr = (32 - ffs(gsr)) / 8; |
| 1060 | 1060 | ||
| 1061 | return fdev->chan[ch_nr] ? fsl_dma_chan_do_interrupt(irq, | 1061 | return fdev->chan[ch_nr] ? fsldma_chan_irq(irq, |
| 1062 | fdev->chan[ch_nr]) : IRQ_NONE; | 1062 | fdev->chan[ch_nr]) : IRQ_NONE; |
| 1063 | } | 1063 | } |
| 1064 | 1064 | ||
| @@ -1075,140 +1075,142 @@ static void dma_do_tasklet(unsigned long data) | |||
| 1075 | static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev, | 1075 | static int __devinit fsl_dma_chan_probe(struct fsldma_device *fdev, |
| 1076 | struct device_node *node, u32 feature, const char *compatible) | 1076 | struct device_node *node, u32 feature, const char *compatible) |
| 1077 | { | 1077 | { |
| 1078 | struct fsldma_chan *new_fsl_chan; | 1078 | struct fsldma_chan *fchan; |
| 1079 | struct resource res; | 1079 | struct resource res; |
| 1080 | int err; | 1080 | int err; |
| 1081 | 1081 | ||
| 1082 | /* alloc channel */ | 1082 | /* alloc channel */ |
| 1083 | new_fsl_chan = kzalloc(sizeof(*new_fsl_chan), GFP_KERNEL); | 1083 | fchan = kzalloc(sizeof(*fchan), GFP_KERNEL); |
| 1084 | if (!new_fsl_chan) { | 1084 | if (!fchan) { |
| 1085 | dev_err(fdev->dev, "No free memory for allocating " | 1085 | dev_err(fdev->dev, "no free memory for DMA channels!\n"); |
| 1086 | "dma channels!\n"); | 1086 | err = -ENOMEM; |
| 1087 | return -ENOMEM; | 1087 | goto out_return; |
| 1088 | } | ||
| 1089 | |||
| 1090 | /* ioremap registers for use */ | ||
| 1091 | fchan->regs = of_iomap(node, 0); | ||
| 1092 | if (!fchan->regs) { | ||
| 1093 | dev_err(fdev->dev, "unable to ioremap registers\n"); | ||
| 1094 | err = -ENOMEM; | ||
| 1095 | goto out_free_fchan; | ||
| 1088 | } | 1096 | } |
| 1089 | 1097 | ||
| 1090 | /* get dma channel register base */ | ||
| 1091 | err = of_address_to_resource(node, 0, &res); | 1098 | err = of_address_to_resource(node, 0, &res); |
| 1092 | if (err) { | 1099 | if (err) { |
| 1093 | dev_err(fdev->dev, "Can't get %s property 'reg'\n", | 1100 | dev_err(fdev->dev, "unable to find 'reg' property\n"); |
| 1094 | node->full_name); | 1101 | goto out_iounmap_regs; |
| 1095 | goto err_no_reg; | ||
| 1096 | } | 1102 | } |
| 1097 | 1103 | ||
| 1098 | new_fsl_chan->feature = feature; | 1104 | fchan->feature = feature; |
| 1099 | |||
| 1100 | if (!fdev->feature) | 1105 | if (!fdev->feature) |
| 1101 | fdev->feature = new_fsl_chan->feature; | 1106 | fdev->feature = fchan->feature; |
| 1102 | 1107 | ||
| 1103 | /* If the DMA device's feature is different than its channels', | 1108 | /* |
| 1104 | * report the bug. | 1109 | * If the DMA device's feature is different than the feature |
| 1110 | * of its channels, report the bug | ||
| 1105 | */ | 1111 | */ |
| 1106 | WARN_ON(fdev->feature != new_fsl_chan->feature); | 1112 | WARN_ON(fdev->feature != fchan->feature); |
| 1107 | 1113 | ||
| 1108 | new_fsl_chan->dev = fdev->dev; | 1114 | fchan->dev = fdev->dev; |
| 1109 | new_fsl_chan->reg_base = ioremap(res.start, resource_size(&res)); | 1115 | fchan->id = ((res.start - 0x100) & 0xfff) >> 7; |
| 1110 | new_fsl_chan->id = ((res.start - 0x100) & 0xfff) >> 7; | 1116 | if (fchan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) { |
| 1111 | if (new_fsl_chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) { | 1117 | dev_err(fdev->dev, "too many channels for device\n"); |
| 1112 | dev_err(fdev->dev, "There is no %d channel!\n", | ||
| 1113 | new_fsl_chan->id); | ||
| 1114 | err = -EINVAL; | 1118 | err = -EINVAL; |
| 1115 | goto err_no_chan; | 1119 | goto out_iounmap_regs; |
| 1116 | } | 1120 | } |
| 1117 | fdev->chan[new_fsl_chan->id] = new_fsl_chan; | ||
| 1118 | tasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet, | ||
| 1119 | (unsigned long)new_fsl_chan); | ||
| 1120 | 1121 | ||
| 1121 | /* Init the channel */ | 1122 | fdev->chan[fchan->id] = fchan; |
| 1122 | dma_init(new_fsl_chan); | 1123 | tasklet_init(&fchan->tasklet, dma_do_tasklet, (unsigned long)fchan); |
| 1124 | |||
| 1125 | /* Initialize the channel */ | ||
| 1126 | dma_init(fchan); | ||
| 1123 | 1127 | ||
| 1124 | /* Clear cdar registers */ | 1128 | /* Clear cdar registers */ |
| 1125 | set_cdar(new_fsl_chan, 0); | 1129 | set_cdar(fchan, 0); |
| 1126 | 1130 | ||
| 1127 | switch (new_fsl_chan->feature & FSL_DMA_IP_MASK) { | 1131 | switch (fchan->feature & FSL_DMA_IP_MASK) { |
| 1128 | case FSL_DMA_IP_85XX: | 1132 | case FSL_DMA_IP_85XX: |
| 1129 | new_fsl_chan->toggle_ext_pause = fsl_chan_toggle_ext_pause; | 1133 | fchan->toggle_ext_pause = fsl_chan_toggle_ext_pause; |
| 1130 | case FSL_DMA_IP_83XX: | 1134 | case FSL_DMA_IP_83XX: |
| 1131 | new_fsl_chan->toggle_ext_start = fsl_chan_toggle_ext_start; | 1135 | fchan->toggle_ext_start = fsl_chan_toggle_ext_start; |
| 1132 | new_fsl_chan->set_src_loop_size = fsl_chan_set_src_loop_size; | 1136 | fchan->set_src_loop_size = fsl_chan_set_src_loop_size; |
| 1133 | new_fsl_chan->set_dst_loop_size = fsl_chan_set_dst_loop_size; | 1137 | fchan->set_dst_loop_size = fsl_chan_set_dst_loop_size; |
| 1134 | new_fsl_chan->set_request_count = fsl_chan_set_request_count; | 1138 | fchan->set_request_count = fsl_chan_set_request_count; |
| 1135 | } | 1139 | } |
| 1136 | 1140 | ||
| 1137 | spin_lock_init(&new_fsl_chan->desc_lock); | 1141 | spin_lock_init(&fchan->desc_lock); |
| 1138 | INIT_LIST_HEAD(&new_fsl_chan->ld_queue); | 1142 | INIT_LIST_HEAD(&fchan->ld_queue); |
| 1139 | 1143 | ||
| 1140 | new_fsl_chan->common.device = &fdev->common; | 1144 | fchan->common.device = &fdev->common; |
| 1141 | 1145 | ||
| 1142 | /* Add the channel to DMA device channel list */ | 1146 | /* Add the channel to DMA device channel list */ |
| 1143 | list_add_tail(&new_fsl_chan->common.device_node, | 1147 | list_add_tail(&fchan->common.device_node, &fdev->common.channels); |
| 1144 | &fdev->common.channels); | ||
| 1145 | fdev->common.chancnt++; | 1148 | fdev->common.chancnt++; |
| 1146 | 1149 | ||
| 1147 | new_fsl_chan->irq = irq_of_parse_and_map(node, 0); | 1150 | fchan->irq = irq_of_parse_and_map(node, 0); |
| 1148 | if (new_fsl_chan->irq != NO_IRQ) { | 1151 | if (fchan->irq != NO_IRQ) { |
| 1149 | err = request_irq(new_fsl_chan->irq, | 1152 | err = request_irq(fchan->irq, &fsldma_chan_irq, |
| 1150 | &fsl_dma_chan_do_interrupt, IRQF_SHARED, | 1153 | IRQF_SHARED, "fsldma-channel", fchan); |
| 1151 | "fsldma-channel", new_fsl_chan); | ||
| 1152 | if (err) { | 1154 | if (err) { |
| 1153 | dev_err(fdev->dev, "DMA channel %s request_irq error " | 1155 | dev_err(fdev->dev, "unable to request IRQ " |
| 1154 | "with return %d\n", node->full_name, err); | 1156 | "for channel %d\n", fchan->id); |
| 1155 | goto err_no_irq; | 1157 | goto out_list_del; |
| 1156 | } | 1158 | } |
| 1157 | } | 1159 | } |
| 1158 | 1160 | ||
| 1159 | dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, | 1161 | dev_info(fdev->dev, "#%d (%s), irq %d\n", fchan->id, compatible, |
| 1160 | compatible, | 1162 | fchan->irq != NO_IRQ ? fchan->irq : fdev->irq); |
| 1161 | new_fsl_chan->irq != NO_IRQ ? new_fsl_chan->irq : fdev->irq); | ||
| 1162 | 1163 | ||
| 1163 | return 0; | 1164 | return 0; |
| 1164 | 1165 | ||
| 1165 | err_no_irq: | 1166 | out_list_del: |
| 1166 | list_del(&new_fsl_chan->common.device_node); | 1167 | irq_dispose_mapping(fchan->irq); |
| 1167 | err_no_chan: | 1168 | list_del_init(&fchan->common.device_node); |
| 1168 | iounmap(new_fsl_chan->reg_base); | 1169 | out_iounmap_regs: |
| 1169 | err_no_reg: | 1170 | iounmap(fchan->regs); |
| 1170 | kfree(new_fsl_chan); | 1171 | out_free_fchan: |
| 1172 | kfree(fchan); | ||
| 1173 | out_return: | ||
| 1171 | return err; | 1174 | return err; |
| 1172 | } | 1175 | } |
| 1173 | 1176 | ||
| 1174 | static void fsl_dma_chan_remove(struct fsldma_chan *fchan) | 1177 | static void fsl_dma_chan_remove(struct fsldma_chan *fchan) |
| 1175 | { | 1178 | { |
| 1176 | if (fchan->irq != NO_IRQ) | 1179 | if (fchan->irq != NO_IRQ) { |
| 1177 | free_irq(fchan->irq, fchan); | 1180 | free_irq(fchan->irq, fchan); |
| 1181 | irq_dispose_mapping(fchan->irq); | ||
| 1182 | } | ||
| 1183 | |||
| 1178 | list_del(&fchan->common.device_node); | 1184 | list_del(&fchan->common.device_node); |
| 1179 | iounmap(fchan->reg_base); | 1185 | iounmap(fchan->regs); |
| 1180 | kfree(fchan); | 1186 | kfree(fchan); |
| 1181 | } | 1187 | } |
| 1182 | 1188 | ||
| 1183 | static int __devinit fsldma_of_probe(struct of_device *dev, | 1189 | static int __devinit fsldma_of_probe(struct of_device *op, |
| 1184 | const struct of_device_id *match) | 1190 | const struct of_device_id *match) |
| 1185 | { | 1191 | { |
| 1186 | int err; | ||
| 1187 | struct fsldma_device *fdev; | 1192 | struct fsldma_device *fdev; |
| 1188 | struct device_node *child; | 1193 | struct device_node *child; |
| 1189 | struct resource res; | 1194 | int err; |
| 1190 | 1195 | ||
| 1191 | fdev = kzalloc(sizeof(*fdev), GFP_KERNEL); | 1196 | fdev = kzalloc(sizeof(*fdev), GFP_KERNEL); |
| 1192 | if (!fdev) { | 1197 | if (!fdev) { |
| 1193 | dev_err(&dev->dev, "No enough memory for 'priv'\n"); | 1198 | dev_err(&op->dev, "No enough memory for 'priv'\n"); |
| 1194 | return -ENOMEM; | 1199 | err = -ENOMEM; |
| 1200 | goto out_return; | ||
| 1195 | } | 1201 | } |
| 1196 | fdev->dev = &dev->dev; | 1202 | |
| 1203 | fdev->dev = &op->dev; | ||
| 1197 | INIT_LIST_HEAD(&fdev->common.channels); | 1204 | INIT_LIST_HEAD(&fdev->common.channels); |
| 1198 | 1205 | ||
| 1199 | /* get DMA controller register base */ | 1206 | /* ioremap the registers for use */ |
| 1200 | err = of_address_to_resource(dev->node, 0, &res); | 1207 | fdev->regs = of_iomap(op->node, 0); |
| 1201 | if (err) { | 1208 | if (!fdev->regs) { |
| 1202 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", | 1209 | dev_err(&op->dev, "unable to ioremap registers\n"); |
| 1203 | dev->node->full_name); | 1210 | err = -ENOMEM; |
| 1204 | goto err_no_reg; | 1211 | goto out_free_fdev; |
| 1205 | } | 1212 | } |
| 1206 | 1213 | ||
| 1207 | dev_info(&dev->dev, "Probe the Freescale DMA driver for %s " | ||
| 1208 | "controller at 0x%llx...\n", | ||
| 1209 | match->compatible, (unsigned long long)res.start); | ||
| 1210 | fdev->reg_base = ioremap(res.start, resource_size(&res)); | ||
| 1211 | |||
| 1212 | dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); | 1214 | dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); |
| 1213 | dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); | 1215 | dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask); |
| 1214 | dma_cap_set(DMA_SLAVE, fdev->common.cap_mask); | 1216 | dma_cap_set(DMA_SLAVE, fdev->common.cap_mask); |
| @@ -1220,66 +1222,69 @@ static int __devinit fsldma_of_probe(struct of_device *dev, | |||
| 1220 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; | 1222 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; |
| 1221 | fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; | 1223 | fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg; |
| 1222 | fdev->common.device_terminate_all = fsl_dma_device_terminate_all; | 1224 | fdev->common.device_terminate_all = fsl_dma_device_terminate_all; |
| 1223 | fdev->common.dev = &dev->dev; | 1225 | fdev->common.dev = &op->dev; |
| 1224 | 1226 | ||
| 1225 | fdev->irq = irq_of_parse_and_map(dev->node, 0); | 1227 | fdev->irq = irq_of_parse_and_map(op->node, 0); |
| 1226 | if (fdev->irq != NO_IRQ) { | 1228 | if (fdev->irq != NO_IRQ) { |
| 1227 | err = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED, | 1229 | err = request_irq(fdev->irq, &fsldma_irq, IRQF_SHARED, |
| 1228 | "fsldma-device", fdev); | 1230 | "fsldma-device", fdev); |
| 1229 | if (err) { | 1231 | if (err) { |
| 1230 | dev_err(&dev->dev, "DMA device request_irq error " | 1232 | dev_err(&op->dev, "unable to request IRQ\n"); |
| 1231 | "with return %d\n", err); | 1233 | goto out_iounmap_regs; |
| 1232 | goto err; | ||
| 1233 | } | 1234 | } |
| 1234 | } | 1235 | } |
| 1235 | 1236 | ||
| 1236 | dev_set_drvdata(&(dev->dev), fdev); | 1237 | dev_set_drvdata(&op->dev, fdev); |
| 1237 | 1238 | ||
| 1238 | /* We cannot use of_platform_bus_probe() because there is no | 1239 | /* |
| 1239 | * of_platform_bus_remove. Instead, we manually instantiate every DMA | 1240 | * We cannot use of_platform_bus_probe() because there is no |
| 1241 | * of_platform_bus_remove(). Instead, we manually instantiate every DMA | ||
| 1240 | * channel object. | 1242 | * channel object. |
| 1241 | */ | 1243 | */ |
| 1242 | for_each_child_of_node(dev->node, child) { | 1244 | for_each_child_of_node(op->node, child) { |
| 1243 | if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) | 1245 | if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) { |
| 1244 | fsl_dma_chan_probe(fdev, child, | 1246 | fsl_dma_chan_probe(fdev, child, |
| 1245 | FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, | 1247 | FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, |
| 1246 | "fsl,eloplus-dma-channel"); | 1248 | "fsl,eloplus-dma-channel"); |
| 1247 | if (of_device_is_compatible(child, "fsl,elo-dma-channel")) | 1249 | } |
| 1250 | |||
| 1251 | if (of_device_is_compatible(child, "fsl,elo-dma-channel")) { | ||
| 1248 | fsl_dma_chan_probe(fdev, child, | 1252 | fsl_dma_chan_probe(fdev, child, |
| 1249 | FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN, | 1253 | FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN, |
| 1250 | "fsl,elo-dma-channel"); | 1254 | "fsl,elo-dma-channel"); |
| 1255 | } | ||
| 1251 | } | 1256 | } |
| 1252 | 1257 | ||
| 1253 | dma_async_device_register(&fdev->common); | 1258 | dma_async_device_register(&fdev->common); |
| 1254 | return 0; | 1259 | return 0; |
| 1255 | 1260 | ||
| 1256 | err: | 1261 | out_iounmap_regs: |
| 1257 | iounmap(fdev->reg_base); | 1262 | iounmap(fdev->regs); |
| 1258 | err_no_reg: | 1263 | out_free_fdev: |
| 1259 | kfree(fdev); | 1264 | kfree(fdev); |
| 1265 | out_return: | ||
| 1260 | return err; | 1266 | return err; |
| 1261 | } | 1267 | } |
| 1262 | 1268 | ||
| 1263 | static int fsldma_of_remove(struct of_device *of_dev) | 1269 | static int fsldma_of_remove(struct of_device *op) |
| 1264 | { | 1270 | { |
| 1265 | struct fsldma_device *fdev; | 1271 | struct fsldma_device *fdev; |
| 1266 | unsigned int i; | 1272 | unsigned int i; |
| 1267 | 1273 | ||
| 1268 | fdev = dev_get_drvdata(&of_dev->dev); | 1274 | fdev = dev_get_drvdata(&op->dev); |
| 1269 | |||
| 1270 | dma_async_device_unregister(&fdev->common); | 1275 | dma_async_device_unregister(&fdev->common); |
| 1271 | 1276 | ||
| 1272 | for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) | 1277 | for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) { |
| 1273 | if (fdev->chan[i]) | 1278 | if (fdev->chan[i]) |
| 1274 | fsl_dma_chan_remove(fdev->chan[i]); | 1279 | fsl_dma_chan_remove(fdev->chan[i]); |
| 1280 | } | ||
| 1275 | 1281 | ||
| 1276 | if (fdev->irq != NO_IRQ) | 1282 | if (fdev->irq != NO_IRQ) |
| 1277 | free_irq(fdev->irq, fdev); | 1283 | free_irq(fdev->irq, fdev); |
| 1278 | 1284 | ||
| 1279 | iounmap(fdev->reg_base); | 1285 | iounmap(fdev->regs); |
| 1280 | 1286 | dev_set_drvdata(&op->dev, NULL); | |
| 1281 | kfree(fdev); | 1287 | kfree(fdev); |
| 1282 | dev_set_drvdata(&of_dev->dev, NULL); | ||
| 1283 | 1288 | ||
| 1284 | return 0; | 1289 | return 0; |
| 1285 | } | 1290 | } |
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index a67b8e3df0fa..ea3b19c8708c 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
| @@ -108,7 +108,7 @@ struct fsldma_chan; | |||
| 108 | #define FSL_DMA_MAX_CHANS_PER_DEVICE 4 | 108 | #define FSL_DMA_MAX_CHANS_PER_DEVICE 4 |
| 109 | 109 | ||
| 110 | struct fsldma_device { | 110 | struct fsldma_device { |
| 111 | void __iomem *reg_base; /* DGSR register base */ | 111 | void __iomem *regs; /* DGSR register base */ |
| 112 | struct device *dev; | 112 | struct device *dev; |
| 113 | struct dma_device common; | 113 | struct dma_device common; |
| 114 | struct fsldma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; | 114 | struct fsldma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; |
| @@ -128,7 +128,7 @@ struct fsldma_device { | |||
| 128 | #define FSL_DMA_CHAN_START_EXT 0x00002000 | 128 | #define FSL_DMA_CHAN_START_EXT 0x00002000 |
| 129 | 129 | ||
| 130 | struct fsldma_chan { | 130 | struct fsldma_chan { |
| 131 | struct fsldma_chan_regs __iomem *reg_base; | 131 | struct fsldma_chan_regs __iomem *regs; |
| 132 | dma_cookie_t completed_cookie; /* The maximum cookie completed */ | 132 | dma_cookie_t completed_cookie; /* The maximum cookie completed */ |
| 133 | spinlock_t desc_lock; /* Descriptor operation lock */ | 133 | spinlock_t desc_lock; /* Descriptor operation lock */ |
| 134 | struct list_head ld_queue; /* Link descriptors queue */ | 134 | struct list_head ld_queue; /* Link descriptors queue */ |
