diff options
author | Markus Pargmann <mpa@pengutronix.de> | 2013-05-26 05:53:20 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-07-05 02:10:26 -0400 |
commit | 290ad0f9d954b445788bf26652b239c59cec2060 (patch) | |
tree | bee92be4769a1f84d599e2e97cd3cc6e25f2caa9 /drivers/dma | |
parent | 8552bb4f16800d5ebc176a2cf5f2aa55b22731ea (diff) |
dma: imx-dma: Add oftree support
Adding devicetree support for imx-dma driver. Use driver name for
function 'imx_dma_is_general_purpose' because the devicename for
devicetree initialized devices is different.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/imx-dma.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f28583370d00..34c54cf08231 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/dmaengine.h> | 28 | #include <linux/dmaengine.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/of_device.h> | ||
31 | #include <linux/of_dma.h> | ||
30 | 32 | ||
31 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
32 | #include <linux/platform_data/dma-imx.h> | 34 | #include <linux/platform_data/dma-imx.h> |
@@ -186,6 +188,11 @@ struct imxdma_engine { | |||
186 | enum imx_dma_type devtype; | 188 | enum imx_dma_type devtype; |
187 | }; | 189 | }; |
188 | 190 | ||
191 | struct imxdma_filter_data { | ||
192 | struct imxdma_engine *imxdma; | ||
193 | int request; | ||
194 | }; | ||
195 | |||
189 | static struct platform_device_id imx_dma_devtype[] = { | 196 | static struct platform_device_id imx_dma_devtype[] = { |
190 | { | 197 | { |
191 | .name = "imx1-dma", | 198 | .name = "imx1-dma", |
@@ -202,6 +209,22 @@ static struct platform_device_id imx_dma_devtype[] = { | |||
202 | }; | 209 | }; |
203 | MODULE_DEVICE_TABLE(platform, imx_dma_devtype); | 210 | MODULE_DEVICE_TABLE(platform, imx_dma_devtype); |
204 | 211 | ||
212 | static const struct of_device_id imx_dma_of_dev_id[] = { | ||
213 | { | ||
214 | .compatible = "fsl,imx1-dma", | ||
215 | .data = &imx_dma_devtype[IMX1_DMA], | ||
216 | }, { | ||
217 | .compatible = "fsl,imx21-dma", | ||
218 | .data = &imx_dma_devtype[IMX21_DMA], | ||
219 | }, { | ||
220 | .compatible = "fsl,imx27-dma", | ||
221 | .data = &imx_dma_devtype[IMX27_DMA], | ||
222 | }, { | ||
223 | /* sentinel */ | ||
224 | } | ||
225 | }; | ||
226 | MODULE_DEVICE_TABLE(of, imx_dma_of_dev_id); | ||
227 | |||
205 | static inline int is_imx1_dma(struct imxdma_engine *imxdma) | 228 | static inline int is_imx1_dma(struct imxdma_engine *imxdma) |
206 | { | 229 | { |
207 | return imxdma->devtype == IMX1_DMA; | 230 | return imxdma->devtype == IMX1_DMA; |
@@ -996,13 +1019,50 @@ static void imxdma_issue_pending(struct dma_chan *chan) | |||
996 | spin_unlock_irqrestore(&imxdma->lock, flags); | 1019 | spin_unlock_irqrestore(&imxdma->lock, flags); |
997 | } | 1020 | } |
998 | 1021 | ||
1022 | static bool imxdma_filter_fn(struct dma_chan *chan, void *param) | ||
1023 | { | ||
1024 | struct imxdma_filter_data *fdata = param; | ||
1025 | struct imxdma_channel *imxdma_chan = to_imxdma_chan(chan); | ||
1026 | |||
1027 | if (chan->device->dev != fdata->imxdma->dev) | ||
1028 | return false; | ||
1029 | |||
1030 | imxdma_chan->dma_request = fdata->request; | ||
1031 | chan->private = NULL; | ||
1032 | |||
1033 | return true; | ||
1034 | } | ||
1035 | |||
1036 | static struct dma_chan *imxdma_xlate(struct of_phandle_args *dma_spec, | ||
1037 | struct of_dma *ofdma) | ||
1038 | { | ||
1039 | int count = dma_spec->args_count; | ||
1040 | struct imxdma_engine *imxdma = ofdma->of_dma_data; | ||
1041 | struct imxdma_filter_data fdata = { | ||
1042 | .imxdma = imxdma, | ||
1043 | }; | ||
1044 | |||
1045 | if (count != 1) | ||
1046 | return NULL; | ||
1047 | |||
1048 | fdata.request = dma_spec->args[0]; | ||
1049 | |||
1050 | return dma_request_channel(imxdma->dma_device.cap_mask, | ||
1051 | imxdma_filter_fn, &fdata); | ||
1052 | } | ||
1053 | |||
999 | static int __init imxdma_probe(struct platform_device *pdev) | 1054 | static int __init imxdma_probe(struct platform_device *pdev) |
1000 | { | 1055 | { |
1001 | struct imxdma_engine *imxdma; | 1056 | struct imxdma_engine *imxdma; |
1002 | struct resource *res; | 1057 | struct resource *res; |
1058 | const struct of_device_id *of_id; | ||
1003 | int ret, i; | 1059 | int ret, i; |
1004 | int irq, irq_err; | 1060 | int irq, irq_err; |
1005 | 1061 | ||
1062 | of_id = of_match_device(imx_dma_of_dev_id, &pdev->dev); | ||
1063 | if (of_id) | ||
1064 | pdev->id_entry = of_id->data; | ||
1065 | |||
1006 | imxdma = devm_kzalloc(&pdev->dev, sizeof(*imxdma), GFP_KERNEL); | 1066 | imxdma = devm_kzalloc(&pdev->dev, sizeof(*imxdma), GFP_KERNEL); |
1007 | if (!imxdma) | 1067 | if (!imxdma) |
1008 | return -ENOMEM; | 1068 | return -ENOMEM; |
@@ -1136,8 +1196,19 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
1136 | goto err; | 1196 | goto err; |
1137 | } | 1197 | } |
1138 | 1198 | ||
1199 | if (pdev->dev.of_node) { | ||
1200 | ret = of_dma_controller_register(pdev->dev.of_node, | ||
1201 | imxdma_xlate, imxdma); | ||
1202 | if (ret) { | ||
1203 | dev_err(&pdev->dev, "unable to register of_dma_controller\n"); | ||
1204 | goto err_of_dma_controller; | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1139 | return 0; | 1208 | return 0; |
1140 | 1209 | ||
1210 | err_of_dma_controller: | ||
1211 | dma_async_device_unregister(&imxdma->dma_device); | ||
1141 | err: | 1212 | err: |
1142 | clk_disable_unprepare(imxdma->dma_ipg); | 1213 | clk_disable_unprepare(imxdma->dma_ipg); |
1143 | clk_disable_unprepare(imxdma->dma_ahb); | 1214 | clk_disable_unprepare(imxdma->dma_ahb); |
@@ -1150,6 +1221,9 @@ static int imxdma_remove(struct platform_device *pdev) | |||
1150 | 1221 | ||
1151 | dma_async_device_unregister(&imxdma->dma_device); | 1222 | dma_async_device_unregister(&imxdma->dma_device); |
1152 | 1223 | ||
1224 | if (pdev->dev.of_node) | ||
1225 | of_dma_controller_free(pdev->dev.of_node); | ||
1226 | |||
1153 | clk_disable_unprepare(imxdma->dma_ipg); | 1227 | clk_disable_unprepare(imxdma->dma_ipg); |
1154 | clk_disable_unprepare(imxdma->dma_ahb); | 1228 | clk_disable_unprepare(imxdma->dma_ahb); |
1155 | 1229 | ||
@@ -1159,6 +1233,7 @@ static int imxdma_remove(struct platform_device *pdev) | |||
1159 | static struct platform_driver imxdma_driver = { | 1233 | static struct platform_driver imxdma_driver = { |
1160 | .driver = { | 1234 | .driver = { |
1161 | .name = "imx-dma", | 1235 | .name = "imx-dma", |
1236 | .of_match_table = imx_dma_of_dev_id, | ||
1162 | }, | 1237 | }, |
1163 | .id_table = imx_dma_devtype, | 1238 | .id_table = imx_dma_devtype, |
1164 | .remove = imxdma_remove, | 1239 | .remove = imxdma_remove, |