aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos4
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos4')
-rw-r--r--arch/arm/mach-exynos4/Kconfig1
-rw-r--r--arch/arm/mach-exynos4/Makefile2
-rw-r--r--arch/arm/mach-exynos4/cpu.c7
-rw-r--r--arch/arm/mach-exynos4/include/mach/map.h4
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-pmu.h3
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-usb-phy.h64
-rw-r--r--arch/arm/mach-exynos4/include/mach/smp.h19
-rw-r--r--arch/arm/mach-exynos4/irq-combiner.c6
-rw-r--r--arch/arm/mach-exynos4/mach-nuri.c16
-rw-r--r--arch/arm/mach-exynos4/platsmp.c5
-rw-r--r--arch/arm/mach-exynos4/pm.c45
-rw-r--r--arch/arm/mach-exynos4/usb-phy.c136
12 files changed, 265 insertions, 43 deletions
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index e849f67be47d..805196207ce8 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -170,6 +170,7 @@ config MACH_NURI
170 select S3C_DEV_HSMMC3 170 select S3C_DEV_HSMMC3
171 select S3C_DEV_I2C1 171 select S3C_DEV_I2C1
172 select S3C_DEV_I2C5 172 select S3C_DEV_I2C5
173 select S5P_DEV_USB_EHCI
173 select EXYNOS4_SETUP_I2C1 174 select EXYNOS4_SETUP_I2C1
174 select EXYNOS4_SETUP_I2C5 175 select EXYNOS4_SETUP_I2C5
175 select EXYNOS4_SETUP_SDHCI 176 select EXYNOS4_SETUP_SDHCI
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 9be104f63c0b..777897551e42 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -54,3 +54,5 @@ obj-$(CONFIG_EXYNOS4_SETUP_I2C7) += setup-i2c7.o
54obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o 54obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD) += setup-keypad.o
55obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o 55obj-$(CONFIG_EXYNOS4_SETUP_SDHCI) += setup-sdhci.o
56obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o 56obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
57
58obj-$(CONFIG_USB_SUPPORT) += usb-phy.o
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index 793011391943..08813a6f66b1 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -97,7 +97,12 @@ static struct map_desc exynos4_iodesc[] __initdata = {
97 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC), 97 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
98 .length = SZ_4K, 98 .length = SZ_4K,
99 .type = MT_DEVICE, 99 .type = MT_DEVICE,
100 }, 100 }, {
101 .virtual = (unsigned long)S5P_VA_USB_HSPHY,
102 .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
103 .length = SZ_4K,
104 .type = MT_DEVICE,
105 }
101}; 106};
102 107
103static void exynos4_idle(void) 108static void exynos4_idle(void)
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 6330b73b9ea7..0009e77a05fc 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -101,6 +101,9 @@
101 101
102#define EXYNOS4_PA_SROMC 0x12570000 102#define EXYNOS4_PA_SROMC 0x12570000
103 103
104#define EXYNOS4_PA_EHCI 0x12580000
105#define EXYNOS4_PA_HSPHY 0x125B0000
106
104#define EXYNOS4_PA_UART 0x13800000 107#define EXYNOS4_PA_UART 0x13800000
105 108
106#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000)) 109#define EXYNOS4_PA_IIC(x) (0x13860000 + ((x) * 0x10000))
@@ -143,6 +146,7 @@
143#define S5P_PA_SROMC EXYNOS4_PA_SROMC 146#define S5P_PA_SROMC EXYNOS4_PA_SROMC
144#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON 147#define S5P_PA_SYSCON EXYNOS4_PA_SYSCON
145#define S5P_PA_TIMER EXYNOS4_PA_TIMER 148#define S5P_PA_TIMER EXYNOS4_PA_TIMER
149#define S5P_PA_EHCI EXYNOS4_PA_EHCI
146 150
147#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD 151#define SAMSUNG_PA_KEYPAD EXYNOS4_PA_KEYPAD
148 152
diff --git a/arch/arm/mach-exynos4/include/mach/regs-pmu.h b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
index 62b0014d05e0..a9643371f8e7 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-pmu.h
+++ b/arch/arm/mach-exynos4/include/mach/regs-pmu.h
@@ -33,6 +33,9 @@
33#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604) 33#define S5P_EINT_WAKEUP_MASK S5P_PMUREG(0x0604)
34#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608) 34#define S5P_WAKEUP_MASK S5P_PMUREG(0x0608)
35 35
36#define S5P_USBHOST_PHY_CONTROL S5P_PMUREG(0x0708)
37#define S5P_USBHOST_PHY_ENABLE (1 << 0)
38
36#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4) 39#define S5P_MIPI_DPHY_CONTROL(n) S5P_PMUREG(0x0710 + (n) * 4)
37#define S5P_MIPI_DPHY_ENABLE (1 << 0) 40#define S5P_MIPI_DPHY_ENABLE (1 << 0)
38#define S5P_MIPI_DPHY_SRESETN (1 << 1) 41#define S5P_MIPI_DPHY_SRESETN (1 << 1)
diff --git a/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
new file mode 100644
index 000000000000..703118d5173c
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@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 __PLAT_S5P_REGS_USB_PHY_H
12#define __PLAT_S5P_REGS_USB_PHY_H
13
14#define EXYNOS4_HSOTG_PHYREG(x) ((x) + S5P_VA_USB_HSPHY)
15
16#define EXYNOS4_PHYPWR EXYNOS4_HSOTG_PHYREG(0x00)
17#define PHY1_HSIC_NORMAL_MASK (0xf << 9)
18#define PHY1_HSIC1_SLEEP (1 << 12)
19#define PHY1_HSIC1_FORCE_SUSPEND (1 << 11)
20#define PHY1_HSIC0_SLEEP (1 << 10)
21#define PHY1_HSIC0_FORCE_SUSPEND (1 << 9)
22
23#define PHY1_STD_NORMAL_MASK (0x7 << 6)
24#define PHY1_STD_SLEEP (1 << 8)
25#define PHY1_STD_ANALOG_POWERDOWN (1 << 7)
26#define PHY1_STD_FORCE_SUSPEND (1 << 6)
27
28#define PHY0_NORMAL_MASK (0x39 << 0)
29#define PHY0_SLEEP (1 << 5)
30#define PHY0_OTG_DISABLE (1 << 4)
31#define PHY0_ANALOG_POWERDOWN (1 << 3)
32#define PHY0_FORCE_SUSPEND (1 << 0)
33
34#define EXYNOS4_PHYCLK EXYNOS4_HSOTG_PHYREG(0x04)
35#define PHY1_COMMON_ON_N (1 << 7)
36#define PHY0_COMMON_ON_N (1 << 4)
37#define PHY0_ID_PULLUP (1 << 2)
38#define CLKSEL_MASK (0x3 << 0)
39#define CLKSEL_SHIFT (0)
40#define CLKSEL_48M (0x0 << 0)
41#define CLKSEL_12M (0x2 << 0)
42#define CLKSEL_24M (0x3 << 0)
43
44#define EXYNOS4_RSTCON EXYNOS4_HSOTG_PHYREG(0x08)
45#define HOST_LINK_PORT_SWRST_MASK (0xf << 6)
46#define HOST_LINK_PORT2_SWRST (1 << 9)
47#define HOST_LINK_PORT1_SWRST (1 << 8)
48#define HOST_LINK_PORT0_SWRST (1 << 7)
49#define HOST_LINK_ALL_SWRST (1 << 6)
50
51#define PHY1_SWRST_MASK (0x7 << 3)
52#define PHY1_HSIC_SWRST (1 << 5)
53#define PHY1_STD_SWRST (1 << 4)
54#define PHY1_ALL_SWRST (1 << 3)
55
56#define PHY0_SWRST_MASK (0x7 << 0)
57#define PHY0_PHYLINK_SWRST (1 << 2)
58#define PHY0_HLINK_SWRST (1 << 1)
59#define PHY0_SWRST (1 << 0)
60
61#define EXYNOS4_PHY1CON EXYNOS4_HSOTG_PHYREG(0x34)
62#define FPENABLEN (1 << 0)
63
64#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/mach-exynos4/include/mach/smp.h b/arch/arm/mach-exynos4/include/mach/smp.h
deleted file mode 100644
index a463dcebcfd3..000000000000
--- a/arch/arm/mach-exynos4/include/mach/smp.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/* linux/arch/arm/mach-exynos4/include/mach/smp.h
2 *
3 * Cloned from arch/arm/mach-realview/include/mach/smp.h
4*/
5
6#ifndef ASM_ARCH_SMP_H
7#define ASM_ARCH_SMP_H __FILE__
8
9#include <asm/hardware/gic.h>
10
11/*
12 * We use IRQ1 as the IPI
13 */
14static inline void smp_cross_call(const struct cpumask *mask, int ipi)
15{
16 gic_raise_softirq(mask, ipi);
17}
18
19#endif
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos4/irq-combiner.c
index f488b66d6806..5a2758ab055e 100644
--- a/arch/arm/mach-exynos4/irq-combiner.c
+++ b/arch/arm/mach-exynos4/irq-combiner.c
@@ -59,8 +59,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
59 unsigned int cascade_irq, combiner_irq; 59 unsigned int cascade_irq, combiner_irq;
60 unsigned long status; 60 unsigned long status;
61 61
62 /* primary controller ack'ing */ 62 chained_irq_enter(chip, desc);
63 chip->irq_ack(&desc->irq_data);
64 63
65 spin_lock(&irq_controller_lock); 64 spin_lock(&irq_controller_lock);
66 status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); 65 status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
@@ -79,8 +78,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
79 generic_handle_irq(cascade_irq); 78 generic_handle_irq(cascade_irq);
80 79
81 out: 80 out:
82 /* primary controller unmasking */ 81 chained_irq_exit(chip, desc);
83 chip->irq_unmask(&desc->irq_data);
84} 82}
85 83
86static struct irq_chip combiner_chip = { 84static struct irq_chip combiner_chip = {
diff --git a/arch/arm/mach-exynos4/mach-nuri.c b/arch/arm/mach-exynos4/mach-nuri.c
index b79ad010d194..bb5d12f43af8 100644
--- a/arch/arm/mach-exynos4/mach-nuri.c
+++ b/arch/arm/mach-exynos4/mach-nuri.c
@@ -30,6 +30,8 @@
30#include <plat/cpu.h> 30#include <plat/cpu.h>
31#include <plat/devs.h> 31#include <plat/devs.h>
32#include <plat/sdhci.h> 32#include <plat/sdhci.h>
33#include <plat/ehci.h>
34#include <plat/clock.h>
33 35
34#include <mach/map.h> 36#include <mach/map.h>
35 37
@@ -262,6 +264,16 @@ static struct i2c_board_info i2c5_devs[] __initdata = {
262 /* max8997, To be updated */ 264 /* max8997, To be updated */
263}; 265};
264 266
267/* USB EHCI */
268static struct s5p_ehci_platdata nuri_ehci_pdata;
269
270static void __init nuri_ehci_init(void)
271{
272 struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata;
273
274 s5p_ehci_set_platdata(pdata);
275}
276
265static struct platform_device *nuri_devices[] __initdata = { 277static struct platform_device *nuri_devices[] __initdata = {
266 /* Samsung Platform Devices */ 278 /* Samsung Platform Devices */
267 &emmc_fixed_voltage, 279 &emmc_fixed_voltage,
@@ -270,6 +282,7 @@ static struct platform_device *nuri_devices[] __initdata = {
270 &s3c_device_hsmmc3, 282 &s3c_device_hsmmc3,
271 &s3c_device_wdt, 283 &s3c_device_wdt,
272 &s3c_device_timer[0], 284 &s3c_device_timer[0],
285 &s5p_device_ehci,
273 286
274 /* NURI Devices */ 287 /* NURI Devices */
275 &nuri_gpio_keys, 288 &nuri_gpio_keys,
@@ -291,6 +304,9 @@ static void __init nuri_machine_init(void)
291 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); 304 i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
292 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs)); 305 i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
293 306
307 nuri_ehci_init();
308 clk_xusbxti.rate = 24000000;
309
294 /* Last */ 310 /* Last */
295 platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices)); 311 platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
296} 312}
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index 6d35878ec1aa..c5e65a02be8d 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -22,6 +22,7 @@
22#include <linux/io.h> 22#include <linux/io.h>
23 23
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/hardware/gic.h>
25#include <asm/smp_scu.h> 26#include <asm/smp_scu.h>
26#include <asm/unified.h> 27#include <asm/unified.h>
27 28
@@ -104,7 +105,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
104 * the boot monitor to read the system wide flags register, 105 * the boot monitor to read the system wide flags register,
105 * and branch to the address found there. 106 * and branch to the address found there.
106 */ 107 */
107 smp_cross_call(cpumask_of(cpu), 1); 108 gic_raise_softirq(cpumask_of(cpu), 1);
108 109
109 timeout = jiffies + (1 * HZ); 110 timeout = jiffies + (1 * HZ);
110 while (time_before(jiffies, timeout)) { 111 while (time_before(jiffies, timeout)) {
@@ -147,6 +148,8 @@ void __init smp_init_cpus(void)
147 148
148 for (i = 0; i < ncores; i++) 149 for (i = 0; i < ncores; i++)
149 set_cpu_possible(i, true); 150 set_cpu_possible(i, true);
151
152 set_smp_cross_call(gic_raise_softirq);
150} 153}
151 154
152void __init platform_smp_prepare_cpus(unsigned int max_cpus) 155void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c
index 10d917d9e3ad..8755ca8dd48d 100644
--- a/arch/arm/mach-exynos4/pm.c
+++ b/arch/arm/mach-exynos4/pm.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/suspend.h> 18#include <linux/suspend.h>
19#include <linux/syscore_ops.h>
19#include <linux/io.h> 20#include <linux/io.h>
20 21
21#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
@@ -372,7 +373,27 @@ void exynos4_scu_enable(void __iomem *scu_base)
372 flush_cache_all(); 373 flush_cache_all();
373} 374}
374 375
375static int exynos4_pm_resume(struct sys_device *dev) 376static struct sysdev_driver exynos4_pm_driver = {
377 .add = exynos4_pm_add,
378};
379
380static __init int exynos4_pm_drvinit(void)
381{
382 unsigned int tmp;
383
384 s3c_pm_init();
385
386 /* All wakeup disable */
387
388 tmp = __raw_readl(S5P_WAKEUP_MASK);
389 tmp |= ((0xFF << 8) | (0x1F << 1));
390 __raw_writel(tmp, S5P_WAKEUP_MASK);
391
392 return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
393}
394arch_initcall(exynos4_pm_drvinit);
395
396static void exynos4_pm_resume(void)
376{ 397{
377 /* For release retention */ 398 /* For release retention */
378 399
@@ -394,27 +415,15 @@ static int exynos4_pm_resume(struct sys_device *dev)
394 /* enable L2X0*/ 415 /* enable L2X0*/
395 writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL); 416 writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
396#endif 417#endif
397
398 return 0;
399} 418}
400 419
401static struct sysdev_driver exynos4_pm_driver = { 420static struct syscore_ops exynos4_pm_syscore_ops = {
402 .add = exynos4_pm_add,
403 .resume = exynos4_pm_resume, 421 .resume = exynos4_pm_resume,
404}; 422};
405 423
406static __init int exynos4_pm_drvinit(void) 424static __init int exynos4_pm_syscore_init(void)
407{ 425{
408 unsigned int tmp; 426 register_syscore_ops(&exynos4_pm_syscore_ops);
409 427 return 0;
410 s3c_pm_init();
411
412 /* All wakeup disable */
413
414 tmp = __raw_readl(S5P_WAKEUP_MASK);
415 tmp |= ((0xFF << 8) | (0x1F << 1));
416 __raw_writel(tmp, S5P_WAKEUP_MASK);
417
418 return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
419} 428}
420arch_initcall(exynos4_pm_drvinit); 429arch_initcall(exynos4_pm_syscore_init);
diff --git a/arch/arm/mach-exynos4/usb-phy.c b/arch/arm/mach-exynos4/usb-phy.c
new file mode 100644
index 000000000000..0883c1b824b9
--- /dev/null
+++ b/arch/arm/mach-exynos4/usb-phy.c
@@ -0,0 +1,136 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@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
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/err.h>
15#include <linux/io.h>
16#include <linux/platform_device.h>
17#include <mach/regs-pmu.h>
18#include <mach/regs-usb-phy.h>
19#include <plat/cpu.h>
20#include <plat/usb-phy.h>
21
22static int exynos4_usb_phy1_init(struct platform_device *pdev)
23{
24 struct clk *otg_clk;
25 struct clk *xusbxti_clk;
26 u32 phyclk;
27 u32 rstcon;
28 int err;
29
30 otg_clk = clk_get(&pdev->dev, "otg");
31 if (IS_ERR(otg_clk)) {
32 dev_err(&pdev->dev, "Failed to get otg clock\n");
33 return PTR_ERR(otg_clk);
34 }
35
36 err = clk_enable(otg_clk);
37 if (err) {
38 clk_put(otg_clk);
39 return err;
40 }
41
42 writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
43 S5P_USBHOST_PHY_CONTROL);
44
45 /* set clock frequency for PLL */
46 phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
47
48 xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
49 if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
50 switch (clk_get_rate(xusbxti_clk)) {
51 case 12 * MHZ:
52 phyclk |= CLKSEL_12M;
53 break;
54 case 24 * MHZ:
55 phyclk |= CLKSEL_24M;
56 break;
57 default:
58 case 48 * MHZ:
59 /* default reference clock */
60 break;
61 }
62 clk_put(xusbxti_clk);
63 }
64
65 writel(phyclk, EXYNOS4_PHYCLK);
66
67 /* floating prevention logic: disable */
68 writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
69
70 /* set to normal HSIC 0 and 1 of PHY1 */
71 writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
72 EXYNOS4_PHYPWR);
73
74 /* set to normal standard USB of PHY1 */
75 writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
76
77 /* reset all ports of both PHY and Link */
78 rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
79 PHY1_SWRST_MASK;
80 writel(rstcon, EXYNOS4_RSTCON);
81 udelay(10);
82
83 rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
84 writel(rstcon, EXYNOS4_RSTCON);
85 udelay(50);
86
87 clk_disable(otg_clk);
88 clk_put(otg_clk);
89
90 return 0;
91}
92
93static int exynos4_usb_phy1_exit(struct platform_device *pdev)
94{
95 struct clk *otg_clk;
96 int err;
97
98 otg_clk = clk_get(&pdev->dev, "otg");
99 if (IS_ERR(otg_clk)) {
100 dev_err(&pdev->dev, "Failed to get otg clock\n");
101 return PTR_ERR(otg_clk);
102 }
103
104 err = clk_enable(otg_clk);
105 if (err) {
106 clk_put(otg_clk);
107 return err;
108 }
109
110 writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
111 EXYNOS4_PHYPWR);
112
113 writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
114 S5P_USBHOST_PHY_CONTROL);
115
116 clk_disable(otg_clk);
117 clk_put(otg_clk);
118
119 return 0;
120}
121
122int s5p_usb_phy_init(struct platform_device *pdev, int type)
123{
124 if (type == S5P_USB_PHY_HOST)
125 return exynos4_usb_phy1_init(pdev);
126
127 return -EINVAL;
128}
129
130int s5p_usb_phy_exit(struct platform_device *pdev, int type)
131{
132 if (type == S5P_USB_PHY_HOST)
133 return exynos4_usb_phy1_exit(pdev);
134
135 return -EINVAL;
136}