diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/amba/bus.c | 26 | ||||
-rw-r--r-- | drivers/input/touchscreen/w90p910_ts.c | 4 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 13 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/ep93xx_pwm.c | 384 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.c | 73 | ||||
-rw-r--r-- | drivers/mmc/host/mmci.h | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/ts7250.c | 5 | ||||
-rw-r--r-- | drivers/net/Kconfig | 2 | ||||
-rw-r--r-- | drivers/serial/amba-pl011.c | 26 | ||||
-rw-r--r-- | drivers/video/Kconfig | 4 | ||||
-rw-r--r-- | drivers/video/atmel_lcdfb.c | 6 | ||||
-rw-r--r-- | drivers/video/backlight/Kconfig | 2 |
13 files changed, 528 insertions, 20 deletions
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 246650673010..f60b2b6a0931 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -204,6 +204,7 @@ static void amba_device_release(struct device *dev) | |||
204 | int amba_device_register(struct amba_device *dev, struct resource *parent) | 204 | int amba_device_register(struct amba_device *dev, struct resource *parent) |
205 | { | 205 | { |
206 | u32 pid, cid; | 206 | u32 pid, cid; |
207 | u32 size; | ||
207 | void __iomem *tmp; | 208 | void __iomem *tmp; |
208 | int i, ret; | 209 | int i, ret; |
209 | 210 | ||
@@ -229,16 +230,25 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) | |||
229 | if (ret) | 230 | if (ret) |
230 | goto err_out; | 231 | goto err_out; |
231 | 232 | ||
232 | tmp = ioremap(dev->res.start, SZ_4K); | 233 | /* |
234 | * Dynamically calculate the size of the resource | ||
235 | * and use this for iomap | ||
236 | */ | ||
237 | size = resource_size(&dev->res); | ||
238 | tmp = ioremap(dev->res.start, size); | ||
233 | if (!tmp) { | 239 | if (!tmp) { |
234 | ret = -ENOMEM; | 240 | ret = -ENOMEM; |
235 | goto err_release; | 241 | goto err_release; |
236 | } | 242 | } |
237 | 243 | ||
244 | /* | ||
245 | * Read pid and cid based on size of resource | ||
246 | * they are located at end of region | ||
247 | */ | ||
238 | for (pid = 0, i = 0; i < 4; i++) | 248 | for (pid = 0, i = 0; i < 4; i++) |
239 | pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); | 249 | pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8); |
240 | for (cid = 0, i = 0; i < 4; i++) | 250 | for (cid = 0, i = 0; i < 4; i++) |
241 | cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); | 251 | cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8); |
242 | 252 | ||
243 | iounmap(tmp); | 253 | iounmap(tmp); |
244 | 254 | ||
@@ -353,11 +363,14 @@ amba_find_device(const char *busid, struct device *parent, unsigned int id, | |||
353 | int amba_request_regions(struct amba_device *dev, const char *name) | 363 | int amba_request_regions(struct amba_device *dev, const char *name) |
354 | { | 364 | { |
355 | int ret = 0; | 365 | int ret = 0; |
366 | u32 size; | ||
356 | 367 | ||
357 | if (!name) | 368 | if (!name) |
358 | name = dev->dev.driver->name; | 369 | name = dev->dev.driver->name; |
359 | 370 | ||
360 | if (!request_mem_region(dev->res.start, SZ_4K, name)) | 371 | size = resource_size(&dev->res); |
372 | |||
373 | if (!request_mem_region(dev->res.start, size, name)) | ||
361 | ret = -EBUSY; | 374 | ret = -EBUSY; |
362 | 375 | ||
363 | return ret; | 376 | return ret; |
@@ -371,7 +384,10 @@ int amba_request_regions(struct amba_device *dev, const char *name) | |||
371 | */ | 384 | */ |
372 | void amba_release_regions(struct amba_device *dev) | 385 | void amba_release_regions(struct amba_device *dev) |
373 | { | 386 | { |
374 | release_mem_region(dev->res.start, SZ_4K); | 387 | u32 size; |
388 | |||
389 | size = resource_size(&dev->res); | ||
390 | release_mem_region(dev->res.start, size); | ||
375 | } | 391 | } |
376 | 392 | ||
377 | EXPORT_SYMBOL(amba_driver_register); | 393 | EXPORT_SYMBOL(amba_driver_register); |
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c index 6071f5882572..937dfe4e9b12 100644 --- a/drivers/input/touchscreen/w90p910_ts.c +++ b/drivers/input/touchscreen/w90p910_ts.c | |||
@@ -326,7 +326,7 @@ static struct platform_driver w90x900ts_driver = { | |||
326 | .probe = w90x900ts_probe, | 326 | .probe = w90x900ts_probe, |
327 | .remove = __devexit_p(w90x900ts_remove), | 327 | .remove = __devexit_p(w90x900ts_remove), |
328 | .driver = { | 328 | .driver = { |
329 | .name = "w90x900-ts", | 329 | .name = "nuc900-ts", |
330 | .owner = THIS_MODULE, | 330 | .owner = THIS_MODULE, |
331 | }, | 331 | }, |
332 | }; | 332 | }; |
@@ -347,4 +347,4 @@ module_exit(w90x900ts_exit); | |||
347 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | 347 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); |
348 | MODULE_DESCRIPTION("w90p910 touch screen driver!"); | 348 | MODULE_DESCRIPTION("w90p910 touch screen driver!"); |
349 | MODULE_LICENSE("GPL"); | 349 | MODULE_LICENSE("GPL"); |
350 | MODULE_ALIAS("platform:w90p910-ts"); | 350 | MODULE_ALIAS("platform:nuc900-ts"); |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 68ab39d7cb35..df1f86b5c83e 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -233,6 +233,19 @@ config ISL29003 | |||
233 | This driver can also be built as a module. If so, the module | 233 | This driver can also be built as a module. If so, the module |
234 | will be called isl29003. | 234 | will be called isl29003. |
235 | 235 | ||
236 | config EP93XX_PWM | ||
237 | tristate "EP93xx PWM support" | ||
238 | depends on ARCH_EP93XX | ||
239 | help | ||
240 | This option enables device driver support for the PWM channels | ||
241 | on the Cirrus EP93xx processors. The EP9307 chip only has one | ||
242 | PWM channel all the others have two, the second channel is an | ||
243 | alternate function of the EGPIO14 pin. A sysfs interface is | ||
244 | provided to control the PWM channels. | ||
245 | |||
246 | To compile this driver as a module, choose M here: the module will | ||
247 | be called ep93xx_pwm. | ||
248 | |||
236 | source "drivers/misc/c2port/Kconfig" | 249 | source "drivers/misc/c2port/Kconfig" |
237 | source "drivers/misc/eeprom/Kconfig" | 250 | source "drivers/misc/eeprom/Kconfig" |
238 | source "drivers/misc/cb710/Kconfig" | 251 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 36f733cd60e6..f982d2ecfde7 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_SGI_XP) += sgi-xp/ | |||
19 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ | 19 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ |
20 | obj-$(CONFIG_HP_ILO) += hpilo.o | 20 | obj-$(CONFIG_HP_ILO) += hpilo.o |
21 | obj-$(CONFIG_ISL29003) += isl29003.o | 21 | obj-$(CONFIG_ISL29003) += isl29003.o |
22 | obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o | ||
22 | obj-$(CONFIG_C2PORT) += c2port/ | 23 | obj-$(CONFIG_C2PORT) += c2port/ |
23 | obj-y += eeprom/ | 24 | obj-y += eeprom/ |
24 | obj-y += cb710/ | 25 | obj-y += cb710/ |
diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c new file mode 100644 index 000000000000..ba4694169d79 --- /dev/null +++ b/drivers/misc/ep93xx_pwm.c | |||
@@ -0,0 +1,384 @@ | |||
1 | /* | ||
2 | * Simple PWM driver for EP93XX | ||
3 | * | ||
4 | * (c) Copyright 2009 Matthieu Crapet <mcrapet@gmail.com> | ||
5 | * (c) Copyright 2009 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version | ||
10 | * 2 of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * EP9307 has only one channel: | ||
13 | * - PWMOUT | ||
14 | * | ||
15 | * EP9301/02/12/15 have two channels: | ||
16 | * - PWMOUT | ||
17 | * - PWMOUT1 (alternate function for EGPIO14) | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #include <mach/platform.h> | ||
27 | |||
28 | #define EP93XX_PWMx_TERM_COUNT 0x00 | ||
29 | #define EP93XX_PWMx_DUTY_CYCLE 0x04 | ||
30 | #define EP93XX_PWMx_ENABLE 0x08 | ||
31 | #define EP93XX_PWMx_INVERT 0x0C | ||
32 | |||
33 | #define EP93XX_PWM_MAX_COUNT 0xFFFF | ||
34 | |||
35 | struct ep93xx_pwm { | ||
36 | void __iomem *mmio_base; | ||
37 | struct clk *clk; | ||
38 | u32 duty_percent; | ||
39 | }; | ||
40 | |||
41 | static inline void ep93xx_pwm_writel(struct ep93xx_pwm *pwm, | ||
42 | unsigned int val, unsigned int off) | ||
43 | { | ||
44 | __raw_writel(val, pwm->mmio_base + off); | ||
45 | } | ||
46 | |||
47 | static inline unsigned int ep93xx_pwm_readl(struct ep93xx_pwm *pwm, | ||
48 | unsigned int off) | ||
49 | { | ||
50 | return __raw_readl(pwm->mmio_base + off); | ||
51 | } | ||
52 | |||
53 | static inline void ep93xx_pwm_write_tc(struct ep93xx_pwm *pwm, u16 value) | ||
54 | { | ||
55 | ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_TERM_COUNT); | ||
56 | } | ||
57 | |||
58 | static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm) | ||
59 | { | ||
60 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT); | ||
61 | } | ||
62 | |||
63 | static inline void ep93xx_pwm_write_dc(struct ep93xx_pwm *pwm, u16 value) | ||
64 | { | ||
65 | ep93xx_pwm_writel(pwm, value, EP93XX_PWMx_DUTY_CYCLE); | ||
66 | } | ||
67 | |||
68 | static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm) | ||
69 | { | ||
70 | ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE); | ||
71 | } | ||
72 | |||
73 | static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm) | ||
74 | { | ||
75 | ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE); | ||
76 | } | ||
77 | |||
78 | static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm) | ||
79 | { | ||
80 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1; | ||
81 | } | ||
82 | |||
83 | static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm) | ||
84 | { | ||
85 | ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT); | ||
86 | } | ||
87 | |||
88 | static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm) | ||
89 | { | ||
90 | ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT); | ||
91 | } | ||
92 | |||
93 | static inline int ep93xx_pwm_is_inverted(struct ep93xx_pwm *pwm) | ||
94 | { | ||
95 | return ep93xx_pwm_readl(pwm, EP93XX_PWMx_INVERT) & 0x1; | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * /sys/devices/platform/ep93xx-pwm.N | ||
100 | * /min_freq read-only minimum pwm output frequency | ||
101 | * /max_req read-only maximum pwm output frequency | ||
102 | * /freq read-write pwm output frequency (0 = disable output) | ||
103 | * /duty_percent read-write pwm duty cycle percent (1..99) | ||
104 | * /invert read-write invert pwm output | ||
105 | */ | ||
106 | |||
107 | static ssize_t ep93xx_pwm_get_min_freq(struct device *dev, | ||
108 | struct device_attribute *attr, char *buf) | ||
109 | { | ||
110 | struct platform_device *pdev = to_platform_device(dev); | ||
111 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
112 | unsigned long rate = clk_get_rate(pwm->clk); | ||
113 | |||
114 | return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1)); | ||
115 | } | ||
116 | |||
117 | static ssize_t ep93xx_pwm_get_max_freq(struct device *dev, | ||
118 | struct device_attribute *attr, char *buf) | ||
119 | { | ||
120 | struct platform_device *pdev = to_platform_device(dev); | ||
121 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
122 | unsigned long rate = clk_get_rate(pwm->clk); | ||
123 | |||
124 | return sprintf(buf, "%ld\n", rate / 2); | ||
125 | } | ||
126 | |||
127 | static ssize_t ep93xx_pwm_get_freq(struct device *dev, | ||
128 | struct device_attribute *attr, char *buf) | ||
129 | { | ||
130 | struct platform_device *pdev = to_platform_device(dev); | ||
131 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
132 | |||
133 | if (ep93xx_pwm_is_enabled(pwm)) { | ||
134 | unsigned long rate = clk_get_rate(pwm->clk); | ||
135 | u16 term = ep93xx_pwm_read_tc(pwm); | ||
136 | |||
137 | return sprintf(buf, "%ld\n", rate / (term + 1)); | ||
138 | } else { | ||
139 | return sprintf(buf, "disabled\n"); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static ssize_t ep93xx_pwm_set_freq(struct device *dev, | ||
144 | struct device_attribute *attr, const char *buf, size_t count) | ||
145 | { | ||
146 | struct platform_device *pdev = to_platform_device(dev); | ||
147 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
148 | long val; | ||
149 | int err; | ||
150 | |||
151 | err = strict_strtol(buf, 10, &val); | ||
152 | if (err) | ||
153 | return -EINVAL; | ||
154 | |||
155 | if (val == 0) { | ||
156 | ep93xx_pwm_disable(pwm); | ||
157 | } else if (val <= (clk_get_rate(pwm->clk) / 2)) { | ||
158 | u32 term, duty; | ||
159 | |||
160 | val = (clk_get_rate(pwm->clk) / val) - 1; | ||
161 | if (val > EP93XX_PWM_MAX_COUNT) | ||
162 | val = EP93XX_PWM_MAX_COUNT; | ||
163 | if (val < 1) | ||
164 | val = 1; | ||
165 | |||
166 | term = ep93xx_pwm_read_tc(pwm); | ||
167 | duty = ((val + 1) * pwm->duty_percent / 100) - 1; | ||
168 | |||
169 | /* If pwm is running, order is important */ | ||
170 | if (val > term) { | ||
171 | ep93xx_pwm_write_tc(pwm, val); | ||
172 | ep93xx_pwm_write_dc(pwm, duty); | ||
173 | } else { | ||
174 | ep93xx_pwm_write_dc(pwm, duty); | ||
175 | ep93xx_pwm_write_tc(pwm, val); | ||
176 | } | ||
177 | |||
178 | if (!ep93xx_pwm_is_enabled(pwm)) | ||
179 | ep93xx_pwm_enable(pwm); | ||
180 | } else { | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | return count; | ||
185 | } | ||
186 | |||
187 | static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev, | ||
188 | struct device_attribute *attr, char *buf) | ||
189 | { | ||
190 | struct platform_device *pdev = to_platform_device(dev); | ||
191 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
192 | |||
193 | return sprintf(buf, "%d\n", pwm->duty_percent); | ||
194 | } | ||
195 | |||
196 | static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev, | ||
197 | struct device_attribute *attr, const char *buf, size_t count) | ||
198 | { | ||
199 | struct platform_device *pdev = to_platform_device(dev); | ||
200 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
201 | long val; | ||
202 | int err; | ||
203 | |||
204 | err = strict_strtol(buf, 10, &val); | ||
205 | if (err) | ||
206 | return -EINVAL; | ||
207 | |||
208 | if (val > 0 && val < 100) { | ||
209 | u32 term = ep93xx_pwm_read_tc(pwm); | ||
210 | ep93xx_pwm_write_dc(pwm, ((term + 1) * val / 100) - 1); | ||
211 | pwm->duty_percent = val; | ||
212 | return count; | ||
213 | } | ||
214 | |||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | static ssize_t ep93xx_pwm_get_invert(struct device *dev, | ||
219 | struct device_attribute *attr, char *buf) | ||
220 | { | ||
221 | struct platform_device *pdev = to_platform_device(dev); | ||
222 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
223 | |||
224 | return sprintf(buf, "%d\n", ep93xx_pwm_is_inverted(pwm)); | ||
225 | } | ||
226 | |||
227 | static ssize_t ep93xx_pwm_set_invert(struct device *dev, | ||
228 | struct device_attribute *attr, const char *buf, size_t count) | ||
229 | { | ||
230 | struct platform_device *pdev = to_platform_device(dev); | ||
231 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
232 | long val; | ||
233 | int err; | ||
234 | |||
235 | err = strict_strtol(buf, 10, &val); | ||
236 | if (err) | ||
237 | return -EINVAL; | ||
238 | |||
239 | if (val == 0) | ||
240 | ep93xx_pwm_normal(pwm); | ||
241 | else if (val == 1) | ||
242 | ep93xx_pwm_invert(pwm); | ||
243 | else | ||
244 | return -EINVAL; | ||
245 | |||
246 | return count; | ||
247 | } | ||
248 | |||
249 | static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL); | ||
250 | static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL); | ||
251 | static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO, | ||
252 | ep93xx_pwm_get_freq, ep93xx_pwm_set_freq); | ||
253 | static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO, | ||
254 | ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent); | ||
255 | static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO, | ||
256 | ep93xx_pwm_get_invert, ep93xx_pwm_set_invert); | ||
257 | |||
258 | static struct attribute *ep93xx_pwm_attrs[] = { | ||
259 | &dev_attr_min_freq.attr, | ||
260 | &dev_attr_max_freq.attr, | ||
261 | &dev_attr_freq.attr, | ||
262 | &dev_attr_duty_percent.attr, | ||
263 | &dev_attr_invert.attr, | ||
264 | NULL | ||
265 | }; | ||
266 | |||
267 | static const struct attribute_group ep93xx_pwm_sysfs_files = { | ||
268 | .attrs = ep93xx_pwm_attrs, | ||
269 | }; | ||
270 | |||
271 | static int __init ep93xx_pwm_probe(struct platform_device *pdev) | ||
272 | { | ||
273 | struct ep93xx_pwm *pwm; | ||
274 | struct resource *res; | ||
275 | int err; | ||
276 | |||
277 | err = ep93xx_pwm_acquire_gpio(pdev); | ||
278 | if (err) | ||
279 | return err; | ||
280 | |||
281 | pwm = kzalloc(sizeof(struct ep93xx_pwm), GFP_KERNEL); | ||
282 | if (!pwm) { | ||
283 | err = -ENOMEM; | ||
284 | goto fail_no_mem; | ||
285 | } | ||
286 | |||
287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
288 | if (res == NULL) { | ||
289 | err = -ENXIO; | ||
290 | goto fail_no_mem_resource; | ||
291 | } | ||
292 | |||
293 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
294 | if (res == NULL) { | ||
295 | err = -EBUSY; | ||
296 | goto fail_no_mem_resource; | ||
297 | } | ||
298 | |||
299 | pwm->mmio_base = ioremap(res->start, resource_size(res)); | ||
300 | if (pwm->mmio_base == NULL) { | ||
301 | err = -ENXIO; | ||
302 | goto fail_no_ioremap; | ||
303 | } | ||
304 | |||
305 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
306 | if (err) | ||
307 | goto fail_no_sysfs; | ||
308 | |||
309 | pwm->clk = clk_get(&pdev->dev, "pwm_clk"); | ||
310 | if (IS_ERR(pwm->clk)) { | ||
311 | err = PTR_ERR(pwm->clk); | ||
312 | goto fail_no_clk; | ||
313 | } | ||
314 | |||
315 | pwm->duty_percent = 50; | ||
316 | |||
317 | platform_set_drvdata(pdev, pwm); | ||
318 | |||
319 | /* disable pwm at startup. Avoids zero value. */ | ||
320 | ep93xx_pwm_disable(pwm); | ||
321 | ep93xx_pwm_write_tc(pwm, EP93XX_PWM_MAX_COUNT); | ||
322 | ep93xx_pwm_write_dc(pwm, EP93XX_PWM_MAX_COUNT / 2); | ||
323 | |||
324 | clk_enable(pwm->clk); | ||
325 | |||
326 | return 0; | ||
327 | |||
328 | fail_no_clk: | ||
329 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
330 | fail_no_sysfs: | ||
331 | iounmap(pwm->mmio_base); | ||
332 | fail_no_ioremap: | ||
333 | release_mem_region(res->start, resource_size(res)); | ||
334 | fail_no_mem_resource: | ||
335 | kfree(pwm); | ||
336 | fail_no_mem: | ||
337 | ep93xx_pwm_release_gpio(pdev); | ||
338 | return err; | ||
339 | } | ||
340 | |||
341 | static int __exit ep93xx_pwm_remove(struct platform_device *pdev) | ||
342 | { | ||
343 | struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); | ||
344 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
345 | |||
346 | ep93xx_pwm_disable(pwm); | ||
347 | clk_disable(pwm->clk); | ||
348 | clk_put(pwm->clk); | ||
349 | platform_set_drvdata(pdev, NULL); | ||
350 | sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); | ||
351 | iounmap(pwm->mmio_base); | ||
352 | release_mem_region(res->start, resource_size(res)); | ||
353 | kfree(pwm); | ||
354 | ep93xx_pwm_release_gpio(pdev); | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static struct platform_driver ep93xx_pwm_driver = { | ||
360 | .driver = { | ||
361 | .name = "ep93xx-pwm", | ||
362 | .owner = THIS_MODULE, | ||
363 | }, | ||
364 | .remove = __exit_p(ep93xx_pwm_remove), | ||
365 | }; | ||
366 | |||
367 | static int __init ep93xx_pwm_init(void) | ||
368 | { | ||
369 | return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe); | ||
370 | } | ||
371 | |||
372 | static void __exit ep93xx_pwm_exit(void) | ||
373 | { | ||
374 | platform_driver_unregister(&ep93xx_pwm_driver); | ||
375 | } | ||
376 | |||
377 | module_init(ep93xx_pwm_init); | ||
378 | module_exit(ep93xx_pwm_exit); | ||
379 | |||
380 | MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " | ||
381 | "H Hartley Sweeten <hsweeten@visionengravers.com>"); | ||
382 | MODULE_DESCRIPTION("EP93xx PWM driver"); | ||
383 | MODULE_LICENSE("GPL"); | ||
384 | MODULE_ALIAS("platform:ep93xx-pwm"); | ||
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index e1aa8471ab1c..a923ee27c09e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/amba/bus.h> | 21 | #include <linux/amba/bus.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
24 | #include <linux/gpio.h> | ||
24 | 25 | ||
25 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
26 | #include <asm/div64.h> | 27 | #include <asm/div64.h> |
@@ -472,17 +473,41 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
472 | } | 473 | } |
473 | } | 474 | } |
474 | 475 | ||
476 | static int mmci_get_ro(struct mmc_host *mmc) | ||
477 | { | ||
478 | struct mmci_host *host = mmc_priv(mmc); | ||
479 | |||
480 | if (host->gpio_wp == -ENOSYS) | ||
481 | return -ENOSYS; | ||
482 | |||
483 | return gpio_get_value(host->gpio_wp); | ||
484 | } | ||
485 | |||
486 | static int mmci_get_cd(struct mmc_host *mmc) | ||
487 | { | ||
488 | struct mmci_host *host = mmc_priv(mmc); | ||
489 | unsigned int status; | ||
490 | |||
491 | if (host->gpio_cd == -ENOSYS) | ||
492 | status = host->plat->status(mmc_dev(host->mmc)); | ||
493 | else | ||
494 | status = gpio_get_value(host->gpio_cd); | ||
495 | |||
496 | return !status; | ||
497 | } | ||
498 | |||
475 | static const struct mmc_host_ops mmci_ops = { | 499 | static const struct mmc_host_ops mmci_ops = { |
476 | .request = mmci_request, | 500 | .request = mmci_request, |
477 | .set_ios = mmci_set_ios, | 501 | .set_ios = mmci_set_ios, |
502 | .get_ro = mmci_get_ro, | ||
503 | .get_cd = mmci_get_cd, | ||
478 | }; | 504 | }; |
479 | 505 | ||
480 | static void mmci_check_status(unsigned long data) | 506 | static void mmci_check_status(unsigned long data) |
481 | { | 507 | { |
482 | struct mmci_host *host = (struct mmci_host *)data; | 508 | struct mmci_host *host = (struct mmci_host *)data; |
483 | unsigned int status; | 509 | unsigned int status = mmci_get_cd(host->mmc); |
484 | 510 | ||
485 | status = host->plat->status(mmc_dev(host->mmc)); | ||
486 | if (status ^ host->oldstat) | 511 | if (status ^ host->oldstat) |
487 | mmc_detect_change(host->mmc, 0); | 512 | mmc_detect_change(host->mmc, 0); |
488 | 513 | ||
@@ -515,12 +540,15 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
515 | 540 | ||
516 | host = mmc_priv(mmc); | 541 | host = mmc_priv(mmc); |
517 | host->mmc = mmc; | 542 | host->mmc = mmc; |
518 | /* Bits 12 thru 19 is the designer */ | 543 | |
519 | host->hw_designer = (dev->periphid >> 12) & 0xff; | 544 | host->gpio_wp = -ENOSYS; |
520 | /* Bits 20 thru 23 is the revison */ | 545 | host->gpio_cd = -ENOSYS; |
521 | host->hw_revision = (dev->periphid >> 20) & 0xf; | 546 | |
547 | host->hw_designer = amba_manf(dev); | ||
548 | host->hw_revision = amba_rev(dev); | ||
522 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); | 549 | DBG(host, "designer ID = 0x%02x\n", host->hw_designer); |
523 | DBG(host, "revision = 0x%01x\n", host->hw_revision); | 550 | DBG(host, "revision = 0x%01x\n", host->hw_revision); |
551 | |||
524 | host->clk = clk_get(&dev->dev, NULL); | 552 | host->clk = clk_get(&dev->dev, NULL); |
525 | if (IS_ERR(host->clk)) { | 553 | if (IS_ERR(host->clk)) { |
526 | ret = PTR_ERR(host->clk); | 554 | ret = PTR_ERR(host->clk); |
@@ -591,6 +619,27 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
591 | writel(0, host->base + MMCIMASK1); | 619 | writel(0, host->base + MMCIMASK1); |
592 | writel(0xfff, host->base + MMCICLEAR); | 620 | writel(0xfff, host->base + MMCICLEAR); |
593 | 621 | ||
622 | #ifdef CONFIG_GPIOLIB | ||
623 | if (gpio_is_valid(plat->gpio_cd)) { | ||
624 | ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); | ||
625 | if (ret == 0) | ||
626 | ret = gpio_direction_input(plat->gpio_cd); | ||
627 | if (ret == 0) | ||
628 | host->gpio_cd = plat->gpio_cd; | ||
629 | else if (ret != -ENOSYS) | ||
630 | goto err_gpio_cd; | ||
631 | } | ||
632 | if (gpio_is_valid(plat->gpio_wp)) { | ||
633 | ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); | ||
634 | if (ret == 0) | ||
635 | ret = gpio_direction_input(plat->gpio_wp); | ||
636 | if (ret == 0) | ||
637 | host->gpio_wp = plat->gpio_wp; | ||
638 | else if (ret != -ENOSYS) | ||
639 | goto err_gpio_wp; | ||
640 | } | ||
641 | #endif | ||
642 | |||
594 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); | 643 | ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); |
595 | if (ret) | 644 | if (ret) |
596 | goto unmap; | 645 | goto unmap; |
@@ -602,6 +651,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
602 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); | 651 | writel(MCI_IRQENABLE, host->base + MMCIMASK0); |
603 | 652 | ||
604 | amba_set_drvdata(dev, mmc); | 653 | amba_set_drvdata(dev, mmc); |
654 | host->oldstat = mmci_get_cd(host->mmc); | ||
605 | 655 | ||
606 | mmc_add_host(mmc); | 656 | mmc_add_host(mmc); |
607 | 657 | ||
@@ -620,6 +670,12 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) | |||
620 | irq0_free: | 670 | irq0_free: |
621 | free_irq(dev->irq[0], host); | 671 | free_irq(dev->irq[0], host); |
622 | unmap: | 672 | unmap: |
673 | if (host->gpio_wp != -ENOSYS) | ||
674 | gpio_free(host->gpio_wp); | ||
675 | err_gpio_wp: | ||
676 | if (host->gpio_cd != -ENOSYS) | ||
677 | gpio_free(host->gpio_cd); | ||
678 | err_gpio_cd: | ||
623 | iounmap(host->base); | 679 | iounmap(host->base); |
624 | clk_disable: | 680 | clk_disable: |
625 | clk_disable(host->clk); | 681 | clk_disable(host->clk); |
@@ -655,6 +711,11 @@ static int __devexit mmci_remove(struct amba_device *dev) | |||
655 | free_irq(dev->irq[0], host); | 711 | free_irq(dev->irq[0], host); |
656 | free_irq(dev->irq[1], host); | 712 | free_irq(dev->irq[1], host); |
657 | 713 | ||
714 | if (host->gpio_wp != -ENOSYS) | ||
715 | gpio_free(host->gpio_wp); | ||
716 | if (host->gpio_cd != -ENOSYS) | ||
717 | gpio_free(host->gpio_cd); | ||
718 | |||
658 | iounmap(host->base); | 719 | iounmap(host->base); |
659 | clk_disable(host->clk); | 720 | clk_disable(host->clk); |
660 | clk_put(host->clk); | 721 | clk_put(host->clk); |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 0441bac1c0ec..839f264c9725 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -151,6 +151,8 @@ struct mmci_host { | |||
151 | struct mmc_data *data; | 151 | struct mmc_data *data; |
152 | struct mmc_host *mmc; | 152 | struct mmc_host *mmc; |
153 | struct clk *clk; | 153 | struct clk *clk; |
154 | int gpio_cd; | ||
155 | int gpio_wp; | ||
154 | 156 | ||
155 | unsigned int data_xfered; | 157 | unsigned int data_xfered; |
156 | 158 | ||
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c index 2c410a011317..0f5562aeedc1 100644 --- a/drivers/mtd/nand/ts7250.c +++ b/drivers/mtd/nand/ts7250.c | |||
@@ -24,8 +24,11 @@ | |||
24 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
25 | #include <linux/mtd/nand.h> | 25 | #include <linux/mtd/nand.h> |
26 | #include <linux/mtd/partitions.h> | 26 | #include <linux/mtd/partitions.h> |
27 | #include <asm/io.h> | 27 | #include <linux/io.h> |
28 | |||
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
30 | #include <mach/ts72xx.h> | ||
31 | |||
29 | #include <asm/sizes.h> | 32 | #include <asm/sizes.h> |
30 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
31 | 34 | ||
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c155bd3ec9f1..f053ba5c37ba 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -209,7 +209,7 @@ config MII | |||
209 | 209 | ||
210 | config MACB | 210 | config MACB |
211 | tristate "Atmel MACB support" | 211 | tristate "Atmel MACB support" |
212 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9 | 212 | depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 |
213 | select PHYLIB | 213 | select PHYLIB |
214 | help | 214 | help |
215 | The Atmel MACB ethernet interface is found on many AT32 and AT91 | 215 | The Atmel MACB ethernet interface is found on many AT32 and AT91 |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index bf82e28770a9..72ba0c6d3551 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -826,6 +826,28 @@ static int pl011_remove(struct amba_device *dev) | |||
826 | return 0; | 826 | return 0; |
827 | } | 827 | } |
828 | 828 | ||
829 | #ifdef CONFIG_PM | ||
830 | static int pl011_suspend(struct amba_device *dev, pm_message_t state) | ||
831 | { | ||
832 | struct uart_amba_port *uap = amba_get_drvdata(dev); | ||
833 | |||
834 | if (!uap) | ||
835 | return -EINVAL; | ||
836 | |||
837 | return uart_suspend_port(&amba_reg, &uap->port); | ||
838 | } | ||
839 | |||
840 | static int pl011_resume(struct amba_device *dev) | ||
841 | { | ||
842 | struct uart_amba_port *uap = amba_get_drvdata(dev); | ||
843 | |||
844 | if (!uap) | ||
845 | return -EINVAL; | ||
846 | |||
847 | return uart_resume_port(&amba_reg, &uap->port); | ||
848 | } | ||
849 | #endif | ||
850 | |||
829 | static struct amba_id pl011_ids[] __initdata = { | 851 | static struct amba_id pl011_ids[] __initdata = { |
830 | { | 852 | { |
831 | .id = 0x00041011, | 853 | .id = 0x00041011, |
@@ -847,6 +869,10 @@ static struct amba_driver pl011_driver = { | |||
847 | .id_table = pl011_ids, | 869 | .id_table = pl011_ids, |
848 | .probe = pl011_probe, | 870 | .probe = pl011_probe, |
849 | .remove = pl011_remove, | 871 | .remove = pl011_remove, |
872 | #ifdef CONFIG_PM | ||
873 | .suspend = pl011_suspend, | ||
874 | .resume = pl011_resume, | ||
875 | #endif | ||
850 | }; | 876 | }; |
851 | 877 | ||
852 | static int __init pl011_init(void) | 878 | static int __init pl011_init(void) |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8afcf08eba98..41296a6807e2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -935,7 +935,7 @@ config FB_S1D13XXX | |||
935 | 935 | ||
936 | config FB_ATMEL | 936 | config FB_ATMEL |
937 | tristate "AT91/AT32 LCD Controller support" | 937 | tristate "AT91/AT32 LCD Controller support" |
938 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9 || AVR32) | 938 | depends on FB && (ARCH_AT91SAM9261 || ARCH_AT91SAM9G10 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 || ARCH_AT91CAP9 || AVR32) |
939 | select FB_CFB_FILLRECT | 939 | select FB_CFB_FILLRECT |
940 | select FB_CFB_COPYAREA | 940 | select FB_CFB_COPYAREA |
941 | select FB_CFB_IMAGEBLIT | 941 | select FB_CFB_IMAGEBLIT |
@@ -951,7 +951,7 @@ config FB_INTSRAM | |||
951 | 951 | ||
952 | config FB_ATMEL_STN | 952 | config FB_ATMEL_STN |
953 | bool "Use a STN display with AT91/AT32 LCD Controller" | 953 | bool "Use a STN display with AT91/AT32 LCD Controller" |
954 | depends on FB_ATMEL && MACH_AT91SAM9261EK | 954 | depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) |
955 | default n | 955 | default n |
956 | help | 956 | help |
957 | Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD | 957 | Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index da05f0801bb7..2830ffd72976 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -182,7 +182,8 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) | |||
182 | { | 182 | { |
183 | unsigned long value; | 183 | unsigned long value; |
184 | 184 | ||
185 | if (!(cpu_is_at91sam9261() || cpu_is_at32ap7000())) | 185 | if (!(cpu_is_at91sam9261() || cpu_is_at91sam9g10() |
186 | || cpu_is_at32ap7000())) | ||
186 | return xres; | 187 | return xres; |
187 | 188 | ||
188 | value = xres; | 189 | value = xres; |
@@ -824,7 +825,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) | |||
824 | info->fix = atmel_lcdfb_fix; | 825 | info->fix = atmel_lcdfb_fix; |
825 | 826 | ||
826 | /* Enable LCDC Clocks */ | 827 | /* Enable LCDC Clocks */ |
827 | if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) { | 828 | if (cpu_is_at91sam9261() || cpu_is_at91sam9g10() |
829 | || cpu_is_at32ap7000()) { | ||
828 | sinfo->bus_clk = clk_get(dev, "hck1"); | 830 | sinfo->bus_clk = clk_get(dev, "hck1"); |
829 | if (IS_ERR(sinfo->bus_clk)) { | 831 | if (IS_ERR(sinfo->bus_clk)) { |
830 | ret = PTR_ERR(sinfo->bus_clk); | 832 | ret = PTR_ERR(sinfo->bus_clk); |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index f9d19be05540..90861cd93165 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -110,7 +110,7 @@ config BACKLIGHT_CLASS_DEVICE | |||
110 | config BACKLIGHT_ATMEL_LCDC | 110 | config BACKLIGHT_ATMEL_LCDC |
111 | bool "Atmel LCDC Contrast-as-Backlight control" | 111 | bool "Atmel LCDC Contrast-as-Backlight control" |
112 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL | 112 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL |
113 | default y if MACH_SAM9261EK || MACH_SAM9263EK | 113 | default y if MACH_SAM9261EK || MACH_SAM9G10EK || MACH_SAM9263EK |
114 | help | 114 | help |
115 | This provides a backlight control internal to the Atmel LCDC | 115 | This provides a backlight control internal to the Atmel LCDC |
116 | driver. If the LCD "contrast control" on your board is wired | 116 | driver. If the LCD "contrast control" on your board is wired |