]>
Commit | Line | Data |
---|---|---|
30f9f2fb DN |
1 | /* |
2 | * NAND Flash Controller Device Driver for DT | |
3 | * | |
4 | * Copyright © 2011, Picochip. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms and conditions of the GNU General Public License, | |
8 | * version 2, as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | * more details. | |
14 | */ | |
15 | #include <linux/clk.h> | |
16 | #include <linux/err.h> | |
17 | #include <linux/io.h> | |
18 | #include <linux/ioport.h> | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/module.h> | |
21 | #include <linux/platform_device.h> | |
22 | #include <linux/of.h> | |
23 | #include <linux/of_device.h> | |
30f9f2fb DN |
24 | |
25 | #include "denali.h" | |
26 | ||
27 | struct denali_dt { | |
28 | struct denali_nand_info denali; | |
29 | struct clk *clk; | |
30 | }; | |
31 | ||
be72a4aa MY |
32 | struct denali_dt_data { |
33 | unsigned int caps; | |
34 | }; | |
35 | ||
a56609c4 MY |
36 | static const struct denali_dt_data denali_socfpga_data = { |
37 | .caps = DENALI_CAP_HW_ECC_FIXUP, | |
38 | }; | |
30f9f2fb | 39 | |
a56609c4 MY |
40 | static const struct of_device_id denali_nand_dt_ids[] = { |
41 | { | |
42 | .compatible = "altr,socfpga-denali-nand", | |
43 | .data = &denali_socfpga_data, | |
44 | }, | |
45 | { /* sentinel */ } | |
46 | }; | |
30f9f2fb DN |
47 | MODULE_DEVICE_TABLE(of, denali_nand_dt_ids); |
48 | ||
3f5c3581 | 49 | static int denali_dt_probe(struct platform_device *pdev) |
30f9f2fb DN |
50 | { |
51 | struct resource *denali_reg, *nand_data; | |
52 | struct denali_dt *dt; | |
be72a4aa | 53 | const struct denali_dt_data *data; |
30f9f2fb DN |
54 | struct denali_nand_info *denali; |
55 | int ret; | |
30f9f2fb | 56 | |
3f5c3581 | 57 | dt = devm_kzalloc(&pdev->dev, sizeof(*dt), GFP_KERNEL); |
30f9f2fb DN |
58 | if (!dt) |
59 | return -ENOMEM; | |
60 | denali = &dt->denali; | |
61 | ||
3f5c3581 | 62 | data = of_device_get_match_data(&pdev->dev); |
be72a4aa MY |
63 | if (data) |
64 | denali->caps = data->caps; | |
65 | ||
30f9f2fb | 66 | denali->platform = DT; |
3f5c3581 MY |
67 | denali->dev = &pdev->dev; |
68 | denali->irq = platform_get_irq(pdev, 0); | |
30f9f2fb | 69 | if (denali->irq < 0) { |
3f5c3581 | 70 | dev_err(&pdev->dev, "no irq defined\n"); |
2f2ff14c | 71 | return denali->irq; |
30f9f2fb DN |
72 | } |
73 | ||
3f5c3581 MY |
74 | denali_reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
75 | "denali_reg"); | |
76 | denali->flash_reg = devm_ioremap_resource(&pdev->dev, denali_reg); | |
7995204e JH |
77 | if (IS_ERR(denali->flash_reg)) |
78 | return PTR_ERR(denali->flash_reg); | |
30f9f2fb | 79 | |
3f5c3581 MY |
80 | nand_data = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
81 | "nand_data"); | |
82 | denali->flash_mem = devm_ioremap_resource(&pdev->dev, nand_data); | |
7995204e JH |
83 | if (IS_ERR(denali->flash_mem)) |
84 | return PTR_ERR(denali->flash_mem); | |
30f9f2fb | 85 | |
3f5c3581 | 86 | dt->clk = devm_clk_get(&pdev->dev, NULL); |
30f9f2fb | 87 | if (IS_ERR(dt->clk)) { |
3f5c3581 | 88 | dev_err(&pdev->dev, "no clk available\n"); |
30f9f2fb DN |
89 | return PTR_ERR(dt->clk); |
90 | } | |
91 | clk_prepare_enable(dt->clk); | |
92 | ||
93 | ret = denali_init(denali); | |
94 | if (ret) | |
95 | goto out_disable_clk; | |
96 | ||
3f5c3581 | 97 | platform_set_drvdata(pdev, dt); |
30f9f2fb DN |
98 | return 0; |
99 | ||
100 | out_disable_clk: | |
101 | clk_disable_unprepare(dt->clk); | |
30f9f2fb DN |
102 | |
103 | return ret; | |
104 | } | |
105 | ||
3f5c3581 | 106 | static int denali_dt_remove(struct platform_device *pdev) |
30f9f2fb | 107 | { |
3f5c3581 | 108 | struct denali_dt *dt = platform_get_drvdata(pdev); |
30f9f2fb DN |
109 | |
110 | denali_remove(&dt->denali); | |
a1a26170 | 111 | clk_disable_unprepare(dt->clk); |
30f9f2fb DN |
112 | |
113 | return 0; | |
114 | } | |
115 | ||
116 | static struct platform_driver denali_dt_driver = { | |
117 | .probe = denali_dt_probe, | |
5153b88c | 118 | .remove = denali_dt_remove, |
30f9f2fb DN |
119 | .driver = { |
120 | .name = "denali-nand-dt", | |
ef54f873 | 121 | .of_match_table = denali_nand_dt_ids, |
30f9f2fb DN |
122 | }, |
123 | }; | |
124 | ||
82fc812c | 125 | module_platform_driver(denali_dt_driver); |
30f9f2fb DN |
126 | |
127 | MODULE_LICENSE("GPL"); | |
128 | MODULE_AUTHOR("Jamie Iles"); | |
129 | MODULE_DESCRIPTION("DT driver for Denali NAND controller"); |