at v3.19 307 lines 7.2 kB view raw
1/* 2 * Platform driver for the Synopsys DesignWare DMA Controller 3 * 4 * Copyright (C) 2007-2008 Atmel Corporation 5 * Copyright (C) 2010-2011 ST Microelectronics 6 * Copyright (C) 2013 Intel Corporation 7 * 8 * Some parts of this driver are derived from the original dw_dmac. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/module.h> 16#include <linux/device.h> 17#include <linux/clk.h> 18#include <linux/pm_runtime.h> 19#include <linux/platform_device.h> 20#include <linux/dmaengine.h> 21#include <linux/dma-mapping.h> 22#include <linux/of.h> 23#include <linux/of_dma.h> 24#include <linux/acpi.h> 25#include <linux/acpi_dma.h> 26 27#include "internal.h" 28 29static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec, 30 struct of_dma *ofdma) 31{ 32 struct dw_dma *dw = ofdma->of_dma_data; 33 struct dw_dma_slave slave = { 34 .dma_dev = dw->dma.dev, 35 }; 36 dma_cap_mask_t cap; 37 38 if (dma_spec->args_count != 3) 39 return NULL; 40 41 slave.src_id = dma_spec->args[0]; 42 slave.dst_id = dma_spec->args[0]; 43 slave.src_master = dma_spec->args[1]; 44 slave.dst_master = dma_spec->args[2]; 45 46 if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS || 47 slave.dst_id >= DW_DMA_MAX_NR_REQUESTS || 48 slave.src_master >= dw->nr_masters || 49 slave.dst_master >= dw->nr_masters)) 50 return NULL; 51 52 dma_cap_zero(cap); 53 dma_cap_set(DMA_SLAVE, cap); 54 55 /* TODO: there should be a simpler way to do this */ 56 return dma_request_channel(cap, dw_dma_filter, &slave); 57} 58 59#ifdef CONFIG_ACPI 60static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) 61{ 62 struct acpi_dma_spec *dma_spec = param; 63 struct dw_dma_slave slave = { 64 .dma_dev = dma_spec->dev, 65 .src_id = dma_spec->slave_id, 66 .dst_id = dma_spec->slave_id, 67 .src_master = 1, 68 .dst_master = 0, 69 }; 70 71 return dw_dma_filter(chan, &slave); 72} 73 74static void dw_dma_acpi_controller_register(struct dw_dma *dw) 75{ 76 struct device *dev = dw->dma.dev; 77 struct acpi_dma_filter_info *info; 78 int ret; 79 80 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 81 if (!info) 82 return; 83 84 dma_cap_zero(info->dma_cap); 85 dma_cap_set(DMA_SLAVE, info->dma_cap); 86 info->filter_fn = dw_dma_acpi_filter; 87 88 ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate, 89 info); 90 if (ret) 91 dev_err(dev, "could not register acpi_dma_controller\n"); 92} 93#else /* !CONFIG_ACPI */ 94static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {} 95#endif /* !CONFIG_ACPI */ 96 97#ifdef CONFIG_OF 98static struct dw_dma_platform_data * 99dw_dma_parse_dt(struct platform_device *pdev) 100{ 101 struct device_node *np = pdev->dev.of_node; 102 struct dw_dma_platform_data *pdata; 103 u32 tmp, arr[4]; 104 105 if (!np) { 106 dev_err(&pdev->dev, "Missing DT data\n"); 107 return NULL; 108 } 109 110 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 111 if (!pdata) 112 return NULL; 113 114 if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels)) 115 return NULL; 116 117 if (of_property_read_bool(np, "is_private")) 118 pdata->is_private = true; 119 120 if (!of_property_read_u32(np, "chan_allocation_order", &tmp)) 121 pdata->chan_allocation_order = (unsigned char)tmp; 122 123 if (!of_property_read_u32(np, "chan_priority", &tmp)) 124 pdata->chan_priority = tmp; 125 126 if (!of_property_read_u32(np, "block_size", &tmp)) 127 pdata->block_size = tmp; 128 129 if (!of_property_read_u32(np, "dma-masters", &tmp)) { 130 if (tmp > 4) 131 return NULL; 132 133 pdata->nr_masters = tmp; 134 } 135 136 if (!of_property_read_u32_array(np, "data_width", arr, 137 pdata->nr_masters)) 138 for (tmp = 0; tmp < pdata->nr_masters; tmp++) 139 pdata->data_width[tmp] = arr[tmp]; 140 141 return pdata; 142} 143#else 144static inline struct dw_dma_platform_data * 145dw_dma_parse_dt(struct platform_device *pdev) 146{ 147 return NULL; 148} 149#endif 150 151static int dw_probe(struct platform_device *pdev) 152{ 153 struct dw_dma_chip *chip; 154 struct device *dev = &pdev->dev; 155 struct resource *mem; 156 struct dw_dma_platform_data *pdata; 157 int err; 158 159 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 160 if (!chip) 161 return -ENOMEM; 162 163 chip->irq = platform_get_irq(pdev, 0); 164 if (chip->irq < 0) 165 return chip->irq; 166 167 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 168 chip->regs = devm_ioremap_resource(dev, mem); 169 if (IS_ERR(chip->regs)) 170 return PTR_ERR(chip->regs); 171 172 err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); 173 if (err) 174 return err; 175 176 pdata = dev_get_platdata(dev); 177 if (!pdata) 178 pdata = dw_dma_parse_dt(pdev); 179 180 chip->dev = dev; 181 182 chip->clk = devm_clk_get(chip->dev, "hclk"); 183 if (IS_ERR(chip->clk)) 184 return PTR_ERR(chip->clk); 185 err = clk_prepare_enable(chip->clk); 186 if (err) 187 return err; 188 189 pm_runtime_enable(&pdev->dev); 190 191 err = dw_dma_probe(chip, pdata); 192 if (err) 193 goto err_dw_dma_probe; 194 195 platform_set_drvdata(pdev, chip); 196 197 if (pdev->dev.of_node) { 198 err = of_dma_controller_register(pdev->dev.of_node, 199 dw_dma_of_xlate, chip->dw); 200 if (err) 201 dev_err(&pdev->dev, 202 "could not register of_dma_controller\n"); 203 } 204 205 if (ACPI_HANDLE(&pdev->dev)) 206 dw_dma_acpi_controller_register(chip->dw); 207 208 return 0; 209 210err_dw_dma_probe: 211 pm_runtime_disable(&pdev->dev); 212 clk_disable_unprepare(chip->clk); 213 return err; 214} 215 216static int dw_remove(struct platform_device *pdev) 217{ 218 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 219 220 if (pdev->dev.of_node) 221 of_dma_controller_free(pdev->dev.of_node); 222 223 dw_dma_remove(chip); 224 pm_runtime_disable(&pdev->dev); 225 clk_disable_unprepare(chip->clk); 226 227 return 0; 228} 229 230static void dw_shutdown(struct platform_device *pdev) 231{ 232 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 233 234 dw_dma_disable(chip); 235 clk_disable_unprepare(chip->clk); 236} 237 238#ifdef CONFIG_OF 239static const struct of_device_id dw_dma_of_id_table[] = { 240 { .compatible = "snps,dma-spear1340" }, 241 {} 242}; 243MODULE_DEVICE_TABLE(of, dw_dma_of_id_table); 244#endif 245 246#ifdef CONFIG_ACPI 247static const struct acpi_device_id dw_dma_acpi_id_table[] = { 248 { "INTL9C60", 0 }, 249 { } 250}; 251MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table); 252#endif 253 254#ifdef CONFIG_PM_SLEEP 255 256static int dw_suspend_late(struct device *dev) 257{ 258 struct platform_device *pdev = to_platform_device(dev); 259 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 260 261 dw_dma_disable(chip); 262 clk_disable_unprepare(chip->clk); 263 264 return 0; 265} 266 267static int dw_resume_early(struct device *dev) 268{ 269 struct platform_device *pdev = to_platform_device(dev); 270 struct dw_dma_chip *chip = platform_get_drvdata(pdev); 271 272 clk_prepare_enable(chip->clk); 273 return dw_dma_enable(chip); 274} 275 276#endif /* CONFIG_PM_SLEEP */ 277 278static const struct dev_pm_ops dw_dev_pm_ops = { 279 SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_suspend_late, dw_resume_early) 280}; 281 282static struct platform_driver dw_driver = { 283 .probe = dw_probe, 284 .remove = dw_remove, 285 .shutdown = dw_shutdown, 286 .driver = { 287 .name = "dw_dmac", 288 .pm = &dw_dev_pm_ops, 289 .of_match_table = of_match_ptr(dw_dma_of_id_table), 290 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), 291 }, 292}; 293 294static int __init dw_init(void) 295{ 296 return platform_driver_register(&dw_driver); 297} 298subsys_initcall(dw_init); 299 300static void __exit dw_exit(void) 301{ 302 platform_driver_unregister(&dw_driver); 303} 304module_exit(dw_exit); 305 306MODULE_LICENSE("GPL v2"); 307MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");