0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/device.h>
0014 #include <linux/clk.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/dmaengine.h>
0018 #include <linux/dma-mapping.h>
0019 #include <linux/of.h>
0020 #include <linux/acpi.h>
0021
0022 #include "internal.h"
0023
0024 #define DRV_NAME "dw_dmac"
0025
0026 static int dw_probe(struct platform_device *pdev)
0027 {
0028 const struct dw_dma_chip_pdata *match;
0029 struct dw_dma_chip_pdata *data;
0030 struct dw_dma_chip *chip;
0031 struct device *dev = &pdev->dev;
0032 int err;
0033
0034 match = device_get_match_data(dev);
0035 if (!match)
0036 return -ENODEV;
0037
0038 data = devm_kmemdup(&pdev->dev, match, sizeof(*match), GFP_KERNEL);
0039 if (!data)
0040 return -ENOMEM;
0041
0042 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
0043 if (!chip)
0044 return -ENOMEM;
0045
0046 chip->irq = platform_get_irq(pdev, 0);
0047 if (chip->irq < 0)
0048 return chip->irq;
0049
0050 chip->regs = devm_platform_ioremap_resource(pdev, 0);
0051 if (IS_ERR(chip->regs))
0052 return PTR_ERR(chip->regs);
0053
0054 err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
0055 if (err)
0056 return err;
0057
0058 if (!data->pdata)
0059 data->pdata = dev_get_platdata(dev);
0060 if (!data->pdata)
0061 data->pdata = dw_dma_parse_dt(pdev);
0062
0063 chip->dev = dev;
0064 chip->id = pdev->id;
0065 chip->pdata = data->pdata;
0066
0067 data->chip = chip;
0068
0069 chip->clk = devm_clk_get_optional(chip->dev, "hclk");
0070 if (IS_ERR(chip->clk))
0071 return PTR_ERR(chip->clk);
0072 err = clk_prepare_enable(chip->clk);
0073 if (err)
0074 return err;
0075
0076 pm_runtime_enable(&pdev->dev);
0077
0078 err = data->probe(chip);
0079 if (err)
0080 goto err_dw_dma_probe;
0081
0082 platform_set_drvdata(pdev, data);
0083
0084 dw_dma_of_controller_register(chip->dw);
0085
0086 dw_dma_acpi_controller_register(chip->dw);
0087
0088 return 0;
0089
0090 err_dw_dma_probe:
0091 pm_runtime_disable(&pdev->dev);
0092 clk_disable_unprepare(chip->clk);
0093 return err;
0094 }
0095
0096 static int dw_remove(struct platform_device *pdev)
0097 {
0098 struct dw_dma_chip_pdata *data = platform_get_drvdata(pdev);
0099 struct dw_dma_chip *chip = data->chip;
0100 int ret;
0101
0102 dw_dma_acpi_controller_free(chip->dw);
0103
0104 dw_dma_of_controller_free(chip->dw);
0105
0106 ret = data->remove(chip);
0107 if (ret)
0108 dev_warn(chip->dev, "can't remove device properly: %d\n", ret);
0109
0110 pm_runtime_disable(&pdev->dev);
0111 clk_disable_unprepare(chip->clk);
0112
0113 return 0;
0114 }
0115
0116 static void dw_shutdown(struct platform_device *pdev)
0117 {
0118 struct dw_dma_chip_pdata *data = platform_get_drvdata(pdev);
0119 struct dw_dma_chip *chip = data->chip;
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 pm_runtime_get_sync(chip->dev);
0131 do_dw_dma_disable(chip);
0132 pm_runtime_put_sync_suspend(chip->dev);
0133
0134 clk_disable_unprepare(chip->clk);
0135 }
0136
0137 #ifdef CONFIG_OF
0138 static const struct of_device_id dw_dma_of_id_table[] = {
0139 { .compatible = "snps,dma-spear1340", .data = &dw_dma_chip_pdata },
0140 { .compatible = "renesas,rzn1-dma", .data = &dw_dma_chip_pdata },
0141 {}
0142 };
0143 MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
0144 #endif
0145
0146 #ifdef CONFIG_ACPI
0147 static const struct acpi_device_id dw_dma_acpi_id_table[] = {
0148 { "INTL9C60", (kernel_ulong_t)&dw_dma_chip_pdata },
0149 { "80862286", (kernel_ulong_t)&dw_dma_chip_pdata },
0150 { "808622C0", (kernel_ulong_t)&dw_dma_chip_pdata },
0151
0152
0153 { "80864BB4", (kernel_ulong_t)&xbar_chip_pdata },
0154 { "80864BB5", (kernel_ulong_t)&xbar_chip_pdata },
0155 { "80864BB6", (kernel_ulong_t)&xbar_chip_pdata },
0156
0157 { }
0158 };
0159 MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table);
0160 #endif
0161
0162 #ifdef CONFIG_PM_SLEEP
0163
0164 static int dw_suspend_late(struct device *dev)
0165 {
0166 struct dw_dma_chip_pdata *data = dev_get_drvdata(dev);
0167 struct dw_dma_chip *chip = data->chip;
0168
0169 do_dw_dma_disable(chip);
0170 clk_disable_unprepare(chip->clk);
0171
0172 return 0;
0173 }
0174
0175 static int dw_resume_early(struct device *dev)
0176 {
0177 struct dw_dma_chip_pdata *data = dev_get_drvdata(dev);
0178 struct dw_dma_chip *chip = data->chip;
0179 int ret;
0180
0181 ret = clk_prepare_enable(chip->clk);
0182 if (ret)
0183 return ret;
0184
0185 return do_dw_dma_enable(chip);
0186 }
0187
0188 #endif
0189
0190 static const struct dev_pm_ops dw_dev_pm_ops = {
0191 SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_suspend_late, dw_resume_early)
0192 };
0193
0194 static struct platform_driver dw_driver = {
0195 .probe = dw_probe,
0196 .remove = dw_remove,
0197 .shutdown = dw_shutdown,
0198 .driver = {
0199 .name = DRV_NAME,
0200 .pm = &dw_dev_pm_ops,
0201 .of_match_table = of_match_ptr(dw_dma_of_id_table),
0202 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
0203 },
0204 };
0205
0206 static int __init dw_init(void)
0207 {
0208 return platform_driver_register(&dw_driver);
0209 }
0210 subsys_initcall(dw_init);
0211
0212 static void __exit dw_exit(void)
0213 {
0214 platform_driver_unregister(&dw_driver);
0215 }
0216 module_exit(dw_exit);
0217
0218 MODULE_LICENSE("GPL v2");
0219 MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");
0220 MODULE_ALIAS("platform:" DRV_NAME);