diff options
Diffstat (limited to 'drivers')
28 files changed, 1581 insertions, 740 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 5099681cf503..e3380137b05b 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -141,6 +141,12 @@ config GPIO_PL061 | |||
141 | help | 141 | help |
142 | Say yes here to support the PrimeCell PL061 GPIO device | 142 | Say yes here to support the PrimeCell PL061 GPIO device |
143 | 143 | ||
144 | config GPIO_PXA | ||
145 | bool "PXA GPIO support" | ||
146 | depends on ARCH_PXA || ARCH_MMP | ||
147 | help | ||
148 | Say yes here to support the PXA GPIO device | ||
149 | |||
144 | config GPIO_XILINX | 150 | config GPIO_XILINX |
145 | bool "Xilinx GPIO support" | 151 | bool "Xilinx GPIO support" |
146 | depends on PPC_OF || MICROBLAZE | 152 | depends on PPC_OF || MICROBLAZE |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 4e018d6a7639..8ef9e9abe970 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -40,7 +40,7 @@ obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o | |||
40 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o | 40 | obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o |
41 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o | 41 | obj-$(CONFIG_GPIO_PCH) += gpio-pch.o |
42 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o | 42 | obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o |
43 | obj-$(CONFIG_PLAT_PXA) += gpio-pxa.o | 43 | obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o |
44 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o | 44 | obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o |
45 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | 45 | obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o |
46 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | 46 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index ee137712f9db..b2d3ee1d183a 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -11,14 +11,46 @@ | |||
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | ||
14 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/gpio-pxa.h> | ||
15 | #include <linux/init.h> | 18 | #include <linux/init.h> |
16 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
17 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/platform_device.h> | ||
18 | #include <linux/syscore_ops.h> | 22 | #include <linux/syscore_ops.h> |
19 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
20 | 24 | ||
21 | #include <mach/gpio-pxa.h> | 25 | /* |
26 | * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with | ||
27 | * one set of registers. The register offsets are organized below: | ||
28 | * | ||
29 | * GPLR GPDR GPSR GPCR GRER GFER GEDR | ||
30 | * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048 | ||
31 | * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C | ||
32 | * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050 | ||
33 | * | ||
34 | * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148 | ||
35 | * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C | ||
36 | * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150 | ||
37 | * | ||
38 | * NOTE: | ||
39 | * BANK 3 is only available on PXA27x and later processors. | ||
40 | * BANK 4 and 5 are only available on PXA935 | ||
41 | */ | ||
42 | |||
43 | #define GPLR_OFFSET 0x00 | ||
44 | #define GPDR_OFFSET 0x0C | ||
45 | #define GPSR_OFFSET 0x18 | ||
46 | #define GPCR_OFFSET 0x24 | ||
47 | #define GRER_OFFSET 0x30 | ||
48 | #define GFER_OFFSET 0x3C | ||
49 | #define GEDR_OFFSET 0x48 | ||
50 | #define GAFR_OFFSET 0x54 | ||
51 | #define ED_MASK_OFFSET 0x9C /* GPIO edge detection for AP side */ | ||
52 | |||
53 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) | ||
22 | 54 | ||
23 | int pxa_last_gpio; | 55 | int pxa_last_gpio; |
24 | 56 | ||
@@ -39,8 +71,20 @@ struct pxa_gpio_chip { | |||
39 | #endif | 71 | #endif |
40 | }; | 72 | }; |
41 | 73 | ||
74 | enum { | ||
75 | PXA25X_GPIO = 0, | ||
76 | PXA26X_GPIO, | ||
77 | PXA27X_GPIO, | ||
78 | PXA3XX_GPIO, | ||
79 | PXA93X_GPIO, | ||
80 | MMP_GPIO = 0x10, | ||
81 | MMP2_GPIO, | ||
82 | }; | ||
83 | |||
42 | static DEFINE_SPINLOCK(gpio_lock); | 84 | static DEFINE_SPINLOCK(gpio_lock); |
43 | static struct pxa_gpio_chip *pxa_gpio_chips; | 85 | static struct pxa_gpio_chip *pxa_gpio_chips; |
86 | static int gpio_type; | ||
87 | static void __iomem *gpio_reg_base; | ||
44 | 88 | ||
45 | #define for_each_gpio_chip(i, c) \ | 89 | #define for_each_gpio_chip(i, c) \ |
46 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) | 90 | for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++) |
@@ -55,6 +99,122 @@ static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) | |||
55 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; | 99 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; |
56 | } | 100 | } |
57 | 101 | ||
102 | static inline int gpio_is_pxa_type(int type) | ||
103 | { | ||
104 | return (type & MMP_GPIO) == 0; | ||
105 | } | ||
106 | |||
107 | static inline int gpio_is_mmp_type(int type) | ||
108 | { | ||
109 | return (type & MMP_GPIO) != 0; | ||
110 | } | ||
111 | |||
112 | /* GPIO86/87/88/89 on PXA26x have their direction bits in PXA_GPDR(2 inverted, | ||
113 | * as well as their Alternate Function value being '1' for GPIO in GAFRx. | ||
114 | */ | ||
115 | static inline int __gpio_is_inverted(int gpio) | ||
116 | { | ||
117 | if ((gpio_type == PXA26X_GPIO) && (gpio > 85)) | ||
118 | return 1; | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate | ||
124 | * function of a GPIO, and GPDRx cannot be altered once configured. It | ||
125 | * is attributed as "occupied" here (I know this terminology isn't | ||
126 | * accurate, you are welcome to propose a better one :-) | ||
127 | */ | ||
128 | static inline int __gpio_is_occupied(unsigned gpio) | ||
129 | { | ||
130 | struct pxa_gpio_chip *pxachip; | ||
131 | void __iomem *base; | ||
132 | unsigned long gafr = 0, gpdr = 0; | ||
133 | int ret, af = 0, dir = 0; | ||
134 | |||
135 | pxachip = gpio_to_pxachip(gpio); | ||
136 | base = gpio_chip_base(&pxachip->chip); | ||
137 | gpdr = readl_relaxed(base + GPDR_OFFSET); | ||
138 | |||
139 | switch (gpio_type) { | ||
140 | case PXA25X_GPIO: | ||
141 | case PXA26X_GPIO: | ||
142 | case PXA27X_GPIO: | ||
143 | gafr = readl_relaxed(base + GAFR_OFFSET); | ||
144 | af = (gafr >> ((gpio & 0xf) * 2)) & 0x3; | ||
145 | dir = gpdr & GPIO_bit(gpio); | ||
146 | |||
147 | if (__gpio_is_inverted(gpio)) | ||
148 | ret = (af != 1) || (dir == 0); | ||
149 | else | ||
150 | ret = (af != 0) || (dir != 0); | ||
151 | break; | ||
152 | default: | ||
153 | ret = gpdr & GPIO_bit(gpio); | ||
154 | break; | ||
155 | } | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | #ifdef CONFIG_ARCH_PXA | ||
160 | static inline int __pxa_gpio_to_irq(int gpio) | ||
161 | { | ||
162 | if (gpio_is_pxa_type(gpio_type)) | ||
163 | return PXA_GPIO_TO_IRQ(gpio); | ||
164 | return -1; | ||
165 | } | ||
166 | |||
167 | static inline int __pxa_irq_to_gpio(int irq) | ||
168 | { | ||
169 | if (gpio_is_pxa_type(gpio_type)) | ||
170 | return irq - PXA_GPIO_TO_IRQ(0); | ||
171 | return -1; | ||
172 | } | ||
173 | #else | ||
174 | static inline int __pxa_gpio_to_irq(int gpio) { return -1; } | ||
175 | static inline int __pxa_irq_to_gpio(int irq) { return -1; } | ||
176 | #endif | ||
177 | |||
178 | #ifdef CONFIG_ARCH_MMP | ||
179 | static inline int __mmp_gpio_to_irq(int gpio) | ||
180 | { | ||
181 | if (gpio_is_mmp_type(gpio_type)) | ||
182 | return MMP_GPIO_TO_IRQ(gpio); | ||
183 | return -1; | ||
184 | } | ||
185 | |||
186 | static inline int __mmp_irq_to_gpio(int irq) | ||
187 | { | ||
188 | if (gpio_is_mmp_type(gpio_type)) | ||
189 | return irq - MMP_GPIO_TO_IRQ(0); | ||
190 | return -1; | ||
191 | } | ||
192 | #else | ||
193 | static inline int __mmp_gpio_to_irq(int gpio) { return -1; } | ||
194 | static inline int __mmp_irq_to_gpio(int irq) { return -1; } | ||
195 | #endif | ||
196 | |||
197 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
198 | { | ||
199 | int gpio, ret; | ||
200 | |||
201 | gpio = chip->base + offset; | ||
202 | ret = __pxa_gpio_to_irq(gpio); | ||
203 | if (ret >= 0) | ||
204 | return ret; | ||
205 | return __mmp_gpio_to_irq(gpio); | ||
206 | } | ||
207 | |||
208 | int pxa_irq_to_gpio(int irq) | ||
209 | { | ||
210 | int ret; | ||
211 | |||
212 | ret = __pxa_irq_to_gpio(irq); | ||
213 | if (ret >= 0) | ||
214 | return ret; | ||
215 | return __mmp_irq_to_gpio(irq); | ||
216 | } | ||
217 | |||
58 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 218 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
59 | { | 219 | { |
60 | void __iomem *base = gpio_chip_base(chip); | 220 | void __iomem *base = gpio_chip_base(chip); |
@@ -63,12 +223,12 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | |||
63 | 223 | ||
64 | spin_lock_irqsave(&gpio_lock, flags); | 224 | spin_lock_irqsave(&gpio_lock, flags); |
65 | 225 | ||
66 | value = __raw_readl(base + GPDR_OFFSET); | 226 | value = readl_relaxed(base + GPDR_OFFSET); |
67 | if (__gpio_is_inverted(chip->base + offset)) | 227 | if (__gpio_is_inverted(chip->base + offset)) |
68 | value |= mask; | 228 | value |= mask; |
69 | else | 229 | else |
70 | value &= ~mask; | 230 | value &= ~mask; |
71 | __raw_writel(value, base + GPDR_OFFSET); | 231 | writel_relaxed(value, base + GPDR_OFFSET); |
72 | 232 | ||
73 | spin_unlock_irqrestore(&gpio_lock, flags); | 233 | spin_unlock_irqrestore(&gpio_lock, flags); |
74 | return 0; | 234 | return 0; |
@@ -81,16 +241,16 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, | |||
81 | uint32_t tmp, mask = 1 << offset; | 241 | uint32_t tmp, mask = 1 << offset; |
82 | unsigned long flags; | 242 | unsigned long flags; |
83 | 243 | ||
84 | __raw_writel(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); | 244 | writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); |
85 | 245 | ||
86 | spin_lock_irqsave(&gpio_lock, flags); | 246 | spin_lock_irqsave(&gpio_lock, flags); |
87 | 247 | ||
88 | tmp = __raw_readl(base + GPDR_OFFSET); | 248 | tmp = readl_relaxed(base + GPDR_OFFSET); |
89 | if (__gpio_is_inverted(chip->base + offset)) | 249 | if (__gpio_is_inverted(chip->base + offset)) |
90 | tmp &= ~mask; | 250 | tmp &= ~mask; |
91 | else | 251 | else |
92 | tmp |= mask; | 252 | tmp |= mask; |
93 | __raw_writel(tmp, base + GPDR_OFFSET); | 253 | writel_relaxed(tmp, base + GPDR_OFFSET); |
94 | 254 | ||
95 | spin_unlock_irqrestore(&gpio_lock, flags); | 255 | spin_unlock_irqrestore(&gpio_lock, flags); |
96 | return 0; | 256 | return 0; |
@@ -98,16 +258,16 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, | |||
98 | 258 | ||
99 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) | 259 | static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset) |
100 | { | 260 | { |
101 | return __raw_readl(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); | 261 | return readl_relaxed(gpio_chip_base(chip) + GPLR_OFFSET) & (1 << offset); |
102 | } | 262 | } |
103 | 263 | ||
104 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 264 | static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
105 | { | 265 | { |
106 | __raw_writel(1 << offset, gpio_chip_base(chip) + | 266 | writel_relaxed(1 << offset, gpio_chip_base(chip) + |
107 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 267 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
108 | } | 268 | } |
109 | 269 | ||
110 | static int __init pxa_init_gpio_chip(int gpio_end) | 270 | static int __devinit pxa_init_gpio_chip(int gpio_end) |
111 | { | 271 | { |
112 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | 272 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; |
113 | struct pxa_gpio_chip *chips; | 273 | struct pxa_gpio_chip *chips; |
@@ -122,7 +282,7 @@ static int __init pxa_init_gpio_chip(int gpio_end) | |||
122 | struct gpio_chip *c = &chips[i].chip; | 282 | struct gpio_chip *c = &chips[i].chip; |
123 | 283 | ||
124 | sprintf(chips[i].label, "gpio-%d", i); | 284 | sprintf(chips[i].label, "gpio-%d", i); |
125 | chips[i].regbase = GPIO_BANK(i); | 285 | chips[i].regbase = gpio_reg_base + BANK_OFF(i); |
126 | 286 | ||
127 | c->base = gpio; | 287 | c->base = gpio; |
128 | c->label = chips[i].label; | 288 | c->label = chips[i].label; |
@@ -131,6 +291,7 @@ static int __init pxa_init_gpio_chip(int gpio_end) | |||
131 | c->direction_output = pxa_gpio_direction_output; | 291 | c->direction_output = pxa_gpio_direction_output; |
132 | c->get = pxa_gpio_get; | 292 | c->get = pxa_gpio_get; |
133 | c->set = pxa_gpio_set; | 293 | c->set = pxa_gpio_set; |
294 | c->to_irq = pxa_gpio_to_irq; | ||
134 | 295 | ||
135 | /* number of GPIOs on last bank may be less than 32 */ | 296 | /* number of GPIOs on last bank may be less than 32 */ |
136 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | 297 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; |
@@ -147,18 +308,18 @@ static inline void update_edge_detect(struct pxa_gpio_chip *c) | |||
147 | { | 308 | { |
148 | uint32_t grer, gfer; | 309 | uint32_t grer, gfer; |
149 | 310 | ||
150 | grer = __raw_readl(c->regbase + GRER_OFFSET) & ~c->irq_mask; | 311 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~c->irq_mask; |
151 | gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~c->irq_mask; | 312 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~c->irq_mask; |
152 | grer |= c->irq_edge_rise & c->irq_mask; | 313 | grer |= c->irq_edge_rise & c->irq_mask; |
153 | gfer |= c->irq_edge_fall & c->irq_mask; | 314 | gfer |= c->irq_edge_fall & c->irq_mask; |
154 | __raw_writel(grer, c->regbase + GRER_OFFSET); | 315 | writel_relaxed(grer, c->regbase + GRER_OFFSET); |
155 | __raw_writel(gfer, c->regbase + GFER_OFFSET); | 316 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
156 | } | 317 | } |
157 | 318 | ||
158 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | 319 | static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) |
159 | { | 320 | { |
160 | struct pxa_gpio_chip *c; | 321 | struct pxa_gpio_chip *c; |
161 | int gpio = irq_to_gpio(d->irq); | 322 | int gpio = pxa_irq_to_gpio(d->irq); |
162 | unsigned long gpdr, mask = GPIO_bit(gpio); | 323 | unsigned long gpdr, mask = GPIO_bit(gpio); |
163 | 324 | ||
164 | c = gpio_to_pxachip(gpio); | 325 | c = gpio_to_pxachip(gpio); |
@@ -176,12 +337,12 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
176 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 337 | type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
177 | } | 338 | } |
178 | 339 | ||
179 | gpdr = __raw_readl(c->regbase + GPDR_OFFSET); | 340 | gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
180 | 341 | ||
181 | if (__gpio_is_inverted(gpio)) | 342 | if (__gpio_is_inverted(gpio)) |
182 | __raw_writel(gpdr | mask, c->regbase + GPDR_OFFSET); | 343 | writel_relaxed(gpdr | mask, c->regbase + GPDR_OFFSET); |
183 | else | 344 | else |
184 | __raw_writel(gpdr & ~mask, c->regbase + GPDR_OFFSET); | 345 | writel_relaxed(gpdr & ~mask, c->regbase + GPDR_OFFSET); |
185 | 346 | ||
186 | if (type & IRQ_TYPE_EDGE_RISING) | 347 | if (type & IRQ_TYPE_EDGE_RISING) |
187 | c->irq_edge_rise |= mask; | 348 | c->irq_edge_rise |= mask; |
@@ -212,9 +373,9 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
212 | for_each_gpio_chip(gpio, c) { | 373 | for_each_gpio_chip(gpio, c) { |
213 | gpio_base = c->chip.base; | 374 | gpio_base = c->chip.base; |
214 | 375 | ||
215 | gedr = __raw_readl(c->regbase + GEDR_OFFSET); | 376 | gedr = readl_relaxed(c->regbase + GEDR_OFFSET); |
216 | gedr = gedr & c->irq_mask; | 377 | gedr = gedr & c->irq_mask; |
217 | __raw_writel(gedr, c->regbase + GEDR_OFFSET); | 378 | writel_relaxed(gedr, c->regbase + GEDR_OFFSET); |
218 | 379 | ||
219 | n = find_first_bit(&gedr, BITS_PER_LONG); | 380 | n = find_first_bit(&gedr, BITS_PER_LONG); |
220 | while (n < BITS_PER_LONG) { | 381 | while (n < BITS_PER_LONG) { |
@@ -229,29 +390,29 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
229 | 390 | ||
230 | static void pxa_ack_muxed_gpio(struct irq_data *d) | 391 | static void pxa_ack_muxed_gpio(struct irq_data *d) |
231 | { | 392 | { |
232 | int gpio = irq_to_gpio(d->irq); | 393 | int gpio = pxa_irq_to_gpio(d->irq); |
233 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 394 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
234 | 395 | ||
235 | __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); | 396 | writel_relaxed(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); |
236 | } | 397 | } |
237 | 398 | ||
238 | static void pxa_mask_muxed_gpio(struct irq_data *d) | 399 | static void pxa_mask_muxed_gpio(struct irq_data *d) |
239 | { | 400 | { |
240 | int gpio = irq_to_gpio(d->irq); | 401 | int gpio = pxa_irq_to_gpio(d->irq); |
241 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 402 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
242 | uint32_t grer, gfer; | 403 | uint32_t grer, gfer; |
243 | 404 | ||
244 | c->irq_mask &= ~GPIO_bit(gpio); | 405 | c->irq_mask &= ~GPIO_bit(gpio); |
245 | 406 | ||
246 | grer = __raw_readl(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); | 407 | grer = readl_relaxed(c->regbase + GRER_OFFSET) & ~GPIO_bit(gpio); |
247 | gfer = __raw_readl(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); | 408 | gfer = readl_relaxed(c->regbase + GFER_OFFSET) & ~GPIO_bit(gpio); |
248 | __raw_writel(grer, c->regbase + GRER_OFFSET); | 409 | writel_relaxed(grer, c->regbase + GRER_OFFSET); |
249 | __raw_writel(gfer, c->regbase + GFER_OFFSET); | 410 | writel_relaxed(gfer, c->regbase + GFER_OFFSET); |
250 | } | 411 | } |
251 | 412 | ||
252 | static void pxa_unmask_muxed_gpio(struct irq_data *d) | 413 | static void pxa_unmask_muxed_gpio(struct irq_data *d) |
253 | { | 414 | { |
254 | int gpio = irq_to_gpio(d->irq); | 415 | int gpio = pxa_irq_to_gpio(d->irq); |
255 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); | 416 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
256 | 417 | ||
257 | c->irq_mask |= GPIO_bit(gpio); | 418 | c->irq_mask |= GPIO_bit(gpio); |
@@ -266,34 +427,143 @@ static struct irq_chip pxa_muxed_gpio_chip = { | |||
266 | .irq_set_type = pxa_gpio_irq_type, | 427 | .irq_set_type = pxa_gpio_irq_type, |
267 | }; | 428 | }; |
268 | 429 | ||
269 | void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn) | 430 | static int pxa_gpio_nums(void) |
270 | { | 431 | { |
271 | struct pxa_gpio_chip *c; | 432 | int count = 0; |
272 | int gpio, irq; | 433 | |
434 | #ifdef CONFIG_ARCH_PXA | ||
435 | if (cpu_is_pxa25x()) { | ||
436 | #ifdef CONFIG_CPU_PXA26x | ||
437 | count = 89; | ||
438 | gpio_type = PXA26X_GPIO; | ||
439 | #elif defined(CONFIG_PXA25x) | ||
440 | count = 84; | ||
441 | gpio_type = PXA26X_GPIO; | ||
442 | #endif /* CONFIG_CPU_PXA26x */ | ||
443 | } else if (cpu_is_pxa27x()) { | ||
444 | count = 120; | ||
445 | gpio_type = PXA27X_GPIO; | ||
446 | } else if (cpu_is_pxa93x() || cpu_is_pxa95x()) { | ||
447 | count = 191; | ||
448 | gpio_type = PXA93X_GPIO; | ||
449 | } else if (cpu_is_pxa3xx()) { | ||
450 | count = 127; | ||
451 | gpio_type = PXA3XX_GPIO; | ||
452 | } | ||
453 | #endif /* CONFIG_ARCH_PXA */ | ||
454 | |||
455 | #ifdef CONFIG_ARCH_MMP | ||
456 | if (cpu_is_pxa168() || cpu_is_pxa910()) { | ||
457 | count = 127; | ||
458 | gpio_type = MMP_GPIO; | ||
459 | } else if (cpu_is_mmp2()) { | ||
460 | count = 191; | ||
461 | gpio_type = MMP2_GPIO; | ||
462 | } | ||
463 | #endif /* CONFIG_ARCH_MMP */ | ||
464 | return count; | ||
465 | } | ||
273 | 466 | ||
274 | pxa_last_gpio = end; | 467 | static int __devinit pxa_gpio_probe(struct platform_device *pdev) |
468 | { | ||
469 | struct pxa_gpio_chip *c; | ||
470 | struct resource *res; | ||
471 | struct clk *clk; | ||
472 | int gpio, irq, ret; | ||
473 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | ||
474 | |||
475 | pxa_last_gpio = pxa_gpio_nums(); | ||
476 | if (!pxa_last_gpio) | ||
477 | return -EINVAL; | ||
478 | |||
479 | irq0 = platform_get_irq_byname(pdev, "gpio0"); | ||
480 | irq1 = platform_get_irq_byname(pdev, "gpio1"); | ||
481 | irq_mux = platform_get_irq_byname(pdev, "gpio_mux"); | ||
482 | if ((irq0 > 0 && irq1 <= 0) || (irq0 <= 0 && irq1 > 0) | ||
483 | || (irq_mux <= 0)) | ||
484 | return -EINVAL; | ||
485 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
486 | if (!res) | ||
487 | return -EINVAL; | ||
488 | gpio_reg_base = ioremap(res->start, resource_size(res)); | ||
489 | if (!gpio_reg_base) | ||
490 | return -EINVAL; | ||
491 | |||
492 | if (irq0 > 0) | ||
493 | gpio_offset = 2; | ||
494 | |||
495 | clk = clk_get(&pdev->dev, NULL); | ||
496 | if (IS_ERR(clk)) { | ||
497 | dev_err(&pdev->dev, "Error %ld to get gpio clock\n", | ||
498 | PTR_ERR(clk)); | ||
499 | iounmap(gpio_reg_base); | ||
500 | return PTR_ERR(clk); | ||
501 | } | ||
502 | ret = clk_prepare(clk); | ||
503 | if (ret) { | ||
504 | clk_put(clk); | ||
505 | iounmap(gpio_reg_base); | ||
506 | return ret; | ||
507 | } | ||
508 | ret = clk_enable(clk); | ||
509 | if (ret) { | ||
510 | clk_unprepare(clk); | ||
511 | clk_put(clk); | ||
512 | iounmap(gpio_reg_base); | ||
513 | return ret; | ||
514 | } | ||
275 | 515 | ||
276 | /* Initialize GPIO chips */ | 516 | /* Initialize GPIO chips */ |
277 | pxa_init_gpio_chip(end); | 517 | pxa_init_gpio_chip(pxa_last_gpio); |
278 | 518 | ||
279 | /* clear all GPIO edge detects */ | 519 | /* clear all GPIO edge detects */ |
280 | for_each_gpio_chip(gpio, c) { | 520 | for_each_gpio_chip(gpio, c) { |
281 | __raw_writel(0, c->regbase + GFER_OFFSET); | 521 | writel_relaxed(0, c->regbase + GFER_OFFSET); |
282 | __raw_writel(0, c->regbase + GRER_OFFSET); | 522 | writel_relaxed(0, c->regbase + GRER_OFFSET); |
283 | __raw_writel(~0,c->regbase + GEDR_OFFSET); | 523 | writel_relaxed(~0,c->regbase + GEDR_OFFSET); |
524 | /* unmask GPIO edge detect for AP side */ | ||
525 | if (gpio_is_mmp_type(gpio_type)) | ||
526 | writel_relaxed(~0, c->regbase + ED_MASK_OFFSET); | ||
284 | } | 527 | } |
285 | 528 | ||
286 | for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) { | 529 | #ifdef CONFIG_ARCH_PXA |
530 | irq = gpio_to_irq(0); | ||
531 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
532 | handle_edge_irq); | ||
533 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
534 | irq_set_chained_handler(IRQ_GPIO0, pxa_gpio_demux_handler); | ||
535 | |||
536 | irq = gpio_to_irq(1); | ||
537 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | ||
538 | handle_edge_irq); | ||
539 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
540 | irq_set_chained_handler(IRQ_GPIO1, pxa_gpio_demux_handler); | ||
541 | #endif | ||
542 | |||
543 | for (irq = gpio_to_irq(gpio_offset); | ||
544 | irq <= gpio_to_irq(pxa_last_gpio); irq++) { | ||
287 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, | 545 | irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip, |
288 | handle_edge_irq); | 546 | handle_edge_irq); |
289 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | 547 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); |
290 | } | 548 | } |
291 | 549 | ||
292 | /* Install handler for GPIO>=2 edge detect interrupts */ | 550 | irq_set_chained_handler(irq_mux, pxa_gpio_demux_handler); |
293 | irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler); | 551 | return 0; |
294 | pxa_muxed_gpio_chip.irq_set_wake = fn; | ||
295 | } | 552 | } |
296 | 553 | ||
554 | static struct platform_driver pxa_gpio_driver = { | ||
555 | .probe = pxa_gpio_probe, | ||
556 | .driver = { | ||
557 | .name = "pxa-gpio", | ||
558 | }, | ||
559 | }; | ||
560 | |||
561 | static int __init pxa_gpio_init(void) | ||
562 | { | ||
563 | return platform_driver_register(&pxa_gpio_driver); | ||
564 | } | ||
565 | postcore_initcall(pxa_gpio_init); | ||
566 | |||
297 | #ifdef CONFIG_PM | 567 | #ifdef CONFIG_PM |
298 | static int pxa_gpio_suspend(void) | 568 | static int pxa_gpio_suspend(void) |
299 | { | 569 | { |
@@ -301,13 +571,13 @@ static int pxa_gpio_suspend(void) | |||
301 | int gpio; | 571 | int gpio; |
302 | 572 | ||
303 | for_each_gpio_chip(gpio, c) { | 573 | for_each_gpio_chip(gpio, c) { |
304 | c->saved_gplr = __raw_readl(c->regbase + GPLR_OFFSET); | 574 | c->saved_gplr = readl_relaxed(c->regbase + GPLR_OFFSET); |
305 | c->saved_gpdr = __raw_readl(c->regbase + GPDR_OFFSET); | 575 | c->saved_gpdr = readl_relaxed(c->regbase + GPDR_OFFSET); |
306 | c->saved_grer = __raw_readl(c->regbase + GRER_OFFSET); | 576 | c->saved_grer = readl_relaxed(c->regbase + GRER_OFFSET); |
307 | c->saved_gfer = __raw_readl(c->regbase + GFER_OFFSET); | 577 | c->saved_gfer = readl_relaxed(c->regbase + GFER_OFFSET); |
308 | 578 | ||
309 | /* Clear GPIO transition detect bits */ | 579 | /* Clear GPIO transition detect bits */ |
310 | __raw_writel(0xffffffff, c->regbase + GEDR_OFFSET); | 580 | writel_relaxed(0xffffffff, c->regbase + GEDR_OFFSET); |
311 | } | 581 | } |
312 | return 0; | 582 | return 0; |
313 | } | 583 | } |
@@ -319,12 +589,12 @@ static void pxa_gpio_resume(void) | |||
319 | 589 | ||
320 | for_each_gpio_chip(gpio, c) { | 590 | for_each_gpio_chip(gpio, c) { |
321 | /* restore level with set/clear */ | 591 | /* restore level with set/clear */ |
322 | __raw_writel( c->saved_gplr, c->regbase + GPSR_OFFSET); | 592 | writel_relaxed( c->saved_gplr, c->regbase + GPSR_OFFSET); |
323 | __raw_writel(~c->saved_gplr, c->regbase + GPCR_OFFSET); | 593 | writel_relaxed(~c->saved_gplr, c->regbase + GPCR_OFFSET); |
324 | 594 | ||
325 | __raw_writel(c->saved_grer, c->regbase + GRER_OFFSET); | 595 | writel_relaxed(c->saved_grer, c->regbase + GRER_OFFSET); |
326 | __raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET); | 596 | writel_relaxed(c->saved_gfer, c->regbase + GFER_OFFSET); |
327 | __raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET); | 597 | writel_relaxed(c->saved_gpdr, c->regbase + GPDR_OFFSET); |
328 | } | 598 | } |
329 | } | 599 | } |
330 | #else | 600 | #else |
@@ -336,3 +606,10 @@ struct syscore_ops pxa_gpio_syscore_ops = { | |||
336 | .suspend = pxa_gpio_suspend, | 606 | .suspend = pxa_gpio_suspend, |
337 | .resume = pxa_gpio_resume, | 607 | .resume = pxa_gpio_resume, |
338 | }; | 608 | }; |
609 | |||
610 | static int __init pxa_gpio_sysinit(void) | ||
611 | { | ||
612 | register_syscore_ops(&pxa_gpio_syscore_ops); | ||
613 | return 0; | ||
614 | } | ||
615 | postcore_initcall(pxa_gpio_sysinit); | ||
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 46b6500c5478..6381604696d3 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -558,7 +558,7 @@ static const struct i2c_algorithm tegra_i2c_algo = { | |||
558 | .functionality = tegra_i2c_func, | 558 | .functionality = tegra_i2c_func, |
559 | }; | 559 | }; |
560 | 560 | ||
561 | static int tegra_i2c_probe(struct platform_device *pdev) | 561 | static int __devinit tegra_i2c_probe(struct platform_device *pdev) |
562 | { | 562 | { |
563 | struct tegra_i2c_dev *i2c_dev; | 563 | struct tegra_i2c_dev *i2c_dev; |
564 | struct tegra_i2c_platform_data *pdata = pdev->dev.platform_data; | 564 | struct tegra_i2c_platform_data *pdata = pdev->dev.platform_data; |
@@ -636,7 +636,10 @@ static int tegra_i2c_probe(struct platform_device *pdev) | |||
636 | i2c_dev->bus_clk_rate = be32_to_cpup(prop); | 636 | i2c_dev->bus_clk_rate = be32_to_cpup(prop); |
637 | } | 637 | } |
638 | 638 | ||
639 | if (pdev->id == 3) | 639 | if (pdev->dev.of_node) |
640 | i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node, | ||
641 | "nvidia,tegra20-i2c-dvc"); | ||
642 | else if (pdev->id == 3) | ||
640 | i2c_dev->is_dvc = 1; | 643 | i2c_dev->is_dvc = 1; |
641 | init_completion(&i2c_dev->msg_complete); | 644 | init_completion(&i2c_dev->msg_complete); |
642 | 645 | ||
@@ -690,7 +693,7 @@ err_iounmap: | |||
690 | return ret; | 693 | return ret; |
691 | } | 694 | } |
692 | 695 | ||
693 | static int tegra_i2c_remove(struct platform_device *pdev) | 696 | static int __devexit tegra_i2c_remove(struct platform_device *pdev) |
694 | { | 697 | { |
695 | struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev); | 698 | struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev); |
696 | i2c_del_adapter(&i2c_dev->adapter); | 699 | i2c_del_adapter(&i2c_dev->adapter); |
@@ -742,6 +745,7 @@ static int tegra_i2c_resume(struct platform_device *pdev) | |||
742 | /* Match table for of_platform binding */ | 745 | /* Match table for of_platform binding */ |
743 | static const struct of_device_id tegra_i2c_of_match[] __devinitconst = { | 746 | static const struct of_device_id tegra_i2c_of_match[] __devinitconst = { |
744 | { .compatible = "nvidia,tegra20-i2c", }, | 747 | { .compatible = "nvidia,tegra20-i2c", }, |
748 | { .compatible = "nvidia,tegra20-i2c-dvc", }, | ||
745 | {}, | 749 | {}, |
746 | }; | 750 | }; |
747 | MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); | 751 | MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); |
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index f6328c0cded6..0a707bbbbea6 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/gpio.h> | ||
25 | #include <linux/irq.h> | 26 | #include <linux/irq.h> |
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
27 | #include <linux/io.h> | 28 | #include <linux/io.h> |
@@ -192,8 +193,8 @@ static int zylonite_wm97xx_probe(struct platform_device *pdev) | |||
192 | else | 193 | else |
193 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); | 194 | gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26); |
194 | 195 | ||
195 | wm->pen_irq = IRQ_GPIO(gpio_touch_irq); | 196 | wm->pen_irq = gpio_to_irq(gpio_touch_irq); |
196 | irq_set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH); | 197 | irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH); |
197 | 198 | ||
198 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, | 199 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, |
199 | WM97XX_GPIO_POL_HIGH, | 200 | WM97XX_GPIO_POL_HIGH, |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 86e14583a082..3f565ef3e149 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -27,8 +27,9 @@ | |||
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <plat/usb.h> | 29 | #include <plat/usb.h> |
30 | #include <linux/pm_runtime.h> | ||
30 | 31 | ||
31 | #define USBHS_DRIVER_NAME "usbhs-omap" | 32 | #define USBHS_DRIVER_NAME "usbhs_omap" |
32 | #define OMAP_EHCI_DEVICE "ehci-omap" | 33 | #define OMAP_EHCI_DEVICE "ehci-omap" |
33 | #define OMAP_OHCI_DEVICE "ohci-omap3" | 34 | #define OMAP_OHCI_DEVICE "ohci-omap3" |
34 | 35 | ||
@@ -147,9 +148,6 @@ | |||
147 | 148 | ||
148 | 149 | ||
149 | struct usbhs_hcd_omap { | 150 | struct usbhs_hcd_omap { |
150 | struct clk *usbhost_ick; | ||
151 | struct clk *usbhost_hs_fck; | ||
152 | struct clk *usbhost_fs_fck; | ||
153 | struct clk *xclk60mhsp1_ck; | 151 | struct clk *xclk60mhsp1_ck; |
154 | struct clk *xclk60mhsp2_ck; | 152 | struct clk *xclk60mhsp2_ck; |
155 | struct clk *utmi_p1_fck; | 153 | struct clk *utmi_p1_fck; |
@@ -159,8 +157,7 @@ struct usbhs_hcd_omap { | |||
159 | struct clk *usbhost_p2_fck; | 157 | struct clk *usbhost_p2_fck; |
160 | struct clk *usbtll_p2_fck; | 158 | struct clk *usbtll_p2_fck; |
161 | struct clk *init_60m_fclk; | 159 | struct clk *init_60m_fclk; |
162 | struct clk *usbtll_fck; | 160 | struct clk *ehci_logic_fck; |
163 | struct clk *usbtll_ick; | ||
164 | 161 | ||
165 | void __iomem *uhh_base; | 162 | void __iomem *uhh_base; |
166 | void __iomem *tll_base; | 163 | void __iomem *tll_base; |
@@ -169,7 +166,6 @@ struct usbhs_hcd_omap { | |||
169 | 166 | ||
170 | u32 usbhs_rev; | 167 | u32 usbhs_rev; |
171 | spinlock_t lock; | 168 | spinlock_t lock; |
172 | int count; | ||
173 | }; | 169 | }; |
174 | /*-------------------------------------------------------------------------*/ | 170 | /*-------------------------------------------------------------------------*/ |
175 | 171 | ||
@@ -319,269 +315,6 @@ err_end: | |||
319 | return ret; | 315 | return ret; |
320 | } | 316 | } |
321 | 317 | ||
322 | /** | ||
323 | * usbhs_omap_probe - initialize TI-based HCDs | ||
324 | * | ||
325 | * Allocates basic resources for this USB host controller. | ||
326 | */ | ||
327 | static int __devinit usbhs_omap_probe(struct platform_device *pdev) | ||
328 | { | ||
329 | struct device *dev = &pdev->dev; | ||
330 | struct usbhs_omap_platform_data *pdata = dev->platform_data; | ||
331 | struct usbhs_hcd_omap *omap; | ||
332 | struct resource *res; | ||
333 | int ret = 0; | ||
334 | int i; | ||
335 | |||
336 | if (!pdata) { | ||
337 | dev_err(dev, "Missing platform data\n"); | ||
338 | ret = -ENOMEM; | ||
339 | goto end_probe; | ||
340 | } | ||
341 | |||
342 | omap = kzalloc(sizeof(*omap), GFP_KERNEL); | ||
343 | if (!omap) { | ||
344 | dev_err(dev, "Memory allocation failed\n"); | ||
345 | ret = -ENOMEM; | ||
346 | goto end_probe; | ||
347 | } | ||
348 | |||
349 | spin_lock_init(&omap->lock); | ||
350 | |||
351 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) | ||
352 | omap->platdata.port_mode[i] = pdata->port_mode[i]; | ||
353 | |||
354 | omap->platdata.ehci_data = pdata->ehci_data; | ||
355 | omap->platdata.ohci_data = pdata->ohci_data; | ||
356 | |||
357 | omap->usbhost_ick = clk_get(dev, "usbhost_ick"); | ||
358 | if (IS_ERR(omap->usbhost_ick)) { | ||
359 | ret = PTR_ERR(omap->usbhost_ick); | ||
360 | dev_err(dev, "usbhost_ick failed error:%d\n", ret); | ||
361 | goto err_end; | ||
362 | } | ||
363 | |||
364 | omap->usbhost_hs_fck = clk_get(dev, "hs_fck"); | ||
365 | if (IS_ERR(omap->usbhost_hs_fck)) { | ||
366 | ret = PTR_ERR(omap->usbhost_hs_fck); | ||
367 | dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); | ||
368 | goto err_usbhost_ick; | ||
369 | } | ||
370 | |||
371 | omap->usbhost_fs_fck = clk_get(dev, "fs_fck"); | ||
372 | if (IS_ERR(omap->usbhost_fs_fck)) { | ||
373 | ret = PTR_ERR(omap->usbhost_fs_fck); | ||
374 | dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret); | ||
375 | goto err_usbhost_hs_fck; | ||
376 | } | ||
377 | |||
378 | omap->usbtll_fck = clk_get(dev, "usbtll_fck"); | ||
379 | if (IS_ERR(omap->usbtll_fck)) { | ||
380 | ret = PTR_ERR(omap->usbtll_fck); | ||
381 | dev_err(dev, "usbtll_fck failed error:%d\n", ret); | ||
382 | goto err_usbhost_fs_fck; | ||
383 | } | ||
384 | |||
385 | omap->usbtll_ick = clk_get(dev, "usbtll_ick"); | ||
386 | if (IS_ERR(omap->usbtll_ick)) { | ||
387 | ret = PTR_ERR(omap->usbtll_ick); | ||
388 | dev_err(dev, "usbtll_ick failed error:%d\n", ret); | ||
389 | goto err_usbtll_fck; | ||
390 | } | ||
391 | |||
392 | omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); | ||
393 | if (IS_ERR(omap->utmi_p1_fck)) { | ||
394 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
395 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
396 | goto err_usbtll_ick; | ||
397 | } | ||
398 | |||
399 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | ||
400 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | ||
401 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | ||
402 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
403 | goto err_utmi_p1_fck; | ||
404 | } | ||
405 | |||
406 | omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); | ||
407 | if (IS_ERR(omap->utmi_p2_fck)) { | ||
408 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
409 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
410 | goto err_xclk60mhsp1_ck; | ||
411 | } | ||
412 | |||
413 | omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | ||
414 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | ||
415 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | ||
416 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
417 | goto err_utmi_p2_fck; | ||
418 | } | ||
419 | |||
420 | omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); | ||
421 | if (IS_ERR(omap->usbhost_p1_fck)) { | ||
422 | ret = PTR_ERR(omap->usbhost_p1_fck); | ||
423 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
424 | goto err_xclk60mhsp2_ck; | ||
425 | } | ||
426 | |||
427 | omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); | ||
428 | if (IS_ERR(omap->usbtll_p1_fck)) { | ||
429 | ret = PTR_ERR(omap->usbtll_p1_fck); | ||
430 | dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); | ||
431 | goto err_usbhost_p1_fck; | ||
432 | } | ||
433 | |||
434 | omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); | ||
435 | if (IS_ERR(omap->usbhost_p2_fck)) { | ||
436 | ret = PTR_ERR(omap->usbhost_p2_fck); | ||
437 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
438 | goto err_usbtll_p1_fck; | ||
439 | } | ||
440 | |||
441 | omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); | ||
442 | if (IS_ERR(omap->usbtll_p2_fck)) { | ||
443 | ret = PTR_ERR(omap->usbtll_p2_fck); | ||
444 | dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); | ||
445 | goto err_usbhost_p2_fck; | ||
446 | } | ||
447 | |||
448 | omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); | ||
449 | if (IS_ERR(omap->init_60m_fclk)) { | ||
450 | ret = PTR_ERR(omap->init_60m_fclk); | ||
451 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | ||
452 | goto err_usbtll_p2_fck; | ||
453 | } | ||
454 | |||
455 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); | ||
456 | if (!res) { | ||
457 | dev_err(dev, "UHH EHCI get resource failed\n"); | ||
458 | ret = -ENODEV; | ||
459 | goto err_init_60m_fclk; | ||
460 | } | ||
461 | |||
462 | omap->uhh_base = ioremap(res->start, resource_size(res)); | ||
463 | if (!omap->uhh_base) { | ||
464 | dev_err(dev, "UHH ioremap failed\n"); | ||
465 | ret = -ENOMEM; | ||
466 | goto err_init_60m_fclk; | ||
467 | } | ||
468 | |||
469 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); | ||
470 | if (!res) { | ||
471 | dev_err(dev, "UHH EHCI get resource failed\n"); | ||
472 | ret = -ENODEV; | ||
473 | goto err_tll; | ||
474 | } | ||
475 | |||
476 | omap->tll_base = ioremap(res->start, resource_size(res)); | ||
477 | if (!omap->tll_base) { | ||
478 | dev_err(dev, "TLL ioremap failed\n"); | ||
479 | ret = -ENOMEM; | ||
480 | goto err_tll; | ||
481 | } | ||
482 | |||
483 | platform_set_drvdata(pdev, omap); | ||
484 | |||
485 | ret = omap_usbhs_alloc_children(pdev); | ||
486 | if (ret) { | ||
487 | dev_err(dev, "omap_usbhs_alloc_children failed\n"); | ||
488 | goto err_alloc; | ||
489 | } | ||
490 | |||
491 | goto end_probe; | ||
492 | |||
493 | err_alloc: | ||
494 | iounmap(omap->tll_base); | ||
495 | |||
496 | err_tll: | ||
497 | iounmap(omap->uhh_base); | ||
498 | |||
499 | err_init_60m_fclk: | ||
500 | clk_put(omap->init_60m_fclk); | ||
501 | |||
502 | err_usbtll_p2_fck: | ||
503 | clk_put(omap->usbtll_p2_fck); | ||
504 | |||
505 | err_usbhost_p2_fck: | ||
506 | clk_put(omap->usbhost_p2_fck); | ||
507 | |||
508 | err_usbtll_p1_fck: | ||
509 | clk_put(omap->usbtll_p1_fck); | ||
510 | |||
511 | err_usbhost_p1_fck: | ||
512 | clk_put(omap->usbhost_p1_fck); | ||
513 | |||
514 | err_xclk60mhsp2_ck: | ||
515 | clk_put(omap->xclk60mhsp2_ck); | ||
516 | |||
517 | err_utmi_p2_fck: | ||
518 | clk_put(omap->utmi_p2_fck); | ||
519 | |||
520 | err_xclk60mhsp1_ck: | ||
521 | clk_put(omap->xclk60mhsp1_ck); | ||
522 | |||
523 | err_utmi_p1_fck: | ||
524 | clk_put(omap->utmi_p1_fck); | ||
525 | |||
526 | err_usbtll_ick: | ||
527 | clk_put(omap->usbtll_ick); | ||
528 | |||
529 | err_usbtll_fck: | ||
530 | clk_put(omap->usbtll_fck); | ||
531 | |||
532 | err_usbhost_fs_fck: | ||
533 | clk_put(omap->usbhost_fs_fck); | ||
534 | |||
535 | err_usbhost_hs_fck: | ||
536 | clk_put(omap->usbhost_hs_fck); | ||
537 | |||
538 | err_usbhost_ick: | ||
539 | clk_put(omap->usbhost_ick); | ||
540 | |||
541 | err_end: | ||
542 | kfree(omap); | ||
543 | |||
544 | end_probe: | ||
545 | return ret; | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs | ||
550 | * @pdev: USB Host Controller being removed | ||
551 | * | ||
552 | * Reverses the effect of usbhs_omap_probe(). | ||
553 | */ | ||
554 | static int __devexit usbhs_omap_remove(struct platform_device *pdev) | ||
555 | { | ||
556 | struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); | ||
557 | |||
558 | if (omap->count != 0) { | ||
559 | dev_err(&pdev->dev, | ||
560 | "Either EHCI or OHCI is still using usbhs core\n"); | ||
561 | return -EBUSY; | ||
562 | } | ||
563 | |||
564 | iounmap(omap->tll_base); | ||
565 | iounmap(omap->uhh_base); | ||
566 | clk_put(omap->init_60m_fclk); | ||
567 | clk_put(omap->usbtll_p2_fck); | ||
568 | clk_put(omap->usbhost_p2_fck); | ||
569 | clk_put(omap->usbtll_p1_fck); | ||
570 | clk_put(omap->usbhost_p1_fck); | ||
571 | clk_put(omap->xclk60mhsp2_ck); | ||
572 | clk_put(omap->utmi_p2_fck); | ||
573 | clk_put(omap->xclk60mhsp1_ck); | ||
574 | clk_put(omap->utmi_p1_fck); | ||
575 | clk_put(omap->usbtll_ick); | ||
576 | clk_put(omap->usbtll_fck); | ||
577 | clk_put(omap->usbhost_fs_fck); | ||
578 | clk_put(omap->usbhost_hs_fck); | ||
579 | clk_put(omap->usbhost_ick); | ||
580 | kfree(omap); | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static bool is_ohci_port(enum usbhs_omap_port_mode pmode) | 318 | static bool is_ohci_port(enum usbhs_omap_port_mode pmode) |
586 | { | 319 | { |
587 | switch (pmode) { | 320 | switch (pmode) { |
@@ -689,30 +422,85 @@ static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count) | |||
689 | } | 422 | } |
690 | } | 423 | } |
691 | 424 | ||
692 | static int usbhs_enable(struct device *dev) | 425 | static int usbhs_runtime_resume(struct device *dev) |
693 | { | 426 | { |
694 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | 427 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); |
695 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | 428 | struct usbhs_omap_platform_data *pdata = &omap->platdata; |
696 | unsigned long flags = 0; | 429 | unsigned long flags; |
697 | int ret = 0; | 430 | |
698 | unsigned long timeout; | 431 | dev_dbg(dev, "usbhs_runtime_resume\n"); |
699 | unsigned reg; | ||
700 | 432 | ||
701 | dev_dbg(dev, "starting TI HSUSB Controller\n"); | ||
702 | if (!pdata) { | 433 | if (!pdata) { |
703 | dev_dbg(dev, "missing platform_data\n"); | 434 | dev_dbg(dev, "missing platform_data\n"); |
704 | return -ENODEV; | 435 | return -ENODEV; |
705 | } | 436 | } |
706 | 437 | ||
707 | spin_lock_irqsave(&omap->lock, flags); | 438 | spin_lock_irqsave(&omap->lock, flags); |
708 | if (omap->count > 0) | ||
709 | goto end_count; | ||
710 | 439 | ||
711 | clk_enable(omap->usbhost_ick); | 440 | if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) |
712 | clk_enable(omap->usbhost_hs_fck); | 441 | clk_enable(omap->ehci_logic_fck); |
713 | clk_enable(omap->usbhost_fs_fck); | 442 | |
714 | clk_enable(omap->usbtll_fck); | 443 | if (is_ehci_tll_mode(pdata->port_mode[0])) { |
715 | clk_enable(omap->usbtll_ick); | 444 | clk_enable(omap->usbhost_p1_fck); |
445 | clk_enable(omap->usbtll_p1_fck); | ||
446 | } | ||
447 | if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
448 | clk_enable(omap->usbhost_p2_fck); | ||
449 | clk_enable(omap->usbtll_p2_fck); | ||
450 | } | ||
451 | clk_enable(omap->utmi_p1_fck); | ||
452 | clk_enable(omap->utmi_p2_fck); | ||
453 | |||
454 | spin_unlock_irqrestore(&omap->lock, flags); | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static int usbhs_runtime_suspend(struct device *dev) | ||
460 | { | ||
461 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | ||
462 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | ||
463 | unsigned long flags; | ||
464 | |||
465 | dev_dbg(dev, "usbhs_runtime_suspend\n"); | ||
466 | |||
467 | if (!pdata) { | ||
468 | dev_dbg(dev, "missing platform_data\n"); | ||
469 | return -ENODEV; | ||
470 | } | ||
471 | |||
472 | spin_lock_irqsave(&omap->lock, flags); | ||
473 | |||
474 | if (is_ehci_tll_mode(pdata->port_mode[0])) { | ||
475 | clk_disable(omap->usbhost_p1_fck); | ||
476 | clk_disable(omap->usbtll_p1_fck); | ||
477 | } | ||
478 | if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
479 | clk_disable(omap->usbhost_p2_fck); | ||
480 | clk_disable(omap->usbtll_p2_fck); | ||
481 | } | ||
482 | clk_disable(omap->utmi_p2_fck); | ||
483 | clk_disable(omap->utmi_p1_fck); | ||
484 | |||
485 | if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) | ||
486 | clk_disable(omap->ehci_logic_fck); | ||
487 | |||
488 | spin_unlock_irqrestore(&omap->lock, flags); | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static void omap_usbhs_init(struct device *dev) | ||
494 | { | ||
495 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | ||
496 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | ||
497 | unsigned long flags; | ||
498 | unsigned reg; | ||
499 | |||
500 | dev_dbg(dev, "starting TI HSUSB Controller\n"); | ||
501 | |||
502 | pm_runtime_get_sync(dev); | ||
503 | spin_lock_irqsave(&omap->lock, flags); | ||
716 | 504 | ||
717 | if (pdata->ehci_data->phy_reset) { | 505 | if (pdata->ehci_data->phy_reset) { |
718 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { | 506 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { |
@@ -736,50 +524,6 @@ static int usbhs_enable(struct device *dev) | |||
736 | omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); | 524 | omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); |
737 | dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); | 525 | dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); |
738 | 526 | ||
739 | /* perform TLL soft reset, and wait until reset is complete */ | ||
740 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | ||
741 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); | ||
742 | |||
743 | /* Wait for TLL reset to complete */ | ||
744 | timeout = jiffies + msecs_to_jiffies(1000); | ||
745 | while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) | ||
746 | & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { | ||
747 | cpu_relax(); | ||
748 | |||
749 | if (time_after(jiffies, timeout)) { | ||
750 | dev_dbg(dev, "operation timed out\n"); | ||
751 | ret = -EINVAL; | ||
752 | goto err_tll; | ||
753 | } | ||
754 | } | ||
755 | |||
756 | dev_dbg(dev, "TLL RESET DONE\n"); | ||
757 | |||
758 | /* (1<<3) = no idle mode only for initial debugging */ | ||
759 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | ||
760 | OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | | ||
761 | OMAP_USBTLL_SYSCONFIG_SIDLEMODE | | ||
762 | OMAP_USBTLL_SYSCONFIG_AUTOIDLE); | ||
763 | |||
764 | /* Put UHH in NoIdle/NoStandby mode */ | ||
765 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); | ||
766 | if (is_omap_usbhs_rev1(omap)) { | ||
767 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | ||
768 | | OMAP_UHH_SYSCONFIG_SIDLEMODE | ||
769 | | OMAP_UHH_SYSCONFIG_CACTIVITY | ||
770 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); | ||
771 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | ||
772 | |||
773 | |||
774 | } else if (is_omap_usbhs_rev2(omap)) { | ||
775 | reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; | ||
776 | reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; | ||
777 | reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; | ||
778 | reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; | ||
779 | } | ||
780 | |||
781 | usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); | ||
782 | |||
783 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); | 527 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); |
784 | /* setup ULPI bypass and burst configurations */ | 528 | /* setup ULPI bypass and burst configurations */ |
785 | reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN | 529 | reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN |
@@ -825,49 +569,6 @@ static int usbhs_enable(struct device *dev) | |||
825 | reg &= ~OMAP4_P1_MODE_CLEAR; | 569 | reg &= ~OMAP4_P1_MODE_CLEAR; |
826 | reg &= ~OMAP4_P2_MODE_CLEAR; | 570 | reg &= ~OMAP4_P2_MODE_CLEAR; |
827 | 571 | ||
828 | if (is_ehci_phy_mode(pdata->port_mode[0])) { | ||
829 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
830 | omap->xclk60mhsp1_ck); | ||
831 | if (ret != 0) { | ||
832 | dev_err(dev, "xclk60mhsp1_ck set parent" | ||
833 | "failed error:%d\n", ret); | ||
834 | goto err_tll; | ||
835 | } | ||
836 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { | ||
837 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
838 | omap->init_60m_fclk); | ||
839 | if (ret != 0) { | ||
840 | dev_err(dev, "init_60m_fclk set parent" | ||
841 | "failed error:%d\n", ret); | ||
842 | goto err_tll; | ||
843 | } | ||
844 | clk_enable(omap->usbhost_p1_fck); | ||
845 | clk_enable(omap->usbtll_p1_fck); | ||
846 | } | ||
847 | |||
848 | if (is_ehci_phy_mode(pdata->port_mode[1])) { | ||
849 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
850 | omap->xclk60mhsp2_ck); | ||
851 | if (ret != 0) { | ||
852 | dev_err(dev, "xclk60mhsp1_ck set parent" | ||
853 | "failed error:%d\n", ret); | ||
854 | goto err_tll; | ||
855 | } | ||
856 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
857 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
858 | omap->init_60m_fclk); | ||
859 | if (ret != 0) { | ||
860 | dev_err(dev, "init_60m_fclk set parent" | ||
861 | "failed error:%d\n", ret); | ||
862 | goto err_tll; | ||
863 | } | ||
864 | clk_enable(omap->usbhost_p2_fck); | ||
865 | clk_enable(omap->usbtll_p2_fck); | ||
866 | } | ||
867 | |||
868 | clk_enable(omap->utmi_p1_fck); | ||
869 | clk_enable(omap->utmi_p2_fck); | ||
870 | |||
871 | if (is_ehci_tll_mode(pdata->port_mode[0]) || | 572 | if (is_ehci_tll_mode(pdata->port_mode[0]) || |
872 | (is_ohci_port(pdata->port_mode[0]))) | 573 | (is_ohci_port(pdata->port_mode[0]))) |
873 | reg |= OMAP4_P1_MODE_TLL; | 574 | reg |= OMAP4_P1_MODE_TLL; |
@@ -913,12 +614,15 @@ static int usbhs_enable(struct device *dev) | |||
913 | (pdata->ehci_data->reset_gpio_port[1], 1); | 614 | (pdata->ehci_data->reset_gpio_port[1], 1); |
914 | } | 615 | } |
915 | 616 | ||
916 | end_count: | ||
917 | omap->count++; | ||
918 | spin_unlock_irqrestore(&omap->lock, flags); | 617 | spin_unlock_irqrestore(&omap->lock, flags); |
919 | return 0; | 618 | pm_runtime_put_sync(dev); |
619 | } | ||
620 | |||
621 | static void omap_usbhs_deinit(struct device *dev) | ||
622 | { | ||
623 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | ||
624 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | ||
920 | 625 | ||
921 | err_tll: | ||
922 | if (pdata->ehci_data->phy_reset) { | 626 | if (pdata->ehci_data->phy_reset) { |
923 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) | 627 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) |
924 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); | 628 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); |
@@ -926,123 +630,272 @@ err_tll: | |||
926 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) | 630 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) |
927 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); | 631 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); |
928 | } | 632 | } |
929 | |||
930 | clk_disable(omap->usbtll_ick); | ||
931 | clk_disable(omap->usbtll_fck); | ||
932 | clk_disable(omap->usbhost_fs_fck); | ||
933 | clk_disable(omap->usbhost_hs_fck); | ||
934 | clk_disable(omap->usbhost_ick); | ||
935 | spin_unlock_irqrestore(&omap->lock, flags); | ||
936 | return ret; | ||
937 | } | 633 | } |
938 | 634 | ||
939 | static void usbhs_disable(struct device *dev) | 635 | |
636 | /** | ||
637 | * usbhs_omap_probe - initialize TI-based HCDs | ||
638 | * | ||
639 | * Allocates basic resources for this USB host controller. | ||
640 | */ | ||
641 | static int __devinit usbhs_omap_probe(struct platform_device *pdev) | ||
940 | { | 642 | { |
941 | struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); | 643 | struct device *dev = &pdev->dev; |
942 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | 644 | struct usbhs_omap_platform_data *pdata = dev->platform_data; |
943 | unsigned long flags = 0; | 645 | struct usbhs_hcd_omap *omap; |
944 | unsigned long timeout; | 646 | struct resource *res; |
647 | int ret = 0; | ||
648 | int i; | ||
945 | 649 | ||
946 | dev_dbg(dev, "stopping TI HSUSB Controller\n"); | 650 | if (!pdata) { |
651 | dev_err(dev, "Missing platform data\n"); | ||
652 | ret = -ENOMEM; | ||
653 | goto end_probe; | ||
654 | } | ||
947 | 655 | ||
948 | spin_lock_irqsave(&omap->lock, flags); | 656 | omap = kzalloc(sizeof(*omap), GFP_KERNEL); |
657 | if (!omap) { | ||
658 | dev_err(dev, "Memory allocation failed\n"); | ||
659 | ret = -ENOMEM; | ||
660 | goto end_probe; | ||
661 | } | ||
949 | 662 | ||
950 | if (omap->count == 0) | 663 | spin_lock_init(&omap->lock); |
951 | goto end_disble; | ||
952 | 664 | ||
953 | omap->count--; | 665 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) |
666 | omap->platdata.port_mode[i] = pdata->port_mode[i]; | ||
667 | |||
668 | omap->platdata.ehci_data = pdata->ehci_data; | ||
669 | omap->platdata.ohci_data = pdata->ohci_data; | ||
954 | 670 | ||
955 | if (omap->count != 0) | 671 | pm_runtime_enable(dev); |
956 | goto end_disble; | ||
957 | 672 | ||
958 | /* Reset OMAP modules for insmod/rmmod to work */ | ||
959 | usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, | ||
960 | is_omap_usbhs_rev2(omap) ? | ||
961 | OMAP4_UHH_SYSCONFIG_SOFTRESET : | ||
962 | OMAP_UHH_SYSCONFIG_SOFTRESET); | ||
963 | 673 | ||
964 | timeout = jiffies + msecs_to_jiffies(100); | 674 | for (i = 0; i < OMAP3_HS_USB_PORTS; i++) |
965 | while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 675 | if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || |
966 | & (1 << 0))) { | 676 | is_ehci_hsic_mode(i)) { |
967 | cpu_relax(); | 677 | omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); |
678 | if (IS_ERR(omap->ehci_logic_fck)) { | ||
679 | ret = PTR_ERR(omap->ehci_logic_fck); | ||
680 | dev_warn(dev, "ehci_logic_fck failed:%d\n", | ||
681 | ret); | ||
682 | } | ||
683 | break; | ||
684 | } | ||
968 | 685 | ||
969 | if (time_after(jiffies, timeout)) | 686 | omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); |
970 | dev_dbg(dev, "operation timed out\n"); | 687 | if (IS_ERR(omap->utmi_p1_fck)) { |
688 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
689 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
690 | goto err_end; | ||
971 | } | 691 | } |
972 | 692 | ||
973 | while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 693 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); |
974 | & (1 << 1))) { | 694 | if (IS_ERR(omap->xclk60mhsp1_ck)) { |
975 | cpu_relax(); | 695 | ret = PTR_ERR(omap->xclk60mhsp1_ck); |
696 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
697 | goto err_utmi_p1_fck; | ||
698 | } | ||
976 | 699 | ||
977 | if (time_after(jiffies, timeout)) | 700 | omap->utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); |
978 | dev_dbg(dev, "operation timed out\n"); | 701 | if (IS_ERR(omap->utmi_p2_fck)) { |
702 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
703 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
704 | goto err_xclk60mhsp1_ck; | ||
979 | } | 705 | } |
980 | 706 | ||
981 | while (!(usbhs_read(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 707 | omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); |
982 | & (1 << 2))) { | 708 | if (IS_ERR(omap->xclk60mhsp2_ck)) { |
983 | cpu_relax(); | 709 | ret = PTR_ERR(omap->xclk60mhsp2_ck); |
710 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
711 | goto err_utmi_p2_fck; | ||
712 | } | ||
984 | 713 | ||
985 | if (time_after(jiffies, timeout)) | 714 | omap->usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); |
986 | dev_dbg(dev, "operation timed out\n"); | 715 | if (IS_ERR(omap->usbhost_p1_fck)) { |
716 | ret = PTR_ERR(omap->usbhost_p1_fck); | ||
717 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
718 | goto err_xclk60mhsp2_ck; | ||
987 | } | 719 | } |
988 | 720 | ||
989 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, (1 << 1)); | 721 | omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk"); |
722 | if (IS_ERR(omap->usbtll_p1_fck)) { | ||
723 | ret = PTR_ERR(omap->usbtll_p1_fck); | ||
724 | dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret); | ||
725 | goto err_usbhost_p1_fck; | ||
726 | } | ||
990 | 727 | ||
991 | while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) | 728 | omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); |
992 | & (1 << 0))) { | 729 | if (IS_ERR(omap->usbhost_p2_fck)) { |
993 | cpu_relax(); | 730 | ret = PTR_ERR(omap->usbhost_p2_fck); |
731 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
732 | goto err_usbtll_p1_fck; | ||
733 | } | ||
994 | 734 | ||
995 | if (time_after(jiffies, timeout)) | 735 | omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk"); |
996 | dev_dbg(dev, "operation timed out\n"); | 736 | if (IS_ERR(omap->usbtll_p2_fck)) { |
737 | ret = PTR_ERR(omap->usbtll_p2_fck); | ||
738 | dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret); | ||
739 | goto err_usbhost_p2_fck; | ||
997 | } | 740 | } |
998 | 741 | ||
999 | if (is_omap_usbhs_rev2(omap)) { | 742 | omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); |
1000 | if (is_ehci_tll_mode(pdata->port_mode[0])) | 743 | if (IS_ERR(omap->init_60m_fclk)) { |
1001 | clk_disable(omap->usbtll_p1_fck); | 744 | ret = PTR_ERR(omap->init_60m_fclk); |
1002 | if (is_ehci_tll_mode(pdata->port_mode[1])) | 745 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); |
1003 | clk_disable(omap->usbtll_p2_fck); | 746 | goto err_usbtll_p2_fck; |
1004 | clk_disable(omap->utmi_p2_fck); | ||
1005 | clk_disable(omap->utmi_p1_fck); | ||
1006 | } | 747 | } |
1007 | 748 | ||
1008 | clk_disable(omap->usbtll_ick); | 749 | if (is_ehci_phy_mode(pdata->port_mode[0])) { |
1009 | clk_disable(omap->usbtll_fck); | 750 | /* for OMAP3 , the clk set paretn fails */ |
1010 | clk_disable(omap->usbhost_fs_fck); | 751 | ret = clk_set_parent(omap->utmi_p1_fck, |
1011 | clk_disable(omap->usbhost_hs_fck); | 752 | omap->xclk60mhsp1_ck); |
1012 | clk_disable(omap->usbhost_ick); | 753 | if (ret != 0) |
754 | dev_err(dev, "xclk60mhsp1_ck set parent" | ||
755 | "failed error:%d\n", ret); | ||
756 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { | ||
757 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
758 | omap->init_60m_fclk); | ||
759 | if (ret != 0) | ||
760 | dev_err(dev, "init_60m_fclk set parent" | ||
761 | "failed error:%d\n", ret); | ||
762 | } | ||
1013 | 763 | ||
1014 | /* The gpio_free migh sleep; so unlock the spinlock */ | 764 | if (is_ehci_phy_mode(pdata->port_mode[1])) { |
1015 | spin_unlock_irqrestore(&omap->lock, flags); | 765 | ret = clk_set_parent(omap->utmi_p2_fck, |
766 | omap->xclk60mhsp2_ck); | ||
767 | if (ret != 0) | ||
768 | dev_err(dev, "xclk60mhsp2_ck set parent" | ||
769 | "failed error:%d\n", ret); | ||
770 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { | ||
771 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
772 | omap->init_60m_fclk); | ||
773 | if (ret != 0) | ||
774 | dev_err(dev, "init_60m_fclk set parent" | ||
775 | "failed error:%d\n", ret); | ||
776 | } | ||
1016 | 777 | ||
1017 | if (pdata->ehci_data->phy_reset) { | 778 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "uhh"); |
1018 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) | 779 | if (!res) { |
1019 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); | 780 | dev_err(dev, "UHH EHCI get resource failed\n"); |
781 | ret = -ENODEV; | ||
782 | goto err_init_60m_fclk; | ||
783 | } | ||
1020 | 784 | ||
1021 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) | 785 | omap->uhh_base = ioremap(res->start, resource_size(res)); |
1022 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); | 786 | if (!omap->uhh_base) { |
787 | dev_err(dev, "UHH ioremap failed\n"); | ||
788 | ret = -ENOMEM; | ||
789 | goto err_init_60m_fclk; | ||
1023 | } | 790 | } |
1024 | return; | ||
1025 | 791 | ||
1026 | end_disble: | 792 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll"); |
1027 | spin_unlock_irqrestore(&omap->lock, flags); | 793 | if (!res) { |
1028 | } | 794 | dev_err(dev, "UHH EHCI get resource failed\n"); |
795 | ret = -ENODEV; | ||
796 | goto err_tll; | ||
797 | } | ||
1029 | 798 | ||
1030 | int omap_usbhs_enable(struct device *dev) | 799 | omap->tll_base = ioremap(res->start, resource_size(res)); |
1031 | { | 800 | if (!omap->tll_base) { |
1032 | return usbhs_enable(dev->parent); | 801 | dev_err(dev, "TLL ioremap failed\n"); |
802 | ret = -ENOMEM; | ||
803 | goto err_tll; | ||
804 | } | ||
805 | |||
806 | platform_set_drvdata(pdev, omap); | ||
807 | |||
808 | ret = omap_usbhs_alloc_children(pdev); | ||
809 | if (ret) { | ||
810 | dev_err(dev, "omap_usbhs_alloc_children failed\n"); | ||
811 | goto err_alloc; | ||
812 | } | ||
813 | |||
814 | omap_usbhs_init(dev); | ||
815 | |||
816 | goto end_probe; | ||
817 | |||
818 | err_alloc: | ||
819 | iounmap(omap->tll_base); | ||
820 | |||
821 | err_tll: | ||
822 | iounmap(omap->uhh_base); | ||
823 | |||
824 | err_init_60m_fclk: | ||
825 | clk_put(omap->init_60m_fclk); | ||
826 | |||
827 | err_usbtll_p2_fck: | ||
828 | clk_put(omap->usbtll_p2_fck); | ||
829 | |||
830 | err_usbhost_p2_fck: | ||
831 | clk_put(omap->usbhost_p2_fck); | ||
832 | |||
833 | err_usbtll_p1_fck: | ||
834 | clk_put(omap->usbtll_p1_fck); | ||
835 | |||
836 | err_usbhost_p1_fck: | ||
837 | clk_put(omap->usbhost_p1_fck); | ||
838 | |||
839 | err_xclk60mhsp2_ck: | ||
840 | clk_put(omap->xclk60mhsp2_ck); | ||
841 | |||
842 | err_utmi_p2_fck: | ||
843 | clk_put(omap->utmi_p2_fck); | ||
844 | |||
845 | err_xclk60mhsp1_ck: | ||
846 | clk_put(omap->xclk60mhsp1_ck); | ||
847 | |||
848 | err_utmi_p1_fck: | ||
849 | clk_put(omap->utmi_p1_fck); | ||
850 | |||
851 | err_end: | ||
852 | clk_put(omap->ehci_logic_fck); | ||
853 | pm_runtime_disable(dev); | ||
854 | kfree(omap); | ||
855 | |||
856 | end_probe: | ||
857 | return ret; | ||
1033 | } | 858 | } |
1034 | EXPORT_SYMBOL_GPL(omap_usbhs_enable); | ||
1035 | 859 | ||
1036 | void omap_usbhs_disable(struct device *dev) | 860 | /** |
861 | * usbhs_omap_remove - shutdown processing for UHH & TLL HCDs | ||
862 | * @pdev: USB Host Controller being removed | ||
863 | * | ||
864 | * Reverses the effect of usbhs_omap_probe(). | ||
865 | */ | ||
866 | static int __devexit usbhs_omap_remove(struct platform_device *pdev) | ||
1037 | { | 867 | { |
1038 | usbhs_disable(dev->parent); | 868 | struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); |
869 | |||
870 | omap_usbhs_deinit(&pdev->dev); | ||
871 | iounmap(omap->tll_base); | ||
872 | iounmap(omap->uhh_base); | ||
873 | clk_put(omap->init_60m_fclk); | ||
874 | clk_put(omap->usbtll_p2_fck); | ||
875 | clk_put(omap->usbhost_p2_fck); | ||
876 | clk_put(omap->usbtll_p1_fck); | ||
877 | clk_put(omap->usbhost_p1_fck); | ||
878 | clk_put(omap->xclk60mhsp2_ck); | ||
879 | clk_put(omap->utmi_p2_fck); | ||
880 | clk_put(omap->xclk60mhsp1_ck); | ||
881 | clk_put(omap->utmi_p1_fck); | ||
882 | clk_put(omap->ehci_logic_fck); | ||
883 | pm_runtime_disable(&pdev->dev); | ||
884 | kfree(omap); | ||
885 | |||
886 | return 0; | ||
1039 | } | 887 | } |
1040 | EXPORT_SYMBOL_GPL(omap_usbhs_disable); | 888 | |
889 | static const struct dev_pm_ops usbhsomap_dev_pm_ops = { | ||
890 | .runtime_suspend = usbhs_runtime_suspend, | ||
891 | .runtime_resume = usbhs_runtime_resume, | ||
892 | }; | ||
1041 | 893 | ||
1042 | static struct platform_driver usbhs_omap_driver = { | 894 | static struct platform_driver usbhs_omap_driver = { |
1043 | .driver = { | 895 | .driver = { |
1044 | .name = (char *)usbhs_driver_name, | 896 | .name = (char *)usbhs_driver_name, |
1045 | .owner = THIS_MODULE, | 897 | .owner = THIS_MODULE, |
898 | .pm = &usbhsomap_dev_pm_ops, | ||
1046 | }, | 899 | }, |
1047 | .remove = __exit_p(usbhs_omap_remove), | 900 | .remove = __exit_p(usbhs_omap_remove), |
1048 | }; | 901 | }; |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d5fe43d53c51..d1fb561e089d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -1991,6 +1991,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1991 | if (mmc_slot(host).nonremovable) | 1991 | if (mmc_slot(host).nonremovable) |
1992 | mmc->caps |= MMC_CAP_NONREMOVABLE; | 1992 | mmc->caps |= MMC_CAP_NONREMOVABLE; |
1993 | 1993 | ||
1994 | mmc->pm_caps = mmc_slot(host).pm_caps; | ||
1995 | |||
1994 | omap_hsmmc_conf_bus_power(host); | 1996 | omap_hsmmc_conf_bus_power(host); |
1995 | 1997 | ||
1996 | /* Select DMA lines */ | 1998 | /* Select DMA lines */ |
@@ -2179,13 +2181,7 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
2179 | cancel_work_sync(&host->mmc_carddetect_work); | 2181 | cancel_work_sync(&host->mmc_carddetect_work); |
2180 | ret = mmc_suspend_host(host->mmc); | 2182 | ret = mmc_suspend_host(host->mmc); |
2181 | 2183 | ||
2182 | if (ret == 0) { | 2184 | if (ret) { |
2183 | omap_hsmmc_disable_irq(host); | ||
2184 | OMAP_HSMMC_WRITE(host->base, HCTL, | ||
2185 | OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); | ||
2186 | if (host->got_dbclk) | ||
2187 | clk_disable(host->dbclk); | ||
2188 | } else { | ||
2189 | host->suspended = 0; | 2185 | host->suspended = 0; |
2190 | if (host->pdata->resume) { | 2186 | if (host->pdata->resume) { |
2191 | ret = host->pdata->resume(&pdev->dev, | 2187 | ret = host->pdata->resume(&pdev->dev, |
@@ -2194,9 +2190,20 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
2194 | dev_dbg(mmc_dev(host->mmc), | 2190 | dev_dbg(mmc_dev(host->mmc), |
2195 | "Unmask interrupt failed\n"); | 2191 | "Unmask interrupt failed\n"); |
2196 | } | 2192 | } |
2193 | goto err; | ||
2197 | } | 2194 | } |
2198 | pm_runtime_put_sync(host->dev); | 2195 | |
2196 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) { | ||
2197 | omap_hsmmc_disable_irq(host); | ||
2198 | OMAP_HSMMC_WRITE(host->base, HCTL, | ||
2199 | OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); | ||
2200 | } | ||
2201 | if (host->got_dbclk) | ||
2202 | clk_disable(host->dbclk); | ||
2203 | |||
2199 | } | 2204 | } |
2205 | err: | ||
2206 | pm_runtime_put_sync(host->dev); | ||
2200 | return ret; | 2207 | return ret; |
2201 | } | 2208 | } |
2202 | 2209 | ||
@@ -2216,7 +2223,8 @@ static int omap_hsmmc_resume(struct device *dev) | |||
2216 | if (host->got_dbclk) | 2223 | if (host->got_dbclk) |
2217 | clk_enable(host->dbclk); | 2224 | clk_enable(host->dbclk); |
2218 | 2225 | ||
2219 | omap_hsmmc_conf_bus_power(host); | 2226 | if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER)) |
2227 | omap_hsmmc_conf_bus_power(host); | ||
2220 | 2228 | ||
2221 | if (host->pdata->resume) { | 2229 | if (host->pdata->resume) { |
2222 | ret = host->pdata->resume(&pdev->dev, host->slot_id); | 2230 | ret = host->pdata->resume(&pdev->dev, host->slot_id); |
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index cd6d69a6a7d2..08d5f0388877 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile | |||
@@ -10,7 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ | |||
10 | obj-$(CONFIG_NET_VENDOR_AMD) += amd/ | 10 | obj-$(CONFIG_NET_VENDOR_AMD) += amd/ |
11 | obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ | 11 | obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ |
12 | obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ | 12 | obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ |
13 | obj-$(CONFIG_NET_ATMEL) += cadence/ | 13 | obj-$(CONFIG_NET_CADENCE) += cadence/ |
14 | obj-$(CONFIG_NET_BFIN) += adi/ | 14 | obj-$(CONFIG_NET_BFIN) += adi/ |
15 | obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/ | 15 | obj-$(CONFIG_NET_VENDOR_BROADCOM) += broadcom/ |
16 | obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/ | 16 | obj-$(CONFIG_NET_VENDOR_BROCADE) += brocade/ |
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index b48378a41e49..db931916da08 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig | |||
@@ -5,8 +5,8 @@ | |||
5 | config HAVE_NET_MACB | 5 | config HAVE_NET_MACB |
6 | bool | 6 | bool |
7 | 7 | ||
8 | config NET_ATMEL | 8 | config NET_CADENCE |
9 | bool "Atmel devices" | 9 | bool "Cadence devices" |
10 | default y | 10 | default y |
11 | depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200) | 11 | depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200) |
12 | ---help--- | 12 | ---help--- |
@@ -21,7 +21,7 @@ config NET_ATMEL | |||
21 | the remaining Atmel network card questions. If you say Y, you will be | 21 | the remaining Atmel network card questions. If you say Y, you will be |
22 | asked for your specific card in the following questions. | 22 | asked for your specific card in the following questions. |
23 | 23 | ||
24 | if NET_ATMEL | 24 | if NET_CADENCE |
25 | 25 | ||
26 | config ARM_AT91_ETHER | 26 | config ARM_AT91_ETHER |
27 | tristate "AT91RM9200 Ethernet support" | 27 | tristate "AT91RM9200 Ethernet support" |
@@ -33,14 +33,16 @@ config ARM_AT91_ETHER | |||
33 | ethernet support, then you should always answer Y to this. | 33 | ethernet support, then you should always answer Y to this. |
34 | 34 | ||
35 | config MACB | 35 | config MACB |
36 | tristate "Atmel MACB support" | 36 | tristate "Cadence MACB/GEM support" |
37 | depends on HAVE_NET_MACB | 37 | depends on HAVE_NET_MACB |
38 | select PHYLIB | 38 | select PHYLIB |
39 | ---help--- | 39 | ---help--- |
40 | The Atmel MACB ethernet interface is found on many AT32 and AT91 | 40 | The Cadence MACB ethernet interface is found on many Atmel AT32 and |
41 | parts. Say Y to include support for the MACB chip. | 41 | AT91 parts. This driver also supports the Cadence GEM (Gigabit |
42 | Ethernet MAC found in some ARM SoC devices). Note: the Gigabit mode | ||
43 | is not yet supported. Say Y to include support for the MACB/GEM chip. | ||
42 | 44 | ||
43 | To compile this driver as a module, choose M here: the module | 45 | To compile this driver as a module, choose M here: the module |
44 | will be called macb. | 46 | will be called macb. |
45 | 47 | ||
46 | endif # NET_ATMEL | 48 | endif # NET_CADENCE |
diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c index dfeb46cb3f74..1a5b6efa0120 100644 --- a/drivers/net/ethernet/cadence/at91_ether.c +++ b/drivers/net/ethernet/cadence/at91_ether.c | |||
@@ -256,8 +256,7 @@ static void enable_phyirq(struct net_device *dev) | |||
256 | unsigned int dsintr, irq_number; | 256 | unsigned int dsintr, irq_number; |
257 | int status; | 257 | int status; |
258 | 258 | ||
259 | irq_number = lp->board_data.phy_irq_pin; | 259 | if (!gpio_is_valid(lp->board_data.phy_irq_pin)) { |
260 | if (!irq_number) { | ||
261 | /* | 260 | /* |
262 | * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), | 261 | * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), |
263 | * or board does not have it connected. | 262 | * or board does not have it connected. |
@@ -266,6 +265,7 @@ static void enable_phyirq(struct net_device *dev) | |||
266 | return; | 265 | return; |
267 | } | 266 | } |
268 | 267 | ||
268 | irq_number = lp->board_data.phy_irq_pin; | ||
269 | status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); | 269 | status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); |
270 | if (status) { | 270 | if (status) { |
271 | printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); | 271 | printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); |
@@ -320,8 +320,7 @@ static void disable_phyirq(struct net_device *dev) | |||
320 | unsigned int dsintr; | 320 | unsigned int dsintr; |
321 | unsigned int irq_number; | 321 | unsigned int irq_number; |
322 | 322 | ||
323 | irq_number = lp->board_data.phy_irq_pin; | 323 | if (!gpio_is_valid(lp->board_data.phy_irq_pin)) { |
324 | if (!irq_number) { | ||
325 | del_timer_sync(&lp->check_timer); | 324 | del_timer_sync(&lp->check_timer); |
326 | return; | 325 | return; |
327 | } | 326 | } |
@@ -366,6 +365,7 @@ static void disable_phyirq(struct net_device *dev) | |||
366 | disable_mdi(); | 365 | disable_mdi(); |
367 | spin_unlock_irq(&lp->lock); | 366 | spin_unlock_irq(&lp->lock); |
368 | 367 | ||
368 | irq_number = lp->board_data.phy_irq_pin; | ||
369 | free_irq(irq_number, dev); /* Free interrupt handler */ | 369 | free_irq(irq_number, dev); /* Free interrupt handler */ |
370 | } | 370 | } |
371 | 371 | ||
@@ -1078,7 +1078,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
1078 | netif_carrier_off(dev); /* will be enabled in open() */ | 1078 | netif_carrier_off(dev); /* will be enabled in open() */ |
1079 | 1079 | ||
1080 | /* If board has no PHY IRQ, use a timer to poll the PHY */ | 1080 | /* If board has no PHY IRQ, use a timer to poll the PHY */ |
1081 | if (!lp->board_data.phy_irq_pin) { | 1081 | if (!gpio_is_valid(lp->board_data.phy_irq_pin)) { |
1082 | init_timer(&lp->check_timer); | 1082 | init_timer(&lp->check_timer); |
1083 | lp->check_timer.data = (unsigned long)dev; | 1083 | lp->check_timer.data = (unsigned long)dev; |
1084 | lp->check_timer.function = at91ether_check_link; | 1084 | lp->check_timer.function = at91ether_check_link; |
@@ -1170,7 +1170,8 @@ static int __devexit at91ether_remove(struct platform_device *pdev) | |||
1170 | struct net_device *dev = platform_get_drvdata(pdev); | 1170 | struct net_device *dev = platform_get_drvdata(pdev); |
1171 | struct at91_private *lp = netdev_priv(dev); | 1171 | struct at91_private *lp = netdev_priv(dev); |
1172 | 1172 | ||
1173 | if (lp->board_data.phy_irq_pin >= 32) | 1173 | if (gpio_is_valid(lp->board_data.phy_irq_pin) && |
1174 | lp->board_data.phy_irq_pin >= 32) | ||
1174 | gpio_free(lp->board_data.phy_irq_pin); | 1175 | gpio_free(lp->board_data.phy_irq_pin); |
1175 | 1176 | ||
1176 | unregister_netdev(dev); | 1177 | unregister_netdev(dev); |
@@ -1189,11 +1190,12 @@ static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1189 | { | 1190 | { |
1190 | struct net_device *net_dev = platform_get_drvdata(pdev); | 1191 | struct net_device *net_dev = platform_get_drvdata(pdev); |
1191 | struct at91_private *lp = netdev_priv(net_dev); | 1192 | struct at91_private *lp = netdev_priv(net_dev); |
1192 | int phy_irq = lp->board_data.phy_irq_pin; | ||
1193 | 1193 | ||
1194 | if (netif_running(net_dev)) { | 1194 | if (netif_running(net_dev)) { |
1195 | if (phy_irq) | 1195 | if (gpio_is_valid(lp->board_data.phy_irq_pin)) { |
1196 | int phy_irq = lp->board_data.phy_irq_pin; | ||
1196 | disable_irq(phy_irq); | 1197 | disable_irq(phy_irq); |
1198 | } | ||
1197 | 1199 | ||
1198 | netif_stop_queue(net_dev); | 1200 | netif_stop_queue(net_dev); |
1199 | netif_device_detach(net_dev); | 1201 | netif_device_detach(net_dev); |
@@ -1207,7 +1209,6 @@ static int at91ether_resume(struct platform_device *pdev) | |||
1207 | { | 1209 | { |
1208 | struct net_device *net_dev = platform_get_drvdata(pdev); | 1210 | struct net_device *net_dev = platform_get_drvdata(pdev); |
1209 | struct at91_private *lp = netdev_priv(net_dev); | 1211 | struct at91_private *lp = netdev_priv(net_dev); |
1210 | int phy_irq = lp->board_data.phy_irq_pin; | ||
1211 | 1212 | ||
1212 | if (netif_running(net_dev)) { | 1213 | if (netif_running(net_dev)) { |
1213 | clk_enable(lp->ether_clk); | 1214 | clk_enable(lp->ether_clk); |
@@ -1215,8 +1216,10 @@ static int at91ether_resume(struct platform_device *pdev) | |||
1215 | netif_device_attach(net_dev); | 1216 | netif_device_attach(net_dev); |
1216 | netif_start_queue(net_dev); | 1217 | netif_start_queue(net_dev); |
1217 | 1218 | ||
1218 | if (phy_irq) | 1219 | if (gpio_is_valid(lp->board_data.phy_irq_pin)) { |
1220 | int phy_irq = lp->board_data.phy_irq_pin; | ||
1219 | enable_irq(phy_irq); | 1221 | enable_irq(phy_irq); |
1222 | } | ||
1220 | } | 1223 | } |
1221 | return 0; | 1224 | return 0; |
1222 | } | 1225 | } |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index aa1d597091a8..f3d5c65d99cf 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Atmel MACB Ethernet Controller driver | 2 | * Cadence MACB/GEM Ethernet Controller driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2006 Atmel Corporation | 4 | * Copyright (C) 2004-2006 Atmel Corporation |
5 | * | 5 | * |
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/platform_data/macb.h> | 23 | #include <linux/platform_data/macb.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/phy.h> | 25 | #include <linux/phy.h> |
26 | #include <linux/of.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #include <linux/of_net.h> | ||
26 | 29 | ||
27 | #include "macb.h" | 30 | #include "macb.h" |
28 | 31 | ||
@@ -59,9 +62,9 @@ static void __macb_set_hwaddr(struct macb *bp) | |||
59 | u16 top; | 62 | u16 top; |
60 | 63 | ||
61 | bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr)); | 64 | bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr)); |
62 | macb_writel(bp, SA1B, bottom); | 65 | macb_or_gem_writel(bp, SA1B, bottom); |
63 | top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); | 66 | top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); |
64 | macb_writel(bp, SA1T, top); | 67 | macb_or_gem_writel(bp, SA1T, top); |
65 | } | 68 | } |
66 | 69 | ||
67 | static void __init macb_get_hwaddr(struct macb *bp) | 70 | static void __init macb_get_hwaddr(struct macb *bp) |
@@ -70,8 +73,8 @@ static void __init macb_get_hwaddr(struct macb *bp) | |||
70 | u16 top; | 73 | u16 top; |
71 | u8 addr[6]; | 74 | u8 addr[6]; |
72 | 75 | ||
73 | bottom = macb_readl(bp, SA1B); | 76 | bottom = macb_or_gem_readl(bp, SA1B); |
74 | top = macb_readl(bp, SA1T); | 77 | top = macb_or_gem_readl(bp, SA1T); |
75 | 78 | ||
76 | addr[0] = bottom & 0xff; | 79 | addr[0] = bottom & 0xff; |
77 | addr[1] = (bottom >> 8) & 0xff; | 80 | addr[1] = (bottom >> 8) & 0xff; |
@@ -191,7 +194,6 @@ static int macb_mii_probe(struct net_device *dev) | |||
191 | { | 194 | { |
192 | struct macb *bp = netdev_priv(dev); | 195 | struct macb *bp = netdev_priv(dev); |
193 | struct phy_device *phydev; | 196 | struct phy_device *phydev; |
194 | struct macb_platform_data *pdata; | ||
195 | int ret; | 197 | int ret; |
196 | 198 | ||
197 | phydev = phy_find_first(bp->mii_bus); | 199 | phydev = phy_find_first(bp->mii_bus); |
@@ -200,14 +202,11 @@ static int macb_mii_probe(struct net_device *dev) | |||
200 | return -1; | 202 | return -1; |
201 | } | 203 | } |
202 | 204 | ||
203 | pdata = bp->pdev->dev.platform_data; | ||
204 | /* TODO : add pin_irq */ | 205 | /* TODO : add pin_irq */ |
205 | 206 | ||
206 | /* attach the mac to the phy */ | 207 | /* attach the mac to the phy */ |
207 | ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0, | 208 | ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0, |
208 | pdata && pdata->is_rmii ? | 209 | bp->phy_interface); |
209 | PHY_INTERFACE_MODE_RMII : | ||
210 | PHY_INTERFACE_MODE_MII); | ||
211 | if (ret) { | 210 | if (ret) { |
212 | netdev_err(dev, "Could not attach to PHY\n"); | 211 | netdev_err(dev, "Could not attach to PHY\n"); |
213 | return ret; | 212 | return ret; |
@@ -285,8 +284,8 @@ err_out: | |||
285 | static void macb_update_stats(struct macb *bp) | 284 | static void macb_update_stats(struct macb *bp) |
286 | { | 285 | { |
287 | u32 __iomem *reg = bp->regs + MACB_PFR; | 286 | u32 __iomem *reg = bp->regs + MACB_PFR; |
288 | u32 *p = &bp->hw_stats.rx_pause_frames; | 287 | u32 *p = &bp->hw_stats.macb.rx_pause_frames; |
289 | u32 *end = &bp->hw_stats.tx_pause_frames + 1; | 288 | u32 *end = &bp->hw_stats.macb.tx_pause_frames + 1; |
290 | 289 | ||
291 | WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); | 290 | WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); |
292 | 291 | ||
@@ -580,7 +579,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
580 | 579 | ||
581 | if (status & MACB_BIT(ISR_ROVR)) { | 580 | if (status & MACB_BIT(ISR_ROVR)) { |
582 | /* We missed at least one packet */ | 581 | /* We missed at least one packet */ |
583 | bp->hw_stats.rx_overruns++; | 582 | if (macb_is_gem(bp)) |
583 | bp->hw_stats.gem.rx_overruns++; | ||
584 | else | ||
585 | bp->hw_stats.macb.rx_overruns++; | ||
584 | } | 586 | } |
585 | 587 | ||
586 | if (status & MACB_BIT(HRESP)) { | 588 | if (status & MACB_BIT(HRESP)) { |
@@ -790,6 +792,84 @@ static void macb_reset_hw(struct macb *bp) | |||
790 | macb_readl(bp, ISR); | 792 | macb_readl(bp, ISR); |
791 | } | 793 | } |
792 | 794 | ||
795 | static u32 gem_mdc_clk_div(struct macb *bp) | ||
796 | { | ||
797 | u32 config; | ||
798 | unsigned long pclk_hz = clk_get_rate(bp->pclk); | ||
799 | |||
800 | if (pclk_hz <= 20000000) | ||
801 | config = GEM_BF(CLK, GEM_CLK_DIV8); | ||
802 | else if (pclk_hz <= 40000000) | ||
803 | config = GEM_BF(CLK, GEM_CLK_DIV16); | ||
804 | else if (pclk_hz <= 80000000) | ||
805 | config = GEM_BF(CLK, GEM_CLK_DIV32); | ||
806 | else if (pclk_hz <= 120000000) | ||
807 | config = GEM_BF(CLK, GEM_CLK_DIV48); | ||
808 | else if (pclk_hz <= 160000000) | ||
809 | config = GEM_BF(CLK, GEM_CLK_DIV64); | ||
810 | else | ||
811 | config = GEM_BF(CLK, GEM_CLK_DIV96); | ||
812 | |||
813 | return config; | ||
814 | } | ||
815 | |||
816 | static u32 macb_mdc_clk_div(struct macb *bp) | ||
817 | { | ||
818 | u32 config; | ||
819 | unsigned long pclk_hz; | ||
820 | |||
821 | if (macb_is_gem(bp)) | ||
822 | return gem_mdc_clk_div(bp); | ||
823 | |||
824 | pclk_hz = clk_get_rate(bp->pclk); | ||
825 | if (pclk_hz <= 20000000) | ||
826 | config = MACB_BF(CLK, MACB_CLK_DIV8); | ||
827 | else if (pclk_hz <= 40000000) | ||
828 | config = MACB_BF(CLK, MACB_CLK_DIV16); | ||
829 | else if (pclk_hz <= 80000000) | ||
830 | config = MACB_BF(CLK, MACB_CLK_DIV32); | ||
831 | else | ||
832 | config = MACB_BF(CLK, MACB_CLK_DIV64); | ||
833 | |||
834 | return config; | ||
835 | } | ||
836 | |||
837 | /* | ||
838 | * Get the DMA bus width field of the network configuration register that we | ||
839 | * should program. We find the width from decoding the design configuration | ||
840 | * register to find the maximum supported data bus width. | ||
841 | */ | ||
842 | static u32 macb_dbw(struct macb *bp) | ||
843 | { | ||
844 | if (!macb_is_gem(bp)) | ||
845 | return 0; | ||
846 | |||
847 | switch (GEM_BFEXT(DBWDEF, gem_readl(bp, DCFG1))) { | ||
848 | case 4: | ||
849 | return GEM_BF(DBW, GEM_DBW128); | ||
850 | case 2: | ||
851 | return GEM_BF(DBW, GEM_DBW64); | ||
852 | case 1: | ||
853 | default: | ||
854 | return GEM_BF(DBW, GEM_DBW32); | ||
855 | } | ||
856 | } | ||
857 | |||
858 | /* | ||
859 | * Configure the receive DMA engine to use the correct receive buffer size. | ||
860 | * This is a configurable parameter for GEM. | ||
861 | */ | ||
862 | static void macb_configure_dma(struct macb *bp) | ||
863 | { | ||
864 | u32 dmacfg; | ||
865 | |||
866 | if (macb_is_gem(bp)) { | ||
867 | dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L); | ||
868 | dmacfg |= GEM_BF(RXBS, RX_BUFFER_SIZE / 64); | ||
869 | gem_writel(bp, DMACFG, dmacfg); | ||
870 | } | ||
871 | } | ||
872 | |||
793 | static void macb_init_hw(struct macb *bp) | 873 | static void macb_init_hw(struct macb *bp) |
794 | { | 874 | { |
795 | u32 config; | 875 | u32 config; |
@@ -797,7 +877,7 @@ static void macb_init_hw(struct macb *bp) | |||
797 | macb_reset_hw(bp); | 877 | macb_reset_hw(bp); |
798 | __macb_set_hwaddr(bp); | 878 | __macb_set_hwaddr(bp); |
799 | 879 | ||
800 | config = macb_readl(bp, NCFGR) & MACB_BF(CLK, -1L); | 880 | config = macb_mdc_clk_div(bp); |
801 | config |= MACB_BIT(PAE); /* PAuse Enable */ | 881 | config |= MACB_BIT(PAE); /* PAuse Enable */ |
802 | config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ | 882 | config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ |
803 | config |= MACB_BIT(BIG); /* Receive oversized frames */ | 883 | config |= MACB_BIT(BIG); /* Receive oversized frames */ |
@@ -805,8 +885,11 @@ static void macb_init_hw(struct macb *bp) | |||
805 | config |= MACB_BIT(CAF); /* Copy All Frames */ | 885 | config |= MACB_BIT(CAF); /* Copy All Frames */ |
806 | if (!(bp->dev->flags & IFF_BROADCAST)) | 886 | if (!(bp->dev->flags & IFF_BROADCAST)) |
807 | config |= MACB_BIT(NBC); /* No BroadCast */ | 887 | config |= MACB_BIT(NBC); /* No BroadCast */ |
888 | config |= macb_dbw(bp); | ||
808 | macb_writel(bp, NCFGR, config); | 889 | macb_writel(bp, NCFGR, config); |
809 | 890 | ||
891 | macb_configure_dma(bp); | ||
892 | |||
810 | /* Initialize TX and RX buffers */ | 893 | /* Initialize TX and RX buffers */ |
811 | macb_writel(bp, RBQP, bp->rx_ring_dma); | 894 | macb_writel(bp, RBQP, bp->rx_ring_dma); |
812 | macb_writel(bp, TBQP, bp->tx_ring_dma); | 895 | macb_writel(bp, TBQP, bp->tx_ring_dma); |
@@ -902,8 +985,8 @@ static void macb_sethashtable(struct net_device *dev) | |||
902 | mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); | 985 | mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); |
903 | } | 986 | } |
904 | 987 | ||
905 | macb_writel(bp, HRB, mc_filter[0]); | 988 | macb_or_gem_writel(bp, HRB, mc_filter[0]); |
906 | macb_writel(bp, HRT, mc_filter[1]); | 989 | macb_or_gem_writel(bp, HRT, mc_filter[1]); |
907 | } | 990 | } |
908 | 991 | ||
909 | /* | 992 | /* |
@@ -925,8 +1008,8 @@ static void macb_set_rx_mode(struct net_device *dev) | |||
925 | 1008 | ||
926 | if (dev->flags & IFF_ALLMULTI) { | 1009 | if (dev->flags & IFF_ALLMULTI) { |
927 | /* Enable all multicast mode */ | 1010 | /* Enable all multicast mode */ |
928 | macb_writel(bp, HRB, -1); | 1011 | macb_or_gem_writel(bp, HRB, -1); |
929 | macb_writel(bp, HRT, -1); | 1012 | macb_or_gem_writel(bp, HRT, -1); |
930 | cfg |= MACB_BIT(NCFGR_MTI); | 1013 | cfg |= MACB_BIT(NCFGR_MTI); |
931 | } else if (!netdev_mc_empty(dev)) { | 1014 | } else if (!netdev_mc_empty(dev)) { |
932 | /* Enable specific multicasts */ | 1015 | /* Enable specific multicasts */ |
@@ -934,8 +1017,8 @@ static void macb_set_rx_mode(struct net_device *dev) | |||
934 | cfg |= MACB_BIT(NCFGR_MTI); | 1017 | cfg |= MACB_BIT(NCFGR_MTI); |
935 | } else if (dev->flags & (~IFF_ALLMULTI)) { | 1018 | } else if (dev->flags & (~IFF_ALLMULTI)) { |
936 | /* Disable all multicast mode */ | 1019 | /* Disable all multicast mode */ |
937 | macb_writel(bp, HRB, 0); | 1020 | macb_or_gem_writel(bp, HRB, 0); |
938 | macb_writel(bp, HRT, 0); | 1021 | macb_or_gem_writel(bp, HRT, 0); |
939 | cfg &= ~MACB_BIT(NCFGR_MTI); | 1022 | cfg &= ~MACB_BIT(NCFGR_MTI); |
940 | } | 1023 | } |
941 | 1024 | ||
@@ -997,11 +1080,62 @@ static int macb_close(struct net_device *dev) | |||
997 | return 0; | 1080 | return 0; |
998 | } | 1081 | } |
999 | 1082 | ||
1083 | static void gem_update_stats(struct macb *bp) | ||
1084 | { | ||
1085 | u32 __iomem *reg = bp->regs + GEM_OTX; | ||
1086 | u32 *p = &bp->hw_stats.gem.tx_octets_31_0; | ||
1087 | u32 *end = &bp->hw_stats.gem.rx_udp_checksum_errors + 1; | ||
1088 | |||
1089 | for (; p < end; p++, reg++) | ||
1090 | *p += __raw_readl(reg); | ||
1091 | } | ||
1092 | |||
1093 | static struct net_device_stats *gem_get_stats(struct macb *bp) | ||
1094 | { | ||
1095 | struct gem_stats *hwstat = &bp->hw_stats.gem; | ||
1096 | struct net_device_stats *nstat = &bp->stats; | ||
1097 | |||
1098 | gem_update_stats(bp); | ||
1099 | |||
1100 | nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + | ||
1101 | hwstat->rx_alignment_errors + | ||
1102 | hwstat->rx_resource_errors + | ||
1103 | hwstat->rx_overruns + | ||
1104 | hwstat->rx_oversize_frames + | ||
1105 | hwstat->rx_jabbers + | ||
1106 | hwstat->rx_undersized_frames + | ||
1107 | hwstat->rx_length_field_frame_errors); | ||
1108 | nstat->tx_errors = (hwstat->tx_late_collisions + | ||
1109 | hwstat->tx_excessive_collisions + | ||
1110 | hwstat->tx_underrun + | ||
1111 | hwstat->tx_carrier_sense_errors); | ||
1112 | nstat->multicast = hwstat->rx_multicast_frames; | ||
1113 | nstat->collisions = (hwstat->tx_single_collision_frames + | ||
1114 | hwstat->tx_multiple_collision_frames + | ||
1115 | hwstat->tx_excessive_collisions); | ||
1116 | nstat->rx_length_errors = (hwstat->rx_oversize_frames + | ||
1117 | hwstat->rx_jabbers + | ||
1118 | hwstat->rx_undersized_frames + | ||
1119 | hwstat->rx_length_field_frame_errors); | ||
1120 | nstat->rx_over_errors = hwstat->rx_resource_errors; | ||
1121 | nstat->rx_crc_errors = hwstat->rx_frame_check_sequence_errors; | ||
1122 | nstat->rx_frame_errors = hwstat->rx_alignment_errors; | ||
1123 | nstat->rx_fifo_errors = hwstat->rx_overruns; | ||
1124 | nstat->tx_aborted_errors = hwstat->tx_excessive_collisions; | ||
1125 | nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors; | ||
1126 | nstat->tx_fifo_errors = hwstat->tx_underrun; | ||
1127 | |||
1128 | return nstat; | ||
1129 | } | ||
1130 | |||
1000 | static struct net_device_stats *macb_get_stats(struct net_device *dev) | 1131 | static struct net_device_stats *macb_get_stats(struct net_device *dev) |
1001 | { | 1132 | { |
1002 | struct macb *bp = netdev_priv(dev); | 1133 | struct macb *bp = netdev_priv(dev); |
1003 | struct net_device_stats *nstat = &bp->stats; | 1134 | struct net_device_stats *nstat = &bp->stats; |
1004 | struct macb_stats *hwstat = &bp->hw_stats; | 1135 | struct macb_stats *hwstat = &bp->hw_stats.macb; |
1136 | |||
1137 | if (macb_is_gem(bp)) | ||
1138 | return gem_get_stats(bp); | ||
1005 | 1139 | ||
1006 | /* read stats from hardware */ | 1140 | /* read stats from hardware */ |
1007 | macb_update_stats(bp); | 1141 | macb_update_stats(bp); |
@@ -1109,6 +1243,52 @@ static const struct net_device_ops macb_netdev_ops = { | |||
1109 | #endif | 1243 | #endif |
1110 | }; | 1244 | }; |
1111 | 1245 | ||
1246 | #if defined(CONFIG_OF) | ||
1247 | static const struct of_device_id macb_dt_ids[] = { | ||
1248 | { .compatible = "cdns,at32ap7000-macb" }, | ||
1249 | { .compatible = "cdns,at91sam9260-macb" }, | ||
1250 | { .compatible = "cdns,macb" }, | ||
1251 | { .compatible = "cdns,pc302-gem" }, | ||
1252 | { .compatible = "cdns,gem" }, | ||
1253 | { /* sentinel */ } | ||
1254 | }; | ||
1255 | |||
1256 | MODULE_DEVICE_TABLE(of, macb_dt_ids); | ||
1257 | |||
1258 | static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev) | ||
1259 | { | ||
1260 | struct device_node *np = pdev->dev.of_node; | ||
1261 | |||
1262 | if (np) | ||
1263 | return of_get_phy_mode(np); | ||
1264 | |||
1265 | return -ENODEV; | ||
1266 | } | ||
1267 | |||
1268 | static int __devinit macb_get_hwaddr_dt(struct macb *bp) | ||
1269 | { | ||
1270 | struct device_node *np = bp->pdev->dev.of_node; | ||
1271 | if (np) { | ||
1272 | const char *mac = of_get_mac_address(np); | ||
1273 | if (mac) { | ||
1274 | memcpy(bp->dev->dev_addr, mac, ETH_ALEN); | ||
1275 | return 0; | ||
1276 | } | ||
1277 | } | ||
1278 | |||
1279 | return -ENODEV; | ||
1280 | } | ||
1281 | #else | ||
1282 | static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev) | ||
1283 | { | ||
1284 | return -ENODEV; | ||
1285 | } | ||
1286 | static int __devinit macb_get_hwaddr_dt(struct macb *bp) | ||
1287 | { | ||
1288 | return -ENODEV; | ||
1289 | } | ||
1290 | #endif | ||
1291 | |||
1112 | static int __init macb_probe(struct platform_device *pdev) | 1292 | static int __init macb_probe(struct platform_device *pdev) |
1113 | { | 1293 | { |
1114 | struct macb_platform_data *pdata; | 1294 | struct macb_platform_data *pdata; |
@@ -1116,7 +1296,6 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1116 | struct net_device *dev; | 1296 | struct net_device *dev; |
1117 | struct macb *bp; | 1297 | struct macb *bp; |
1118 | struct phy_device *phydev; | 1298 | struct phy_device *phydev; |
1119 | unsigned long pclk_hz; | ||
1120 | u32 config; | 1299 | u32 config; |
1121 | int err = -ENXIO; | 1300 | int err = -ENXIO; |
1122 | 1301 | ||
@@ -1180,31 +1359,37 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1180 | dev->base_addr = regs->start; | 1359 | dev->base_addr = regs->start; |
1181 | 1360 | ||
1182 | /* Set MII management clock divider */ | 1361 | /* Set MII management clock divider */ |
1183 | pclk_hz = clk_get_rate(bp->pclk); | 1362 | config = macb_mdc_clk_div(bp); |
1184 | if (pclk_hz <= 20000000) | 1363 | config |= macb_dbw(bp); |
1185 | config = MACB_BF(CLK, MACB_CLK_DIV8); | ||
1186 | else if (pclk_hz <= 40000000) | ||
1187 | config = MACB_BF(CLK, MACB_CLK_DIV16); | ||
1188 | else if (pclk_hz <= 80000000) | ||
1189 | config = MACB_BF(CLK, MACB_CLK_DIV32); | ||
1190 | else | ||
1191 | config = MACB_BF(CLK, MACB_CLK_DIV64); | ||
1192 | macb_writel(bp, NCFGR, config); | 1364 | macb_writel(bp, NCFGR, config); |
1193 | 1365 | ||
1194 | macb_get_hwaddr(bp); | 1366 | err = macb_get_hwaddr_dt(bp); |
1195 | pdata = pdev->dev.platform_data; | 1367 | if (err < 0) |
1368 | macb_get_hwaddr(bp); | ||
1369 | |||
1370 | err = macb_get_phy_mode_dt(pdev); | ||
1371 | if (err < 0) { | ||
1372 | pdata = pdev->dev.platform_data; | ||
1373 | if (pdata && pdata->is_rmii) | ||
1374 | bp->phy_interface = PHY_INTERFACE_MODE_RMII; | ||
1375 | else | ||
1376 | bp->phy_interface = PHY_INTERFACE_MODE_MII; | ||
1377 | } else { | ||
1378 | bp->phy_interface = err; | ||
1379 | } | ||
1196 | 1380 | ||
1197 | if (pdata && pdata->is_rmii) | 1381 | if (bp->phy_interface == PHY_INTERFACE_MODE_RMII) |
1198 | #if defined(CONFIG_ARCH_AT91) | 1382 | #if defined(CONFIG_ARCH_AT91) |
1199 | macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) ); | 1383 | macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) | |
1384 | MACB_BIT(CLKEN))); | ||
1200 | #else | 1385 | #else |
1201 | macb_writel(bp, USRIO, 0); | 1386 | macb_or_gem_writel(bp, USRIO, 0); |
1202 | #endif | 1387 | #endif |
1203 | else | 1388 | else |
1204 | #if defined(CONFIG_ARCH_AT91) | 1389 | #if defined(CONFIG_ARCH_AT91) |
1205 | macb_writel(bp, USRIO, MACB_BIT(CLKEN)); | 1390 | macb_or_gem_writel(bp, USRIO, MACB_BIT(CLKEN)); |
1206 | #else | 1391 | #else |
1207 | macb_writel(bp, USRIO, MACB_BIT(MII)); | 1392 | macb_or_gem_writel(bp, USRIO, MACB_BIT(MII)); |
1208 | #endif | 1393 | #endif |
1209 | 1394 | ||
1210 | bp->tx_pending = DEF_TX_RING_PENDING; | 1395 | bp->tx_pending = DEF_TX_RING_PENDING; |
@@ -1221,8 +1406,9 @@ static int __init macb_probe(struct platform_device *pdev) | |||
1221 | 1406 | ||
1222 | platform_set_drvdata(pdev, dev); | 1407 | platform_set_drvdata(pdev, dev); |
1223 | 1408 | ||
1224 | netdev_info(dev, "Atmel MACB at 0x%08lx irq %d (%pM)\n", | 1409 | netdev_info(dev, "Cadence %s at 0x%08lx irq %d (%pM)\n", |
1225 | dev->base_addr, dev->irq, dev->dev_addr); | 1410 | macb_is_gem(bp) ? "GEM" : "MACB", dev->base_addr, |
1411 | dev->irq, dev->dev_addr); | ||
1226 | 1412 | ||
1227 | phydev = bp->phy_dev; | 1413 | phydev = bp->phy_dev; |
1228 | netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", | 1414 | netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", |
@@ -1315,6 +1501,7 @@ static struct platform_driver macb_driver = { | |||
1315 | .driver = { | 1501 | .driver = { |
1316 | .name = "macb", | 1502 | .name = "macb", |
1317 | .owner = THIS_MODULE, | 1503 | .owner = THIS_MODULE, |
1504 | .of_match_table = of_match_ptr(macb_dt_ids), | ||
1318 | }, | 1505 | }, |
1319 | }; | 1506 | }; |
1320 | 1507 | ||
@@ -1332,6 +1519,6 @@ module_init(macb_init); | |||
1332 | module_exit(macb_exit); | 1519 | module_exit(macb_exit); |
1333 | 1520 | ||
1334 | MODULE_LICENSE("GPL"); | 1521 | MODULE_LICENSE("GPL"); |
1335 | MODULE_DESCRIPTION("Atmel MACB Ethernet driver"); | 1522 | MODULE_DESCRIPTION("Cadence MACB/GEM Ethernet driver"); |
1336 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); | 1523 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
1337 | MODULE_ALIAS("platform:macb"); | 1524 | MODULE_ALIAS("platform:macb"); |
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index d3212f6db703..335e288f5314 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h | |||
@@ -59,6 +59,24 @@ | |||
59 | #define MACB_TPQ 0x00bc | 59 | #define MACB_TPQ 0x00bc |
60 | #define MACB_USRIO 0x00c0 | 60 | #define MACB_USRIO 0x00c0 |
61 | #define MACB_WOL 0x00c4 | 61 | #define MACB_WOL 0x00c4 |
62 | #define MACB_MID 0x00fc | ||
63 | |||
64 | /* GEM register offsets. */ | ||
65 | #define GEM_NCFGR 0x0004 | ||
66 | #define GEM_USRIO 0x000c | ||
67 | #define GEM_DMACFG 0x0010 | ||
68 | #define GEM_HRB 0x0080 | ||
69 | #define GEM_HRT 0x0084 | ||
70 | #define GEM_SA1B 0x0088 | ||
71 | #define GEM_SA1T 0x008C | ||
72 | #define GEM_OTX 0x0100 | ||
73 | #define GEM_DCFG1 0x0280 | ||
74 | #define GEM_DCFG2 0x0284 | ||
75 | #define GEM_DCFG3 0x0288 | ||
76 | #define GEM_DCFG4 0x028c | ||
77 | #define GEM_DCFG5 0x0290 | ||
78 | #define GEM_DCFG6 0x0294 | ||
79 | #define GEM_DCFG7 0x0298 | ||
62 | 80 | ||
63 | /* Bitfields in NCR */ | 81 | /* Bitfields in NCR */ |
64 | #define MACB_LB_OFFSET 0 | 82 | #define MACB_LB_OFFSET 0 |
@@ -126,6 +144,21 @@ | |||
126 | #define MACB_IRXFCS_OFFSET 19 | 144 | #define MACB_IRXFCS_OFFSET 19 |
127 | #define MACB_IRXFCS_SIZE 1 | 145 | #define MACB_IRXFCS_SIZE 1 |
128 | 146 | ||
147 | /* GEM specific NCFGR bitfields. */ | ||
148 | #define GEM_CLK_OFFSET 18 | ||
149 | #define GEM_CLK_SIZE 3 | ||
150 | #define GEM_DBW_OFFSET 21 | ||
151 | #define GEM_DBW_SIZE 2 | ||
152 | |||
153 | /* Constants for data bus width. */ | ||
154 | #define GEM_DBW32 0 | ||
155 | #define GEM_DBW64 1 | ||
156 | #define GEM_DBW128 2 | ||
157 | |||
158 | /* Bitfields in DMACFG. */ | ||
159 | #define GEM_RXBS_OFFSET 16 | ||
160 | #define GEM_RXBS_SIZE 8 | ||
161 | |||
129 | /* Bitfields in NSR */ | 162 | /* Bitfields in NSR */ |
130 | #define MACB_NSR_LINK_OFFSET 0 | 163 | #define MACB_NSR_LINK_OFFSET 0 |
131 | #define MACB_NSR_LINK_SIZE 1 | 164 | #define MACB_NSR_LINK_SIZE 1 |
@@ -228,12 +261,30 @@ | |||
228 | #define MACB_WOL_MTI_OFFSET 19 | 261 | #define MACB_WOL_MTI_OFFSET 19 |
229 | #define MACB_WOL_MTI_SIZE 1 | 262 | #define MACB_WOL_MTI_SIZE 1 |
230 | 263 | ||
264 | /* Bitfields in MID */ | ||
265 | #define MACB_IDNUM_OFFSET 16 | ||
266 | #define MACB_IDNUM_SIZE 16 | ||
267 | #define MACB_REV_OFFSET 0 | ||
268 | #define MACB_REV_SIZE 16 | ||
269 | |||
270 | /* Bitfields in DCFG1. */ | ||
271 | #define GEM_DBWDEF_OFFSET 25 | ||
272 | #define GEM_DBWDEF_SIZE 3 | ||
273 | |||
231 | /* Constants for CLK */ | 274 | /* Constants for CLK */ |
232 | #define MACB_CLK_DIV8 0 | 275 | #define MACB_CLK_DIV8 0 |
233 | #define MACB_CLK_DIV16 1 | 276 | #define MACB_CLK_DIV16 1 |
234 | #define MACB_CLK_DIV32 2 | 277 | #define MACB_CLK_DIV32 2 |
235 | #define MACB_CLK_DIV64 3 | 278 | #define MACB_CLK_DIV64 3 |
236 | 279 | ||
280 | /* GEM specific constants for CLK. */ | ||
281 | #define GEM_CLK_DIV8 0 | ||
282 | #define GEM_CLK_DIV16 1 | ||
283 | #define GEM_CLK_DIV32 2 | ||
284 | #define GEM_CLK_DIV48 3 | ||
285 | #define GEM_CLK_DIV64 4 | ||
286 | #define GEM_CLK_DIV96 5 | ||
287 | |||
237 | /* Constants for MAN register */ | 288 | /* Constants for MAN register */ |
238 | #define MACB_MAN_SOF 1 | 289 | #define MACB_MAN_SOF 1 |
239 | #define MACB_MAN_WRITE 1 | 290 | #define MACB_MAN_WRITE 1 |
@@ -254,11 +305,52 @@ | |||
254 | << MACB_##name##_OFFSET)) \ | 305 | << MACB_##name##_OFFSET)) \ |
255 | | MACB_BF(name,value)) | 306 | | MACB_BF(name,value)) |
256 | 307 | ||
308 | #define GEM_BIT(name) \ | ||
309 | (1 << GEM_##name##_OFFSET) | ||
310 | #define GEM_BF(name, value) \ | ||
311 | (((value) & ((1 << GEM_##name##_SIZE) - 1)) \ | ||
312 | << GEM_##name##_OFFSET) | ||
313 | #define GEM_BFEXT(name, value)\ | ||
314 | (((value) >> GEM_##name##_OFFSET) \ | ||
315 | & ((1 << GEM_##name##_SIZE) - 1)) | ||
316 | #define GEM_BFINS(name, value, old) \ | ||
317 | (((old) & ~(((1 << GEM_##name##_SIZE) - 1) \ | ||
318 | << GEM_##name##_OFFSET)) \ | ||
319 | | GEM_BF(name, value)) | ||
320 | |||
257 | /* Register access macros */ | 321 | /* Register access macros */ |
258 | #define macb_readl(port,reg) \ | 322 | #define macb_readl(port,reg) \ |
259 | __raw_readl((port)->regs + MACB_##reg) | 323 | __raw_readl((port)->regs + MACB_##reg) |
260 | #define macb_writel(port,reg,value) \ | 324 | #define macb_writel(port,reg,value) \ |
261 | __raw_writel((value), (port)->regs + MACB_##reg) | 325 | __raw_writel((value), (port)->regs + MACB_##reg) |
326 | #define gem_readl(port, reg) \ | ||
327 | __raw_readl((port)->regs + GEM_##reg) | ||
328 | #define gem_writel(port, reg, value) \ | ||
329 | __raw_writel((value), (port)->regs + GEM_##reg) | ||
330 | |||
331 | /* | ||
332 | * Conditional GEM/MACB macros. These perform the operation to the correct | ||
333 | * register dependent on whether the device is a GEM or a MACB. For registers | ||
334 | * and bitfields that are common across both devices, use macb_{read,write}l | ||
335 | * to avoid the cost of the conditional. | ||
336 | */ | ||
337 | #define macb_or_gem_writel(__bp, __reg, __value) \ | ||
338 | ({ \ | ||
339 | if (macb_is_gem((__bp))) \ | ||
340 | gem_writel((__bp), __reg, __value); \ | ||
341 | else \ | ||
342 | macb_writel((__bp), __reg, __value); \ | ||
343 | }) | ||
344 | |||
345 | #define macb_or_gem_readl(__bp, __reg) \ | ||
346 | ({ \ | ||
347 | u32 __v; \ | ||
348 | if (macb_is_gem((__bp))) \ | ||
349 | __v = gem_readl((__bp), __reg); \ | ||
350 | else \ | ||
351 | __v = macb_readl((__bp), __reg); \ | ||
352 | __v; \ | ||
353 | }) | ||
262 | 354 | ||
263 | struct dma_desc { | 355 | struct dma_desc { |
264 | u32 addr; | 356 | u32 addr; |
@@ -358,6 +450,54 @@ struct macb_stats { | |||
358 | u32 tx_pause_frames; | 450 | u32 tx_pause_frames; |
359 | }; | 451 | }; |
360 | 452 | ||
453 | struct gem_stats { | ||
454 | u32 tx_octets_31_0; | ||
455 | u32 tx_octets_47_32; | ||
456 | u32 tx_frames; | ||
457 | u32 tx_broadcast_frames; | ||
458 | u32 tx_multicast_frames; | ||
459 | u32 tx_pause_frames; | ||
460 | u32 tx_64_byte_frames; | ||
461 | u32 tx_65_127_byte_frames; | ||
462 | u32 tx_128_255_byte_frames; | ||
463 | u32 tx_256_511_byte_frames; | ||
464 | u32 tx_512_1023_byte_frames; | ||
465 | u32 tx_1024_1518_byte_frames; | ||
466 | u32 tx_greater_than_1518_byte_frames; | ||
467 | u32 tx_underrun; | ||
468 | u32 tx_single_collision_frames; | ||
469 | u32 tx_multiple_collision_frames; | ||
470 | u32 tx_excessive_collisions; | ||
471 | u32 tx_late_collisions; | ||
472 | u32 tx_deferred_frames; | ||
473 | u32 tx_carrier_sense_errors; | ||
474 | u32 rx_octets_31_0; | ||
475 | u32 rx_octets_47_32; | ||
476 | u32 rx_frames; | ||
477 | u32 rx_broadcast_frames; | ||
478 | u32 rx_multicast_frames; | ||
479 | u32 rx_pause_frames; | ||
480 | u32 rx_64_byte_frames; | ||
481 | u32 rx_65_127_byte_frames; | ||
482 | u32 rx_128_255_byte_frames; | ||
483 | u32 rx_256_511_byte_frames; | ||
484 | u32 rx_512_1023_byte_frames; | ||
485 | u32 rx_1024_1518_byte_frames; | ||
486 | u32 rx_greater_than_1518_byte_frames; | ||
487 | u32 rx_undersized_frames; | ||
488 | u32 rx_oversize_frames; | ||
489 | u32 rx_jabbers; | ||
490 | u32 rx_frame_check_sequence_errors; | ||
491 | u32 rx_length_field_frame_errors; | ||
492 | u32 rx_symbol_errors; | ||
493 | u32 rx_alignment_errors; | ||
494 | u32 rx_resource_errors; | ||
495 | u32 rx_overruns; | ||
496 | u32 rx_ip_header_checksum_errors; | ||
497 | u32 rx_tcp_checksum_errors; | ||
498 | u32 rx_udp_checksum_errors; | ||
499 | }; | ||
500 | |||
361 | struct macb { | 501 | struct macb { |
362 | void __iomem *regs; | 502 | void __iomem *regs; |
363 | 503 | ||
@@ -376,7 +516,10 @@ struct macb { | |||
376 | struct net_device *dev; | 516 | struct net_device *dev; |
377 | struct napi_struct napi; | 517 | struct napi_struct napi; |
378 | struct net_device_stats stats; | 518 | struct net_device_stats stats; |
379 | struct macb_stats hw_stats; | 519 | union { |
520 | struct macb_stats macb; | ||
521 | struct gem_stats gem; | ||
522 | } hw_stats; | ||
380 | 523 | ||
381 | dma_addr_t rx_ring_dma; | 524 | dma_addr_t rx_ring_dma; |
382 | dma_addr_t tx_ring_dma; | 525 | dma_addr_t tx_ring_dma; |
@@ -389,6 +532,13 @@ struct macb { | |||
389 | unsigned int link; | 532 | unsigned int link; |
390 | unsigned int speed; | 533 | unsigned int speed; |
391 | unsigned int duplex; | 534 | unsigned int duplex; |
535 | |||
536 | phy_interface_t phy_interface; | ||
392 | }; | 537 | }; |
393 | 538 | ||
539 | static inline bool macb_is_gem(struct macb *bp) | ||
540 | { | ||
541 | return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2; | ||
542 | } | ||
543 | |||
394 | #endif /* _MACB_H */ | 544 | #endif /* _MACB_H */ |
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c index 0b4f946cf13a..31ab6ddf52c9 100644 --- a/drivers/pcmcia/pxa2xx_cm_x255.c +++ b/drivers/pcmcia/pxa2xx_cm_x255.c | |||
@@ -16,8 +16,6 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | 18 | ||
19 | #include <asm/mach-types.h> | ||
20 | |||
21 | #include "soc_common.h" | 19 | #include "soc_common.h" |
22 | 20 | ||
23 | #define GPIO_PCMCIA_SKTSEL (54) | 21 | #define GPIO_PCMCIA_SKTSEL (54) |
@@ -27,15 +25,15 @@ | |||
27 | #define GPIO_PCMCIA_S1_RDYINT (8) | 25 | #define GPIO_PCMCIA_S1_RDYINT (8) |
28 | #define GPIO_PCMCIA_RESET (9) | 26 | #define GPIO_PCMCIA_RESET (9) |
29 | 27 | ||
30 | #define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID) | 28 | #define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID) |
31 | #define PCMCIA_S1_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S1_CD_VALID) | 29 | #define PCMCIA_S1_CD_VALID gpio_to_irq(GPIO_PCMCIA_S1_CD_VALID) |
32 | #define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT) | 30 | #define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT) |
33 | #define PCMCIA_S1_RDYINT IRQ_GPIO(GPIO_PCMCIA_S1_RDYINT) | 31 | #define PCMCIA_S1_RDYINT gpio_to_irq(GPIO_PCMCIA_S1_RDYINT) |
34 | 32 | ||
35 | 33 | ||
36 | static struct pcmcia_irqs irqs[] = { | 34 | static struct pcmcia_irqs irqs[] = { |
37 | { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" }, | 35 | { .sock = 0, .str = "PCMCIA0 CD" }, |
38 | { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" }, | 36 | { .sock = 1, .str = "PCMCIA1 CD" }, |
39 | }; | 37 | }; |
40 | 38 | ||
41 | static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 39 | static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -46,6 +44,8 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
46 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); | 44 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); |
47 | 45 | ||
48 | skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; | 46 | skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; |
47 | irqs[0].irq = PCMCIA_S0_CD_VALID; | ||
48 | irqs[1].irq = PCMCIA_S1_CD_VALID; | ||
49 | ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 49 | ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
50 | if (!ret) | 50 | if (!ret) |
51 | gpio_free(GPIO_PCMCIA_RESET); | 51 | gpio_free(GPIO_PCMCIA_RESET); |
diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index 923f315926ef..3dc7621a0767 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c | |||
@@ -16,20 +16,18 @@ | |||
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | 18 | ||
19 | #include <asm/mach-types.h> | ||
20 | |||
21 | #include "soc_common.h" | 19 | #include "soc_common.h" |
22 | 20 | ||
23 | #define GPIO_PCMCIA_S0_CD_VALID (84) | 21 | #define GPIO_PCMCIA_S0_CD_VALID (84) |
24 | #define GPIO_PCMCIA_S0_RDYINT (82) | 22 | #define GPIO_PCMCIA_S0_RDYINT (82) |
25 | #define GPIO_PCMCIA_RESET (53) | 23 | #define GPIO_PCMCIA_RESET (53) |
26 | 24 | ||
27 | #define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID) | 25 | #define PCMCIA_S0_CD_VALID gpio_to_irq(GPIO_PCMCIA_S0_CD_VALID) |
28 | #define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT) | 26 | #define PCMCIA_S0_RDYINT gpio_to_irq(GPIO_PCMCIA_S0_RDYINT) |
29 | 27 | ||
30 | 28 | ||
31 | static struct pcmcia_irqs irqs[] = { | 29 | static struct pcmcia_irqs irqs[] = { |
32 | { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" }, | 30 | { .sock = 0, .str = "PCMCIA0 CD" }, |
33 | }; | 31 | }; |
34 | 32 | ||
35 | static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 33 | static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
@@ -40,6 +38,7 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
40 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); | 38 | gpio_direction_output(GPIO_PCMCIA_RESET, 0); |
41 | 39 | ||
42 | skt->socket.pci_irq = PCMCIA_S0_RDYINT; | 40 | skt->socket.pci_irq = PCMCIA_S0_RDYINT; |
41 | irqs[0].irq = PCMCIA_S0_CD_VALID; | ||
43 | ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 42 | ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
44 | if (!ret) | 43 | if (!ret) |
45 | gpio_free(GPIO_PCMCIA_RESET); | 44 | gpio_free(GPIO_PCMCIA_RESET); |
diff --git a/drivers/pcmcia/pxa2xx_e740.c b/drivers/pcmcia/pxa2xx_e740.c index 8bfbd4dca131..17cd2ce7428f 100644 --- a/drivers/pcmcia/pxa2xx_e740.c +++ b/drivers/pcmcia/pxa2xx_e740.c | |||
@@ -26,20 +26,23 @@ | |||
26 | static struct pcmcia_irqs cd_irqs[] = { | 26 | static struct pcmcia_irqs cd_irqs[] = { |
27 | { | 27 | { |
28 | .sock = 0, | 28 | .sock = 0, |
29 | .irq = IRQ_GPIO(GPIO_E740_PCMCIA_CD0), | ||
30 | .str = "CF card detect" | 29 | .str = "CF card detect" |
31 | }, | 30 | }, |
32 | { | 31 | { |
33 | .sock = 1, | 32 | .sock = 1, |
34 | .irq = IRQ_GPIO(GPIO_E740_PCMCIA_CD1), | ||
35 | .str = "Wifi switch" | 33 | .str = "Wifi switch" |
36 | }, | 34 | }, |
37 | }; | 35 | }; |
38 | 36 | ||
39 | static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 37 | static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
40 | { | 38 | { |
41 | skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) : | 39 | if (skt->nr == 0) |
42 | IRQ_GPIO(GPIO_E740_PCMCIA_RDY1); | 40 | skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY0); |
41 | else | ||
42 | skt->socket.pci_irq = gpio_to_irq(GPIO_E740_PCMCIA_RDY1); | ||
43 | |||
44 | cd_irqs[0].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD0); | ||
45 | cd_irqs[1].irq = gpio_to_irq(GPIO_E740_PCMCIA_CD1); | ||
43 | 46 | ||
44 | return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); | 47 | return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1); |
45 | } | 48 | } |
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index d589ad1dcd4c..6a8e011a8c13 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c | |||
@@ -33,7 +33,7 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
33 | ret = gpio_request_array(palmld_pcmcia_gpios, | 33 | ret = gpio_request_array(palmld_pcmcia_gpios, |
34 | ARRAY_SIZE(palmld_pcmcia_gpios)); | 34 | ARRAY_SIZE(palmld_pcmcia_gpios)); |
35 | 35 | ||
36 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); | 36 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMLD_PCMCIA_READY); |
37 | 37 | ||
38 | return ret; | 38 | return ret; |
39 | } | 39 | } |
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 9c6a04b2f71b..9e38de769ba3 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c | |||
@@ -37,7 +37,7 @@ static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
37 | ret = gpio_request_array(palmtc_pcmcia_gpios, | 37 | ret = gpio_request_array(palmtc_pcmcia_gpios, |
38 | ARRAY_SIZE(palmtc_pcmcia_gpios)); | 38 | ARRAY_SIZE(palmtc_pcmcia_gpios)); |
39 | 39 | ||
40 | skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); | 40 | skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTC_PCMCIA_READY); |
41 | 41 | ||
42 | return ret; | 42 | return ret; |
43 | } | 43 | } |
diff --git a/drivers/pcmcia/pxa2xx_stargate2.c b/drivers/pcmcia/pxa2xx_stargate2.c index 939622251dfb..6c2366b74a35 100644 --- a/drivers/pcmcia/pxa2xx_stargate2.c +++ b/drivers/pcmcia/pxa2xx_stargate2.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #define SG2_S0_GPIO_READY 81 | 34 | #define SG2_S0_GPIO_READY 81 |
35 | 35 | ||
36 | static struct pcmcia_irqs irqs[] = { | 36 | static struct pcmcia_irqs irqs[] = { |
37 | { 0, IRQ_GPIO(SG2_S0_GPIO_DETECT), "PCMCIA0 CD" }, | 37 | {.sock = 0, .str = "PCMCIA0 CD" }, |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct gpio sg2_pcmcia_gpios[] = { | 40 | static struct gpio sg2_pcmcia_gpios[] = { |
@@ -44,7 +44,9 @@ static struct gpio sg2_pcmcia_gpios[] = { | |||
44 | 44 | ||
45 | static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | 45 | static int sg2_pcmcia_hw_init(struct soc_pcmcia_socket *skt) |
46 | { | 46 | { |
47 | skt->socket.pci_irq = IRQ_GPIO(SG2_S0_GPIO_READY); | 47 | skt->socket.pci_irq = gpio_to_irq(SG2_S0_GPIO_READY); |
48 | irqs[0].irq = gpio_to_irq(SG2_S0_GPIO_DETECT); | ||
49 | |||
48 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); | 50 | return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); |
49 | } | 51 | } |
50 | 52 | ||
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index 57ddb969d888..7c33f898135a 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c | |||
@@ -30,7 +30,7 @@ | |||
30 | extern void board_pcmcia_power(int power); | 30 | extern void board_pcmcia_power(int power); |
31 | 31 | ||
32 | static struct pcmcia_irqs irqs[] = { | 32 | static struct pcmcia_irqs irqs[] = { |
33 | { 0, IRQ_GPIO(GPIO_PCD), "cs0_cd" } | 33 | { .sock = 0, .str = "cs0_cd" } |
34 | /* on other baseboards we can have more inputs */ | 34 | /* on other baseboards we can have more inputs */ |
35 | }; | 35 | }; |
36 | 36 | ||
@@ -53,7 +53,8 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
53 | gpio_free(GPIO_PRDY); | 53 | gpio_free(GPIO_PRDY); |
54 | return -EINVAL; | 54 | return -EINVAL; |
55 | } | 55 | } |
56 | skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY); | 56 | skt->socket.pci_irq = gpio_to_irq(GPIO_PRDY); |
57 | irqs[0].irq = gpio_to_irq(GPIO_PCD); | ||
57 | break; | 58 | break; |
58 | default: | 59 | default: |
59 | break; | 60 | break; |
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 66ab92cf3105..61b17d235dbe 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c | |||
@@ -38,12 +38,10 @@ static struct gpio vpac270_cf_gpios[] = { | |||
38 | static struct pcmcia_irqs cd_irqs[] = { | 38 | static struct pcmcia_irqs cd_irqs[] = { |
39 | { | 39 | { |
40 | .sock = 0, | 40 | .sock = 0, |
41 | .irq = IRQ_GPIO(GPIO84_VPAC270_PCMCIA_CD), | ||
42 | .str = "PCMCIA CD" | 41 | .str = "PCMCIA CD" |
43 | }, | 42 | }, |
44 | { | 43 | { |
45 | .sock = 1, | 44 | .sock = 1, |
46 | .irq = IRQ_GPIO(GPIO17_VPAC270_CF_CD), | ||
47 | .str = "CF CD" | 45 | .str = "CF CD" |
48 | }, | 46 | }, |
49 | }; | 47 | }; |
@@ -57,6 +55,7 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
57 | ARRAY_SIZE(vpac270_pcmcia_gpios)); | 55 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
58 | 56 | ||
59 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); | 57 | skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); |
58 | cd_irqs[0].irq = gpio_to_irq(GPIO84_VPAC270_PCMCIA_CD); | ||
60 | 59 | ||
61 | if (!ret) | 60 | if (!ret) |
62 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); | 61 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); |
@@ -65,6 +64,7 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
65 | ARRAY_SIZE(vpac270_cf_gpios)); | 64 | ARRAY_SIZE(vpac270_cf_gpios)); |
66 | 65 | ||
67 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); | 66 | skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); |
67 | cd_irqs[1].irq = gpio_to_irq(GPIO17_VPAC270_CF_CD); | ||
68 | 68 | ||
69 | if (!ret) | 69 | if (!ret) |
70 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); | 70 | ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 53eb4e55b289..877cf6fdcf24 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -774,7 +774,7 @@ config RTC_DRV_EP93XX | |||
774 | 774 | ||
775 | config RTC_DRV_SA1100 | 775 | config RTC_DRV_SA1100 |
776 | tristate "SA11x0/PXA2xx" | 776 | tristate "SA11x0/PXA2xx" |
777 | depends on ARCH_SA1100 || ARCH_PXA | 777 | depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP |
778 | help | 778 | help |
779 | If you say Y here you will get access to the real time clock | 779 | If you say Y here you will get access to the real time clock |
780 | built into your SA11x0 or PXA2xx CPU. | 780 | built into your SA11x0 or PXA2xx CPU. |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 0b40bb88a884..fc1ffe97fca1 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -27,35 +27,42 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/string.h> | ||
31 | #include <linux/pm.h> | 30 | #include <linux/pm.h> |
32 | #include <linux/bitops.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/clk.h> | ||
33 | #include <linux/io.h> | ||
33 | 34 | ||
34 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
35 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
36 | 37 | ||
37 | #ifdef CONFIG_ARCH_PXA | ||
38 | #include <mach/regs-rtc.h> | ||
39 | #include <mach/regs-ost.h> | ||
40 | #endif | ||
41 | |||
42 | #define RTC_DEF_DIVIDER (32768 - 1) | 38 | #define RTC_DEF_DIVIDER (32768 - 1) |
43 | #define RTC_DEF_TRIM 0 | 39 | #define RTC_DEF_TRIM 0 |
44 | 40 | #define RTC_FREQ 1024 | |
45 | static const unsigned long RTC_FREQ = 1024; | 41 | |
46 | static struct rtc_time rtc_alarm; | 42 | #define RCNR 0x00 /* RTC Count Register */ |
47 | static DEFINE_SPINLOCK(sa1100_rtc_lock); | 43 | #define RTAR 0x04 /* RTC Alarm Register */ |
48 | 44 | #define RTSR 0x08 /* RTC Status Register */ | |
49 | static inline int rtc_periodic_alarm(struct rtc_time *tm) | 45 | #define RTTR 0x0c /* RTC Timer Trim Register */ |
50 | { | 46 | |
51 | return (tm->tm_year == -1) || | 47 | #define RTSR_HZE (1 << 3) /* HZ interrupt enable */ |
52 | ((unsigned)tm->tm_mon >= 12) || | 48 | #define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ |
53 | ((unsigned)(tm->tm_mday - 1) >= 31) || | 49 | #define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ |
54 | ((unsigned)tm->tm_hour > 23) || | 50 | #define RTSR_AL (1 << 0) /* RTC alarm detected */ |
55 | ((unsigned)tm->tm_min > 59) || | 51 | |
56 | ((unsigned)tm->tm_sec > 59); | 52 | #define rtc_readl(sa1100_rtc, reg) \ |
57 | } | 53 | readl_relaxed((sa1100_rtc)->base + (reg)) |
58 | 54 | #define rtc_writel(sa1100_rtc, reg, value) \ | |
55 | writel_relaxed((value), (sa1100_rtc)->base + (reg)) | ||
56 | |||
57 | struct sa1100_rtc { | ||
58 | struct resource *ress; | ||
59 | void __iomem *base; | ||
60 | struct clk *clk; | ||
61 | int irq_1Hz; | ||
62 | int irq_Alrm; | ||
63 | struct rtc_device *rtc; | ||
64 | spinlock_t lock; /* Protects this structure */ | ||
65 | }; | ||
59 | /* | 66 | /* |
60 | * Calculate the next alarm time given the requested alarm time mask | 67 | * Calculate the next alarm time given the requested alarm time mask |
61 | * and the current time. | 68 | * and the current time. |
@@ -83,46 +90,26 @@ static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, | |||
83 | } | 90 | } |
84 | } | 91 | } |
85 | 92 | ||
86 | static int rtc_update_alarm(struct rtc_time *alrm) | ||
87 | { | ||
88 | struct rtc_time alarm_tm, now_tm; | ||
89 | unsigned long now, time; | ||
90 | int ret; | ||
91 | |||
92 | do { | ||
93 | now = RCNR; | ||
94 | rtc_time_to_tm(now, &now_tm); | ||
95 | rtc_next_alarm_time(&alarm_tm, &now_tm, alrm); | ||
96 | ret = rtc_tm_to_time(&alarm_tm, &time); | ||
97 | if (ret != 0) | ||
98 | break; | ||
99 | |||
100 | RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL); | ||
101 | RTAR = time; | ||
102 | } while (now != RCNR); | ||
103 | |||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | 93 | static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) |
108 | { | 94 | { |
109 | struct platform_device *pdev = to_platform_device(dev_id); | 95 | struct platform_device *pdev = to_platform_device(dev_id); |
110 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 96 | struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); |
111 | unsigned int rtsr; | 97 | unsigned int rtsr; |
112 | unsigned long events = 0; | 98 | unsigned long events = 0; |
113 | 99 | ||
114 | spin_lock(&sa1100_rtc_lock); | 100 | spin_lock(&sa1100_rtc->lock); |
115 | 101 | ||
116 | rtsr = RTSR; | ||
117 | /* clear interrupt sources */ | 102 | /* clear interrupt sources */ |
118 | RTSR = 0; | 103 | rtsr = rtc_readl(sa1100_rtc, RTSR); |
104 | rtc_writel(sa1100_rtc, RTSR, 0); | ||
105 | |||
119 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | 106 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
120 | * See also the comments in sa1100_rtc_probe(). */ | 107 | * See also the comments in sa1100_rtc_probe(). */ |
121 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { | 108 | if (rtsr & (RTSR_ALE | RTSR_HZE)) { |
122 | /* This is the original code, before there was the if test | 109 | /* This is the original code, before there was the if test |
123 | * above. This code does not clear interrupts that were not | 110 | * above. This code does not clear interrupts that were not |
124 | * enabled. */ | 111 | * enabled. */ |
125 | RTSR = (RTSR_AL | RTSR_HZ) & (rtsr >> 2); | 112 | rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ) & (rtsr >> 2)); |
126 | } else { | 113 | } else { |
127 | /* For some reason, it is possible to enter this routine | 114 | /* For some reason, it is possible to enter this routine |
128 | * without interruptions enabled, it has been tested with | 115 | * without interruptions enabled, it has been tested with |
@@ -131,13 +118,13 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
131 | * This situation leads to an infinite "loop" of interrupt | 118 | * This situation leads to an infinite "loop" of interrupt |
132 | * routine calling and as a result the processor seems to | 119 | * routine calling and as a result the processor seems to |
133 | * lock on its first call to open(). */ | 120 | * lock on its first call to open(). */ |
134 | RTSR = RTSR_AL | RTSR_HZ; | 121 | rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); |
135 | } | 122 | } |
136 | 123 | ||
137 | /* clear alarm interrupt if it has occurred */ | 124 | /* clear alarm interrupt if it has occurred */ |
138 | if (rtsr & RTSR_AL) | 125 | if (rtsr & RTSR_AL) |
139 | rtsr &= ~RTSR_ALE; | 126 | rtsr &= ~RTSR_ALE; |
140 | RTSR = rtsr & (RTSR_ALE | RTSR_HZE); | 127 | rtc_writel(sa1100_rtc, RTSR, rtsr & (RTSR_ALE | RTSR_HZE)); |
141 | 128 | ||
142 | /* update irq data & counter */ | 129 | /* update irq data & counter */ |
143 | if (rtsr & RTSR_AL) | 130 | if (rtsr & RTSR_AL) |
@@ -145,91 +132,100 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) | |||
145 | if (rtsr & RTSR_HZ) | 132 | if (rtsr & RTSR_HZ) |
146 | events |= RTC_UF | RTC_IRQF; | 133 | events |= RTC_UF | RTC_IRQF; |
147 | 134 | ||
148 | rtc_update_irq(rtc, 1, events); | 135 | rtc_update_irq(sa1100_rtc->rtc, 1, events); |
149 | 136 | ||
150 | if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) | 137 | spin_unlock(&sa1100_rtc->lock); |
151 | rtc_update_alarm(&rtc_alarm); | ||
152 | |||
153 | spin_unlock(&sa1100_rtc_lock); | ||
154 | 138 | ||
155 | return IRQ_HANDLED; | 139 | return IRQ_HANDLED; |
156 | } | 140 | } |
157 | 141 | ||
158 | static int sa1100_rtc_open(struct device *dev) | 142 | static int sa1100_rtc_open(struct device *dev) |
159 | { | 143 | { |
144 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
160 | int ret; | 145 | int ret; |
161 | struct platform_device *plat_dev = to_platform_device(dev); | ||
162 | struct rtc_device *rtc = platform_get_drvdata(plat_dev); | ||
163 | 146 | ||
164 | ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED, | 147 | ret = request_irq(sa1100_rtc->irq_1Hz, sa1100_rtc_interrupt, |
165 | "rtc 1Hz", dev); | 148 | IRQF_DISABLED, "rtc 1Hz", dev); |
166 | if (ret) { | 149 | if (ret) { |
167 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz); | 150 | dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_1Hz); |
168 | goto fail_ui; | 151 | goto fail_ui; |
169 | } | 152 | } |
170 | ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED, | 153 | ret = request_irq(sa1100_rtc->irq_Alrm, sa1100_rtc_interrupt, |
171 | "rtc Alrm", dev); | 154 | IRQF_DISABLED, "rtc Alrm", dev); |
172 | if (ret) { | 155 | if (ret) { |
173 | dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm); | 156 | dev_err(dev, "IRQ %d already in use.\n", sa1100_rtc->irq_Alrm); |
174 | goto fail_ai; | 157 | goto fail_ai; |
175 | } | 158 | } |
176 | rtc->max_user_freq = RTC_FREQ; | 159 | sa1100_rtc->rtc->max_user_freq = RTC_FREQ; |
177 | rtc_irq_set_freq(rtc, NULL, RTC_FREQ); | 160 | rtc_irq_set_freq(sa1100_rtc->rtc, NULL, RTC_FREQ); |
178 | 161 | ||
179 | return 0; | 162 | return 0; |
180 | 163 | ||
181 | fail_ai: | 164 | fail_ai: |
182 | free_irq(IRQ_RTC1Hz, dev); | 165 | free_irq(sa1100_rtc->irq_1Hz, dev); |
183 | fail_ui: | 166 | fail_ui: |
184 | return ret; | 167 | return ret; |
185 | } | 168 | } |
186 | 169 | ||
187 | static void sa1100_rtc_release(struct device *dev) | 170 | static void sa1100_rtc_release(struct device *dev) |
188 | { | 171 | { |
189 | spin_lock_irq(&sa1100_rtc_lock); | 172 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); |
190 | RTSR = 0; | 173 | |
191 | OIER &= ~OIER_E1; | 174 | spin_lock_irq(&sa1100_rtc->lock); |
192 | OSSR = OSSR_M1; | 175 | rtc_writel(sa1100_rtc, RTSR, 0); |
193 | spin_unlock_irq(&sa1100_rtc_lock); | 176 | spin_unlock_irq(&sa1100_rtc->lock); |
194 | 177 | ||
195 | free_irq(IRQ_RTCAlrm, dev); | 178 | free_irq(sa1100_rtc->irq_Alrm, dev); |
196 | free_irq(IRQ_RTC1Hz, dev); | 179 | free_irq(sa1100_rtc->irq_1Hz, dev); |
197 | } | 180 | } |
198 | 181 | ||
199 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | 182 | static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) |
200 | { | 183 | { |
201 | spin_lock_irq(&sa1100_rtc_lock); | 184 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); |
185 | unsigned int rtsr; | ||
186 | |||
187 | spin_lock_irq(&sa1100_rtc->lock); | ||
188 | |||
189 | rtsr = rtc_readl(sa1100_rtc, RTSR); | ||
202 | if (enabled) | 190 | if (enabled) |
203 | RTSR |= RTSR_ALE; | 191 | rtsr |= RTSR_ALE; |
204 | else | 192 | else |
205 | RTSR &= ~RTSR_ALE; | 193 | rtsr &= ~RTSR_ALE; |
206 | spin_unlock_irq(&sa1100_rtc_lock); | 194 | rtc_writel(sa1100_rtc, RTSR, rtsr); |
195 | |||
196 | spin_unlock_irq(&sa1100_rtc->lock); | ||
207 | return 0; | 197 | return 0; |
208 | } | 198 | } |
209 | 199 | ||
210 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) | 200 | static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) |
211 | { | 201 | { |
212 | rtc_time_to_tm(RCNR, tm); | 202 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); |
203 | |||
204 | rtc_time_to_tm(rtc_readl(sa1100_rtc, RCNR), tm); | ||
213 | return 0; | 205 | return 0; |
214 | } | 206 | } |
215 | 207 | ||
216 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) | 208 | static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) |
217 | { | 209 | { |
210 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
218 | unsigned long time; | 211 | unsigned long time; |
219 | int ret; | 212 | int ret; |
220 | 213 | ||
221 | ret = rtc_tm_to_time(tm, &time); | 214 | ret = rtc_tm_to_time(tm, &time); |
222 | if (ret == 0) | 215 | if (ret == 0) |
223 | RCNR = time; | 216 | rtc_writel(sa1100_rtc, RCNR, time); |
224 | return ret; | 217 | return ret; |
225 | } | 218 | } |
226 | 219 | ||
227 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 220 | static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
228 | { | 221 | { |
229 | u32 rtsr; | 222 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); |
223 | unsigned long time; | ||
224 | unsigned int rtsr; | ||
230 | 225 | ||
231 | memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time)); | 226 | time = rtc_readl(sa1100_rtc, RCNR); |
232 | rtsr = RTSR; | 227 | rtc_time_to_tm(time, &alrm->time); |
228 | rtsr = rtc_readl(sa1100_rtc, RTSR); | ||
233 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; | 229 | alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0; |
234 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; | 230 | alrm->pending = (rtsr & RTSR_AL) ? 1 : 0; |
235 | return 0; | 231 | return 0; |
@@ -237,26 +233,39 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
237 | 233 | ||
238 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 234 | static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
239 | { | 235 | { |
240 | int ret; | 236 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); |
237 | struct rtc_time now_tm, alarm_tm; | ||
238 | unsigned long time, alarm; | ||
239 | unsigned int rtsr; | ||
241 | 240 | ||
242 | spin_lock_irq(&sa1100_rtc_lock); | 241 | spin_lock_irq(&sa1100_rtc->lock); |
243 | ret = rtc_update_alarm(&alrm->time); | ||
244 | if (ret == 0) { | ||
245 | if (alrm->enabled) | ||
246 | RTSR |= RTSR_ALE; | ||
247 | else | ||
248 | RTSR &= ~RTSR_ALE; | ||
249 | } | ||
250 | spin_unlock_irq(&sa1100_rtc_lock); | ||
251 | 242 | ||
252 | return ret; | 243 | time = rtc_readl(sa1100_rtc, RCNR); |
244 | rtc_time_to_tm(time, &now_tm); | ||
245 | rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); | ||
246 | rtc_tm_to_time(&alarm_tm, &alarm); | ||
247 | rtc_writel(sa1100_rtc, RTAR, alarm); | ||
248 | |||
249 | rtsr = rtc_readl(sa1100_rtc, RTSR); | ||
250 | if (alrm->enabled) | ||
251 | rtsr |= RTSR_ALE; | ||
252 | else | ||
253 | rtsr &= ~RTSR_ALE; | ||
254 | rtc_writel(sa1100_rtc, RTSR, rtsr); | ||
255 | |||
256 | spin_unlock_irq(&sa1100_rtc->lock); | ||
257 | |||
258 | return 0; | ||
253 | } | 259 | } |
254 | 260 | ||
255 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) | 261 | static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) |
256 | { | 262 | { |
257 | seq_printf(seq, "trim/divider\t\t: 0x%08x\n", (u32) RTTR); | 263 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); |
258 | seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", (u32)RTSR); | ||
259 | 264 | ||
265 | seq_printf(seq, "trim/divider\t\t: 0x%08x\n", | ||
266 | rtc_readl(sa1100_rtc, RTTR)); | ||
267 | seq_printf(seq, "RTSR\t\t\t: 0x%08x\n", | ||
268 | rtc_readl(sa1100_rtc, RTSR)); | ||
260 | return 0; | 269 | return 0; |
261 | } | 270 | } |
262 | 271 | ||
@@ -273,7 +282,51 @@ static const struct rtc_class_ops sa1100_rtc_ops = { | |||
273 | 282 | ||
274 | static int sa1100_rtc_probe(struct platform_device *pdev) | 283 | static int sa1100_rtc_probe(struct platform_device *pdev) |
275 | { | 284 | { |
276 | struct rtc_device *rtc; | 285 | struct sa1100_rtc *sa1100_rtc; |
286 | unsigned int rttr; | ||
287 | int ret; | ||
288 | |||
289 | sa1100_rtc = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL); | ||
290 | if (!sa1100_rtc) | ||
291 | return -ENOMEM; | ||
292 | |||
293 | spin_lock_init(&sa1100_rtc->lock); | ||
294 | platform_set_drvdata(pdev, sa1100_rtc); | ||
295 | |||
296 | ret = -ENXIO; | ||
297 | sa1100_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
298 | if (!sa1100_rtc->ress) { | ||
299 | dev_err(&pdev->dev, "No I/O memory resource defined\n"); | ||
300 | goto err_ress; | ||
301 | } | ||
302 | |||
303 | sa1100_rtc->irq_1Hz = platform_get_irq(pdev, 0); | ||
304 | if (sa1100_rtc->irq_1Hz < 0) { | ||
305 | dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n"); | ||
306 | goto err_ress; | ||
307 | } | ||
308 | sa1100_rtc->irq_Alrm = platform_get_irq(pdev, 1); | ||
309 | if (sa1100_rtc->irq_Alrm < 0) { | ||
310 | dev_err(&pdev->dev, "No alarm IRQ resource defined\n"); | ||
311 | goto err_ress; | ||
312 | } | ||
313 | |||
314 | ret = -ENOMEM; | ||
315 | sa1100_rtc->base = ioremap(sa1100_rtc->ress->start, | ||
316 | resource_size(sa1100_rtc->ress)); | ||
317 | if (!sa1100_rtc->base) { | ||
318 | dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n"); | ||
319 | goto err_map; | ||
320 | } | ||
321 | |||
322 | sa1100_rtc->clk = clk_get(&pdev->dev, NULL); | ||
323 | if (IS_ERR(sa1100_rtc->clk)) { | ||
324 | dev_err(&pdev->dev, "failed to find rtc clock source\n"); | ||
325 | ret = PTR_ERR(sa1100_rtc->clk); | ||
326 | goto err_clk; | ||
327 | } | ||
328 | clk_prepare(sa1100_rtc->clk); | ||
329 | clk_enable(sa1100_rtc->clk); | ||
277 | 330 | ||
278 | /* | 331 | /* |
279 | * According to the manual we should be able to let RTTR be zero | 332 | * According to the manual we should be able to let RTTR be zero |
@@ -282,24 +335,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
282 | * If the clock divider is uninitialized then reset it to the | 335 | * If the clock divider is uninitialized then reset it to the |
283 | * default value to get the 1Hz clock. | 336 | * default value to get the 1Hz clock. |
284 | */ | 337 | */ |
285 | if (RTTR == 0) { | 338 | if (rtc_readl(sa1100_rtc, RTTR) == 0) { |
286 | RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | 339 | rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); |
287 | dev_warn(&pdev->dev, "warning: " | 340 | rtc_writel(sa1100_rtc, RTTR, rttr); |
288 | "initializing default clock divider/trim value\n"); | 341 | dev_warn(&pdev->dev, "warning: initializing default clock" |
342 | " divider/trim value\n"); | ||
289 | /* The current RTC value probably doesn't make sense either */ | 343 | /* The current RTC value probably doesn't make sense either */ |
290 | RCNR = 0; | 344 | rtc_writel(sa1100_rtc, RCNR, 0); |
291 | } | 345 | } |
292 | 346 | ||
293 | device_init_wakeup(&pdev->dev, 1); | 347 | device_init_wakeup(&pdev->dev, 1); |
294 | 348 | ||
295 | rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops, | 349 | sa1100_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
296 | THIS_MODULE); | 350 | &sa1100_rtc_ops, THIS_MODULE); |
297 | 351 | if (IS_ERR(sa1100_rtc->rtc)) { | |
298 | if (IS_ERR(rtc)) | 352 | dev_err(&pdev->dev, "Failed to register RTC device -> %d\n", |
299 | return PTR_ERR(rtc); | 353 | ret); |
300 | 354 | goto err_rtc_reg; | |
301 | platform_set_drvdata(pdev, rtc); | 355 | } |
302 | |||
303 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | 356 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
304 | * See also the comments in sa1100_rtc_interrupt(). | 357 | * See also the comments in sa1100_rtc_interrupt(). |
305 | * | 358 | * |
@@ -322,33 +375,46 @@ static int sa1100_rtc_probe(struct platform_device *pdev) | |||
322 | * | 375 | * |
323 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to | 376 | * Notice that clearing bit 1 and 0 is accomplished by writting ONES to |
324 | * the corresponding bits in RTSR. */ | 377 | * the corresponding bits in RTSR. */ |
325 | RTSR = RTSR_AL | RTSR_HZ; | 378 | rtc_writel(sa1100_rtc, RTSR, (RTSR_AL | RTSR_HZ)); |
326 | 379 | ||
327 | return 0; | 380 | return 0; |
381 | |||
382 | err_rtc_reg: | ||
383 | err_clk: | ||
384 | iounmap(sa1100_rtc->base); | ||
385 | err_ress: | ||
386 | err_map: | ||
387 | kfree(sa1100_rtc); | ||
388 | return ret; | ||
328 | } | 389 | } |
329 | 390 | ||
330 | static int sa1100_rtc_remove(struct platform_device *pdev) | 391 | static int sa1100_rtc_remove(struct platform_device *pdev) |
331 | { | 392 | { |
332 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 393 | struct sa1100_rtc *sa1100_rtc = platform_get_drvdata(pdev); |
333 | |||
334 | if (rtc) | ||
335 | rtc_device_unregister(rtc); | ||
336 | 394 | ||
395 | rtc_device_unregister(sa1100_rtc->rtc); | ||
396 | clk_disable(sa1100_rtc->clk); | ||
397 | clk_unprepare(sa1100_rtc->clk); | ||
398 | iounmap(sa1100_rtc->base); | ||
337 | return 0; | 399 | return 0; |
338 | } | 400 | } |
339 | 401 | ||
340 | #ifdef CONFIG_PM | 402 | #ifdef CONFIG_PM |
341 | static int sa1100_rtc_suspend(struct device *dev) | 403 | static int sa1100_rtc_suspend(struct device *dev) |
342 | { | 404 | { |
405 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
406 | |||
343 | if (device_may_wakeup(dev)) | 407 | if (device_may_wakeup(dev)) |
344 | enable_irq_wake(IRQ_RTCAlrm); | 408 | enable_irq_wake(sa1100_rtc->irq_Alrm); |
345 | return 0; | 409 | return 0; |
346 | } | 410 | } |
347 | 411 | ||
348 | static int sa1100_rtc_resume(struct device *dev) | 412 | static int sa1100_rtc_resume(struct device *dev) |
349 | { | 413 | { |
414 | struct sa1100_rtc *sa1100_rtc = dev_get_drvdata(dev); | ||
415 | |||
350 | if (device_may_wakeup(dev)) | 416 | if (device_may_wakeup(dev)) |
351 | disable_irq_wake(IRQ_RTCAlrm); | 417 | disable_irq_wake(sa1100_rtc->irq_Alrm); |
352 | return 0; | 418 | return 0; |
353 | } | 419 | } |
354 | 420 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 791f11bed606..75823a1abeb6 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -48,6 +48,7 @@ config USB_ARCH_HAS_OHCI | |||
48 | default y if ARCH_DAVINCI_DA8XX | 48 | default y if ARCH_DAVINCI_DA8XX |
49 | default y if ARCH_CNS3XXX | 49 | default y if ARCH_CNS3XXX |
50 | default y if PLAT_SPEAR | 50 | default y if PLAT_SPEAR |
51 | default y if ARCH_EXYNOS | ||
51 | # PPC: | 52 | # PPC: |
52 | default y if STB03xxx | 53 | default y if STB03xxx |
53 | default y if PPC_MPC52xx | 54 | default y if PPC_MPC52xx |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index a52769b5c904..4c0c9734251d 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -380,6 +380,12 @@ config USB_OHCI_SH | |||
380 | Enables support for the on-chip OHCI controller on the SuperH. | 380 | Enables support for the on-chip OHCI controller on the SuperH. |
381 | If you use the PCI OHCI controller, this option is not necessary. | 381 | If you use the PCI OHCI controller, this option is not necessary. |
382 | 382 | ||
383 | config USB_OHCI_EXYNOS | ||
384 | boolean "OHCI support for Samsung EXYNOS SoC Series" | ||
385 | depends on USB_OHCI_HCD && ARCH_EXYNOS | ||
386 | help | ||
387 | Enable support for the Samsung Exynos SOC's on-chip OHCI controller. | ||
388 | |||
383 | config USB_CNS3XXX_OHCI | 389 | config USB_CNS3XXX_OHCI |
384 | bool "Cavium CNS3XXX OHCI Module" | 390 | bool "Cavium CNS3XXX OHCI Module" |
385 | depends on USB_OHCI_HCD && ARCH_CNS3XXX | 391 | depends on USB_OHCI_HCD && ARCH_CNS3XXX |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index e33baf9052cb..bba9850f32f0 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/usb/ulpi.h> | 41 | #include <linux/usb/ulpi.h> |
42 | #include <plat/usb.h> | 42 | #include <plat/usb.h> |
43 | #include <linux/regulator/consumer.h> | 43 | #include <linux/regulator/consumer.h> |
44 | #include <linux/pm_runtime.h> | ||
44 | 45 | ||
45 | /* EHCI Register Set */ | 46 | /* EHCI Register Set */ |
46 | #define EHCI_INSNREG04 (0xA0) | 47 | #define EHCI_INSNREG04 (0xA0) |
@@ -190,11 +191,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
190 | } | 191 | } |
191 | } | 192 | } |
192 | 193 | ||
193 | ret = omap_usbhs_enable(dev); | 194 | pm_runtime_enable(dev); |
194 | if (ret) { | 195 | pm_runtime_get_sync(dev); |
195 | dev_err(dev, "failed to start usbhs with err %d\n", ret); | ||
196 | goto err_enable; | ||
197 | } | ||
198 | 196 | ||
199 | /* | 197 | /* |
200 | * An undocumented "feature" in the OMAP3 EHCI controller, | 198 | * An undocumented "feature" in the OMAP3 EHCI controller, |
@@ -242,11 +240,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
242 | return 0; | 240 | return 0; |
243 | 241 | ||
244 | err_add_hcd: | 242 | err_add_hcd: |
245 | omap_usbhs_disable(dev); | ||
246 | |||
247 | err_enable: | ||
248 | disable_put_regulator(pdata); | 243 | disable_put_regulator(pdata); |
249 | usb_put_hcd(hcd); | 244 | pm_runtime_put_sync(dev); |
250 | 245 | ||
251 | err_io: | 246 | err_io: |
252 | iounmap(regs); | 247 | iounmap(regs); |
@@ -268,10 +263,12 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
268 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 263 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
269 | 264 | ||
270 | usb_remove_hcd(hcd); | 265 | usb_remove_hcd(hcd); |
271 | omap_usbhs_disable(dev); | ||
272 | disable_put_regulator(dev->platform_data); | 266 | disable_put_regulator(dev->platform_data); |
273 | iounmap(hcd->regs); | 267 | iounmap(hcd->regs); |
274 | usb_put_hcd(hcd); | 268 | usb_put_hcd(hcd); |
269 | pm_runtime_put_sync(dev); | ||
270 | pm_runtime_disable(dev); | ||
271 | |||
275 | return 0; | 272 | return 0; |
276 | } | 273 | } |
277 | 274 | ||
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c new file mode 100644 index 000000000000..55aa35aa3d7b --- /dev/null +++ b/drivers/usb/host/ohci-exynos.c | |||
@@ -0,0 +1,274 @@ | |||
1 | /* | ||
2 | * SAMSUNG EXYNOS USB HOST OHCI Controller | ||
3 | * | ||
4 | * Copyright (C) 2011 Samsung Electronics Co.Ltd | ||
5 | * Author: Jingoo Han <jg1.han@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/clk.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <mach/ohci.h> | ||
17 | #include <plat/usb-phy.h> | ||
18 | |||
19 | struct exynos_ohci_hcd { | ||
20 | struct device *dev; | ||
21 | struct usb_hcd *hcd; | ||
22 | struct clk *clk; | ||
23 | }; | ||
24 | |||
25 | static int ohci_exynos_start(struct usb_hcd *hcd) | ||
26 | { | ||
27 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
28 | int ret; | ||
29 | |||
30 | ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci); | ||
31 | |||
32 | ret = ohci_init(ohci); | ||
33 | if (ret < 0) | ||
34 | return ret; | ||
35 | |||
36 | ret = ohci_run(ohci); | ||
37 | if (ret < 0) { | ||
38 | err("can't start %s", hcd->self.bus_name); | ||
39 | ohci_stop(hcd); | ||
40 | return ret; | ||
41 | } | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static const struct hc_driver exynos_ohci_hc_driver = { | ||
47 | .description = hcd_name, | ||
48 | .product_desc = "EXYNOS OHCI Host Controller", | ||
49 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
50 | |||
51 | .irq = ohci_irq, | ||
52 | .flags = HCD_MEMORY|HCD_USB11, | ||
53 | |||
54 | .start = ohci_exynos_start, | ||
55 | .stop = ohci_stop, | ||
56 | .shutdown = ohci_shutdown, | ||
57 | |||
58 | .get_frame_number = ohci_get_frame, | ||
59 | |||
60 | .urb_enqueue = ohci_urb_enqueue, | ||
61 | .urb_dequeue = ohci_urb_dequeue, | ||
62 | .endpoint_disable = ohci_endpoint_disable, | ||
63 | |||
64 | .hub_status_data = ohci_hub_status_data, | ||
65 | .hub_control = ohci_hub_control, | ||
66 | #ifdef CONFIG_PM | ||
67 | .bus_suspend = ohci_bus_suspend, | ||
68 | .bus_resume = ohci_bus_resume, | ||
69 | #endif | ||
70 | .start_port_reset = ohci_start_port_reset, | ||
71 | }; | ||
72 | |||
73 | static int __devinit exynos_ohci_probe(struct platform_device *pdev) | ||
74 | { | ||
75 | struct exynos4_ohci_platdata *pdata; | ||
76 | struct exynos_ohci_hcd *exynos_ohci; | ||
77 | struct usb_hcd *hcd; | ||
78 | struct ohci_hcd *ohci; | ||
79 | struct resource *res; | ||
80 | int irq; | ||
81 | int err; | ||
82 | |||
83 | pdata = pdev->dev.platform_data; | ||
84 | if (!pdata) { | ||
85 | dev_err(&pdev->dev, "No platform data defined\n"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | |||
89 | exynos_ohci = kzalloc(sizeof(struct exynos_ohci_hcd), GFP_KERNEL); | ||
90 | if (!exynos_ohci) | ||
91 | return -ENOMEM; | ||
92 | |||
93 | exynos_ohci->dev = &pdev->dev; | ||
94 | |||
95 | hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, | ||
96 | dev_name(&pdev->dev)); | ||
97 | if (!hcd) { | ||
98 | dev_err(&pdev->dev, "Unable to create HCD\n"); | ||
99 | err = -ENOMEM; | ||
100 | goto fail_hcd; | ||
101 | } | ||
102 | |||
103 | exynos_ohci->hcd = hcd; | ||
104 | exynos_ohci->clk = clk_get(&pdev->dev, "usbhost"); | ||
105 | |||
106 | if (IS_ERR(exynos_ohci->clk)) { | ||
107 | dev_err(&pdev->dev, "Failed to get usbhost clock\n"); | ||
108 | err = PTR_ERR(exynos_ohci->clk); | ||
109 | goto fail_clk; | ||
110 | } | ||
111 | |||
112 | err = clk_enable(exynos_ohci->clk); | ||
113 | if (err) | ||
114 | goto fail_clken; | ||
115 | |||
116 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
117 | if (!res) { | ||
118 | dev_err(&pdev->dev, "Failed to get I/O memory\n"); | ||
119 | err = -ENXIO; | ||
120 | goto fail_io; | ||
121 | } | ||
122 | |||
123 | hcd->rsrc_start = res->start; | ||
124 | hcd->rsrc_len = resource_size(res); | ||
125 | hcd->regs = ioremap(res->start, resource_size(res)); | ||
126 | if (!hcd->regs) { | ||
127 | dev_err(&pdev->dev, "Failed to remap I/O memory\n"); | ||
128 | err = -ENOMEM; | ||
129 | goto fail_io; | ||
130 | } | ||
131 | |||
132 | irq = platform_get_irq(pdev, 0); | ||
133 | if (!irq) { | ||
134 | dev_err(&pdev->dev, "Failed to get IRQ\n"); | ||
135 | err = -ENODEV; | ||
136 | goto fail; | ||
137 | } | ||
138 | |||
139 | if (pdata->phy_init) | ||
140 | pdata->phy_init(pdev, S5P_USB_PHY_HOST); | ||
141 | |||
142 | ohci = hcd_to_ohci(hcd); | ||
143 | ohci_hcd_init(ohci); | ||
144 | |||
145 | err = usb_add_hcd(hcd, irq, IRQF_SHARED); | ||
146 | if (err) { | ||
147 | dev_err(&pdev->dev, "Failed to add USB HCD\n"); | ||
148 | goto fail; | ||
149 | } | ||
150 | |||
151 | platform_set_drvdata(pdev, exynos_ohci); | ||
152 | |||
153 | return 0; | ||
154 | |||
155 | fail: | ||
156 | iounmap(hcd->regs); | ||
157 | fail_io: | ||
158 | clk_disable(exynos_ohci->clk); | ||
159 | fail_clken: | ||
160 | clk_put(exynos_ohci->clk); | ||
161 | fail_clk: | ||
162 | usb_put_hcd(hcd); | ||
163 | fail_hcd: | ||
164 | kfree(exynos_ohci); | ||
165 | return err; | ||
166 | } | ||
167 | |||
168 | static int __devexit exynos_ohci_remove(struct platform_device *pdev) | ||
169 | { | ||
170 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; | ||
171 | struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); | ||
172 | struct usb_hcd *hcd = exynos_ohci->hcd; | ||
173 | |||
174 | usb_remove_hcd(hcd); | ||
175 | |||
176 | if (pdata && pdata->phy_exit) | ||
177 | pdata->phy_exit(pdev, S5P_USB_PHY_HOST); | ||
178 | |||
179 | iounmap(hcd->regs); | ||
180 | |||
181 | clk_disable(exynos_ohci->clk); | ||
182 | clk_put(exynos_ohci->clk); | ||
183 | |||
184 | usb_put_hcd(hcd); | ||
185 | kfree(exynos_ohci); | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | static void exynos_ohci_shutdown(struct platform_device *pdev) | ||
191 | { | ||
192 | struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); | ||
193 | struct usb_hcd *hcd = exynos_ohci->hcd; | ||
194 | |||
195 | if (hcd->driver->shutdown) | ||
196 | hcd->driver->shutdown(hcd); | ||
197 | } | ||
198 | |||
199 | #ifdef CONFIG_PM | ||
200 | static int exynos_ohci_suspend(struct device *dev) | ||
201 | { | ||
202 | struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); | ||
203 | struct usb_hcd *hcd = exynos_ohci->hcd; | ||
204 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
205 | struct platform_device *pdev = to_platform_device(dev); | ||
206 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; | ||
207 | unsigned long flags; | ||
208 | int rc = 0; | ||
209 | |||
210 | /* | ||
211 | * Root hub was already suspended. Disable irq emission and | ||
212 | * mark HW unaccessible, bail out if RH has been resumed. Use | ||
213 | * the spinlock to properly synchronize with possible pending | ||
214 | * RH suspend or resume activity. | ||
215 | * | ||
216 | * This is still racy as hcd->state is manipulated outside of | ||
217 | * any locks =P But that will be a different fix. | ||
218 | */ | ||
219 | spin_lock_irqsave(&ohci->lock, flags); | ||
220 | if (hcd->state != HC_STATE_SUSPENDED && hcd->state != HC_STATE_HALT) { | ||
221 | rc = -EINVAL; | ||
222 | goto fail; | ||
223 | } | ||
224 | |||
225 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
226 | |||
227 | if (pdata && pdata->phy_exit) | ||
228 | pdata->phy_exit(pdev, S5P_USB_PHY_HOST); | ||
229 | fail: | ||
230 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
231 | |||
232 | return rc; | ||
233 | } | ||
234 | |||
235 | static int exynos_ohci_resume(struct device *dev) | ||
236 | { | ||
237 | struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); | ||
238 | struct usb_hcd *hcd = exynos_ohci->hcd; | ||
239 | struct platform_device *pdev = to_platform_device(dev); | ||
240 | struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; | ||
241 | |||
242 | if (pdata && pdata->phy_init) | ||
243 | pdata->phy_init(pdev, S5P_USB_PHY_HOST); | ||
244 | |||
245 | /* Mark hardware accessible again as we are out of D3 state by now */ | ||
246 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
247 | |||
248 | ohci_finish_controller_resume(hcd); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | #else | ||
253 | #define exynos_ohci_suspend NULL | ||
254 | #define exynos_ohci_resume NULL | ||
255 | #endif | ||
256 | |||
257 | static const struct dev_pm_ops exynos_ohci_pm_ops = { | ||
258 | .suspend = exynos_ohci_suspend, | ||
259 | .resume = exynos_ohci_resume, | ||
260 | }; | ||
261 | |||
262 | static struct platform_driver exynos_ohci_driver = { | ||
263 | .probe = exynos_ohci_probe, | ||
264 | .remove = __devexit_p(exynos_ohci_remove), | ||
265 | .shutdown = exynos_ohci_shutdown, | ||
266 | .driver = { | ||
267 | .name = "exynos-ohci", | ||
268 | .owner = THIS_MODULE, | ||
269 | .pm = &exynos_ohci_pm_ops, | ||
270 | } | ||
271 | }; | ||
272 | |||
273 | MODULE_ALIAS("platform:exynos-ohci"); | ||
274 | MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 4fa5d8c4d239..5f5a63241436 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1005,6 +1005,11 @@ MODULE_LICENSE ("GPL"); | |||
1005 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | 1005 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver |
1006 | #endif | 1006 | #endif |
1007 | 1007 | ||
1008 | #ifdef CONFIG_USB_OHCI_EXYNOS | ||
1009 | #include "ohci-exynos.c" | ||
1010 | #define PLATFORM_DRIVER exynos_ohci_driver | ||
1011 | #endif | ||
1012 | |||
1008 | #ifdef CONFIG_USB_OHCI_HCD_OMAP1 | 1013 | #ifdef CONFIG_USB_OHCI_HCD_OMAP1 |
1009 | #include "ohci-omap.c" | 1014 | #include "ohci-omap.c" |
1010 | #define OMAP1_PLATFORM_DRIVER ohci_hcd_omap_driver | 1015 | #define OMAP1_PLATFORM_DRIVER ohci_hcd_omap_driver |
diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 516ebc4d6cc2..1b8133b6e451 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
33 | #include <plat/usb.h> | 33 | #include <plat/usb.h> |
34 | #include <linux/pm_runtime.h> | ||
34 | 35 | ||
35 | /*-------------------------------------------------------------------------*/ | 36 | /*-------------------------------------------------------------------------*/ |
36 | 37 | ||
@@ -134,7 +135,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) | |||
134 | int irq; | 135 | int irq; |
135 | 136 | ||
136 | if (usb_disabled()) | 137 | if (usb_disabled()) |
137 | goto err_end; | 138 | return -ENODEV; |
138 | 139 | ||
139 | if (!dev->parent) { | 140 | if (!dev->parent) { |
140 | dev_err(dev, "Missing parent device\n"); | 141 | dev_err(dev, "Missing parent device\n"); |
@@ -172,11 +173,8 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) | |||
172 | hcd->rsrc_len = resource_size(res); | 173 | hcd->rsrc_len = resource_size(res); |
173 | hcd->regs = regs; | 174 | hcd->regs = regs; |
174 | 175 | ||
175 | ret = omap_usbhs_enable(dev); | 176 | pm_runtime_enable(dev); |
176 | if (ret) { | 177 | pm_runtime_get_sync(dev); |
177 | dev_dbg(dev, "failed to start ohci\n"); | ||
178 | goto err_end; | ||
179 | } | ||
180 | 178 | ||
181 | ohci_hcd_init(hcd_to_ohci(hcd)); | 179 | ohci_hcd_init(hcd_to_ohci(hcd)); |
182 | 180 | ||
@@ -189,9 +187,7 @@ static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) | |||
189 | return 0; | 187 | return 0; |
190 | 188 | ||
191 | err_add_hcd: | 189 | err_add_hcd: |
192 | omap_usbhs_disable(dev); | 190 | pm_runtime_put_sync(dev); |
193 | |||
194 | err_end: | ||
195 | usb_put_hcd(hcd); | 191 | usb_put_hcd(hcd); |
196 | 192 | ||
197 | err_io: | 193 | err_io: |
@@ -220,9 +216,9 @@ static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev) | |||
220 | 216 | ||
221 | iounmap(hcd->regs); | 217 | iounmap(hcd->regs); |
222 | usb_remove_hcd(hcd); | 218 | usb_remove_hcd(hcd); |
223 | omap_usbhs_disable(dev); | 219 | pm_runtime_put_sync(dev); |
220 | pm_runtime_disable(dev); | ||
224 | usb_put_hcd(hcd); | 221 | usb_put_hcd(hcd); |
225 | |||
226 | return 0; | 222 | return 0; |
227 | } | 223 | } |
228 | 224 | ||