diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-01 18:36:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-01 18:36:01 -0400 |
commit | 43a0a98aa8da71583f84b84fd72e265c24d4c5f8 (patch) | |
tree | 3830aff2b36f48a67be5f485f00f56cf4269729d /drivers/memory | |
parent | 6911a5281430cf6897376487698504620f454791 (diff) | |
parent | f8c6d88b2c874295f49b9ad1ca0826b9a8ef3180 (diff) |
Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC driver updates from Olof Johansson:
"Driver updates for ARM SoCs.
A slew of changes this release cycle. The reset driver tree, that we
merge through arm-soc for historical reasons, is also sizable this
time around.
Among the changes:
- clps711x: Treewide changes to compatible strings, merged here for simplicity.
- Qualcomm: SCM firmware driver cleanups, move to platform driver
- ux500: Major cleanups, removal of old mach-specific infrastructure.
- Atmel external bus memory driver
- Move of brcmstb platform to the rest of bcm
- PMC driver updates for tegra, various fixes and improvements
- Samsung platform driver updates to support 64-bit Exynos platforms
- Reset controller cleanups moving to devm_reset_controller_register() APIs
- Reset controller driver for Amlogic Meson
- Reset controller driver for Hisilicon hi6220
- ARM SCPI power domain support"
* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (100 commits)
ARM: ux500: consolidate base platform files
ARM: ux500: move soc_id driver to drivers/soc
ARM: ux500: call ux500_setup_id later
ARM: ux500: consolidate soc_device code in id.c
ARM: ux500: remove cpu_is_u* helpers
ARM: ux500: use CLK_OF_DECLARE()
ARM: ux500: move l2x0 init to .init_irq
mfd: db8500 stop passing around platform data
ASoC: ab8500-codec: remove platform data based probe
ARM: ux500: move ab8500_regulator_plat_data into driver
ARM: ux500: remove unused regulator data
soc: raspberrypi-power: add CONFIG_OF dependency
firmware: scpi: add CONFIG_OF dependency
video: clps711x-fb: Changing the compatibility string to match with the smallest supported chip
input: clps711x-keypad: Changing the compatibility string to match with the smallest supported chip
pwm: clps711x: Changing the compatibility string to match with the smallest supported chip
serial: clps711x: Changing the compatibility string to match with the smallest supported chip
irqchip: clps711x: Changing the compatibility string to match with the smallest supported chip
clocksource: clps711x: Changing the compatibility string to match with the smallest supported chip
clk: clps711x: Changing the compatibility string to match with the smallest supported chip
...
Diffstat (limited to 'drivers/memory')
-rw-r--r-- | drivers/memory/Kconfig | 11 | ||||
-rw-r--r-- | drivers/memory/Makefile | 1 | ||||
-rw-r--r-- | drivers/memory/atmel-ebi.c | 766 | ||||
-rw-r--r-- | drivers/memory/atmel-sdramc.c | 11 | ||||
-rw-r--r-- | drivers/memory/omap-gpmc.c | 136 | ||||
-rw-r--r-- | drivers/memory/samsung/exynos-srom.c | 41 | ||||
-rw-r--r-- | drivers/memory/tegra/mc.c | 10 | ||||
-rw-r--r-- | drivers/memory/tegra/tegra124-emc.c | 8 |
8 files changed, 867 insertions, 117 deletions
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index 81ddb17575a9..133712346911 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig | |||
@@ -25,6 +25,17 @@ config ATMEL_SDRAMC | |||
25 | Starting with the at91sam9g45, this controller supports SDR, DDR and | 25 | Starting with the at91sam9g45, this controller supports SDR, DDR and |
26 | LP-DDR memories. | 26 | LP-DDR memories. |
27 | 27 | ||
28 | config ATMEL_EBI | ||
29 | bool "Atmel EBI driver" | ||
30 | default y | ||
31 | depends on ARCH_AT91 && OF | ||
32 | select MFD_SYSCON | ||
33 | help | ||
34 | Driver for Atmel EBI controller. | ||
35 | Used to configure the EBI (external bus interface) when the device- | ||
36 | tree is used. This bus supports NANDs, external ethernet controller, | ||
37 | SRAMs, ATA devices, etc. | ||
38 | |||
28 | config TI_AEMIF | 39 | config TI_AEMIF |
29 | tristate "Texas Instruments AEMIF driver" | 40 | tristate "Texas Instruments AEMIF driver" |
30 | depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF | 41 | depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF |
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index cb0b7a1df11a..b20ae38b5bfb 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_OF) += of_memory.o | |||
7 | endif | 7 | endif |
8 | obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o | 8 | obj-$(CONFIG_ARM_PL172_MPMC) += pl172.o |
9 | obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o | 9 | obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o |
10 | obj-$(CONFIG_ATMEL_EBI) += atmel-ebi.o | ||
10 | obj-$(CONFIG_TI_AEMIF) += ti-aemif.o | 11 | obj-$(CONFIG_TI_AEMIF) += ti-aemif.o |
11 | obj-$(CONFIG_TI_EMIF) += emif.o | 12 | obj-$(CONFIG_TI_EMIF) += emif.o |
12 | obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o | 13 | obj-$(CONFIG_OMAP_GPMC) += omap-gpmc.o |
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c new file mode 100644 index 000000000000..f87ad6f5d2dc --- /dev/null +++ b/drivers/memory/atmel-ebi.c | |||
@@ -0,0 +1,766 @@ | |||
1 | /* | ||
2 | * EBI driver for Atmel chips | ||
3 | * inspired by the fsl weim bus driver | ||
4 | * | ||
5 | * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/mfd/syscon.h> | ||
15 | #include <linux/mfd/syscon/atmel-matrix.h> | ||
16 | #include <linux/mfd/syscon/atmel-smc.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/of_device.h> | ||
19 | #include <linux/regmap.h> | ||
20 | |||
21 | struct at91sam9_smc_timings { | ||
22 | u32 ncs_rd_setup_ns; | ||
23 | u32 nrd_setup_ns; | ||
24 | u32 ncs_wr_setup_ns; | ||
25 | u32 nwe_setup_ns; | ||
26 | u32 ncs_rd_pulse_ns; | ||
27 | u32 nrd_pulse_ns; | ||
28 | u32 ncs_wr_pulse_ns; | ||
29 | u32 nwe_pulse_ns; | ||
30 | u32 nrd_cycle_ns; | ||
31 | u32 nwe_cycle_ns; | ||
32 | u32 tdf_ns; | ||
33 | }; | ||
34 | |||
35 | struct at91sam9_smc_generic_fields { | ||
36 | struct regmap_field *setup; | ||
37 | struct regmap_field *pulse; | ||
38 | struct regmap_field *cycle; | ||
39 | struct regmap_field *mode; | ||
40 | }; | ||
41 | |||
42 | struct at91sam9_ebi_dev_config { | ||
43 | struct at91sam9_smc_timings timings; | ||
44 | u32 mode; | ||
45 | }; | ||
46 | |||
47 | struct at91_ebi_dev_config { | ||
48 | int cs; | ||
49 | union { | ||
50 | struct at91sam9_ebi_dev_config sam9; | ||
51 | }; | ||
52 | }; | ||
53 | |||
54 | struct at91_ebi; | ||
55 | |||
56 | struct at91_ebi_dev { | ||
57 | struct list_head node; | ||
58 | struct at91_ebi *ebi; | ||
59 | u32 mode; | ||
60 | int numcs; | ||
61 | struct at91_ebi_dev_config configs[]; | ||
62 | }; | ||
63 | |||
64 | struct at91_ebi_caps { | ||
65 | unsigned int available_cs; | ||
66 | const struct reg_field *ebi_csa; | ||
67 | void (*get_config)(struct at91_ebi_dev *ebid, | ||
68 | struct at91_ebi_dev_config *conf); | ||
69 | int (*xlate_config)(struct at91_ebi_dev *ebid, | ||
70 | struct device_node *configs_np, | ||
71 | struct at91_ebi_dev_config *conf); | ||
72 | int (*apply_config)(struct at91_ebi_dev *ebid, | ||
73 | struct at91_ebi_dev_config *conf); | ||
74 | int (*init)(struct at91_ebi *ebi); | ||
75 | }; | ||
76 | |||
77 | struct at91_ebi { | ||
78 | struct clk *clk; | ||
79 | struct regmap *smc; | ||
80 | struct regmap *matrix; | ||
81 | |||
82 | struct regmap_field *ebi_csa; | ||
83 | |||
84 | struct device *dev; | ||
85 | const struct at91_ebi_caps *caps; | ||
86 | struct list_head devs; | ||
87 | union { | ||
88 | struct at91sam9_smc_generic_fields sam9; | ||
89 | }; | ||
90 | }; | ||
91 | |||
92 | static void at91sam9_ebi_get_config(struct at91_ebi_dev *ebid, | ||
93 | struct at91_ebi_dev_config *conf) | ||
94 | { | ||
95 | struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9; | ||
96 | unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); | ||
97 | struct at91sam9_ebi_dev_config *config = &conf->sam9; | ||
98 | struct at91sam9_smc_timings *timings = &config->timings; | ||
99 | unsigned int val; | ||
100 | |||
101 | regmap_fields_read(fields->mode, conf->cs, &val); | ||
102 | config->mode = val & ~AT91_SMC_TDF; | ||
103 | |||
104 | val = (val & AT91_SMC_TDF) >> 16; | ||
105 | timings->tdf_ns = clk_rate * val; | ||
106 | |||
107 | regmap_fields_read(fields->setup, conf->cs, &val); | ||
108 | timings->ncs_rd_setup_ns = (val >> 24) & 0x1f; | ||
109 | timings->ncs_rd_setup_ns += ((val >> 29) & 0x1) * 128; | ||
110 | timings->ncs_rd_setup_ns *= clk_rate; | ||
111 | timings->nrd_setup_ns = (val >> 16) & 0x1f; | ||
112 | timings->nrd_setup_ns += ((val >> 21) & 0x1) * 128; | ||
113 | timings->nrd_setup_ns *= clk_rate; | ||
114 | timings->ncs_wr_setup_ns = (val >> 8) & 0x1f; | ||
115 | timings->ncs_wr_setup_ns += ((val >> 13) & 0x1) * 128; | ||
116 | timings->ncs_wr_setup_ns *= clk_rate; | ||
117 | timings->nwe_setup_ns = val & 0x1f; | ||
118 | timings->nwe_setup_ns += ((val >> 5) & 0x1) * 128; | ||
119 | timings->nwe_setup_ns *= clk_rate; | ||
120 | |||
121 | regmap_fields_read(fields->pulse, conf->cs, &val); | ||
122 | timings->ncs_rd_pulse_ns = (val >> 24) & 0x3f; | ||
123 | timings->ncs_rd_pulse_ns += ((val >> 30) & 0x1) * 256; | ||
124 | timings->ncs_rd_pulse_ns *= clk_rate; | ||
125 | timings->nrd_pulse_ns = (val >> 16) & 0x3f; | ||
126 | timings->nrd_pulse_ns += ((val >> 22) & 0x1) * 256; | ||
127 | timings->nrd_pulse_ns *= clk_rate; | ||
128 | timings->ncs_wr_pulse_ns = (val >> 8) & 0x3f; | ||
129 | timings->ncs_wr_pulse_ns += ((val >> 14) & 0x1) * 256; | ||
130 | timings->ncs_wr_pulse_ns *= clk_rate; | ||
131 | timings->nwe_pulse_ns = val & 0x3f; | ||
132 | timings->nwe_pulse_ns += ((val >> 6) & 0x1) * 256; | ||
133 | timings->nwe_pulse_ns *= clk_rate; | ||
134 | |||
135 | regmap_fields_read(fields->cycle, conf->cs, &val); | ||
136 | timings->nrd_cycle_ns = (val >> 16) & 0x7f; | ||
137 | timings->nrd_cycle_ns += ((val >> 23) & 0x3) * 256; | ||
138 | timings->nrd_cycle_ns *= clk_rate; | ||
139 | timings->nwe_cycle_ns = val & 0x7f; | ||
140 | timings->nwe_cycle_ns += ((val >> 7) & 0x3) * 256; | ||
141 | timings->nwe_cycle_ns *= clk_rate; | ||
142 | } | ||
143 | |||
144 | static int at91_xlate_timing(struct device_node *np, const char *prop, | ||
145 | u32 *val, bool *required) | ||
146 | { | ||
147 | if (!of_property_read_u32(np, prop, val)) { | ||
148 | *required = true; | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | if (*required) | ||
153 | return -EINVAL; | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int at91sam9_smc_xslate_timings(struct at91_ebi_dev *ebid, | ||
159 | struct device_node *np, | ||
160 | struct at91sam9_smc_timings *timings, | ||
161 | bool *required) | ||
162 | { | ||
163 | int ret; | ||
164 | |||
165 | ret = at91_xlate_timing(np, "atmel,smc-ncs-rd-setup-ns", | ||
166 | &timings->ncs_rd_setup_ns, required); | ||
167 | if (ret) | ||
168 | goto out; | ||
169 | |||
170 | ret = at91_xlate_timing(np, "atmel,smc-nrd-setup-ns", | ||
171 | &timings->nrd_setup_ns, required); | ||
172 | if (ret) | ||
173 | goto out; | ||
174 | |||
175 | ret = at91_xlate_timing(np, "atmel,smc-ncs-wr-setup-ns", | ||
176 | &timings->ncs_wr_setup_ns, required); | ||
177 | if (ret) | ||
178 | goto out; | ||
179 | |||
180 | ret = at91_xlate_timing(np, "atmel,smc-nwe-setup-ns", | ||
181 | &timings->nwe_setup_ns, required); | ||
182 | if (ret) | ||
183 | goto out; | ||
184 | |||
185 | ret = at91_xlate_timing(np, "atmel,smc-ncs-rd-pulse-ns", | ||
186 | &timings->ncs_rd_pulse_ns, required); | ||
187 | if (ret) | ||
188 | goto out; | ||
189 | |||
190 | ret = at91_xlate_timing(np, "atmel,smc-nrd-pulse-ns", | ||
191 | &timings->nrd_pulse_ns, required); | ||
192 | if (ret) | ||
193 | goto out; | ||
194 | |||
195 | ret = at91_xlate_timing(np, "atmel,smc-ncs-wr-pulse-ns", | ||
196 | &timings->ncs_wr_pulse_ns, required); | ||
197 | if (ret) | ||
198 | goto out; | ||
199 | |||
200 | ret = at91_xlate_timing(np, "atmel,smc-nwe-pulse-ns", | ||
201 | &timings->nwe_pulse_ns, required); | ||
202 | if (ret) | ||
203 | goto out; | ||
204 | |||
205 | ret = at91_xlate_timing(np, "atmel,smc-nwe-cycle-ns", | ||
206 | &timings->nwe_cycle_ns, required); | ||
207 | if (ret) | ||
208 | goto out; | ||
209 | |||
210 | ret = at91_xlate_timing(np, "atmel,smc-nrd-cycle-ns", | ||
211 | &timings->nrd_cycle_ns, required); | ||
212 | if (ret) | ||
213 | goto out; | ||
214 | |||
215 | ret = at91_xlate_timing(np, "atmel,smc-tdf-ns", | ||
216 | &timings->tdf_ns, required); | ||
217 | |||
218 | out: | ||
219 | if (ret) | ||
220 | dev_err(ebid->ebi->dev, | ||
221 | "missing or invalid timings definition in %s", | ||
222 | np->full_name); | ||
223 | |||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | static int at91sam9_ebi_xslate_config(struct at91_ebi_dev *ebid, | ||
228 | struct device_node *np, | ||
229 | struct at91_ebi_dev_config *conf) | ||
230 | { | ||
231 | struct at91sam9_ebi_dev_config *config = &conf->sam9; | ||
232 | bool required = false; | ||
233 | const char *tmp_str; | ||
234 | u32 tmp; | ||
235 | int ret; | ||
236 | |||
237 | ret = of_property_read_u32(np, "atmel,smc-bus-width", &tmp); | ||
238 | if (!ret) { | ||
239 | switch (tmp) { | ||
240 | case 8: | ||
241 | config->mode |= AT91_SMC_DBW_8; | ||
242 | break; | ||
243 | |||
244 | case 16: | ||
245 | config->mode |= AT91_SMC_DBW_16; | ||
246 | break; | ||
247 | |||
248 | case 32: | ||
249 | config->mode |= AT91_SMC_DBW_32; | ||
250 | break; | ||
251 | |||
252 | default: | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | |||
256 | required = true; | ||
257 | } | ||
258 | |||
259 | if (of_property_read_bool(np, "atmel,smc-tdf-optimized")) { | ||
260 | config->mode |= AT91_SMC_TDFMODE_OPTIMIZED; | ||
261 | required = true; | ||
262 | } | ||
263 | |||
264 | tmp_str = NULL; | ||
265 | of_property_read_string(np, "atmel,smc-byte-access-type", &tmp_str); | ||
266 | if (tmp_str && !strcmp(tmp_str, "write")) { | ||
267 | config->mode |= AT91_SMC_BAT_WRITE; | ||
268 | required = true; | ||
269 | } | ||
270 | |||
271 | tmp_str = NULL; | ||
272 | of_property_read_string(np, "atmel,smc-read-mode", &tmp_str); | ||
273 | if (tmp_str && !strcmp(tmp_str, "nrd")) { | ||
274 | config->mode |= AT91_SMC_READMODE_NRD; | ||
275 | required = true; | ||
276 | } | ||
277 | |||
278 | tmp_str = NULL; | ||
279 | of_property_read_string(np, "atmel,smc-write-mode", &tmp_str); | ||
280 | if (tmp_str && !strcmp(tmp_str, "nwe")) { | ||
281 | config->mode |= AT91_SMC_WRITEMODE_NWE; | ||
282 | required = true; | ||
283 | } | ||
284 | |||
285 | tmp_str = NULL; | ||
286 | of_property_read_string(np, "atmel,smc-exnw-mode", &tmp_str); | ||
287 | if (tmp_str) { | ||
288 | if (!strcmp(tmp_str, "frozen")) | ||
289 | config->mode |= AT91_SMC_EXNWMODE_FROZEN; | ||
290 | else if (!strcmp(tmp_str, "ready")) | ||
291 | config->mode |= AT91_SMC_EXNWMODE_READY; | ||
292 | else if (strcmp(tmp_str, "disabled")) | ||
293 | return -EINVAL; | ||
294 | |||
295 | required = true; | ||
296 | } | ||
297 | |||
298 | ret = of_property_read_u32(np, "atmel,smc-page-mode", &tmp); | ||
299 | if (!ret) { | ||
300 | switch (tmp) { | ||
301 | case 4: | ||
302 | config->mode |= AT91_SMC_PS_4; | ||
303 | break; | ||
304 | |||
305 | case 8: | ||
306 | config->mode |= AT91_SMC_PS_8; | ||
307 | break; | ||
308 | |||
309 | case 16: | ||
310 | config->mode |= AT91_SMC_PS_16; | ||
311 | break; | ||
312 | |||
313 | case 32: | ||
314 | config->mode |= AT91_SMC_PS_32; | ||
315 | break; | ||
316 | |||
317 | default: | ||
318 | return -EINVAL; | ||
319 | } | ||
320 | |||
321 | config->mode |= AT91_SMC_PMEN; | ||
322 | required = true; | ||
323 | } | ||
324 | |||
325 | ret = at91sam9_smc_xslate_timings(ebid, np, &config->timings, | ||
326 | &required); | ||
327 | if (ret) | ||
328 | return ret; | ||
329 | |||
330 | return required; | ||
331 | } | ||
332 | |||
333 | static int at91sam9_ebi_apply_config(struct at91_ebi_dev *ebid, | ||
334 | struct at91_ebi_dev_config *conf) | ||
335 | { | ||
336 | unsigned int clk_rate = clk_get_rate(ebid->ebi->clk); | ||
337 | struct at91sam9_ebi_dev_config *config = &conf->sam9; | ||
338 | struct at91sam9_smc_timings *timings = &config->timings; | ||
339 | struct at91sam9_smc_generic_fields *fields = &ebid->ebi->sam9; | ||
340 | u32 coded_val; | ||
341 | u32 val; | ||
342 | |||
343 | coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, | ||
344 | timings->ncs_rd_setup_ns); | ||
345 | val = AT91SAM9_SMC_NCS_NRDSETUP(coded_val); | ||
346 | coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, | ||
347 | timings->nrd_setup_ns); | ||
348 | val |= AT91SAM9_SMC_NRDSETUP(coded_val); | ||
349 | coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, | ||
350 | timings->ncs_wr_setup_ns); | ||
351 | val |= AT91SAM9_SMC_NCS_WRSETUP(coded_val); | ||
352 | coded_val = at91sam9_smc_setup_ns_to_cycles(clk_rate, | ||
353 | timings->nwe_setup_ns); | ||
354 | val |= AT91SAM9_SMC_NWESETUP(coded_val); | ||
355 | regmap_fields_write(fields->setup, conf->cs, val); | ||
356 | |||
357 | coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, | ||
358 | timings->ncs_rd_pulse_ns); | ||
359 | val = AT91SAM9_SMC_NCS_NRDPULSE(coded_val); | ||
360 | coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, | ||
361 | timings->nrd_pulse_ns); | ||
362 | val |= AT91SAM9_SMC_NRDPULSE(coded_val); | ||
363 | coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, | ||
364 | timings->ncs_wr_pulse_ns); | ||
365 | val |= AT91SAM9_SMC_NCS_WRPULSE(coded_val); | ||
366 | coded_val = at91sam9_smc_pulse_ns_to_cycles(clk_rate, | ||
367 | timings->nwe_pulse_ns); | ||
368 | val |= AT91SAM9_SMC_NWEPULSE(coded_val); | ||
369 | regmap_fields_write(fields->pulse, conf->cs, val); | ||
370 | |||
371 | coded_val = at91sam9_smc_cycle_ns_to_cycles(clk_rate, | ||
372 | timings->nrd_cycle_ns); | ||
373 | val = AT91SAM9_SMC_NRDCYCLE(coded_val); | ||
374 | coded_val = at91sam9_smc_cycle_ns_to_cycles(clk_rate, | ||
375 | timings->nwe_cycle_ns); | ||
376 | val |= AT91SAM9_SMC_NWECYCLE(coded_val); | ||
377 | regmap_fields_write(fields->cycle, conf->cs, val); | ||
378 | |||
379 | val = DIV_ROUND_UP(timings->tdf_ns, clk_rate); | ||
380 | if (val > AT91_SMC_TDF_MAX) | ||
381 | val = AT91_SMC_TDF_MAX; | ||
382 | regmap_fields_write(fields->mode, conf->cs, | ||
383 | config->mode | AT91_SMC_TDF_(val)); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int at91sam9_ebi_init(struct at91_ebi *ebi) | ||
389 | { | ||
390 | struct at91sam9_smc_generic_fields *fields = &ebi->sam9; | ||
391 | struct reg_field field = REG_FIELD(0, 0, 31); | ||
392 | |||
393 | field.id_size = fls(ebi->caps->available_cs); | ||
394 | field.id_offset = AT91SAM9_SMC_GENERIC_BLK_SZ; | ||
395 | |||
396 | field.reg = AT91SAM9_SMC_SETUP(AT91SAM9_SMC_GENERIC); | ||
397 | fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
398 | if (IS_ERR(fields->setup)) | ||
399 | return PTR_ERR(fields->setup); | ||
400 | |||
401 | field.reg = AT91SAM9_SMC_PULSE(AT91SAM9_SMC_GENERIC); | ||
402 | fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
403 | if (IS_ERR(fields->pulse)) | ||
404 | return PTR_ERR(fields->pulse); | ||
405 | |||
406 | field.reg = AT91SAM9_SMC_CYCLE(AT91SAM9_SMC_GENERIC); | ||
407 | fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
408 | if (IS_ERR(fields->cycle)) | ||
409 | return PTR_ERR(fields->cycle); | ||
410 | |||
411 | field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC); | ||
412 | fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
413 | if (IS_ERR(fields->mode)) | ||
414 | return PTR_ERR(fields->mode); | ||
415 | |||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static int sama5d3_ebi_init(struct at91_ebi *ebi) | ||
420 | { | ||
421 | struct at91sam9_smc_generic_fields *fields = &ebi->sam9; | ||
422 | struct reg_field field = REG_FIELD(0, 0, 31); | ||
423 | |||
424 | field.id_size = fls(ebi->caps->available_cs); | ||
425 | field.id_offset = SAMA5_SMC_GENERIC_BLK_SZ; | ||
426 | |||
427 | field.reg = AT91SAM9_SMC_SETUP(SAMA5_SMC_GENERIC); | ||
428 | fields->setup = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
429 | if (IS_ERR(fields->setup)) | ||
430 | return PTR_ERR(fields->setup); | ||
431 | |||
432 | field.reg = AT91SAM9_SMC_PULSE(SAMA5_SMC_GENERIC); | ||
433 | fields->pulse = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
434 | if (IS_ERR(fields->pulse)) | ||
435 | return PTR_ERR(fields->pulse); | ||
436 | |||
437 | field.reg = AT91SAM9_SMC_CYCLE(SAMA5_SMC_GENERIC); | ||
438 | fields->cycle = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
439 | if (IS_ERR(fields->cycle)) | ||
440 | return PTR_ERR(fields->cycle); | ||
441 | |||
442 | field.reg = SAMA5_SMC_MODE(SAMA5_SMC_GENERIC); | ||
443 | fields->mode = devm_regmap_field_alloc(ebi->dev, ebi->smc, field); | ||
444 | if (IS_ERR(fields->mode)) | ||
445 | return PTR_ERR(fields->mode); | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int at91_ebi_dev_setup(struct at91_ebi *ebi, struct device_node *np, | ||
451 | int reg_cells) | ||
452 | { | ||
453 | const struct at91_ebi_caps *caps = ebi->caps; | ||
454 | struct at91_ebi_dev_config conf = { }; | ||
455 | struct device *dev = ebi->dev; | ||
456 | struct at91_ebi_dev *ebid; | ||
457 | int ret, numcs = 0, i; | ||
458 | bool apply = false; | ||
459 | |||
460 | numcs = of_property_count_elems_of_size(np, "reg", | ||
461 | reg_cells * sizeof(u32)); | ||
462 | if (numcs <= 0) { | ||
463 | dev_err(dev, "invalid reg property in %s\n", np->full_name); | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | |||
467 | ebid = devm_kzalloc(ebi->dev, | ||
468 | sizeof(*ebid) + (numcs * sizeof(*ebid->configs)), | ||
469 | GFP_KERNEL); | ||
470 | if (!ebid) | ||
471 | return -ENOMEM; | ||
472 | |||
473 | ebid->ebi = ebi; | ||
474 | |||
475 | ret = caps->xlate_config(ebid, np, &conf); | ||
476 | if (ret < 0) | ||
477 | return ret; | ||
478 | else if (ret) | ||
479 | apply = true; | ||
480 | |||
481 | for (i = 0; i < numcs; i++) { | ||
482 | u32 cs; | ||
483 | |||
484 | ret = of_property_read_u32_index(np, "reg", i * reg_cells, | ||
485 | &cs); | ||
486 | if (ret) | ||
487 | return ret; | ||
488 | |||
489 | if (cs > AT91_MATRIX_EBI_NUM_CS || | ||
490 | !(ebi->caps->available_cs & BIT(cs))) { | ||
491 | dev_err(dev, "invalid reg property in %s\n", | ||
492 | np->full_name); | ||
493 | return -EINVAL; | ||
494 | } | ||
495 | |||
496 | ebid->configs[i].cs = cs; | ||
497 | |||
498 | if (apply) { | ||
499 | conf.cs = cs; | ||
500 | ret = caps->apply_config(ebid, &conf); | ||
501 | if (ret) | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | caps->get_config(ebid, &ebid->configs[i]); | ||
506 | |||
507 | /* | ||
508 | * Attach the EBI device to the generic SMC logic if at least | ||
509 | * one "atmel,smc-" property is present. | ||
510 | */ | ||
511 | if (ebi->ebi_csa && ret) | ||
512 | regmap_field_update_bits(ebi->ebi_csa, | ||
513 | BIT(cs), 0); | ||
514 | } | ||
515 | |||
516 | list_add_tail(&ebid->node, &ebi->devs); | ||
517 | |||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | static const struct reg_field at91sam9260_ebi_csa = | ||
522 | REG_FIELD(AT91SAM9260_MATRIX_EBICSA, 0, | ||
523 | AT91_MATRIX_EBI_NUM_CS - 1); | ||
524 | |||
525 | static const struct at91_ebi_caps at91sam9260_ebi_caps = { | ||
526 | .available_cs = 0xff, | ||
527 | .ebi_csa = &at91sam9260_ebi_csa, | ||
528 | .get_config = at91sam9_ebi_get_config, | ||
529 | .xlate_config = at91sam9_ebi_xslate_config, | ||
530 | .apply_config = at91sam9_ebi_apply_config, | ||
531 | .init = at91sam9_ebi_init, | ||
532 | }; | ||
533 | |||
534 | static const struct reg_field at91sam9261_ebi_csa = | ||
535 | REG_FIELD(AT91SAM9261_MATRIX_EBICSA, 0, | ||
536 | AT91_MATRIX_EBI_NUM_CS - 1); | ||
537 | |||
538 | static const struct at91_ebi_caps at91sam9261_ebi_caps = { | ||
539 | .available_cs = 0xff, | ||
540 | .ebi_csa = &at91sam9261_ebi_csa, | ||
541 | .get_config = at91sam9_ebi_get_config, | ||
542 | .xlate_config = at91sam9_ebi_xslate_config, | ||
543 | .apply_config = at91sam9_ebi_apply_config, | ||
544 | .init = at91sam9_ebi_init, | ||
545 | }; | ||
546 | |||
547 | static const struct reg_field at91sam9263_ebi0_csa = | ||
548 | REG_FIELD(AT91SAM9263_MATRIX_EBI0CSA, 0, | ||
549 | AT91_MATRIX_EBI_NUM_CS - 1); | ||
550 | |||
551 | static const struct at91_ebi_caps at91sam9263_ebi0_caps = { | ||
552 | .available_cs = 0x3f, | ||
553 | .ebi_csa = &at91sam9263_ebi0_csa, | ||
554 | .get_config = at91sam9_ebi_get_config, | ||
555 | .xlate_config = at91sam9_ebi_xslate_config, | ||
556 | .apply_config = at91sam9_ebi_apply_config, | ||
557 | .init = at91sam9_ebi_init, | ||
558 | }; | ||
559 | |||
560 | static const struct reg_field at91sam9263_ebi1_csa = | ||
561 | REG_FIELD(AT91SAM9263_MATRIX_EBI1CSA, 0, | ||
562 | AT91_MATRIX_EBI_NUM_CS - 1); | ||
563 | |||
564 | static const struct at91_ebi_caps at91sam9263_ebi1_caps = { | ||
565 | .available_cs = 0x7, | ||
566 | .ebi_csa = &at91sam9263_ebi1_csa, | ||
567 | .get_config = at91sam9_ebi_get_config, | ||
568 | .xlate_config = at91sam9_ebi_xslate_config, | ||
569 | .apply_config = at91sam9_ebi_apply_config, | ||
570 | .init = at91sam9_ebi_init, | ||
571 | }; | ||
572 | |||
573 | static const struct reg_field at91sam9rl_ebi_csa = | ||
574 | REG_FIELD(AT91SAM9RL_MATRIX_EBICSA, 0, | ||
575 | AT91_MATRIX_EBI_NUM_CS - 1); | ||
576 | |||
577 | static const struct at91_ebi_caps at91sam9rl_ebi_caps = { | ||
578 | .available_cs = 0x3f, | ||
579 | .ebi_csa = &at91sam9rl_ebi_csa, | ||
580 | .get_config = at91sam9_ebi_get_config, | ||
581 | .xlate_config = at91sam9_ebi_xslate_config, | ||
582 | .apply_config = at91sam9_ebi_apply_config, | ||
583 | .init = at91sam9_ebi_init, | ||
584 | }; | ||
585 | |||
586 | static const struct reg_field at91sam9g45_ebi_csa = | ||
587 | REG_FIELD(AT91SAM9G45_MATRIX_EBICSA, 0, | ||
588 | AT91_MATRIX_EBI_NUM_CS - 1); | ||
589 | |||
590 | static const struct at91_ebi_caps at91sam9g45_ebi_caps = { | ||
591 | .available_cs = 0x3f, | ||
592 | .ebi_csa = &at91sam9g45_ebi_csa, | ||
593 | .get_config = at91sam9_ebi_get_config, | ||
594 | .xlate_config = at91sam9_ebi_xslate_config, | ||
595 | .apply_config = at91sam9_ebi_apply_config, | ||
596 | .init = at91sam9_ebi_init, | ||
597 | }; | ||
598 | |||
599 | static const struct at91_ebi_caps at91sam9x5_ebi_caps = { | ||
600 | .available_cs = 0x3f, | ||
601 | .ebi_csa = &at91sam9263_ebi0_csa, | ||
602 | .get_config = at91sam9_ebi_get_config, | ||
603 | .xlate_config = at91sam9_ebi_xslate_config, | ||
604 | .apply_config = at91sam9_ebi_apply_config, | ||
605 | .init = at91sam9_ebi_init, | ||
606 | }; | ||
607 | |||
608 | static const struct at91_ebi_caps sama5d3_ebi_caps = { | ||
609 | .available_cs = 0xf, | ||
610 | .get_config = at91sam9_ebi_get_config, | ||
611 | .xlate_config = at91sam9_ebi_xslate_config, | ||
612 | .apply_config = at91sam9_ebi_apply_config, | ||
613 | .init = sama5d3_ebi_init, | ||
614 | }; | ||
615 | |||
616 | static const struct of_device_id at91_ebi_id_table[] = { | ||
617 | { | ||
618 | .compatible = "atmel,at91sam9260-ebi", | ||
619 | .data = &at91sam9260_ebi_caps, | ||
620 | }, | ||
621 | { | ||
622 | .compatible = "atmel,at91sam9261-ebi", | ||
623 | .data = &at91sam9261_ebi_caps, | ||
624 | }, | ||
625 | { | ||
626 | .compatible = "atmel,at91sam9263-ebi0", | ||
627 | .data = &at91sam9263_ebi0_caps, | ||
628 | }, | ||
629 | { | ||
630 | .compatible = "atmel,at91sam9263-ebi1", | ||
631 | .data = &at91sam9263_ebi1_caps, | ||
632 | }, | ||
633 | { | ||
634 | .compatible = "atmel,at91sam9rl-ebi", | ||
635 | .data = &at91sam9rl_ebi_caps, | ||
636 | }, | ||
637 | { | ||
638 | .compatible = "atmel,at91sam9g45-ebi", | ||
639 | .data = &at91sam9g45_ebi_caps, | ||
640 | }, | ||
641 | { | ||
642 | .compatible = "atmel,at91sam9x5-ebi", | ||
643 | .data = &at91sam9x5_ebi_caps, | ||
644 | }, | ||
645 | { | ||
646 | .compatible = "atmel,sama5d3-ebi", | ||
647 | .data = &sama5d3_ebi_caps, | ||
648 | }, | ||
649 | { /* sentinel */ } | ||
650 | }; | ||
651 | |||
652 | static int at91_ebi_dev_disable(struct at91_ebi *ebi, struct device_node *np) | ||
653 | { | ||
654 | struct device *dev = ebi->dev; | ||
655 | struct property *newprop; | ||
656 | |||
657 | newprop = devm_kzalloc(dev, sizeof(*newprop), GFP_KERNEL); | ||
658 | if (!newprop) | ||
659 | return -ENOMEM; | ||
660 | |||
661 | newprop->name = devm_kstrdup(dev, "status", GFP_KERNEL); | ||
662 | if (!newprop->name) | ||
663 | return -ENOMEM; | ||
664 | |||
665 | newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL); | ||
666 | if (!newprop->name) | ||
667 | return -ENOMEM; | ||
668 | |||
669 | newprop->length = sizeof("disabled"); | ||
670 | |||
671 | return of_update_property(np, newprop); | ||
672 | } | ||
673 | |||
674 | static int at91_ebi_probe(struct platform_device *pdev) | ||
675 | { | ||
676 | struct device *dev = &pdev->dev; | ||
677 | struct device_node *child, *np = dev->of_node; | ||
678 | const struct of_device_id *match; | ||
679 | struct at91_ebi *ebi; | ||
680 | int ret, reg_cells; | ||
681 | struct clk *clk; | ||
682 | u32 val; | ||
683 | |||
684 | match = of_match_device(at91_ebi_id_table, dev); | ||
685 | if (!match || !match->data) | ||
686 | return -EINVAL; | ||
687 | |||
688 | ebi = devm_kzalloc(dev, sizeof(*ebi), GFP_KERNEL); | ||
689 | if (!ebi) | ||
690 | return -ENOMEM; | ||
691 | |||
692 | INIT_LIST_HEAD(&ebi->devs); | ||
693 | ebi->caps = match->data; | ||
694 | ebi->dev = dev; | ||
695 | |||
696 | clk = devm_clk_get(dev, NULL); | ||
697 | if (IS_ERR(clk)) | ||
698 | return PTR_ERR(clk); | ||
699 | |||
700 | ebi->clk = clk; | ||
701 | |||
702 | ebi->smc = syscon_regmap_lookup_by_phandle(np, "atmel,smc"); | ||
703 | if (IS_ERR(ebi->smc)) | ||
704 | return PTR_ERR(ebi->smc); | ||
705 | |||
706 | /* | ||
707 | * The sama5d3 does not provide an EBICSA register and thus does need | ||
708 | * to access the matrix registers. | ||
709 | */ | ||
710 | if (ebi->caps->ebi_csa) { | ||
711 | ebi->matrix = | ||
712 | syscon_regmap_lookup_by_phandle(np, "atmel,matrix"); | ||
713 | if (IS_ERR(ebi->matrix)) | ||
714 | return PTR_ERR(ebi->matrix); | ||
715 | |||
716 | ebi->ebi_csa = regmap_field_alloc(ebi->matrix, | ||
717 | *ebi->caps->ebi_csa); | ||
718 | if (IS_ERR(ebi->ebi_csa)) | ||
719 | return PTR_ERR(ebi->ebi_csa); | ||
720 | } | ||
721 | |||
722 | ret = ebi->caps->init(ebi); | ||
723 | if (ret) | ||
724 | return ret; | ||
725 | |||
726 | ret = of_property_read_u32(np, "#address-cells", &val); | ||
727 | if (ret) { | ||
728 | dev_err(dev, "missing #address-cells property\n"); | ||
729 | return ret; | ||
730 | } | ||
731 | |||
732 | reg_cells = val; | ||
733 | |||
734 | ret = of_property_read_u32(np, "#size-cells", &val); | ||
735 | if (ret) { | ||
736 | dev_err(dev, "missing #address-cells property\n"); | ||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | reg_cells += val; | ||
741 | |||
742 | for_each_available_child_of_node(np, child) { | ||
743 | if (!of_find_property(child, "reg", NULL)) | ||
744 | continue; | ||
745 | |||
746 | ret = at91_ebi_dev_setup(ebi, child, reg_cells); | ||
747 | if (ret) { | ||
748 | dev_err(dev, "failed to configure EBI bus for %s, disabling the device", | ||
749 | child->full_name); | ||
750 | |||
751 | ret = at91_ebi_dev_disable(ebi, child); | ||
752 | if (ret) | ||
753 | return ret; | ||
754 | } | ||
755 | } | ||
756 | |||
757 | return of_platform_populate(np, NULL, NULL, dev); | ||
758 | } | ||
759 | |||
760 | static struct platform_driver at91_ebi_driver = { | ||
761 | .driver = { | ||
762 | .name = "atmel-ebi", | ||
763 | .of_match_table = at91_ebi_id_table, | ||
764 | }, | ||
765 | }; | ||
766 | builtin_platform_driver_probe(at91_ebi_driver, at91_ebi_probe); | ||
diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c index a3ebc8a87479..53a341f3b305 100644 --- a/drivers/memory/atmel-sdramc.c +++ b/drivers/memory/atmel-sdramc.c | |||
@@ -1,6 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Atmel (Multi-port DDR-)SDRAM Controller driver | 2 | * Atmel (Multi-port DDR-)SDRAM Controller driver |
3 | * | 3 | * |
4 | * Author: Alexandre Belloni <alexandre.belloni@free-electrons.com> | ||
5 | * | ||
4 | * Copyright (C) 2014 Atmel | 6 | * Copyright (C) 2014 Atmel |
5 | * | 7 | * |
6 | * This program is free software: you can redistribute it and/or modify | 8 | * This program is free software: you can redistribute it and/or modify |
@@ -20,7 +22,7 @@ | |||
20 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
21 | #include <linux/err.h> | 23 | #include <linux/err.h> |
22 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 25 | #include <linux/init.h> |
24 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
25 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
26 | 28 | ||
@@ -48,7 +50,6 @@ static const struct of_device_id atmel_ramc_of_match[] = { | |||
48 | { .compatible = "atmel,sama5d3-ddramc", .data = &sama5d3_caps, }, | 50 | { .compatible = "atmel,sama5d3-ddramc", .data = &sama5d3_caps, }, |
49 | {}, | 51 | {}, |
50 | }; | 52 | }; |
51 | MODULE_DEVICE_TABLE(of, atmel_ramc_of_match); | ||
52 | 53 | ||
53 | static int atmel_ramc_probe(struct platform_device *pdev) | 54 | static int atmel_ramc_probe(struct platform_device *pdev) |
54 | { | 55 | { |
@@ -90,8 +91,4 @@ static int __init atmel_ramc_init(void) | |||
90 | { | 91 | { |
91 | return platform_driver_register(&atmel_ramc_driver); | 92 | return platform_driver_register(&atmel_ramc_driver); |
92 | } | 93 | } |
93 | module_init(atmel_ramc_init); | 94 | device_initcall(atmel_ramc_init); |
94 | |||
95 | MODULE_LICENSE("GPL v2"); | ||
96 | MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>"); | ||
97 | MODULE_DESCRIPTION("Atmel (Multi-port DDR-)SDRAM Controller"); | ||
diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 4721b591994f..869c83fb3c5d 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/module.h> | ||
24 | #include <linux/gpio/driver.h> | 23 | #include <linux/gpio/driver.h> |
25 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
26 | #include <linux/irqdomain.h> | 25 | #include <linux/irqdomain.h> |
@@ -1807,7 +1806,6 @@ static const struct of_device_id gpmc_dt_ids[] = { | |||
1807 | { .compatible = "ti,am3352-gpmc" }, /* am335x devices */ | 1806 | { .compatible = "ti,am3352-gpmc" }, /* am335x devices */ |
1808 | { } | 1807 | { } |
1809 | }; | 1808 | }; |
1810 | MODULE_DEVICE_TABLE(of, gpmc_dt_ids); | ||
1811 | 1809 | ||
1812 | /** | 1810 | /** |
1813 | * gpmc_read_settings_dt - read gpmc settings from device-tree | 1811 | * gpmc_read_settings_dt - read gpmc settings from device-tree |
@@ -2154,68 +2152,6 @@ err: | |||
2154 | return ret; | 2152 | return ret; |
2155 | } | 2153 | } |
2156 | 2154 | ||
2157 | static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) | ||
2158 | { | ||
2159 | return 1; /* we're input only */ | ||
2160 | } | ||
2161 | |||
2162 | static int gpmc_gpio_direction_input(struct gpio_chip *chip, | ||
2163 | unsigned int offset) | ||
2164 | { | ||
2165 | return 0; /* we're input only */ | ||
2166 | } | ||
2167 | |||
2168 | static int gpmc_gpio_direction_output(struct gpio_chip *chip, | ||
2169 | unsigned int offset, int value) | ||
2170 | { | ||
2171 | return -EINVAL; /* we're input only */ | ||
2172 | } | ||
2173 | |||
2174 | static void gpmc_gpio_set(struct gpio_chip *chip, unsigned int offset, | ||
2175 | int value) | ||
2176 | { | ||
2177 | } | ||
2178 | |||
2179 | static int gpmc_gpio_get(struct gpio_chip *chip, unsigned int offset) | ||
2180 | { | ||
2181 | u32 reg; | ||
2182 | |||
2183 | offset += 8; | ||
2184 | |||
2185 | reg = gpmc_read_reg(GPMC_STATUS) & BIT(offset); | ||
2186 | |||
2187 | return !!reg; | ||
2188 | } | ||
2189 | |||
2190 | static int gpmc_gpio_init(struct gpmc_device *gpmc) | ||
2191 | { | ||
2192 | int ret; | ||
2193 | |||
2194 | gpmc->gpio_chip.parent = gpmc->dev; | ||
2195 | gpmc->gpio_chip.owner = THIS_MODULE; | ||
2196 | gpmc->gpio_chip.label = DEVICE_NAME; | ||
2197 | gpmc->gpio_chip.ngpio = gpmc_nr_waitpins; | ||
2198 | gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction; | ||
2199 | gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input; | ||
2200 | gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output; | ||
2201 | gpmc->gpio_chip.set = gpmc_gpio_set; | ||
2202 | gpmc->gpio_chip.get = gpmc_gpio_get; | ||
2203 | gpmc->gpio_chip.base = -1; | ||
2204 | |||
2205 | ret = gpiochip_add(&gpmc->gpio_chip); | ||
2206 | if (ret < 0) { | ||
2207 | dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret); | ||
2208 | return ret; | ||
2209 | } | ||
2210 | |||
2211 | return 0; | ||
2212 | } | ||
2213 | |||
2214 | static void gpmc_gpio_exit(struct gpmc_device *gpmc) | ||
2215 | { | ||
2216 | gpiochip_remove(&gpmc->gpio_chip); | ||
2217 | } | ||
2218 | |||
2219 | static int gpmc_probe_dt(struct platform_device *pdev) | 2155 | static int gpmc_probe_dt(struct platform_device *pdev) |
2220 | { | 2156 | { |
2221 | int ret; | 2157 | int ret; |
@@ -2280,7 +2216,69 @@ static int gpmc_probe_dt_children(struct platform_device *pdev) | |||
2280 | { | 2216 | { |
2281 | return 0; | 2217 | return 0; |
2282 | } | 2218 | } |
2283 | #endif | 2219 | #endif /* CONFIG_OF */ |
2220 | |||
2221 | static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) | ||
2222 | { | ||
2223 | return 1; /* we're input only */ | ||
2224 | } | ||
2225 | |||
2226 | static int gpmc_gpio_direction_input(struct gpio_chip *chip, | ||
2227 | unsigned int offset) | ||
2228 | { | ||
2229 | return 0; /* we're input only */ | ||
2230 | } | ||
2231 | |||
2232 | static int gpmc_gpio_direction_output(struct gpio_chip *chip, | ||
2233 | unsigned int offset, int value) | ||
2234 | { | ||
2235 | return -EINVAL; /* we're input only */ | ||
2236 | } | ||
2237 | |||
2238 | static void gpmc_gpio_set(struct gpio_chip *chip, unsigned int offset, | ||
2239 | int value) | ||
2240 | { | ||
2241 | } | ||
2242 | |||
2243 | static int gpmc_gpio_get(struct gpio_chip *chip, unsigned int offset) | ||
2244 | { | ||
2245 | u32 reg; | ||
2246 | |||
2247 | offset += 8; | ||
2248 | |||
2249 | reg = gpmc_read_reg(GPMC_STATUS) & BIT(offset); | ||
2250 | |||
2251 | return !!reg; | ||
2252 | } | ||
2253 | |||
2254 | static int gpmc_gpio_init(struct gpmc_device *gpmc) | ||
2255 | { | ||
2256 | int ret; | ||
2257 | |||
2258 | gpmc->gpio_chip.parent = gpmc->dev; | ||
2259 | gpmc->gpio_chip.owner = THIS_MODULE; | ||
2260 | gpmc->gpio_chip.label = DEVICE_NAME; | ||
2261 | gpmc->gpio_chip.ngpio = gpmc_nr_waitpins; | ||
2262 | gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction; | ||
2263 | gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input; | ||
2264 | gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output; | ||
2265 | gpmc->gpio_chip.set = gpmc_gpio_set; | ||
2266 | gpmc->gpio_chip.get = gpmc_gpio_get; | ||
2267 | gpmc->gpio_chip.base = -1; | ||
2268 | |||
2269 | ret = gpiochip_add(&gpmc->gpio_chip); | ||
2270 | if (ret < 0) { | ||
2271 | dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret); | ||
2272 | return ret; | ||
2273 | } | ||
2274 | |||
2275 | return 0; | ||
2276 | } | ||
2277 | |||
2278 | static void gpmc_gpio_exit(struct gpmc_device *gpmc) | ||
2279 | { | ||
2280 | gpiochip_remove(&gpmc->gpio_chip); | ||
2281 | } | ||
2284 | 2282 | ||
2285 | static int gpmc_probe(struct platform_device *pdev) | 2283 | static int gpmc_probe(struct platform_device *pdev) |
2286 | { | 2284 | { |
@@ -2436,15 +2434,7 @@ static __init int gpmc_init(void) | |||
2436 | { | 2434 | { |
2437 | return platform_driver_register(&gpmc_driver); | 2435 | return platform_driver_register(&gpmc_driver); |
2438 | } | 2436 | } |
2439 | |||
2440 | static __exit void gpmc_exit(void) | ||
2441 | { | ||
2442 | platform_driver_unregister(&gpmc_driver); | ||
2443 | |||
2444 | } | ||
2445 | |||
2446 | postcore_initcall(gpmc_init); | 2437 | postcore_initcall(gpmc_init); |
2447 | module_exit(gpmc_exit); | ||
2448 | 2438 | ||
2449 | static struct omap3_gpmc_regs gpmc_context; | 2439 | static struct omap3_gpmc_regs gpmc_context; |
2450 | 2440 | ||
diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c index 96756fb4d6bd..bf827a666694 100644 --- a/drivers/memory/samsung/exynos-srom.c +++ b/drivers/memory/samsung/exynos-srom.c | |||
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/module.h> | 14 | #include <linux/init.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/of_address.h> | 16 | #include <linux/of_address.h> |
17 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
@@ -91,17 +91,17 @@ static int exynos_srom_configure_bank(struct exynos_srom *srom, | |||
91 | if (width == 2) | 91 | if (width == 2) |
92 | cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT; | 92 | cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT; |
93 | 93 | ||
94 | bw = __raw_readl(srom->reg_base + EXYNOS_SROM_BW); | 94 | bw = readl_relaxed(srom->reg_base + EXYNOS_SROM_BW); |
95 | bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank); | 95 | bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank); |
96 | __raw_writel(bw, srom->reg_base + EXYNOS_SROM_BW); | 96 | writel_relaxed(bw, srom->reg_base + EXYNOS_SROM_BW); |
97 | 97 | ||
98 | __raw_writel(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) | | 98 | writel_relaxed(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) | |
99 | (timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) | | 99 | (timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) | |
100 | (timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) | | 100 | (timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) | |
101 | (timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) | | 101 | (timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) | |
102 | (timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) | | 102 | (timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) | |
103 | (timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT), | 103 | (timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT), |
104 | srom->reg_base + EXYNOS_SROM_BC0 + bank); | 104 | srom->reg_base + EXYNOS_SROM_BC0 + bank); |
105 | 105 | ||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
@@ -134,7 +134,7 @@ static int exynos_srom_probe(struct platform_device *pdev) | |||
134 | platform_set_drvdata(pdev, srom); | 134 | platform_set_drvdata(pdev, srom); |
135 | 135 | ||
136 | srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets, | 136 | srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets, |
137 | sizeof(exynos_srom_offsets)); | 137 | ARRAY_SIZE(exynos_srom_offsets)); |
138 | if (!srom->reg_offset) { | 138 | if (!srom->reg_offset) { |
139 | iounmap(srom->reg_base); | 139 | iounmap(srom->reg_base); |
140 | return -ENOMEM; | 140 | return -ENOMEM; |
@@ -159,16 +159,6 @@ static int exynos_srom_probe(struct platform_device *pdev) | |||
159 | return of_platform_populate(np, NULL, NULL, dev); | 159 | return of_platform_populate(np, NULL, NULL, dev); |
160 | } | 160 | } |
161 | 161 | ||
162 | static int exynos_srom_remove(struct platform_device *pdev) | ||
163 | { | ||
164 | struct exynos_srom *srom = platform_get_drvdata(pdev); | ||
165 | |||
166 | kfree(srom->reg_offset); | ||
167 | iounmap(srom->reg_base); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | #ifdef CONFIG_PM_SLEEP | 162 | #ifdef CONFIG_PM_SLEEP |
173 | static void exynos_srom_save(void __iomem *base, | 163 | static void exynos_srom_save(void __iomem *base, |
174 | struct exynos_srom_reg_dump *rd, | 164 | struct exynos_srom_reg_dump *rd, |
@@ -211,21 +201,16 @@ static const struct of_device_id of_exynos_srom_ids[] = { | |||
211 | }, | 201 | }, |
212 | {}, | 202 | {}, |
213 | }; | 203 | }; |
214 | MODULE_DEVICE_TABLE(of, of_exynos_srom_ids); | ||
215 | 204 | ||
216 | static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume); | 205 | static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume); |
217 | 206 | ||
218 | static struct platform_driver exynos_srom_driver = { | 207 | static struct platform_driver exynos_srom_driver = { |
219 | .probe = exynos_srom_probe, | 208 | .probe = exynos_srom_probe, |
220 | .remove = exynos_srom_remove, | ||
221 | .driver = { | 209 | .driver = { |
222 | .name = "exynos-srom", | 210 | .name = "exynos-srom", |
223 | .of_match_table = of_exynos_srom_ids, | 211 | .of_match_table = of_exynos_srom_ids, |
224 | .pm = &exynos_srom_pm_ops, | 212 | .pm = &exynos_srom_pm_ops, |
213 | .suppress_bind_attrs = true, | ||
225 | }, | 214 | }, |
226 | }; | 215 | }; |
227 | module_platform_driver(exynos_srom_driver); | 216 | builtin_platform_driver(exynos_srom_driver); |
228 | |||
229 | MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>"); | ||
230 | MODULE_DESCRIPTION("Exynos SROM Controller Driver"); | ||
231 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c index a1ae0cc2b86d..a4803ac192bb 100644 --- a/drivers/memory/tegra/mc.c +++ b/drivers/memory/tegra/mc.c | |||
@@ -186,8 +186,10 @@ static int load_timings(struct tegra_mc *mc, struct device_node *node) | |||
186 | timing = &mc->timings[i++]; | 186 | timing = &mc->timings[i++]; |
187 | 187 | ||
188 | err = load_one_timing(mc, timing, child); | 188 | err = load_one_timing(mc, timing, child); |
189 | if (err) | 189 | if (err) { |
190 | of_node_put(child); | ||
190 | return err; | 191 | return err; |
192 | } | ||
191 | } | 193 | } |
192 | 194 | ||
193 | return 0; | 195 | return 0; |
@@ -206,15 +208,13 @@ static int tegra_mc_setup_timings(struct tegra_mc *mc) | |||
206 | for_each_child_of_node(mc->dev->of_node, node) { | 208 | for_each_child_of_node(mc->dev->of_node, node) { |
207 | err = of_property_read_u32(node, "nvidia,ram-code", | 209 | err = of_property_read_u32(node, "nvidia,ram-code", |
208 | &node_ram_code); | 210 | &node_ram_code); |
209 | if (err || (node_ram_code != ram_code)) { | 211 | if (err || (node_ram_code != ram_code)) |
210 | of_node_put(node); | ||
211 | continue; | 212 | continue; |
212 | } | ||
213 | 213 | ||
214 | err = load_timings(mc, node); | 214 | err = load_timings(mc, node); |
215 | of_node_put(node); | ||
215 | if (err) | 216 | if (err) |
216 | return err; | 217 | return err; |
217 | of_node_put(node); | ||
218 | break; | 218 | break; |
219 | } | 219 | } |
220 | 220 | ||
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 3dac7be39654..06cc781ebac1 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c | |||
@@ -970,8 +970,10 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, | |||
970 | timing = &emc->timings[i++]; | 970 | timing = &emc->timings[i++]; |
971 | 971 | ||
972 | err = load_one_timing_from_dt(emc, timing, child); | 972 | err = load_one_timing_from_dt(emc, timing, child); |
973 | if (err) | 973 | if (err) { |
974 | of_node_put(child); | ||
974 | return err; | 975 | return err; |
976 | } | ||
975 | } | 977 | } |
976 | 978 | ||
977 | sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, | 979 | sort(emc->timings, emc->num_timings, sizeof(*timing), cmp_timings, |
@@ -995,10 +997,8 @@ tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) | |||
995 | u32 value; | 997 | u32 value; |
996 | 998 | ||
997 | err = of_property_read_u32(np, "nvidia,ram-code", &value); | 999 | err = of_property_read_u32(np, "nvidia,ram-code", &value); |
998 | if (err || (value != ram_code)) { | 1000 | if (err || (value != ram_code)) |
999 | of_node_put(np); | ||
1000 | continue; | 1001 | continue; |
1001 | } | ||
1002 | 1002 | ||
1003 | return np; | 1003 | return np; |
1004 | } | 1004 | } |