aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-12-27 18:41:37 -0500
committerArnd Bergmann <arnd@arndb.de>2011-12-27 18:41:37 -0500
commite814fb635cd269532a6a95a921c05841ababa7ae (patch)
treeb6764b819736ea0d3390fc11c564d321d63344d6 /arch
parent4551ae0a24bba06972247a80f721fc21f6b2b758 (diff)
parentfcf932350e979db9a29831a8a03bc300c4502bd5 (diff)
Merge branch 'samsung/ohci' into next/drivers
* samsung/ohci: ARM: EXYNOS: Add USB OHCI support to ORIGEN board USB: Add Samsung Exynos OHCI diver ARM: EXYNOS: Add USB OHCI support to SMDKV310 board ARM: EXYNOS: Add USB OHCI device
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-exynos/Kconfig7
-rw-r--r--arch/arm/mach-exynos/Makefile1
-rw-r--r--arch/arm/mach-exynos/dev-ohci.c52
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h1
-rw-r--r--arch/arm/mach-exynos/include/mach/ohci.h21
-rw-r--r--arch/arm/mach-exynos/mach-origen.c13
-rw-r--r--arch/arm/mach-exynos/mach-smdkv310.c13
-rw-r--r--arch/arm/mach-exynos/setup-usb-phy.c15
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h1
9 files changed, 124 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 724ec0f3560d..5ca0bddf65fa 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -82,6 +82,11 @@ config EXYNOS4_DEV_DWMCI
82 help 82 help
83 Compile in platform device definitions for DWMCI 83 Compile in platform device definitions for DWMCI
84 84
85config EXYNOS4_DEV_USB_OHCI
86 bool
87 help
88 Compile in platform device definition for USB OHCI
89
85config EXYNOS4_SETUP_I2C1 90config EXYNOS4_SETUP_I2C1
86 bool 91 bool
87 help 92 help
@@ -179,6 +184,7 @@ config MACH_SMDKV310
179 select SAMSUNG_DEV_KEYPAD 184 select SAMSUNG_DEV_KEYPAD
180 select EXYNOS4_DEV_PD 185 select EXYNOS4_DEV_PD
181 select SAMSUNG_DEV_PWM 186 select SAMSUNG_DEV_PWM
187 select EXYNOS4_DEV_USB_OHCI
182 select EXYNOS4_DEV_SYSMMU 188 select EXYNOS4_DEV_SYSMMU
183 select EXYNOS4_SETUP_FIMD0 189 select EXYNOS4_SETUP_FIMD0
184 select EXYNOS4_SETUP_I2C1 190 select EXYNOS4_SETUP_I2C1
@@ -288,6 +294,7 @@ config MACH_ORIGEN
288 select SAMSUNG_DEV_BACKLIGHT 294 select SAMSUNG_DEV_BACKLIGHT
289 select SAMSUNG_DEV_PWM 295 select SAMSUNG_DEV_PWM
290 select EXYNOS4_DEV_PD 296 select EXYNOS4_DEV_PD
297 select EXYNOS4_DEV_USB_OHCI
291 select EXYNOS4_SETUP_FIMD0 298 select EXYNOS4_SETUP_FIMD0
292 select EXYNOS4_SETUP_SDHCI 299 select EXYNOS4_SETUP_SDHCI
293 select EXYNOS4_SETUP_USB_PHY 300 select EXYNOS4_SETUP_USB_PHY
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 59069a35e40b..f5f3b7994923 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
44obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o 44obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
45obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o 45obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
46obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o 46obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
47obj-$(CONFIG_EXYNOS4_DEV_USB_OHCI) += dev-ohci.o
47 48
48obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o 49obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
49obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o 50obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
diff --git a/arch/arm/mach-exynos/dev-ohci.c b/arch/arm/mach-exynos/dev-ohci.c
new file mode 100644
index 000000000000..b8e75300c77d
--- /dev/null
+++ b/arch/arm/mach-exynos/dev-ohci.c
@@ -0,0 +1,52 @@
1/* linux/arch/arm/mach-exynos/dev-ohci.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * EXYNOS - OHCI support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15
16#include <mach/irqs.h>
17#include <mach/map.h>
18#include <mach/ohci.h>
19
20#include <plat/devs.h>
21#include <plat/usb-phy.h>
22
23static struct resource exynos4_ohci_resource[] = {
24 [0] = DEFINE_RES_MEM(EXYNOS4_PA_OHCI, SZ_256),
25 [1] = DEFINE_RES_IRQ(IRQ_USB_HOST),
26};
27
28static u64 exynos4_ohci_dma_mask = DMA_BIT_MASK(32);
29
30struct platform_device exynos4_device_ohci = {
31 .name = "exynos-ohci",
32 .id = -1,
33 .num_resources = ARRAY_SIZE(exynos4_ohci_resource),
34 .resource = exynos4_ohci_resource,
35 .dev = {
36 .dma_mask = &exynos4_ohci_dma_mask,
37 .coherent_dma_mask = DMA_BIT_MASK(32),
38 }
39};
40
41void __init exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd)
42{
43 struct exynos4_ohci_platdata *npd;
44
45 npd = s3c_set_platdata(pd, sizeof(struct exynos4_ohci_platdata),
46 &exynos4_device_ohci);
47
48 if (!npd->phy_init)
49 npd->phy_init = s5p_usb_phy_init;
50 if (!npd->phy_exit)
51 npd->phy_exit = s5p_usb_phy_exit;
52}
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 058541d45af0..01e1cf3f9341 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -107,6 +107,7 @@
107#define EXYNOS4_PA_SROMC 0x12570000 107#define EXYNOS4_PA_SROMC 0x12570000
108 108
109#define EXYNOS4_PA_EHCI 0x12580000 109#define EXYNOS4_PA_EHCI 0x12580000
110#define EXYNOS4_PA_OHCI 0x12590000
110#define EXYNOS4_PA_HSPHY 0x125B0000 111#define EXYNOS4_PA_HSPHY 0x125B0000
111#define EXYNOS4_PA_MFC 0x13400000 112#define EXYNOS4_PA_MFC 0x13400000
112 113
diff --git a/arch/arm/mach-exynos/include/mach/ohci.h b/arch/arm/mach-exynos/include/mach/ohci.h
new file mode 100644
index 000000000000..c256c595be5e
--- /dev/null
+++ b/arch/arm/mach-exynos/include/mach/ohci.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * http://www.samsung.com/
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __MACH_EXYNOS_OHCI_H
12#define __MACH_EXYNOS_OHCI_H
13
14struct exynos4_ohci_platdata {
15 int (*phy_init)(struct platform_device *pdev, int type);
16 int (*phy_exit)(struct platform_device *pdev, int type);
17};
18
19extern void exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd);
20
21#endif /* __MACH_EXYNOS_OHCI_H */
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index f80b563f2be7..b805e595cc35 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -41,6 +41,7 @@
41#include <plat/fb.h> 41#include <plat/fb.h>
42#include <plat/mfc.h> 42#include <plat/mfc.h>
43 43
44#include <mach/ohci.h>
44#include <mach/map.h> 45#include <mach/map.h>
45 46
46/* Following are default values for UCON, ULCON and UFCON UART registers */ 47/* Following are default values for UCON, ULCON and UFCON UART registers */
@@ -483,6 +484,16 @@ static void __init origen_ehci_init(void)
483 s5p_ehci_set_platdata(pdata); 484 s5p_ehci_set_platdata(pdata);
484} 485}
485 486
487/* USB OHCI */
488static struct exynos4_ohci_platdata origen_ohci_pdata;
489
490static void __init origen_ohci_init(void)
491{
492 struct exynos4_ohci_platdata *pdata = &origen_ohci_pdata;
493
494 exynos4_ohci_set_platdata(pdata);
495}
496
486static struct gpio_keys_button origen_gpio_keys_table[] = { 497static struct gpio_keys_button origen_gpio_keys_table[] = {
487 { 498 {
488 .code = KEY_MENU, 499 .code = KEY_MENU,
@@ -606,6 +617,7 @@ static struct platform_device *origen_devices[] __initdata = {
606 &s5p_device_mfc_l, 617 &s5p_device_mfc_l,
607 &s5p_device_mfc_r, 618 &s5p_device_mfc_r,
608 &s5p_device_mixer, 619 &s5p_device_mixer,
620 &exynos4_device_ohci,
609 &exynos4_device_pd[PD_LCD0], 621 &exynos4_device_pd[PD_LCD0],
610 &exynos4_device_pd[PD_TV], 622 &exynos4_device_pd[PD_TV],
611 &exynos4_device_pd[PD_G3D], 623 &exynos4_device_pd[PD_G3D],
@@ -670,6 +682,7 @@ static void __init origen_machine_init(void)
670 s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata); 682 s3c_sdhci0_set_platdata(&origen_hsmmc0_pdata);
671 683
672 origen_ehci_init(); 684 origen_ehci_init();
685 origen_ohci_init();
673 clk_xusbxti.rate = 24000000; 686 clk_xusbxti.rate = 24000000;
674 687
675 s5p_tv_setup(); 688 s5p_tv_setup();
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index cec2afabe7b4..25a5a405c4bf 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -42,6 +42,7 @@
42#include <plat/clock.h> 42#include <plat/clock.h>
43 43
44#include <mach/map.h> 44#include <mach/map.h>
45#include <mach/ohci.h>
45 46
46/* Following are default values for UCON, ULCON and UFCON UART registers */ 47/* Following are default values for UCON, ULCON and UFCON UART registers */
47#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 48#define SMDKV310_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -245,6 +246,16 @@ static void __init smdkv310_ehci_init(void)
245 s5p_ehci_set_platdata(pdata); 246 s5p_ehci_set_platdata(pdata);
246} 247}
247 248
249/* USB OHCI */
250static struct exynos4_ohci_platdata smdkv310_ohci_pdata;
251
252static void __init smdkv310_ohci_init(void)
253{
254 struct exynos4_ohci_platdata *pdata = &smdkv310_ohci_pdata;
255
256 exynos4_ohci_set_platdata(pdata);
257}
258
248static struct platform_device *smdkv310_devices[] __initdata = { 259static struct platform_device *smdkv310_devices[] __initdata = {
249 &s3c_device_hsmmc0, 260 &s3c_device_hsmmc0,
250 &s3c_device_hsmmc1, 261 &s3c_device_hsmmc1,
@@ -261,6 +272,7 @@ static struct platform_device *smdkv310_devices[] __initdata = {
261 &s5p_device_fimc3, 272 &s5p_device_fimc3,
262 &exynos4_device_ac97, 273 &exynos4_device_ac97,
263 &exynos4_device_i2s0, 274 &exynos4_device_i2s0,
275 &exynos4_device_ohci,
264 &samsung_device_keypad, 276 &samsung_device_keypad,
265 &s5p_device_mfc, 277 &s5p_device_mfc,
266 &s5p_device_mfc_l, 278 &s5p_device_mfc_l,
@@ -363,6 +375,7 @@ static void __init smdkv310_machine_init(void)
363 s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata); 375 s5p_fimd0_set_platdata(&smdkv310_lcd0_pdata);
364 376
365 smdkv310_ehci_init(); 377 smdkv310_ehci_init();
378 smdkv310_ohci_init();
366 clk_xusbxti.rate = 24000000; 379 clk_xusbxti.rate = 24000000;
367 380
368 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices)); 381 platform_add_devices(smdkv310_devices, ARRAY_SIZE(smdkv310_devices));
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c
index 39aca045f660..41743d21e8c6 100644
--- a/arch/arm/mach-exynos/setup-usb-phy.c
+++ b/arch/arm/mach-exynos/setup-usb-phy.c
@@ -19,6 +19,13 @@
19#include <plat/cpu.h> 19#include <plat/cpu.h>
20#include <plat/usb-phy.h> 20#include <plat/usb-phy.h>
21 21
22static atomic_t host_usage;
23
24static int exynos4_usb_host_phy_is_on(void)
25{
26 return (readl(EXYNOS4_PHYPWR) & PHY1_STD_ANALOG_POWERDOWN) ? 0 : 1;
27}
28
22static int exynos4_usb_phy1_init(struct platform_device *pdev) 29static int exynos4_usb_phy1_init(struct platform_device *pdev)
23{ 30{
24 struct clk *otg_clk; 31 struct clk *otg_clk;
@@ -27,6 +34,8 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
27 u32 rstcon; 34 u32 rstcon;
28 int err; 35 int err;
29 36
37 atomic_inc(&host_usage);
38
30 otg_clk = clk_get(&pdev->dev, "otg"); 39 otg_clk = clk_get(&pdev->dev, "otg");
31 if (IS_ERR(otg_clk)) { 40 if (IS_ERR(otg_clk)) {
32 dev_err(&pdev->dev, "Failed to get otg clock\n"); 41 dev_err(&pdev->dev, "Failed to get otg clock\n");
@@ -39,6 +48,9 @@ static int exynos4_usb_phy1_init(struct platform_device *pdev)
39 return err; 48 return err;
40 } 49 }
41 50
51 if (exynos4_usb_host_phy_is_on())
52 return 0;
53
42 writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE, 54 writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
43 S5P_USBHOST_PHY_CONTROL); 55 S5P_USBHOST_PHY_CONTROL);
44 56
@@ -95,6 +107,9 @@ static int exynos4_usb_phy1_exit(struct platform_device *pdev)
95 struct clk *otg_clk; 107 struct clk *otg_clk;
96 int err; 108 int err;
97 109
110 if (atomic_dec_return(&host_usage) > 0)
111 return 0;
112
98 otg_clk = clk_get(&pdev->dev, "otg"); 113 otg_clk = clk_get(&pdev->dev, "otg");
99 if (IS_ERR(otg_clk)) { 114 if (IS_ERR(otg_clk)) {
100 dev_err(&pdev->dev, "Failed to get otg clock\n"); 115 dev_err(&pdev->dev, "Failed to get otg clock\n");
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index ab633c9c2aec..a2ff27e3ec30 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -129,6 +129,7 @@ extern struct platform_device exynos4_device_dwmci;
129extern struct platform_device exynos4_device_i2s0; 129extern struct platform_device exynos4_device_i2s0;
130extern struct platform_device exynos4_device_i2s1; 130extern struct platform_device exynos4_device_i2s1;
131extern struct platform_device exynos4_device_i2s2; 131extern struct platform_device exynos4_device_i2s2;
132extern struct platform_device exynos4_device_ohci;
132extern struct platform_device exynos4_device_pcm0; 133extern struct platform_device exynos4_device_pcm0;
133extern struct platform_device exynos4_device_pcm1; 134extern struct platform_device exynos4_device_pcm1;
134extern struct platform_device exynos4_device_pcm2; 135extern struct platform_device exynos4_device_pcm2;