aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/amba/bus.c26
-rw-r--r--drivers/input/touchscreen/w90p910_ts.c4
-rw-r--r--drivers/misc/Kconfig13
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/ep93xx_pwm.c384
-rw-r--r--drivers/mmc/host/mmci.c73
-rw-r--r--drivers/mmc/host/mmci.h2
-rw-r--r--drivers/mtd/nand/ts7250.c5
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/serial/amba-pl011.c26
-rw-r--r--drivers/spi/amba-pl022.c2
-rw-r--r--drivers/video/Kconfig4
-rw-r--r--drivers/video/atmel_lcdfb.c6
-rw-r--r--drivers/video/backlight/Kconfig2
14 files changed, 528 insertions, 22 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)
204int amba_device_register(struct amba_device *dev, struct resource *parent) 204int 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,
353int amba_request_regions(struct amba_device *dev, const char *name) 363int 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 */
372void amba_release_regions(struct amba_device *dev) 385void 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
377EXPORT_SYMBOL(amba_driver_register); 393EXPORT_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);
347MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); 347MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
348MODULE_DESCRIPTION("w90p910 touch screen driver!"); 348MODULE_DESCRIPTION("w90p910 touch screen driver!");
349MODULE_LICENSE("GPL"); 349MODULE_LICENSE("GPL");
350MODULE_ALIAS("platform:w90p910-ts"); 350MODULE_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
236config 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
236source "drivers/misc/c2port/Kconfig" 249source "drivers/misc/c2port/Kconfig"
237source "drivers/misc/eeprom/Kconfig" 250source "drivers/misc/eeprom/Kconfig"
238source "drivers/misc/cb710/Kconfig" 251source "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/
19obj-$(CONFIG_SGI_GRU) += sgi-gru/ 19obj-$(CONFIG_SGI_GRU) += sgi-gru/
20obj-$(CONFIG_HP_ILO) += hpilo.o 20obj-$(CONFIG_HP_ILO) += hpilo.o
21obj-$(CONFIG_ISL29003) += isl29003.o 21obj-$(CONFIG_ISL29003) += isl29003.o
22obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
22obj-$(CONFIG_C2PORT) += c2port/ 23obj-$(CONFIG_C2PORT) += c2port/
23obj-y += eeprom/ 24obj-y += eeprom/
24obj-y += cb710/ 25obj-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
35struct ep93xx_pwm {
36 void __iomem *mmio_base;
37 struct clk *clk;
38 u32 duty_percent;
39};
40
41static 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
47static 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
53static 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
58static inline u16 ep93xx_pwm_read_tc(struct ep93xx_pwm *pwm)
59{
60 return ep93xx_pwm_readl(pwm, EP93XX_PWMx_TERM_COUNT);
61}
62
63static 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
68static inline void ep93xx_pwm_enable(struct ep93xx_pwm *pwm)
69{
70 ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_ENABLE);
71}
72
73static inline void ep93xx_pwm_disable(struct ep93xx_pwm *pwm)
74{
75 ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_ENABLE);
76}
77
78static inline int ep93xx_pwm_is_enabled(struct ep93xx_pwm *pwm)
79{
80 return ep93xx_pwm_readl(pwm, EP93XX_PWMx_ENABLE) & 0x1;
81}
82
83static inline void ep93xx_pwm_invert(struct ep93xx_pwm *pwm)
84{
85 ep93xx_pwm_writel(pwm, 0x1, EP93XX_PWMx_INVERT);
86}
87
88static inline void ep93xx_pwm_normal(struct ep93xx_pwm *pwm)
89{
90 ep93xx_pwm_writel(pwm, 0x0, EP93XX_PWMx_INVERT);
91}
92
93static 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
107static 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
117static 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
127static 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
143static 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
187static 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
196static 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
218static 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
227static 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
249static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL);
250static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL);
251static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO,
252 ep93xx_pwm_get_freq, ep93xx_pwm_set_freq);
253static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO,
254 ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent);
255static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO,
256 ep93xx_pwm_get_invert, ep93xx_pwm_set_invert);
257
258static 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
267static const struct attribute_group ep93xx_pwm_sysfs_files = {
268 .attrs = ep93xx_pwm_attrs,
269};
270
271static 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
328fail_no_clk:
329 sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files);
330fail_no_sysfs:
331 iounmap(pwm->mmio_base);
332fail_no_ioremap:
333 release_mem_region(res->start, resource_size(res));
334fail_no_mem_resource:
335 kfree(pwm);
336fail_no_mem:
337 ep93xx_pwm_release_gpio(pdev);
338 return err;
339}
340
341static 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
359static 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
367static int __init ep93xx_pwm_init(void)
368{
369 return platform_driver_probe(&ep93xx_pwm_driver, ep93xx_pwm_probe);
370}
371
372static void __exit ep93xx_pwm_exit(void)
373{
374 platform_driver_unregister(&ep93xx_pwm_driver);
375}
376
377module_init(ep93xx_pwm_init);
378module_exit(ep93xx_pwm_exit);
379
380MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, "
381 "H Hartley Sweeten <hsweeten@visionengravers.com>");
382MODULE_DESCRIPTION("EP93xx PWM driver");
383MODULE_LICENSE("GPL");
384MODULE_ALIAS("platform:ep93xx-pwm");
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index d78b1e460d7d..8741d0f5146a 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
476static 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
486static 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
475static const struct mmc_host_ops mmci_ops = { 499static 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
480static void mmci_check_status(unsigned long data) 506static 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 5f6509a5f640..3ed49f1337c7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -209,7 +209,7 @@ config MII
209 209
210config MACB 210config 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
830static 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
840static 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
829static struct amba_id pl011_ids[] __initdata = { 851static 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
852static int __init pl011_init(void) 878static int __init pl011_init(void)
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index da76797ce8b9..c0f950a7cbec 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -38,14 +38,12 @@
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/spi/spi.h> 39#include <linux/spi/spi.h>
40#include <linux/workqueue.h> 40#include <linux/workqueue.h>
41#include <linux/errno.h>
42#include <linux/delay.h> 41#include <linux/delay.h>
43#include <linux/clk.h> 42#include <linux/clk.h>
44#include <linux/err.h> 43#include <linux/err.h>
45#include <linux/amba/bus.h> 44#include <linux/amba/bus.h>
46#include <linux/amba/pl022.h> 45#include <linux/amba/pl022.h>
47#include <linux/io.h> 46#include <linux/io.h>
48#include <linux/delay.h>
49 47
50/* 48/*
51 * This macro is used to define some register default values. 49 * This macro is used to define some register default values.
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3b54b3940178..1999b1834814 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -935,7 +935,7 @@ config FB_S1D13XXX
935 935
936config FB_ATMEL 936config 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
952config FB_ATMEL_STN 952config 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
110config BACKLIGHT_ATMEL_LCDC 110config 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