diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2012-10-29 04:15:34 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2012-11-08 03:52:03 -0500 |
commit | 94e1f7fbe0478f00ccbdb22d9b269943e1daeba6 (patch) | |
tree | fc309d1d6029027d8fc0bc5e0402f39cb7ed0641 /arch/arm/mach-shmobile/board-marzen.c | |
parent | b5ce635d45fc7da686c9f3071877689d8db1d284 (diff) |
ARM: shmobile: marzen: add USB EHCI driver support
This patch supports CN21/CN22 USB 2.0 (port 0/1/2),
and enable USB momery on defconfig
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'arch/arm/mach-shmobile/board-marzen.c')
-rw-r--r-- | arch/arm/mach-shmobile/board-marzen.c | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 74c7f0b64718..707b3bdaee8a 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c | |||
@@ -34,6 +34,9 @@ | |||
34 | #include <linux/spi/sh_hspi.h> | 34 | #include <linux/spi/sh_hspi.h> |
35 | #include <linux/mmc/sh_mobile_sdhi.h> | 35 | #include <linux/mmc/sh_mobile_sdhi.h> |
36 | #include <linux/mfd/tmio.h> | 36 | #include <linux/mfd/tmio.h> |
37 | #include <linux/usb/otg.h> | ||
38 | #include <linux/usb/ehci_pdriver.h> | ||
39 | #include <linux/pm_runtime.h> | ||
37 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
38 | #include <mach/r8a7779.h> | 41 | #include <mach/r8a7779.h> |
39 | #include <mach/common.h> | 42 | #include <mach/common.h> |
@@ -172,6 +175,101 @@ static struct platform_device *marzen_devices[] __initdata = { | |||
172 | &usb_phy_device, | 175 | &usb_phy_device, |
173 | }; | 176 | }; |
174 | 177 | ||
178 | /* USB */ | ||
179 | static struct usb_phy *phy; | ||
180 | static int usb_power_on(struct platform_device *pdev) | ||
181 | { | ||
182 | if (!phy) | ||
183 | return -EIO; | ||
184 | |||
185 | pm_runtime_enable(&pdev->dev); | ||
186 | pm_runtime_get_sync(&pdev->dev); | ||
187 | |||
188 | usb_phy_init(phy); | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static void usb_power_off(struct platform_device *pdev) | ||
194 | { | ||
195 | if (!phy) | ||
196 | return; | ||
197 | |||
198 | usb_phy_shutdown(phy); | ||
199 | |||
200 | pm_runtime_put_sync(&pdev->dev); | ||
201 | pm_runtime_disable(&pdev->dev); | ||
202 | } | ||
203 | |||
204 | static struct usb_ehci_pdata ehcix_pdata = { | ||
205 | .power_on = usb_power_on, | ||
206 | .power_off = usb_power_off, | ||
207 | .power_suspend = usb_power_off, | ||
208 | }; | ||
209 | |||
210 | static struct resource ehci0_resources[] = { | ||
211 | [0] = { | ||
212 | .start = 0xffe70000, | ||
213 | .end = 0xffe70400 - 1, | ||
214 | .flags = IORESOURCE_MEM, | ||
215 | }, | ||
216 | [1] = { | ||
217 | .start = gic_spi(44), | ||
218 | .flags = IORESOURCE_IRQ, | ||
219 | }, | ||
220 | }; | ||
221 | |||
222 | static struct platform_device ehci0_device = { | ||
223 | .name = "ehci-platform", | ||
224 | .id = 0, | ||
225 | .dev = { | ||
226 | .dma_mask = &ehci0_device.dev.coherent_dma_mask, | ||
227 | .coherent_dma_mask = 0xffffffff, | ||
228 | .platform_data = &ehcix_pdata, | ||
229 | }, | ||
230 | .num_resources = ARRAY_SIZE(ehci0_resources), | ||
231 | .resource = ehci0_resources, | ||
232 | }; | ||
233 | |||
234 | static struct resource ehci1_resources[] = { | ||
235 | [0] = { | ||
236 | .start = 0xfff70000, | ||
237 | .end = 0xfff70400 - 1, | ||
238 | .flags = IORESOURCE_MEM, | ||
239 | }, | ||
240 | [1] = { | ||
241 | .start = gic_spi(45), | ||
242 | .flags = IORESOURCE_IRQ, | ||
243 | }, | ||
244 | }; | ||
245 | |||
246 | static struct platform_device ehci1_device = { | ||
247 | .name = "ehci-platform", | ||
248 | .id = 1, | ||
249 | .dev = { | ||
250 | .dma_mask = &ehci1_device.dev.coherent_dma_mask, | ||
251 | .coherent_dma_mask = 0xffffffff, | ||
252 | .platform_data = &ehcix_pdata, | ||
253 | }, | ||
254 | .num_resources = ARRAY_SIZE(ehci1_resources), | ||
255 | .resource = ehci1_resources, | ||
256 | }; | ||
257 | |||
258 | static struct platform_device *marzen_late_devices[] __initdata = { | ||
259 | &ehci0_device, | ||
260 | &ehci1_device, | ||
261 | }; | ||
262 | |||
263 | void __init marzen_init_late(void) | ||
264 | { | ||
265 | /* get usb phy */ | ||
266 | phy = usb_get_phy(USB_PHY_TYPE_USB2); | ||
267 | |||
268 | shmobile_init_late(); | ||
269 | platform_add_devices(marzen_late_devices, | ||
270 | ARRAY_SIZE(marzen_late_devices)); | ||
271 | } | ||
272 | |||
175 | static void __init marzen_init(void) | 273 | static void __init marzen_init(void) |
176 | { | 274 | { |
177 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | 275 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, |
@@ -209,6 +307,14 @@ static void __init marzen_init(void) | |||
209 | gpio_request(GPIO_FN_HSPI_TX0, NULL); | 307 | gpio_request(GPIO_FN_HSPI_TX0, NULL); |
210 | gpio_request(GPIO_FN_HSPI_RX0, NULL); | 308 | gpio_request(GPIO_FN_HSPI_RX0, NULL); |
211 | 309 | ||
310 | /* USB (CN21) */ | ||
311 | gpio_request(GPIO_FN_USB_OVC0, NULL); | ||
312 | gpio_request(GPIO_FN_USB_OVC1, NULL); | ||
313 | gpio_request(GPIO_FN_USB_OVC2, NULL); | ||
314 | |||
315 | /* USB (CN22) */ | ||
316 | gpio_request(GPIO_FN_USB_PENC2, NULL); | ||
317 | |||
212 | r8a7779_add_standard_devices(); | 318 | r8a7779_add_standard_devices(); |
213 | platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); | 319 | platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); |
214 | } | 320 | } |
@@ -221,6 +327,6 @@ MACHINE_START(MARZEN, "marzen") | |||
221 | .init_irq = r8a7779_init_irq, | 327 | .init_irq = r8a7779_init_irq, |
222 | .handle_irq = gic_handle_irq, | 328 | .handle_irq = gic_handle_irq, |
223 | .init_machine = marzen_init, | 329 | .init_machine = marzen_init, |
224 | .init_late = shmobile_init_late, | 330 | .init_late = marzen_init_late, |
225 | .timer = &shmobile_timer, | 331 | .timer = &shmobile_timer, |
226 | MACHINE_END | 332 | MACHINE_END |