aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/usb/dwc3.txt22
-rw-r--r--Documentation/devicetree/bindings/usb/omap-usb.txt34
-rw-r--r--Documentation/devicetree/bindings/usb/samsung-usbphy.txt55
-rw-r--r--Documentation/devicetree/bindings/usb/usb-phy.txt35
-rw-r--r--drivers/usb/dwc3/core.c24
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c37
-rw-r--r--drivers/usb/host/ehci-s5p.c81
-rw-r--r--drivers/usb/host/ohci-exynos.c85
-rw-r--r--drivers/usb/musb/Kconfig1
-rw-r--r--drivers/usb/musb/omap2430.c75
-rw-r--r--drivers/usb/musb/omap2430.h9
-rw-r--r--drivers/usb/otg/mv_otg.c2
-rw-r--r--drivers/usb/otg/mxs-phy.c20
-rw-r--r--drivers/usb/otg/otg.c235
-rw-r--r--drivers/usb/otg/twl4030-usb.c3
-rw-r--r--drivers/usb/phy/Kconfig29
-rw-r--r--drivers/usb/phy/Makefile3
-rw-r--r--drivers/usb/phy/omap-control-usb.c295
-rw-r--r--drivers/usb/phy/omap-usb2.c72
-rw-r--r--drivers/usb/phy/omap-usb3.c355
-rw-r--r--drivers/usb/phy/samsung-usbphy.c930
-rw-r--r--include/linux/platform_data/samsung-usbphy.h27
-rw-r--r--include/linux/usb/omap_control_usb.h92
-rw-r--r--include/linux/usb/omap_usb.h27
-rw-r--r--include/linux/usb/phy.h43
-rw-r--r--include/linux/usb/samsung_usb_phy.h16
26 files changed, 2449 insertions, 158 deletions
diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt
new file mode 100644
index 000000000000..7a95c651ceb3
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -0,0 +1,22 @@
1synopsys DWC3 CORE
2
3DWC3- USB3 CONTROLLER
4
5Required properties:
6 - compatible: must be "synopsys,dwc3"
7 - reg : Address and length of the register set for the device
8 - interrupts: Interrupts used by the dwc3 controller.
9 - usb-phy : array of phandle for the PHY device
10
11Optional properties:
12 - tx-fifo-resize: determines if the FIFO *has* to be reallocated.
13
14This is usually a subnode to DWC3 glue to which it is connected.
15
16dwc3@4a030000 {
17 compatible = "synopsys,dwc3";
18 reg = <0x4a030000 0xcfff>;
19 interrupts = <0 92 4>
20 usb-phy = <&usb2_phy>, <&usb3,phy>;
21 tx-fifo-resize;
22};
diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt
index 29a043ecda52..1ef0ce71f8fa 100644
--- a/Documentation/devicetree/bindings/usb/omap-usb.txt
+++ b/Documentation/devicetree/bindings/usb/omap-usb.txt
@@ -1,8 +1,11 @@
1OMAP GLUE 1OMAP GLUE AND OTHER OMAP SPECIFIC COMPONENTS
2 2
3OMAP MUSB GLUE 3OMAP MUSB GLUE
4 - compatible : Should be "ti,omap4-musb" or "ti,omap3-musb" 4 - compatible : Should be "ti,omap4-musb" or "ti,omap3-musb"
5 - ti,hwmods : must be "usb_otg_hs" 5 - ti,hwmods : must be "usb_otg_hs"
6 - ti,has-mailbox : to specify that omap uses an external mailbox
7 (in control module) to communicate with the musb core during device connect
8 and disconnect.
6 - multipoint : Should be "1" indicating the musb controller supports 9 - multipoint : Should be "1" indicating the musb controller supports
7 multipoint. This is a MUSB configuration-specific setting. 10 multipoint. This is a MUSB configuration-specific setting.
8 - num_eps : Specifies the number of endpoints. This is also a 11 - num_eps : Specifies the number of endpoints. This is also a
@@ -16,13 +19,19 @@ OMAP MUSB GLUE
16 - power : Should be "50". This signifies the controller can supply upto 19 - power : Should be "50". This signifies the controller can supply upto
17 100mA when operating in host mode. 20 100mA when operating in host mode.
18 21
22Optional properties:
23 - ctrl-module : phandle of the control module this glue uses to write to
24 mailbox
25
19SOC specific device node entry 26SOC specific device node entry
20usb_otg_hs: usb_otg_hs@4a0ab000 { 27usb_otg_hs: usb_otg_hs@4a0ab000 {
21 compatible = "ti,omap4-musb"; 28 compatible = "ti,omap4-musb";
22 ti,hwmods = "usb_otg_hs"; 29 ti,hwmods = "usb_otg_hs";
30 ti,has-mailbox;
23 multipoint = <1>; 31 multipoint = <1>;
24 num_eps = <16>; 32 num_eps = <16>;
25 ram_bits = <12>; 33 ram_bits = <12>;
34 ctrl-module = <&omap_control_usb>;
26}; 35};
27 36
28Board specific device node entry 37Board specific device node entry
@@ -31,3 +40,26 @@ Board specific device node entry
31 mode = <3>; 40 mode = <3>;
32 power = <50>; 41 power = <50>;
33}; 42};
43
44OMAP CONTROL USB
45
46Required properties:
47 - compatible: Should be "ti,omap-control-usb"
48 - reg : Address and length of the register set for the device. It contains
49 the address of "control_dev_conf" and "otghs_control" or "phy_power_usb"
50 depending upon omap4 or omap5.
51 - reg-names: The names of the register addresses corresponding to the registers
52 filled in "reg".
53 - ti,type: This is used to differentiate whether the control module has
54 usb mailbox or usb3 phy power. omap4 has usb mailbox in control module to
55 notify events to the musb core and omap5 has usb3 phy power register to
56 power on usb3 phy. Should be "1" if it has mailbox and "2" if it has usb3
57 phy power.
58
59omap_control_usb: omap-control-usb@4a002300 {
60 compatible = "ti,omap-control-usb";
61 reg = <0x4a002300 0x4>,
62 <0x4a00233c 0x4>;
63 reg-names = "control_dev_conf", "otghs_control";
64 ti,type = <1>;
65};
diff --git a/Documentation/devicetree/bindings/usb/samsung-usbphy.txt b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
new file mode 100644
index 000000000000..033194934f64
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung-usbphy.txt
@@ -0,0 +1,55 @@
1* Samsung's usb phy transceiver
2
3The Samsung's phy transceiver is used for controlling usb phy for
4s3c-hsotg as well as ehci-s5p and ohci-exynos usb controllers
5across Samsung SOCs.
6TODO: Adding the PHY binding with controller(s) according to the under
7developement generic PHY driver.
8
9Required properties:
10
11Exynos4210:
12- compatible : should be "samsung,exynos4210-usbphy"
13- reg : base physical address of the phy registers and length of memory mapped
14 region.
15
16Exynos5250:
17- compatible : should be "samsung,exynos5250-usbphy"
18- reg : base physical address of the phy registers and length of memory mapped
19 region.
20
21Optional properties:
22- #address-cells: should be '1' when usbphy node has a child node with 'reg'
23 property.
24- #size-cells: should be '1' when usbphy node has a child node with 'reg'
25 property.
26- ranges: allows valid translation between child's address space and parent's
27 address space.
28
29- The child node 'usbphy-sys' to the node 'usbphy' is for the system controller
30 interface for usb-phy. It should provide the following information required by
31 usb-phy controller to control phy.
32 - reg : base physical address of PHY_CONTROL registers.
33 The size of this register is the total sum of size of all PHY_CONTROL
34 registers that the SoC has. For example, the size will be
35 '0x4' in case we have only one PHY_CONTROL register (e.g.
36 OTHERS register in S3C64XX or USB_PHY_CONTROL register in S5PV210)
37 and, '0x8' in case we have two PHY_CONTROL registers (e.g.
38 USBDEVICE_PHY_CONTROL and USBHOST_PHY_CONTROL registers in exynos4x).
39 and so on.
40
41Example:
42 - Exynos4210
43
44 usbphy@125B0000 {
45 #address-cells = <1>;
46 #size-cells = <1>;
47 compatible = "samsung,exynos4210-usbphy";
48 reg = <0x125B0000 0x100>;
49 ranges;
50
51 usbphy-sys {
52 /* USB device and host PHY_CONTROL registers */
53 reg = <0x10020704 0x8>;
54 };
55 };
diff --git a/Documentation/devicetree/bindings/usb/usb-phy.txt b/Documentation/devicetree/bindings/usb/usb-phy.txt
index 80d4148cb661..61496f5cb095 100644
--- a/Documentation/devicetree/bindings/usb/usb-phy.txt
+++ b/Documentation/devicetree/bindings/usb/usb-phy.txt
@@ -4,14 +4,39 @@ OMAP USB2 PHY
4 4
5Required properties: 5Required properties:
6 - compatible: Should be "ti,omap-usb2" 6 - compatible: Should be "ti,omap-usb2"
7 - reg : Address and length of the register set for the device. Also 7 - reg : Address and length of the register set for the device.
8add the address of control module dev conf register until a driver for 8
9control module is added 9Optional properties:
10 - ctrl-module : phandle of the control module used by PHY driver to power on
11 the PHY.
10 12
11This is usually a subnode of ocp2scp to which it is connected. 13This is usually a subnode of ocp2scp to which it is connected.
12 14
13usb2phy@4a0ad080 { 15usb2phy@4a0ad080 {
14 compatible = "ti,omap-usb2"; 16 compatible = "ti,omap-usb2";
15 reg = <0x4a0ad080 0x58>, 17 reg = <0x4a0ad080 0x58>;
16 <0x4a002300 0x4>; 18 ctrl-module = <&omap_control_usb>;
19};
20
21OMAP USB3 PHY
22
23Required properties:
24 - compatible: Should be "ti,omap-usb3"
25 - reg : Address and length of the register set for the device.
26 - reg-names: The names of the register addresses corresponding to the registers
27 filled in "reg".
28
29Optional properties:
30 - ctrl-module : phandle of the control module used by PHY driver to power on
31 the PHY.
32
33This is usually a subnode of ocp2scp to which it is connected.
34
35usb3phy@4a084400 {
36 compatible = "ti,omap-usb3";
37 reg = <0x4a084400 0x80>,
38 <0x4a084800 0x64>,
39 <0x4a084c00 0x40>;
40 reg-names = "phy_rx", "phy_tx", "pll_ctrl";
41 ctrl-module = <&omap_control_usb>;
17}; 42};
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 177f4c61acab..999909451e37 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -420,13 +420,19 @@ static int dwc3_probe(struct platform_device *pdev)
420 return -ENOMEM; 420 return -ENOMEM;
421 } 421 }
422 422
423 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); 423 if (node) {
424 dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
425 dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);
426 } else {
427 dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
428 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
429 }
430
424 if (IS_ERR_OR_NULL(dwc->usb2_phy)) { 431 if (IS_ERR_OR_NULL(dwc->usb2_phy)) {
425 dev_err(dev, "no usb2 phy configured\n"); 432 dev_err(dev, "no usb2 phy configured\n");
426 return -EPROBE_DEFER; 433 return -EPROBE_DEFER;
427 } 434 }
428 435
429 dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
430 if (IS_ERR_OR_NULL(dwc->usb3_phy)) { 436 if (IS_ERR_OR_NULL(dwc->usb3_phy)) {
431 dev_err(dev, "no usb3 phy configured\n"); 437 dev_err(dev, "no usb3 phy configured\n");
432 return -EPROBE_DEFER; 438 return -EPROBE_DEFER;
@@ -453,8 +459,7 @@ static int dwc3_probe(struct platform_device *pdev)
453 else 459 else
454 dwc->maximum_speed = DWC3_DCFG_SUPERSPEED; 460 dwc->maximum_speed = DWC3_DCFG_SUPERSPEED;
455 461
456 if (of_get_property(node, "tx-fifo-resize", NULL)) 462 dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
457 dwc->needs_fifo_resize = true;
458 463
459 pm_runtime_enable(dev); 464 pm_runtime_enable(dev);
460 pm_runtime_get_sync(dev); 465 pm_runtime_get_sync(dev);
@@ -583,11 +588,22 @@ static int dwc3_remove(struct platform_device *pdev)
583 return 0; 588 return 0;
584} 589}
585 590
591#ifdef CONFIG_OF
592static const struct of_device_id of_dwc3_match[] = {
593 {
594 .compatible = "synopsys,dwc3"
595 },
596 { },
597};
598MODULE_DEVICE_TABLE(of, of_dwc3_match);
599#endif
600
586static struct platform_driver dwc3_driver = { 601static struct platform_driver dwc3_driver = {
587 .probe = dwc3_probe, 602 .probe = dwc3_probe,
588 .remove = dwc3_remove, 603 .remove = dwc3_remove,
589 .driver = { 604 .driver = {
590 .name = "dwc3", 605 .name = "dwc3",
606 .of_match_table = of_match_ptr(of_dwc3_match),
591 }, 607 },
592}; 608};
593 609
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index e1cd0f1adfb9..e97df1d094dd 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -32,6 +32,7 @@
32 32
33#include <linux/usb/ch9.h> 33#include <linux/usb/ch9.h>
34#include <linux/usb/gadget.h> 34#include <linux/usb/gadget.h>
35#include <linux/usb/phy.h>
35#include <linux/platform_data/s3c-hsotg.h> 36#include <linux/platform_data/s3c-hsotg.h>
36 37
37#include <mach/map.h> 38#include <mach/map.h>
@@ -133,7 +134,9 @@ struct s3c_hsotg_ep {
133 * struct s3c_hsotg - driver state. 134 * struct s3c_hsotg - driver state.
134 * @dev: The parent device supplied to the probe function 135 * @dev: The parent device supplied to the probe function
135 * @driver: USB gadget driver 136 * @driver: USB gadget driver
136 * @plat: The platform specific configuration data. 137 * @phy: The otg phy transceiver structure for phy control.
138 * @plat: The platform specific configuration data. This can be removed once
139 * all SoCs support usb transceiver.
137 * @regs: The memory area mapped for accessing registers. 140 * @regs: The memory area mapped for accessing registers.
138 * @irq: The IRQ number we are using 141 * @irq: The IRQ number we are using
139 * @supplies: Definition of USB power supplies 142 * @supplies: Definition of USB power supplies
@@ -153,6 +156,7 @@ struct s3c_hsotg_ep {
153struct s3c_hsotg { 156struct s3c_hsotg {
154 struct device *dev; 157 struct device *dev;
155 struct usb_gadget_driver *driver; 158 struct usb_gadget_driver *driver;
159 struct usb_phy *phy;
156 struct s3c_hsotg_plat *plat; 160 struct s3c_hsotg_plat *plat;
157 161
158 spinlock_t lock; 162 spinlock_t lock;
@@ -2854,7 +2858,10 @@ static void s3c_hsotg_phy_enable(struct s3c_hsotg *hsotg)
2854 struct platform_device *pdev = to_platform_device(hsotg->dev); 2858 struct platform_device *pdev = to_platform_device(hsotg->dev);
2855 2859
2856 dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev); 2860 dev_dbg(hsotg->dev, "pdev 0x%p\n", pdev);
2857 if (hsotg->plat->phy_init) 2861
2862 if (hsotg->phy)
2863 usb_phy_init(hsotg->phy);
2864 else if (hsotg->plat->phy_init)
2858 hsotg->plat->phy_init(pdev, hsotg->plat->phy_type); 2865 hsotg->plat->phy_init(pdev, hsotg->plat->phy_type);
2859} 2866}
2860 2867
@@ -2869,7 +2876,9 @@ static void s3c_hsotg_phy_disable(struct s3c_hsotg *hsotg)
2869{ 2876{
2870 struct platform_device *pdev = to_platform_device(hsotg->dev); 2877 struct platform_device *pdev = to_platform_device(hsotg->dev);
2871 2878
2872 if (hsotg->plat->phy_exit) 2879 if (hsotg->phy)
2880 usb_phy_shutdown(hsotg->phy);
2881 else if (hsotg->plat->phy_exit)
2873 hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type); 2882 hsotg->plat->phy_exit(pdev, hsotg->plat->phy_type);
2874} 2883}
2875 2884
@@ -3492,6 +3501,7 @@ static void s3c_hsotg_release(struct device *dev)
3492static int s3c_hsotg_probe(struct platform_device *pdev) 3501static int s3c_hsotg_probe(struct platform_device *pdev)
3493{ 3502{
3494 struct s3c_hsotg_plat *plat = pdev->dev.platform_data; 3503 struct s3c_hsotg_plat *plat = pdev->dev.platform_data;
3504 struct usb_phy *phy;
3495 struct device *dev = &pdev->dev; 3505 struct device *dev = &pdev->dev;
3496 struct s3c_hsotg_ep *eps; 3506 struct s3c_hsotg_ep *eps;
3497 struct s3c_hsotg *hsotg; 3507 struct s3c_hsotg *hsotg;
@@ -3500,20 +3510,27 @@ static int s3c_hsotg_probe(struct platform_device *pdev)
3500 int ret; 3510 int ret;
3501 int i; 3511 int i;
3502 3512
3503 plat = pdev->dev.platform_data;
3504 if (!plat) {
3505 dev_err(&pdev->dev, "no platform data defined\n");
3506 return -EINVAL;
3507 }
3508
3509 hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); 3513 hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL);
3510 if (!hsotg) { 3514 if (!hsotg) {
3511 dev_err(dev, "cannot get memory\n"); 3515 dev_err(dev, "cannot get memory\n");
3512 return -ENOMEM; 3516 return -ENOMEM;
3513 } 3517 }
3514 3518
3519 phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
3520 if (IS_ERR_OR_NULL(phy)) {
3521 /* Fallback for pdata */
3522 plat = pdev->dev.platform_data;
3523 if (!plat) {
3524 dev_err(&pdev->dev, "no platform data or transceiver defined\n");
3525 return -EPROBE_DEFER;
3526 } else {
3527 hsotg->plat = plat;
3528 }
3529 } else {
3530 hsotg->phy = phy;
3531 }
3532
3515 hsotg->dev = dev; 3533 hsotg->dev = dev;
3516 hsotg->plat = plat;
3517 3534
3518 hsotg->clk = devm_clk_get(&pdev->dev, "otg"); 3535 hsotg->clk = devm_clk_get(&pdev->dev, "otg");
3519 if (IS_ERR(hsotg->clk)) { 3536 if (IS_ERR(hsotg->clk)) {
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c
index f18e6ac081aa..20ebf6a8b7f4 100644
--- a/drivers/usb/host/ehci-s5p.c
+++ b/drivers/usb/host/ehci-s5p.c
@@ -17,6 +17,8 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/of_gpio.h> 18#include <linux/of_gpio.h>
19#include <linux/platform_data/usb-ehci-s5p.h> 19#include <linux/platform_data/usb-ehci-s5p.h>
20#include <linux/usb/phy.h>
21#include <linux/usb/samsung_usb_phy.h>
20#include <plat/usb-phy.h> 22#include <plat/usb-phy.h>
21 23
22#define EHCI_INSNREG00(base) (base + 0x90) 24#define EHCI_INSNREG00(base) (base + 0x90)
@@ -32,6 +34,9 @@ struct s5p_ehci_hcd {
32 struct device *dev; 34 struct device *dev;
33 struct usb_hcd *hcd; 35 struct usb_hcd *hcd;
34 struct clk *clk; 36 struct clk *clk;
37 struct usb_phy *phy;
38 struct usb_otg *otg;
39 struct s5p_ehci_platdata *pdata;
35}; 40};
36 41
37static const struct hc_driver s5p_ehci_hc_driver = { 42static const struct hc_driver s5p_ehci_hc_driver = {
@@ -65,6 +70,26 @@ static const struct hc_driver s5p_ehci_hc_driver = {
65 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, 70 .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
66}; 71};
67 72
73static void s5p_ehci_phy_enable(struct s5p_ehci_hcd *s5p_ehci)
74{
75 struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
76
77 if (s5p_ehci->phy)
78 usb_phy_init(s5p_ehci->phy);
79 else if (s5p_ehci->pdata->phy_init)
80 s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
81}
82
83static void s5p_ehci_phy_disable(struct s5p_ehci_hcd *s5p_ehci)
84{
85 struct platform_device *pdev = to_platform_device(s5p_ehci->dev);
86
87 if (s5p_ehci->phy)
88 usb_phy_shutdown(s5p_ehci->phy);
89 else if (s5p_ehci->pdata->phy_exit)
90 s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
91}
92
68static void s5p_setup_vbus_gpio(struct platform_device *pdev) 93static void s5p_setup_vbus_gpio(struct platform_device *pdev)
69{ 94{
70 int err; 95 int err;
@@ -87,20 +112,15 @@ static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32);
87 112
88static int s5p_ehci_probe(struct platform_device *pdev) 113static int s5p_ehci_probe(struct platform_device *pdev)
89{ 114{
90 struct s5p_ehci_platdata *pdata; 115 struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
91 struct s5p_ehci_hcd *s5p_ehci; 116 struct s5p_ehci_hcd *s5p_ehci;
92 struct usb_hcd *hcd; 117 struct usb_hcd *hcd;
93 struct ehci_hcd *ehci; 118 struct ehci_hcd *ehci;
94 struct resource *res; 119 struct resource *res;
120 struct usb_phy *phy;
95 int irq; 121 int irq;
96 int err; 122 int err;
97 123
98 pdata = pdev->dev.platform_data;
99 if (!pdata) {
100 dev_err(&pdev->dev, "No platform data defined\n");
101 return -EINVAL;
102 }
103
104 /* 124 /*
105 * Right now device-tree probed devices don't get dma_mask set. 125 * Right now device-tree probed devices don't get dma_mask set.
106 * Since shared usb code relies on it, set it here for now. 126 * Since shared usb code relies on it, set it here for now.
@@ -118,6 +138,20 @@ static int s5p_ehci_probe(struct platform_device *pdev)
118 if (!s5p_ehci) 138 if (!s5p_ehci)
119 return -ENOMEM; 139 return -ENOMEM;
120 140
141 phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
142 if (IS_ERR_OR_NULL(phy)) {
143 /* Fallback to pdata */
144 if (!pdata) {
145 dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
146 return -EPROBE_DEFER;
147 } else {
148 s5p_ehci->pdata = pdata;
149 }
150 } else {
151 s5p_ehci->phy = phy;
152 s5p_ehci->otg = phy->otg;
153 }
154
121 s5p_ehci->dev = &pdev->dev; 155 s5p_ehci->dev = &pdev->dev;
122 156
123 hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev, 157 hcd = usb_create_hcd(&s5p_ehci_hc_driver, &pdev->dev,
@@ -163,8 +197,10 @@ static int s5p_ehci_probe(struct platform_device *pdev)
163 goto fail_io; 197 goto fail_io;
164 } 198 }
165 199
166 if (pdata->phy_init) 200 if (s5p_ehci->otg)
167 pdata->phy_init(pdev, S5P_USB_PHY_HOST); 201 s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self);
202
203 s5p_ehci_phy_enable(s5p_ehci);
168 204
169 ehci = hcd_to_ehci(hcd); 205 ehci = hcd_to_ehci(hcd);
170 ehci->caps = hcd->regs; 206 ehci->caps = hcd->regs;
@@ -175,13 +211,15 @@ static int s5p_ehci_probe(struct platform_device *pdev)
175 err = usb_add_hcd(hcd, irq, IRQF_SHARED); 211 err = usb_add_hcd(hcd, irq, IRQF_SHARED);
176 if (err) { 212 if (err) {
177 dev_err(&pdev->dev, "Failed to add USB HCD\n"); 213 dev_err(&pdev->dev, "Failed to add USB HCD\n");
178 goto fail_io; 214 goto fail_add_hcd;
179 } 215 }
180 216
181 platform_set_drvdata(pdev, s5p_ehci); 217 platform_set_drvdata(pdev, s5p_ehci);
182 218
183 return 0; 219 return 0;
184 220
221fail_add_hcd:
222 s5p_ehci_phy_disable(s5p_ehci);
185fail_io: 223fail_io:
186 clk_disable_unprepare(s5p_ehci->clk); 224 clk_disable_unprepare(s5p_ehci->clk);
187fail_clk: 225fail_clk:
@@ -191,14 +229,15 @@ fail_clk:
191 229
192static int s5p_ehci_remove(struct platform_device *pdev) 230static int s5p_ehci_remove(struct platform_device *pdev)
193{ 231{
194 struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
195 struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); 232 struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev);
196 struct usb_hcd *hcd = s5p_ehci->hcd; 233 struct usb_hcd *hcd = s5p_ehci->hcd;
197 234
198 usb_remove_hcd(hcd); 235 usb_remove_hcd(hcd);
199 236
200 if (pdata && pdata->phy_exit) 237 if (s5p_ehci->otg)
201 pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 238 s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self);
239
240 s5p_ehci_phy_disable(s5p_ehci);
202 241
203 clk_disable_unprepare(s5p_ehci->clk); 242 clk_disable_unprepare(s5p_ehci->clk);
204 243
@@ -222,14 +261,14 @@ static int s5p_ehci_suspend(struct device *dev)
222 struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev); 261 struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
223 struct usb_hcd *hcd = s5p_ehci->hcd; 262 struct usb_hcd *hcd = s5p_ehci->hcd;
224 bool do_wakeup = device_may_wakeup(dev); 263 bool do_wakeup = device_may_wakeup(dev);
225 struct platform_device *pdev = to_platform_device(dev);
226 struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
227 int rc; 264 int rc;
228 265
229 rc = ehci_suspend(hcd, do_wakeup); 266 rc = ehci_suspend(hcd, do_wakeup);
230 267
231 if (pdata && pdata->phy_exit) 268 if (s5p_ehci->otg)
232 pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 269 s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self);
270
271 s5p_ehci_phy_disable(s5p_ehci);
233 272
234 clk_disable_unprepare(s5p_ehci->clk); 273 clk_disable_unprepare(s5p_ehci->clk);
235 274
@@ -240,13 +279,13 @@ static int s5p_ehci_resume(struct device *dev)
240{ 279{
241 struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev); 280 struct s5p_ehci_hcd *s5p_ehci = dev_get_drvdata(dev);
242 struct usb_hcd *hcd = s5p_ehci->hcd; 281 struct usb_hcd *hcd = s5p_ehci->hcd;
243 struct platform_device *pdev = to_platform_device(dev);
244 struct s5p_ehci_platdata *pdata = pdev->dev.platform_data;
245 282
246 clk_prepare_enable(s5p_ehci->clk); 283 clk_prepare_enable(s5p_ehci->clk);
247 284
248 if (pdata && pdata->phy_init) 285 if (s5p_ehci->otg)
249 pdata->phy_init(pdev, S5P_USB_PHY_HOST); 286 s5p_ehci->otg->set_host(s5p_ehci->otg, &s5p_ehci->hcd->self);
287
288 s5p_ehci_phy_enable(s5p_ehci);
250 289
251 /* DMA burst Enable */ 290 /* DMA burst Enable */
252 writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); 291 writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c
index 77f2017c33c4..e3b7e85120e4 100644
--- a/drivers/usb/host/ohci-exynos.c
+++ b/drivers/usb/host/ohci-exynos.c
@@ -15,14 +15,39 @@
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/platform_data/usb-exynos.h> 17#include <linux/platform_data/usb-exynos.h>
18#include <linux/usb/phy.h>
19#include <linux/usb/samsung_usb_phy.h>
18#include <plat/usb-phy.h> 20#include <plat/usb-phy.h>
19 21
20struct exynos_ohci_hcd { 22struct exynos_ohci_hcd {
21 struct device *dev; 23 struct device *dev;
22 struct usb_hcd *hcd; 24 struct usb_hcd *hcd;
23 struct clk *clk; 25 struct clk *clk;
26 struct usb_phy *phy;
27 struct usb_otg *otg;
28 struct exynos4_ohci_platdata *pdata;
24}; 29};
25 30
31static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci)
32{
33 struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
34
35 if (exynos_ohci->phy)
36 usb_phy_init(exynos_ohci->phy);
37 else if (exynos_ohci->pdata->phy_init)
38 exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST);
39}
40
41static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci)
42{
43 struct platform_device *pdev = to_platform_device(exynos_ohci->dev);
44
45 if (exynos_ohci->phy)
46 usb_phy_shutdown(exynos_ohci->phy);
47 else if (exynos_ohci->pdata->phy_exit)
48 exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST);
49}
50
26static int ohci_exynos_reset(struct usb_hcd *hcd) 51static int ohci_exynos_reset(struct usb_hcd *hcd)
27{ 52{
28 return ohci_init(hcd_to_ohci(hcd)); 53 return ohci_init(hcd_to_ohci(hcd));
@@ -78,20 +103,15 @@ static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32);
78 103
79static int exynos_ohci_probe(struct platform_device *pdev) 104static int exynos_ohci_probe(struct platform_device *pdev)
80{ 105{
81 struct exynos4_ohci_platdata *pdata; 106 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
82 struct exynos_ohci_hcd *exynos_ohci; 107 struct exynos_ohci_hcd *exynos_ohci;
83 struct usb_hcd *hcd; 108 struct usb_hcd *hcd;
84 struct ohci_hcd *ohci; 109 struct ohci_hcd *ohci;
85 struct resource *res; 110 struct resource *res;
111 struct usb_phy *phy;
86 int irq; 112 int irq;
87 int err; 113 int err;
88 114
89 pdata = pdev->dev.platform_data;
90 if (!pdata) {
91 dev_err(&pdev->dev, "No platform data defined\n");
92 return -EINVAL;
93 }
94
95 /* 115 /*
96 * Right now device-tree probed devices don't get dma_mask set. 116 * Right now device-tree probed devices don't get dma_mask set.
97 * Since shared usb code relies on it, set it here for now. 117 * Since shared usb code relies on it, set it here for now.
@@ -107,6 +127,20 @@ static int exynos_ohci_probe(struct platform_device *pdev)
107 if (!exynos_ohci) 127 if (!exynos_ohci)
108 return -ENOMEM; 128 return -ENOMEM;
109 129
130 phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
131 if (IS_ERR_OR_NULL(phy)) {
132 /* Fallback to pdata */
133 if (!pdata) {
134 dev_warn(&pdev->dev, "no platform data or transceiver defined\n");
135 return -EPROBE_DEFER;
136 } else {
137 exynos_ohci->pdata = pdata;
138 }
139 } else {
140 exynos_ohci->phy = phy;
141 exynos_ohci->otg = phy->otg;
142 }
143
110 exynos_ohci->dev = &pdev->dev; 144 exynos_ohci->dev = &pdev->dev;
111 145
112 hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, 146 hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev,
@@ -152,8 +186,11 @@ static int exynos_ohci_probe(struct platform_device *pdev)
152 goto fail_io; 186 goto fail_io;
153 } 187 }
154 188
155 if (pdata->phy_init) 189 if (exynos_ohci->otg)
156 pdata->phy_init(pdev, S5P_USB_PHY_HOST); 190 exynos_ohci->otg->set_host(exynos_ohci->otg,
191 &exynos_ohci->hcd->self);
192
193 exynos_ohci_phy_enable(exynos_ohci);
157 194
158 ohci = hcd_to_ohci(hcd); 195 ohci = hcd_to_ohci(hcd);
159 ohci_hcd_init(ohci); 196 ohci_hcd_init(ohci);
@@ -161,13 +198,15 @@ static int exynos_ohci_probe(struct platform_device *pdev)
161 err = usb_add_hcd(hcd, irq, IRQF_SHARED); 198 err = usb_add_hcd(hcd, irq, IRQF_SHARED);
162 if (err) { 199 if (err) {
163 dev_err(&pdev->dev, "Failed to add USB HCD\n"); 200 dev_err(&pdev->dev, "Failed to add USB HCD\n");
164 goto fail_io; 201 goto fail_add_hcd;
165 } 202 }
166 203
167 platform_set_drvdata(pdev, exynos_ohci); 204 platform_set_drvdata(pdev, exynos_ohci);
168 205
169 return 0; 206 return 0;
170 207
208fail_add_hcd:
209 exynos_ohci_phy_disable(exynos_ohci);
171fail_io: 210fail_io:
172 clk_disable_unprepare(exynos_ohci->clk); 211 clk_disable_unprepare(exynos_ohci->clk);
173fail_clk: 212fail_clk:
@@ -177,14 +216,16 @@ fail_clk:
177 216
178static int exynos_ohci_remove(struct platform_device *pdev) 217static int exynos_ohci_remove(struct platform_device *pdev)
179{ 218{
180 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
181 struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); 219 struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev);
182 struct usb_hcd *hcd = exynos_ohci->hcd; 220 struct usb_hcd *hcd = exynos_ohci->hcd;
183 221
184 usb_remove_hcd(hcd); 222 usb_remove_hcd(hcd);
185 223
186 if (pdata && pdata->phy_exit) 224 if (exynos_ohci->otg)
187 pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 225 exynos_ohci->otg->set_host(exynos_ohci->otg,
226 &exynos_ohci->hcd->self);
227
228 exynos_ohci_phy_disable(exynos_ohci);
188 229
189 clk_disable_unprepare(exynos_ohci->clk); 230 clk_disable_unprepare(exynos_ohci->clk);
190 231
@@ -208,8 +249,6 @@ static int exynos_ohci_suspend(struct device *dev)
208 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); 249 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
209 struct usb_hcd *hcd = exynos_ohci->hcd; 250 struct usb_hcd *hcd = exynos_ohci->hcd;
210 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 251 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
211 struct platform_device *pdev = to_platform_device(dev);
212 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
213 unsigned long flags; 252 unsigned long flags;
214 int rc = 0; 253 int rc = 0;
215 254
@@ -228,8 +267,11 @@ static int exynos_ohci_suspend(struct device *dev)
228 267
229 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 268 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
230 269
231 if (pdata && pdata->phy_exit) 270 if (exynos_ohci->otg)
232 pdata->phy_exit(pdev, S5P_USB_PHY_HOST); 271 exynos_ohci->otg->set_host(exynos_ohci->otg,
272 &exynos_ohci->hcd->self);
273
274 exynos_ohci_phy_disable(exynos_ohci);
233 275
234 clk_disable_unprepare(exynos_ohci->clk); 276 clk_disable_unprepare(exynos_ohci->clk);
235 277
@@ -243,13 +285,14 @@ static int exynos_ohci_resume(struct device *dev)
243{ 285{
244 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); 286 struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev);
245 struct usb_hcd *hcd = exynos_ohci->hcd; 287 struct usb_hcd *hcd = exynos_ohci->hcd;
246 struct platform_device *pdev = to_platform_device(dev);
247 struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data;
248 288
249 clk_prepare_enable(exynos_ohci->clk); 289 clk_prepare_enable(exynos_ohci->clk);
250 290
251 if (pdata && pdata->phy_init) 291 if (exynos_ohci->otg)
252 pdata->phy_init(pdev, S5P_USB_PHY_HOST); 292 exynos_ohci->otg->set_host(exynos_ohci->otg,
293 &exynos_ohci->hcd->self);
294
295 exynos_ohci_phy_enable(exynos_ohci);
253 296
254 ohci_resume(hcd, false); 297 ohci_resume(hcd, false);
255 298
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 23a0b7f0892d..de6e5ce26316 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC
11 select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) 11 select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX)
12 select TWL4030_USB if MACH_OMAP_3430SDP 12 select TWL4030_USB if MACH_OMAP_3430SDP
13 select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA 13 select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
14 select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
14 select USB_OTG_UTILS 15 select USB_OTG_UTILS
15 help 16 help
16 Say Y here if your system has a dual role high speed USB 17 Say Y here if your system has a dual role high speed USB
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index bb48796e5213..1762354fe793 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -37,6 +37,7 @@
37#include <linux/err.h> 37#include <linux/err.h>
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/usb/musb-omap.h> 39#include <linux/usb/musb-omap.h>
40#include <linux/usb/omap_control_usb.h>
40 41
41#include "musb_core.h" 42#include "musb_core.h"
42#include "omap2430.h" 43#include "omap2430.h"
@@ -46,7 +47,7 @@ struct omap2430_glue {
46 struct platform_device *musb; 47 struct platform_device *musb;
47 enum omap_musb_vbus_id_status status; 48 enum omap_musb_vbus_id_status status;
48 struct work_struct omap_musb_mailbox_work; 49 struct work_struct omap_musb_mailbox_work;
49 u32 __iomem *control_otghs; 50 struct device *control_otghs;
50}; 51};
51#define glue_to_musb(g) platform_get_drvdata(g->musb) 52#define glue_to_musb(g) platform_get_drvdata(g->musb)
52 53
@@ -54,26 +55,6 @@ struct omap2430_glue *_glue;
54 55
55static struct timer_list musb_idle_timer; 56static struct timer_list musb_idle_timer;
56 57
57/**
58 * omap4_usb_phy_mailbox - write to usb otg mailbox
59 * @glue: struct omap2430_glue *
60 * @val: the value to be written to the mailbox
61 *
62 * On detection of a device (ID pin is grounded), this API should be called
63 * to set AVALID, VBUSVALID and ID pin is grounded.
64 *
65 * When OMAP is connected to a host (OMAP in device mode), this API
66 * is called to set AVALID, VBUSVALID and ID pin in high impedance.
67 *
68 * XXX: This function will be removed once we have a seperate driver for
69 * control module
70 */
71static void omap4_usb_phy_mailbox(struct omap2430_glue *glue, u32 val)
72{
73 if (glue->control_otghs)
74 writel(val, glue->control_otghs);
75}
76
77static void musb_do_idle(unsigned long _musb) 58static void musb_do_idle(unsigned long _musb)
78{ 59{
79 struct musb *musb = (void *)_musb; 60 struct musb *musb = (void *)_musb;
@@ -269,7 +250,6 @@ EXPORT_SYMBOL_GPL(omap_musb_mailbox);
269 250
270static void omap_musb_set_mailbox(struct omap2430_glue *glue) 251static void omap_musb_set_mailbox(struct omap2430_glue *glue)
271{ 252{
272 u32 val;
273 struct musb *musb = glue_to_musb(glue); 253 struct musb *musb = glue_to_musb(glue);
274 struct device *dev = musb->controller; 254 struct device *dev = musb->controller;
275 struct musb_hdrc_platform_data *pdata = dev->platform_data; 255 struct musb_hdrc_platform_data *pdata = dev->platform_data;
@@ -285,8 +265,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
285 musb->xceiv->last_event = USB_EVENT_ID; 265 musb->xceiv->last_event = USB_EVENT_ID;
286 if (musb->gadget_driver) { 266 if (musb->gadget_driver) {
287 pm_runtime_get_sync(dev); 267 pm_runtime_get_sync(dev);
288 val = AVALID | VBUSVALID; 268 omap_control_usb_set_mode(glue->control_otghs,
289 omap4_usb_phy_mailbox(glue, val); 269 USB_MODE_HOST);
290 omap2430_musb_set_vbus(musb, 1); 270 omap2430_musb_set_vbus(musb, 1);
291 } 271 }
292 break; 272 break;
@@ -299,8 +279,7 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
299 musb->xceiv->last_event = USB_EVENT_VBUS; 279 musb->xceiv->last_event = USB_EVENT_VBUS;
300 if (musb->gadget_driver) 280 if (musb->gadget_driver)
301 pm_runtime_get_sync(dev); 281 pm_runtime_get_sync(dev);
302 val = IDDIG | AVALID | VBUSVALID; 282 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
303 omap4_usb_phy_mailbox(glue, val);
304 break; 283 break;
305 284
306 case OMAP_MUSB_ID_FLOAT: 285 case OMAP_MUSB_ID_FLOAT:
@@ -317,8 +296,8 @@ static void omap_musb_set_mailbox(struct omap2430_glue *glue)
317 if (musb->xceiv->otg->set_vbus) 296 if (musb->xceiv->otg->set_vbus)
318 otg_set_vbus(musb->xceiv->otg, 0); 297 otg_set_vbus(musb->xceiv->otg, 0);
319 } 298 }
320 val = SESSEND | IDDIG; 299 omap_control_usb_set_mode(glue->control_otghs,
321 omap4_usb_phy_mailbox(glue, val); 300 USB_MODE_DISCONNECT);
322 break; 301 break;
323 default: 302 default:
324 dev_dbg(dev, "ID float\n"); 303 dev_dbg(dev, "ID float\n");
@@ -366,7 +345,12 @@ static int omap2430_musb_init(struct musb *musb)
366 * up through ULPI. TWL4030-family PMICs include one, 345 * up through ULPI. TWL4030-family PMICs include one,
367 * which needs a driver, drivers aren't always needed. 346 * which needs a driver, drivers aren't always needed.
368 */ 347 */
369 musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); 348 if (dev->parent->of_node)
349 musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
350 "usb-phy", 0);
351 else
352 musb->xceiv = devm_usb_get_phy_dev(dev, 0);
353
370 if (IS_ERR_OR_NULL(musb->xceiv)) { 354 if (IS_ERR_OR_NULL(musb->xceiv)) {
371 pr_err("HS USB OTG: no transceiver configured\n"); 355 pr_err("HS USB OTG: no transceiver configured\n");
372 return -EPROBE_DEFER; 356 return -EPROBE_DEFER;
@@ -415,7 +399,6 @@ err1:
415static void omap2430_musb_enable(struct musb *musb) 399static void omap2430_musb_enable(struct musb *musb)
416{ 400{
417 u8 devctl; 401 u8 devctl;
418 u32 val;
419 unsigned long timeout = jiffies + msecs_to_jiffies(1000); 402 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
420 struct device *dev = musb->controller; 403 struct device *dev = musb->controller;
421 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 404 struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
@@ -425,8 +408,7 @@ static void omap2430_musb_enable(struct musb *musb)
425 switch (glue->status) { 408 switch (glue->status) {
426 409
427 case OMAP_MUSB_ID_GROUND: 410 case OMAP_MUSB_ID_GROUND:
428 val = AVALID | VBUSVALID; 411 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_HOST);
429 omap4_usb_phy_mailbox(glue, val);
430 if (data->interface_type != MUSB_INTERFACE_UTMI) 412 if (data->interface_type != MUSB_INTERFACE_UTMI)
431 break; 413 break;
432 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); 414 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
@@ -445,8 +427,7 @@ static void omap2430_musb_enable(struct musb *musb)
445 break; 427 break;
446 428
447 case OMAP_MUSB_VBUS_VALID: 429 case OMAP_MUSB_VBUS_VALID:
448 val = IDDIG | AVALID | VBUSVALID; 430 omap_control_usb_set_mode(glue->control_otghs, USB_MODE_DEVICE);
449 omap4_usb_phy_mailbox(glue, val);
450 break; 431 break;
451 432
452 default: 433 default:
@@ -456,14 +437,12 @@ static void omap2430_musb_enable(struct musb *musb)
456 437
457static void omap2430_musb_disable(struct musb *musb) 438static void omap2430_musb_disable(struct musb *musb)
458{ 439{
459 u32 val;
460 struct device *dev = musb->controller; 440 struct device *dev = musb->controller;
461 struct omap2430_glue *glue = dev_get_drvdata(dev->parent); 441 struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
462 442
463 if (glue->status != OMAP_MUSB_UNKNOWN) { 443 if (glue->status != OMAP_MUSB_UNKNOWN)
464 val = SESSEND | IDDIG; 444 omap_control_usb_set_mode(glue->control_otghs,
465 omap4_usb_phy_mailbox(glue, val); 445 USB_MODE_DISCONNECT);
466 }
467} 446}
468 447
469static int omap2430_musb_exit(struct musb *musb) 448static int omap2430_musb_exit(struct musb *musb)
@@ -498,7 +477,6 @@ static int omap2430_probe(struct platform_device *pdev)
498 struct omap2430_glue *glue; 477 struct omap2430_glue *glue;
499 struct device_node *np = pdev->dev.of_node; 478 struct device_node *np = pdev->dev.of_node;
500 struct musb_hdrc_config *config; 479 struct musb_hdrc_config *config;
501 struct resource *res;
502 int ret = -ENOMEM; 480 int ret = -ENOMEM;
503 481
504 glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); 482 glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
@@ -521,12 +499,6 @@ static int omap2430_probe(struct platform_device *pdev)
521 glue->musb = musb; 499 glue->musb = musb;
522 glue->status = OMAP_MUSB_UNKNOWN; 500 glue->status = OMAP_MUSB_UNKNOWN;
523 501
524 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
525
526 glue->control_otghs = devm_request_and_ioremap(&pdev->dev, res);
527 if (glue->control_otghs == NULL)
528 dev_dbg(&pdev->dev, "Failed to obtain control memory\n");
529
530 if (np) { 502 if (np) {
531 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 503 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
532 if (!pdata) { 504 if (!pdata) {
@@ -556,11 +528,22 @@ static int omap2430_probe(struct platform_device *pdev)
556 of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits); 528 of_property_read_u32(np, "ram_bits", (u32 *)&config->ram_bits);
557 of_property_read_u32(np, "power", (u32 *)&pdata->power); 529 of_property_read_u32(np, "power", (u32 *)&pdata->power);
558 config->multipoint = of_property_read_bool(np, "multipoint"); 530 config->multipoint = of_property_read_bool(np, "multipoint");
531 pdata->has_mailbox = of_property_read_bool(np,
532 "ti,has-mailbox");
559 533
560 pdata->board_data = data; 534 pdata->board_data = data;
561 pdata->config = config; 535 pdata->config = config;
562 } 536 }
563 537
538 if (pdata->has_mailbox) {
539 glue->control_otghs = omap_get_control_dev();
540 if (IS_ERR(glue->control_otghs)) {
541 dev_vdbg(&pdev->dev, "Failed to get control device\n");
542 return -ENODEV;
543 }
544 } else {
545 glue->control_otghs = ERR_PTR(-ENODEV);
546 }
564 pdata->platform_ops = &omap2430_ops; 547 pdata->platform_ops = &omap2430_ops;
565 548
566 platform_set_drvdata(pdev, glue); 549 platform_set_drvdata(pdev, glue);
diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h
index 8ef656659fcb..1b5e83a9840e 100644
--- a/drivers/usb/musb/omap2430.h
+++ b/drivers/usb/musb/omap2430.h
@@ -49,13 +49,4 @@
49#define OTG_FORCESTDBY 0x414 49#define OTG_FORCESTDBY 0x414
50# define ENABLEFORCE (1 << 0) 50# define ENABLEFORCE (1 << 0)
51 51
52/*
53 * Control Module bit definitions
54 * XXX: Will be removed once we have a driver for control module.
55 */
56#define AVALID BIT(0)
57#define BVALID BIT(1)
58#define VBUSVALID BIT(2)
59#define SESSEND BIT(3)
60#define IDDIG BIT(4)
61#endif /* __MUSB_OMAP243X_H__ */ 52#endif /* __MUSB_OMAP243X_H__ */
diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c
index da2d60c06f15..b6a9be31133b 100644
--- a/drivers/usb/otg/mv_otg.c
+++ b/drivers/usb/otg/mv_otg.c
@@ -420,7 +420,7 @@ static void mv_otg_work(struct work_struct *work)
420 struct usb_otg *otg; 420 struct usb_otg *otg;
421 int old_state; 421 int old_state;
422 422
423 mvotg = container_of((struct delayed_work *)work, struct mv_otg, work); 423 mvotg = container_of(to_delayed_work(work), struct mv_otg, work);
424 424
425run: 425run:
426 /* work queue is single thread, or we need spin_lock to protect */ 426 /* work queue is single thread, or we need spin_lock to protect */
diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index 76302720055a..5158332522b1 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -76,6 +76,25 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
76 clk_disable_unprepare(mxs_phy->clk); 76 clk_disable_unprepare(mxs_phy->clk);
77} 77}
78 78
79static int mxs_phy_suspend(struct usb_phy *x, int suspend)
80{
81 struct mxs_phy *mxs_phy = to_mxs_phy(x);
82
83 if (suspend) {
84 writel_relaxed(0xffffffff, x->io_priv + HW_USBPHY_PWD);
85 writel_relaxed(BM_USBPHY_CTRL_CLKGATE,
86 x->io_priv + HW_USBPHY_CTRL_SET);
87 clk_disable_unprepare(mxs_phy->clk);
88 } else {
89 clk_prepare_enable(mxs_phy->clk);
90 writel_relaxed(BM_USBPHY_CTRL_CLKGATE,
91 x->io_priv + HW_USBPHY_CTRL_CLR);
92 writel_relaxed(0, x->io_priv + HW_USBPHY_PWD);
93 }
94
95 return 0;
96}
97
79static int mxs_phy_on_connect(struct usb_phy *phy, 98static int mxs_phy_on_connect(struct usb_phy *phy,
80 enum usb_device_speed speed) 99 enum usb_device_speed speed)
81{ 100{
@@ -137,6 +156,7 @@ static int mxs_phy_probe(struct platform_device *pdev)
137 mxs_phy->phy.label = DRIVER_NAME; 156 mxs_phy->phy.label = DRIVER_NAME;
138 mxs_phy->phy.init = mxs_phy_init; 157 mxs_phy->phy.init = mxs_phy_init;
139 mxs_phy->phy.shutdown = mxs_phy_shutdown; 158 mxs_phy->phy.shutdown = mxs_phy_shutdown;
159 mxs_phy->phy.set_suspend = mxs_phy_suspend;
140 mxs_phy->phy.notify_connect = mxs_phy_on_connect; 160 mxs_phy->phy.notify_connect = mxs_phy_on_connect;
141 mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect; 161 mxs_phy->phy.notify_disconnect = mxs_phy_on_disconnect;
142 162
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c
index a30c04115115..e1814397ca3a 100644
--- a/drivers/usb/otg/otg.c
+++ b/drivers/usb/otg/otg.c
@@ -13,11 +13,14 @@
13#include <linux/export.h> 13#include <linux/export.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/module.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/of.h>
17 19
18#include <linux/usb/otg.h> 20#include <linux/usb/otg.h>
19 21
20static LIST_HEAD(phy_list); 22static LIST_HEAD(phy_list);
23static LIST_HEAD(phy_bind_list);
21static DEFINE_SPINLOCK(phy_lock); 24static DEFINE_SPINLOCK(phy_lock);
22 25
23static struct usb_phy *__usb_find_phy(struct list_head *list, 26static struct usb_phy *__usb_find_phy(struct list_head *list,
@@ -35,6 +38,38 @@ static struct usb_phy *__usb_find_phy(struct list_head *list,
35 return ERR_PTR(-ENODEV); 38 return ERR_PTR(-ENODEV);
36} 39}
37 40
41static struct usb_phy *__usb_find_phy_dev(struct device *dev,
42 struct list_head *list, u8 index)
43{
44 struct usb_phy_bind *phy_bind = NULL;
45
46 list_for_each_entry(phy_bind, list, list) {
47 if (!(strcmp(phy_bind->dev_name, dev_name(dev))) &&
48 phy_bind->index == index) {
49 if (phy_bind->phy)
50 return phy_bind->phy;
51 else
52 return ERR_PTR(-EPROBE_DEFER);
53 }
54 }
55
56 return ERR_PTR(-ENODEV);
57}
58
59static struct usb_phy *__of_usb_find_phy(struct device_node *node)
60{
61 struct usb_phy *phy;
62
63 list_for_each_entry(phy, &phy_list, head) {
64 if (node != phy->dev->of_node)
65 continue;
66
67 return phy;
68 }
69
70 return ERR_PTR(-ENODEV);
71}
72
38static void devm_usb_phy_release(struct device *dev, void *res) 73static void devm_usb_phy_release(struct device *dev, void *res)
39{ 74{
40 struct usb_phy *phy = *(struct usb_phy **)res; 75 struct usb_phy *phy = *(struct usb_phy **)res;
@@ -110,6 +145,133 @@ err0:
110} 145}
111EXPORT_SYMBOL(usb_get_phy); 146EXPORT_SYMBOL(usb_get_phy);
112 147
148 /**
149 * devm_usb_get_phy_by_phandle - find the USB PHY by phandle
150 * @dev - device that requests this phy
151 * @phandle - name of the property holding the phy phandle value
152 * @index - the index of the phy
153 *
154 * Returns the phy driver associated with the given phandle value,
155 * after getting a refcount to it, -ENODEV if there is no such phy or
156 * -EPROBE_DEFER if there is a phandle to the phy, but the device is
157 * not yet loaded. While at that, it also associates the device with
158 * the phy using devres. On driver detach, release function is invoked
159 * on the devres data, then, devres data is freed.
160 *
161 * For use by USB host and peripheral drivers.
162 */
163struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
164 const char *phandle, u8 index)
165{
166 struct usb_phy *phy = ERR_PTR(-ENOMEM), **ptr;
167 unsigned long flags;
168 struct device_node *node;
169
170 if (!dev->of_node) {
171 dev_dbg(dev, "device does not have a device node entry\n");
172 return ERR_PTR(-EINVAL);
173 }
174
175 node = of_parse_phandle(dev->of_node, phandle, index);
176 if (!node) {
177 dev_dbg(dev, "failed to get %s phandle in %s node\n", phandle,
178 dev->of_node->full_name);
179 return ERR_PTR(-ENODEV);
180 }
181
182 ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
183 if (!ptr) {
184 dev_dbg(dev, "failed to allocate memory for devres\n");
185 goto err0;
186 }
187
188 spin_lock_irqsave(&phy_lock, flags);
189
190 phy = __of_usb_find_phy(node);
191 if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) {
192 phy = ERR_PTR(-EPROBE_DEFER);
193 devres_free(ptr);
194 goto err1;
195 }
196
197 *ptr = phy;
198 devres_add(dev, ptr);
199
200 get_device(phy->dev);
201
202err1:
203 spin_unlock_irqrestore(&phy_lock, flags);
204
205err0:
206 of_node_put(node);
207
208 return phy;
209}
210EXPORT_SYMBOL(devm_usb_get_phy_by_phandle);
211
212/**
213 * usb_get_phy_dev - find the USB PHY
214 * @dev - device that requests this phy
215 * @index - the index of the phy
216 *
217 * Returns the phy driver, after getting a refcount to it; or
218 * -ENODEV if there is no such phy. The caller is responsible for
219 * calling usb_put_phy() to release that count.
220 *
221 * For use by USB host and peripheral drivers.
222 */
223struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
224{
225 struct usb_phy *phy = NULL;
226 unsigned long flags;
227
228 spin_lock_irqsave(&phy_lock, flags);
229
230 phy = __usb_find_phy_dev(dev, &phy_bind_list, index);
231 if (IS_ERR(phy)) {
232 pr_err("unable to find transceiver\n");
233 goto err0;
234 }
235
236 get_device(phy->dev);
237
238err0:
239 spin_unlock_irqrestore(&phy_lock, flags);
240
241 return phy;
242}
243EXPORT_SYMBOL(usb_get_phy_dev);
244
245/**
246 * devm_usb_get_phy_dev - find the USB PHY using device ptr and index
247 * @dev - device that requests this phy
248 * @index - the index of the phy
249 *
250 * Gets the phy using usb_get_phy_dev(), and associates a device with it using
251 * devres. On driver detach, release function is invoked on the devres data,
252 * then, devres data is freed.
253 *
254 * For use by USB host and peripheral drivers.
255 */
256struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index)
257{
258 struct usb_phy **ptr, *phy;
259
260 ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL);
261 if (!ptr)
262 return NULL;
263
264 phy = usb_get_phy_dev(dev, index);
265 if (!IS_ERR(phy)) {
266 *ptr = phy;
267 devres_add(dev, ptr);
268 } else
269 devres_free(ptr);
270
271 return phy;
272}
273EXPORT_SYMBOL(devm_usb_get_phy_dev);
274
113/** 275/**
114 * devm_usb_put_phy - release the USB PHY 276 * devm_usb_put_phy - release the USB PHY
115 * @dev - device that wants to release this phy 277 * @dev - device that wants to release this phy
@@ -185,6 +347,36 @@ out:
185EXPORT_SYMBOL(usb_add_phy); 347EXPORT_SYMBOL(usb_add_phy);
186 348
187/** 349/**
350 * usb_add_phy_dev - declare the USB PHY
351 * @x: the USB phy to be used; or NULL
352 *
353 * This call is exclusively for use by phy drivers, which
354 * coordinate the activities of drivers for host and peripheral
355 * controllers, and in some cases for VBUS current regulation.
356 */
357int usb_add_phy_dev(struct usb_phy *x)
358{
359 struct usb_phy_bind *phy_bind;
360 unsigned long flags;
361
362 if (!x->dev) {
363 dev_err(x->dev, "no device provided for PHY\n");
364 return -EINVAL;
365 }
366
367 spin_lock_irqsave(&phy_lock, flags);
368 list_for_each_entry(phy_bind, &phy_bind_list, list)
369 if (!(strcmp(phy_bind->phy_dev_name, dev_name(x->dev))))
370 phy_bind->phy = x;
371
372 list_add_tail(&x->head, &phy_list);
373
374 spin_unlock_irqrestore(&phy_lock, flags);
375 return 0;
376}
377EXPORT_SYMBOL(usb_add_phy_dev);
378
379/**
188 * usb_remove_phy - remove the OTG PHY 380 * usb_remove_phy - remove the OTG PHY
189 * @x: the USB OTG PHY to be removed; 381 * @x: the USB OTG PHY to be removed;
190 * 382 *
@@ -193,14 +385,55 @@ EXPORT_SYMBOL(usb_add_phy);
193void usb_remove_phy(struct usb_phy *x) 385void usb_remove_phy(struct usb_phy *x)
194{ 386{
195 unsigned long flags; 387 unsigned long flags;
388 struct usb_phy_bind *phy_bind;
196 389
197 spin_lock_irqsave(&phy_lock, flags); 390 spin_lock_irqsave(&phy_lock, flags);
198 if (x) 391 if (x) {
392 list_for_each_entry(phy_bind, &phy_bind_list, list)
393 if (phy_bind->phy == x)
394 phy_bind->phy = NULL;
199 list_del(&x->head); 395 list_del(&x->head);
396 }
200 spin_unlock_irqrestore(&phy_lock, flags); 397 spin_unlock_irqrestore(&phy_lock, flags);
201} 398}
202EXPORT_SYMBOL(usb_remove_phy); 399EXPORT_SYMBOL(usb_remove_phy);
203 400
401/**
402 * usb_bind_phy - bind the phy and the controller that uses the phy
403 * @dev_name: the device name of the device that will bind to the phy
404 * @index: index to specify the port number
405 * @phy_dev_name: the device name of the phy
406 *
407 * Fills the phy_bind structure with the dev_name and phy_dev_name. This will
408 * be used when the phy driver registers the phy and when the controller
409 * requests this phy.
410 *
411 * To be used by platform specific initialization code.
412 */
413int __init usb_bind_phy(const char *dev_name, u8 index,
414 const char *phy_dev_name)
415{
416 struct usb_phy_bind *phy_bind;
417 unsigned long flags;
418
419 phy_bind = kzalloc(sizeof(*phy_bind), GFP_KERNEL);
420 if (!phy_bind) {
421 pr_err("phy_bind(): No memory for phy_bind");
422 return -ENOMEM;
423 }
424
425 phy_bind->dev_name = dev_name;
426 phy_bind->phy_dev_name = phy_dev_name;
427 phy_bind->index = index;
428
429 spin_lock_irqsave(&phy_lock, flags);
430 list_add_tail(&phy_bind->list, &phy_bind_list);
431 spin_unlock_irqrestore(&phy_lock, flags);
432
433 return 0;
434}
435EXPORT_SYMBOL_GPL(usb_bind_phy);
436
204const char *otg_state_string(enum usb_otg_state state) 437const char *otg_state_string(enum usb_otg_state state)
205{ 438{
206 switch (state) { 439 switch (state) {
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c
index 0a701938ab53..a994715a3101 100644
--- a/drivers/usb/otg/twl4030-usb.c
+++ b/drivers/usb/otg/twl4030-usb.c
@@ -610,6 +610,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
610 twl->phy.dev = twl->dev; 610 twl->phy.dev = twl->dev;
611 twl->phy.label = "twl4030"; 611 twl->phy.label = "twl4030";
612 twl->phy.otg = otg; 612 twl->phy.otg = otg;
613 twl->phy.type = USB_PHY_TYPE_USB2;
613 twl->phy.set_suspend = twl4030_set_suspend; 614 twl->phy.set_suspend = twl4030_set_suspend;
614 615
615 otg->phy = &twl->phy; 616 otg->phy = &twl->phy;
@@ -624,7 +625,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
624 dev_err(&pdev->dev, "ldo init failed\n"); 625 dev_err(&pdev->dev, "ldo init failed\n");
625 return err; 626 return err;
626 } 627 }
627 usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); 628 usb_add_phy_dev(&twl->phy);
628 629
629 platform_set_drvdata(pdev, twl); 630 platform_set_drvdata(pdev, twl);
630 if (device_create_file(&pdev->dev, &dev_attr_vbus)) 631 if (device_create_file(&pdev->dev, &dev_attr_vbus))
diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig
index 5de6e7f39f9c..9bbedecb3371 100644
--- a/drivers/usb/phy/Kconfig
+++ b/drivers/usb/phy/Kconfig
@@ -8,12 +8,33 @@ config OMAP_USB2
8 tristate "OMAP USB2 PHY Driver" 8 tristate "OMAP USB2 PHY Driver"
9 depends on ARCH_OMAP2PLUS 9 depends on ARCH_OMAP2PLUS
10 select USB_OTG_UTILS 10 select USB_OTG_UTILS
11 select OMAP_CONTROL_USB
11 help 12 help
12 Enable this to support the transceiver that is part of SOC. This 13 Enable this to support the transceiver that is part of SOC. This
13 driver takes care of all the PHY functionality apart from comparator. 14 driver takes care of all the PHY functionality apart from comparator.
14 The USB OTG controller communicates with the comparator using this 15 The USB OTG controller communicates with the comparator using this
15 driver. 16 driver.
16 17
18config OMAP_USB3
19 tristate "OMAP USB3 PHY Driver"
20 select USB_OTG_UTILS
21 select OMAP_CONTROL_USB
22 help
23 Enable this to support the USB3 PHY that is part of SOC. This
24 driver takes care of all the PHY functionality apart from comparator.
25 This driver interacts with the "OMAP Control USB Driver" to power
26 on/off the PHY.
27
28config OMAP_CONTROL_USB
29 tristate "OMAP CONTROL USB Driver"
30 depends on ARCH_OMAP2PLUS
31 help
32 Enable this to add support for the USB part present in the control
33 module. This driver has API to power on the USB2 PHY and to write to
34 the mailbox. The mailbox is present only in omap4 and the register to
35 power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
36 additional register to power on USB3 PHY.
37
17config USB_ISP1301 38config USB_ISP1301
18 tristate "NXP ISP1301 USB transceiver support" 39 tristate "NXP ISP1301 USB transceiver support"
19 depends on USB || USB_GADGET 40 depends on USB || USB_GADGET
@@ -45,3 +66,11 @@ config USB_RCAR_PHY
45 66
46 To compile this driver as a module, choose M here: the 67 To compile this driver as a module, choose M here: the
47 module will be called rcar-phy. 68 module will be called rcar-phy.
69
70config SAMSUNG_USBPHY
71 bool "Samsung USB PHY controller Driver"
72 depends on USB_S3C_HSOTG || USB_EHCI_S5P || USB_OHCI_EXYNOS
73 select USB_OTG_UTILS
74 help
75 Enable this to support Samsung USB phy controller for samsung
76 SoCs.
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
index 1a579a860a03..b13faa193e0c 100644
--- a/drivers/usb/phy/Makefile
+++ b/drivers/usb/phy/Makefile
@@ -5,7 +5,10 @@
5ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG 5ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG
6 6
7obj-$(CONFIG_OMAP_USB2) += omap-usb2.o 7obj-$(CONFIG_OMAP_USB2) += omap-usb2.o
8obj-$(CONFIG_OMAP_USB3) += omap-usb3.o
9obj-$(CONFIG_OMAP_CONTROL_USB) += omap-control-usb.o
8obj-$(CONFIG_USB_ISP1301) += isp1301.o 10obj-$(CONFIG_USB_ISP1301) += isp1301.o
9obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o 11obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o
10obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o 12obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o
11obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o 13obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o
14obj-$(CONFIG_SAMSUNG_USBPHY) += samsung-usbphy.o
diff --git a/drivers/usb/phy/omap-control-usb.c b/drivers/usb/phy/omap-control-usb.c
new file mode 100644
index 000000000000..5323b71c3521
--- /dev/null
+++ b/drivers/usb/phy/omap-control-usb.c
@@ -0,0 +1,295 @@
1/*
2 * omap-control-usb.c - The USB part of control module.
3 *
4 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/of.h>
23#include <linux/err.h>
24#include <linux/io.h>
25#include <linux/clk.h>
26#include <linux/usb/omap_control_usb.h>
27
28static struct omap_control_usb *control_usb;
29
30/**
31 * omap_get_control_dev - returns the device pointer for this control device
32 *
33 * This API should be called to get the device pointer for this control
34 * module device. This device pointer should be used for called other
35 * exported API's in this driver.
36 *
37 * To be used by PHY driver and glue driver.
38 */
39struct device *omap_get_control_dev(void)
40{
41 if (!control_usb)
42 return ERR_PTR(-ENODEV);
43
44 return control_usb->dev;
45}
46EXPORT_SYMBOL_GPL(omap_get_control_dev);
47
48/**
49 * omap_control_usb3_phy_power - power on/off the serializer using control
50 * module
51 * @dev: the control module device
52 * @on: 0 to off and 1 to on based on powering on or off the PHY
53 *
54 * usb3 PHY driver should call this API to power on or off the PHY.
55 */
56void omap_control_usb3_phy_power(struct device *dev, bool on)
57{
58 u32 val;
59 unsigned long rate;
60 struct omap_control_usb *control_usb = dev_get_drvdata(dev);
61
62 if (control_usb->type != OMAP_CTRL_DEV_TYPE2)
63 return;
64
65 rate = clk_get_rate(control_usb->sys_clk);
66 rate = rate/1000000;
67
68 val = readl(control_usb->phy_power);
69
70 if (on) {
71 val &= ~(OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK |
72 OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK);
73 val |= OMAP_CTRL_USB3_PHY_TX_RX_POWERON <<
74 OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
75 val |= rate << OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT;
76 } else {
77 val &= ~OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK;
78 val |= OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF <<
79 OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT;
80 }
81
82 writel(val, control_usb->phy_power);
83}
84EXPORT_SYMBOL_GPL(omap_control_usb3_phy_power);
85
86/**
87 * omap_control_usb_phy_power - power on/off the phy using control module reg
88 * @dev: the control module device
89 * @on: 0 or 1, based on powering on or off the PHY
90 */
91void omap_control_usb_phy_power(struct device *dev, int on)
92{
93 u32 val;
94 struct omap_control_usb *control_usb = dev_get_drvdata(dev);
95
96 val = readl(control_usb->dev_conf);
97
98 if (on)
99 val &= ~OMAP_CTRL_DEV_PHY_PD;
100 else
101 val |= OMAP_CTRL_DEV_PHY_PD;
102
103 writel(val, control_usb->dev_conf);
104}
105EXPORT_SYMBOL_GPL(omap_control_usb_phy_power);
106
107/**
108 * omap_control_usb_host_mode - set AVALID, VBUSVALID and ID pin in grounded
109 * @ctrl_usb: struct omap_control_usb *
110 *
111 * Writes to the mailbox register to notify the usb core that a usb
112 * device has been connected.
113 */
114static void omap_control_usb_host_mode(struct omap_control_usb *ctrl_usb)
115{
116 u32 val;
117
118 val = readl(ctrl_usb->otghs_control);
119 val &= ~(OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND);
120 val |= OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID;
121 writel(val, ctrl_usb->otghs_control);
122}
123
124/**
125 * omap_control_usb_device_mode - set AVALID, VBUSVALID and ID pin in high
126 * impedance
127 * @ctrl_usb: struct omap_control_usb *
128 *
129 * Writes to the mailbox register to notify the usb core that it has been
130 * connected to a usb host.
131 */
132static void omap_control_usb_device_mode(struct omap_control_usb *ctrl_usb)
133{
134 u32 val;
135
136 val = readl(ctrl_usb->otghs_control);
137 val &= ~OMAP_CTRL_DEV_SESSEND;
138 val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_AVALID |
139 OMAP_CTRL_DEV_VBUSVALID;
140 writel(val, ctrl_usb->otghs_control);
141}
142
143/**
144 * omap_control_usb_set_sessionend - Enable SESSIONEND and IDIG to high
145 * impedance
146 * @ctrl_usb: struct omap_control_usb *
147 *
148 * Writes to the mailbox register to notify the usb core it's now in
149 * disconnected state.
150 */
151static void omap_control_usb_set_sessionend(struct omap_control_usb *ctrl_usb)
152{
153 u32 val;
154
155 val = readl(ctrl_usb->otghs_control);
156 val &= ~(OMAP_CTRL_DEV_AVALID | OMAP_CTRL_DEV_VBUSVALID);
157 val |= OMAP_CTRL_DEV_IDDIG | OMAP_CTRL_DEV_SESSEND;
158 writel(val, ctrl_usb->otghs_control);
159}
160
161/**
162 * omap_control_usb_set_mode - Calls to functions to set USB in one of host mode
163 * or device mode or to denote disconnected state
164 * @dev: the control module device
165 * @mode: The mode to which usb should be configured
166 *
167 * This is an API to write to the mailbox register to notify the usb core that
168 * a usb device has been connected.
169 */
170void omap_control_usb_set_mode(struct device *dev,
171 enum omap_control_usb_mode mode)
172{
173 struct omap_control_usb *ctrl_usb;
174
175 if (IS_ERR(dev) || control_usb->type != OMAP_CTRL_DEV_TYPE1)
176 return;
177
178 ctrl_usb = dev_get_drvdata(dev);
179
180 switch (mode) {
181 case USB_MODE_HOST:
182 omap_control_usb_host_mode(ctrl_usb);
183 break;
184 case USB_MODE_DEVICE:
185 omap_control_usb_device_mode(ctrl_usb);
186 break;
187 case USB_MODE_DISCONNECT:
188 omap_control_usb_set_sessionend(ctrl_usb);
189 break;
190 default:
191 dev_vdbg(dev, "invalid omap control usb mode\n");
192 }
193}
194EXPORT_SYMBOL_GPL(omap_control_usb_set_mode);
195
196static int omap_control_usb_probe(struct platform_device *pdev)
197{
198 struct resource *res;
199 struct device_node *np = pdev->dev.of_node;
200 struct omap_control_usb_platform_data *pdata = pdev->dev.platform_data;
201
202 control_usb = devm_kzalloc(&pdev->dev, sizeof(*control_usb),
203 GFP_KERNEL);
204 if (!control_usb) {
205 dev_err(&pdev->dev, "unable to alloc memory for control usb\n");
206 return -ENOMEM;
207 }
208
209 if (np) {
210 of_property_read_u32(np, "ti,type", &control_usb->type);
211 } else if (pdata) {
212 control_usb->type = pdata->type;
213 } else {
214 dev_err(&pdev->dev, "no pdata present\n");
215 return -EINVAL;
216 }
217
218 control_usb->dev = &pdev->dev;
219
220 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
221 "control_dev_conf");
222 control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res);
223 if (!control_usb->dev_conf) {
224 dev_err(&pdev->dev, "Failed to obtain io memory\n");
225 return -EADDRNOTAVAIL;
226 }
227
228 if (control_usb->type == OMAP_CTRL_DEV_TYPE1) {
229 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
230 "otghs_control");
231 control_usb->otghs_control = devm_request_and_ioremap(
232 &pdev->dev, res);
233 if (!control_usb->otghs_control) {
234 dev_err(&pdev->dev, "Failed to obtain io memory\n");
235 return -EADDRNOTAVAIL;
236 }
237 }
238
239 if (control_usb->type == OMAP_CTRL_DEV_TYPE2) {
240 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
241 "phy_power_usb");
242 control_usb->phy_power = devm_request_and_ioremap(
243 &pdev->dev, res);
244 if (!control_usb->phy_power) {
245 dev_dbg(&pdev->dev, "Failed to obtain io memory\n");
246 return -EADDRNOTAVAIL;
247 }
248
249 control_usb->sys_clk = devm_clk_get(control_usb->dev,
250 "sys_clkin");
251 if (IS_ERR(control_usb->sys_clk)) {
252 pr_err("%s: unable to get sys_clkin\n", __func__);
253 return -EINVAL;
254 }
255 }
256
257
258 dev_set_drvdata(control_usb->dev, control_usb);
259
260 return 0;
261}
262
263#ifdef CONFIG_OF
264static const struct of_device_id omap_control_usb_id_table[] = {
265 { .compatible = "ti,omap-control-usb" },
266 {}
267};
268MODULE_DEVICE_TABLE(of, omap_control_usb_id_table);
269#endif
270
271static struct platform_driver omap_control_usb_driver = {
272 .probe = omap_control_usb_probe,
273 .driver = {
274 .name = "omap-control-usb",
275 .owner = THIS_MODULE,
276 .of_match_table = of_match_ptr(omap_control_usb_id_table),
277 },
278};
279
280static int __init omap_control_usb_init(void)
281{
282 return platform_driver_register(&omap_control_usb_driver);
283}
284subsys_initcall(omap_control_usb_init);
285
286static void __exit omap_control_usb_exit(void)
287{
288 platform_driver_unregister(&omap_control_usb_driver);
289}
290module_exit(omap_control_usb_exit);
291
292MODULE_ALIAS("platform: omap_control_usb");
293MODULE_AUTHOR("Texas Instruments Inc.");
294MODULE_DESCRIPTION("OMAP Control Module USB Driver");
295MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c
index 26ae8f49225c..844ab68f08d0 100644
--- a/drivers/usb/phy/omap-usb2.c
+++ b/drivers/usb/phy/omap-usb2.c
@@ -27,6 +27,7 @@
27#include <linux/err.h> 27#include <linux/err.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/usb/omap_control_usb.h>
30 31
31/** 32/**
32 * omap_usb2_set_comparator - links the comparator present in the sytem with 33 * omap_usb2_set_comparator - links the comparator present in the sytem with
@@ -52,29 +53,6 @@ int omap_usb2_set_comparator(struct phy_companion *comparator)
52} 53}
53EXPORT_SYMBOL_GPL(omap_usb2_set_comparator); 54EXPORT_SYMBOL_GPL(omap_usb2_set_comparator);
54 55
55/**
56 * omap_usb_phy_power - power on/off the phy using control module reg
57 * @phy: struct omap_usb *
58 * @on: 0 or 1, based on powering on or off the PHY
59 *
60 * XXX: Remove this function once control module driver gets merged
61 */
62static void omap_usb_phy_power(struct omap_usb *phy, int on)
63{
64 u32 val;
65
66 if (on) {
67 val = readl(phy->control_dev);
68 if (val & PHY_PD) {
69 writel(~PHY_PD, phy->control_dev);
70 /* XXX: add proper documentation for this delay */
71 mdelay(200);
72 }
73 } else {
74 writel(PHY_PD, phy->control_dev);
75 }
76}
77
78static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled) 56static int omap_usb_set_vbus(struct usb_otg *otg, bool enabled)
79{ 57{
80 struct omap_usb *phy = phy_to_omapusb(otg->phy); 58 struct omap_usb *phy = phy_to_omapusb(otg->phy);
@@ -124,7 +102,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
124 struct omap_usb *phy = phy_to_omapusb(x); 102 struct omap_usb *phy = phy_to_omapusb(x);
125 103
126 if (suspend && !phy->is_suspended) { 104 if (suspend && !phy->is_suspended) {
127 omap_usb_phy_power(phy, 0); 105 omap_control_usb_phy_power(phy->control_dev, 0);
128 pm_runtime_put_sync(phy->dev); 106 pm_runtime_put_sync(phy->dev);
129 phy->is_suspended = 1; 107 phy->is_suspended = 1;
130 } else if (!suspend && phy->is_suspended) { 108 } else if (!suspend && phy->is_suspended) {
@@ -134,7 +112,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend)
134 ret); 112 ret);
135 return ret; 113 return ret;
136 } 114 }
137 omap_usb_phy_power(phy, 1); 115 omap_control_usb_phy_power(phy->control_dev, 1);
138 phy->is_suspended = 0; 116 phy->is_suspended = 0;
139 } 117 }
140 118
@@ -145,7 +123,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
145{ 123{
146 struct omap_usb *phy; 124 struct omap_usb *phy;
147 struct usb_otg *otg; 125 struct usb_otg *otg;
148 struct resource *res;
149 126
150 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 127 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
151 if (!phy) { 128 if (!phy) {
@@ -165,17 +142,16 @@ static int omap_usb2_probe(struct platform_device *pdev)
165 phy->phy.label = "omap-usb2"; 142 phy->phy.label = "omap-usb2";
166 phy->phy.set_suspend = omap_usb2_suspend; 143 phy->phy.set_suspend = omap_usb2_suspend;
167 phy->phy.otg = otg; 144 phy->phy.otg = otg;
145 phy->phy.type = USB_PHY_TYPE_USB2;
168 146
169 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 147 phy->control_dev = omap_get_control_dev();
170 148 if (IS_ERR(phy->control_dev)) {
171 phy->control_dev = devm_request_and_ioremap(&pdev->dev, res); 149 dev_dbg(&pdev->dev, "Failed to get control device\n");
172 if (phy->control_dev == NULL) { 150 return -ENODEV;
173 dev_err(&pdev->dev, "Failed to obtain io memory\n");
174 return -ENXIO;
175 } 151 }
176 152
177 phy->is_suspended = 1; 153 phy->is_suspended = 1;
178 omap_usb_phy_power(phy, 0); 154 omap_control_usb_phy_power(phy->control_dev, 0);
179 155
180 otg->set_host = omap_usb_set_host; 156 otg->set_host = omap_usb_set_host;
181 otg->set_peripheral = omap_usb_set_peripheral; 157 otg->set_peripheral = omap_usb_set_peripheral;
@@ -190,7 +166,13 @@ static int omap_usb2_probe(struct platform_device *pdev)
190 } 166 }
191 clk_prepare(phy->wkupclk); 167 clk_prepare(phy->wkupclk);
192 168
193 usb_add_phy(&phy->phy, USB_PHY_TYPE_USB2); 169 phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m");
170 if (IS_ERR(phy->optclk))
171 dev_vdbg(&pdev->dev, "unable to get refclk960m\n");
172 else
173 clk_prepare(phy->optclk);
174
175 usb_add_phy_dev(&phy->phy);
194 176
195 platform_set_drvdata(pdev, phy); 177 platform_set_drvdata(pdev, phy);
196 178
@@ -204,6 +186,8 @@ static int omap_usb2_remove(struct platform_device *pdev)
204 struct omap_usb *phy = platform_get_drvdata(pdev); 186 struct omap_usb *phy = platform_get_drvdata(pdev);
205 187
206 clk_unprepare(phy->wkupclk); 188 clk_unprepare(phy->wkupclk);
189 if (!IS_ERR(phy->optclk))
190 clk_unprepare(phy->optclk);
207 usb_remove_phy(&phy->phy); 191 usb_remove_phy(&phy->phy);
208 192
209 return 0; 193 return 0;
@@ -217,6 +201,8 @@ static int omap_usb2_runtime_suspend(struct device *dev)
217 struct omap_usb *phy = platform_get_drvdata(pdev); 201 struct omap_usb *phy = platform_get_drvdata(pdev);
218 202
219 clk_disable(phy->wkupclk); 203 clk_disable(phy->wkupclk);
204 if (!IS_ERR(phy->optclk))
205 clk_disable(phy->optclk);
220 206
221 return 0; 207 return 0;
222} 208}
@@ -228,9 +214,25 @@ static int omap_usb2_runtime_resume(struct device *dev)
228 struct omap_usb *phy = platform_get_drvdata(pdev); 214 struct omap_usb *phy = platform_get_drvdata(pdev);
229 215
230 ret = clk_enable(phy->wkupclk); 216 ret = clk_enable(phy->wkupclk);
231 if (ret < 0) 217 if (ret < 0) {
232 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); 218 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
219 goto err0;
220 }
221
222 if (!IS_ERR(phy->optclk)) {
223 ret = clk_enable(phy->optclk);
224 if (ret < 0) {
225 dev_err(phy->dev, "Failed to enable optclk %d\n", ret);
226 goto err1;
227 }
228 }
229
230 return 0;
231
232err1:
233 clk_disable(phy->wkupclk);
233 234
235err0:
234 return ret; 236 return ret;
235} 237}
236 238
diff --git a/drivers/usb/phy/omap-usb3.c b/drivers/usb/phy/omap-usb3.c
new file mode 100644
index 000000000000..fadc0c2b65bb
--- /dev/null
+++ b/drivers/usb/phy/omap-usb3.c
@@ -0,0 +1,355 @@
1/*
2 * omap-usb3 - USB PHY, talking to dwc3 controller in OMAP.
3 *
4 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/usb/omap_usb.h>
23#include <linux/of.h>
24#include <linux/clk.h>
25#include <linux/err.h>
26#include <linux/pm_runtime.h>
27#include <linux/delay.h>
28#include <linux/usb/omap_control_usb.h>
29
30#define NUM_SYS_CLKS 5
31#define PLL_STATUS 0x00000004
32#define PLL_GO 0x00000008
33#define PLL_CONFIGURATION1 0x0000000C
34#define PLL_CONFIGURATION2 0x00000010
35#define PLL_CONFIGURATION3 0x00000014
36#define PLL_CONFIGURATION4 0x00000020
37
38#define PLL_REGM_MASK 0x001FFE00
39#define PLL_REGM_SHIFT 0x9
40#define PLL_REGM_F_MASK 0x0003FFFF
41#define PLL_REGM_F_SHIFT 0x0
42#define PLL_REGN_MASK 0x000001FE
43#define PLL_REGN_SHIFT 0x1
44#define PLL_SELFREQDCO_MASK 0x0000000E
45#define PLL_SELFREQDCO_SHIFT 0x1
46#define PLL_SD_MASK 0x0003FC00
47#define PLL_SD_SHIFT 0x9
48#define SET_PLL_GO 0x1
49#define PLL_TICOPWDN 0x10000
50#define PLL_LOCK 0x2
51#define PLL_IDLE 0x1
52
53/*
54 * This is an Empirical value that works, need to confirm the actual
55 * value required for the USB3PHY_PLL_CONFIGURATION2.PLL_IDLE status
56 * to be correctly reflected in the USB3PHY_PLL_STATUS register.
57 */
58# define PLL_IDLE_TIME 100;
59
60enum sys_clk_rate {
61 CLK_RATE_UNDEFINED = -1,
62 CLK_RATE_12MHZ,
63 CLK_RATE_16MHZ,
64 CLK_RATE_19MHZ,
65 CLK_RATE_26MHZ,
66 CLK_RATE_38MHZ
67};
68
69static struct usb_dpll_params omap_usb3_dpll_params[NUM_SYS_CLKS] = {
70 {1250, 5, 4, 20, 0}, /* 12 MHz */
71 {3125, 20, 4, 20, 0}, /* 16.8 MHz */
72 {1172, 8, 4, 20, 65537}, /* 19.2 MHz */
73 {1250, 12, 4, 20, 0}, /* 26 MHz */
74 {3125, 47, 4, 20, 92843}, /* 38.4 MHz */
75};
76
77static int omap_usb3_suspend(struct usb_phy *x, int suspend)
78{
79 struct omap_usb *phy = phy_to_omapusb(x);
80 int val;
81 int timeout = PLL_IDLE_TIME;
82
83 if (suspend && !phy->is_suspended) {
84 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
85 val |= PLL_IDLE;
86 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
87
88 do {
89 val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
90 if (val & PLL_TICOPWDN)
91 break;
92 udelay(1);
93 } while (--timeout);
94
95 omap_control_usb3_phy_power(phy->control_dev, 0);
96
97 phy->is_suspended = 1;
98 } else if (!suspend && phy->is_suspended) {
99 phy->is_suspended = 0;
100
101 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
102 val &= ~PLL_IDLE;
103 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
104
105 do {
106 val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
107 if (!(val & PLL_TICOPWDN))
108 break;
109 udelay(1);
110 } while (--timeout);
111 }
112
113 return 0;
114}
115
116static inline enum sys_clk_rate __get_sys_clk_index(unsigned long rate)
117{
118 switch (rate) {
119 case 12000000:
120 return CLK_RATE_12MHZ;
121 case 16800000:
122 return CLK_RATE_16MHZ;
123 case 19200000:
124 return CLK_RATE_19MHZ;
125 case 26000000:
126 return CLK_RATE_26MHZ;
127 case 38400000:
128 return CLK_RATE_38MHZ;
129 default:
130 return CLK_RATE_UNDEFINED;
131 }
132}
133
134static void omap_usb_dpll_relock(struct omap_usb *phy)
135{
136 u32 val;
137 unsigned long timeout;
138
139 omap_usb_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO);
140
141 timeout = jiffies + msecs_to_jiffies(20);
142 do {
143 val = omap_usb_readl(phy->pll_ctrl_base, PLL_STATUS);
144 if (val & PLL_LOCK)
145 break;
146 } while (!WARN_ON(time_after(jiffies, timeout)));
147}
148
149static int omap_usb_dpll_lock(struct omap_usb *phy)
150{
151 u32 val;
152 unsigned long rate;
153 enum sys_clk_rate clk_index;
154
155 rate = clk_get_rate(phy->sys_clk);
156 clk_index = __get_sys_clk_index(rate);
157
158 if (clk_index == CLK_RATE_UNDEFINED) {
159 pr_err("dpll cannot be locked for sys clk freq:%luHz\n", rate);
160 return -EINVAL;
161 }
162
163 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
164 val &= ~PLL_REGN_MASK;
165 val |= omap_usb3_dpll_params[clk_index].n << PLL_REGN_SHIFT;
166 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
167
168 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
169 val &= ~PLL_SELFREQDCO_MASK;
170 val |= omap_usb3_dpll_params[clk_index].freq << PLL_SELFREQDCO_SHIFT;
171 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val);
172
173 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
174 val &= ~PLL_REGM_MASK;
175 val |= omap_usb3_dpll_params[clk_index].m << PLL_REGM_SHIFT;
176 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val);
177
178 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4);
179 val &= ~PLL_REGM_F_MASK;
180 val |= omap_usb3_dpll_params[clk_index].mf << PLL_REGM_F_SHIFT;
181 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val);
182
183 val = omap_usb_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3);
184 val &= ~PLL_SD_MASK;
185 val |= omap_usb3_dpll_params[clk_index].sd << PLL_SD_SHIFT;
186 omap_usb_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val);
187
188 omap_usb_dpll_relock(phy);
189
190 return 0;
191}
192
193static int omap_usb3_init(struct usb_phy *x)
194{
195 struct omap_usb *phy = phy_to_omapusb(x);
196
197 omap_usb_dpll_lock(phy);
198 omap_control_usb3_phy_power(phy->control_dev, 1);
199
200 return 0;
201}
202
203static int omap_usb3_probe(struct platform_device *pdev)
204{
205 struct omap_usb *phy;
206 struct resource *res;
207
208 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
209 if (!phy) {
210 dev_err(&pdev->dev, "unable to alloc mem for OMAP USB3 PHY\n");
211 return -ENOMEM;
212 }
213
214 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
215 phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res);
216 if (!phy->pll_ctrl_base) {
217 dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n");
218 return -ENOMEM;
219 }
220
221 phy->dev = &pdev->dev;
222
223 phy->phy.dev = phy->dev;
224 phy->phy.label = "omap-usb3";
225 phy->phy.init = omap_usb3_init;
226 phy->phy.set_suspend = omap_usb3_suspend;
227 phy->phy.type = USB_PHY_TYPE_USB3;
228
229 phy->is_suspended = 1;
230 phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k");
231 if (IS_ERR(phy->wkupclk)) {
232 dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
233 return PTR_ERR(phy->wkupclk);
234 }
235 clk_prepare(phy->wkupclk);
236
237 phy->optclk = devm_clk_get(phy->dev, "usb_otg_ss_refclk960m");
238 if (IS_ERR(phy->optclk)) {
239 dev_err(&pdev->dev, "unable to get usb_otg_ss_refclk960m\n");
240 return PTR_ERR(phy->optclk);
241 }
242 clk_prepare(phy->optclk);
243
244 phy->sys_clk = devm_clk_get(phy->dev, "sys_clkin");
245 if (IS_ERR(phy->sys_clk)) {
246 pr_err("%s: unable to get sys_clkin\n", __func__);
247 return -EINVAL;
248 }
249
250 phy->control_dev = omap_get_control_dev();
251 if (IS_ERR(phy->control_dev)) {
252 dev_dbg(&pdev->dev, "Failed to get control device\n");
253 return -ENODEV;
254 }
255
256 omap_control_usb3_phy_power(phy->control_dev, 0);
257 usb_add_phy_dev(&phy->phy);
258
259 platform_set_drvdata(pdev, phy);
260
261 pm_runtime_enable(phy->dev);
262 pm_runtime_get(&pdev->dev);
263
264 return 0;
265}
266
267static int omap_usb3_remove(struct platform_device *pdev)
268{
269 struct omap_usb *phy = platform_get_drvdata(pdev);
270
271 clk_unprepare(phy->wkupclk);
272 clk_unprepare(phy->optclk);
273 usb_remove_phy(&phy->phy);
274 if (!pm_runtime_suspended(&pdev->dev))
275 pm_runtime_put(&pdev->dev);
276 pm_runtime_disable(&pdev->dev);
277
278 return 0;
279}
280
281#ifdef CONFIG_PM_RUNTIME
282
283static int omap_usb3_runtime_suspend(struct device *dev)
284{
285 struct platform_device *pdev = to_platform_device(dev);
286 struct omap_usb *phy = platform_get_drvdata(pdev);
287
288 clk_disable(phy->wkupclk);
289 clk_disable(phy->optclk);
290
291 return 0;
292}
293
294static int omap_usb3_runtime_resume(struct device *dev)
295{
296 u32 ret = 0;
297 struct platform_device *pdev = to_platform_device(dev);
298 struct omap_usb *phy = platform_get_drvdata(pdev);
299
300 ret = clk_enable(phy->optclk);
301 if (ret) {
302 dev_err(phy->dev, "Failed to enable optclk %d\n", ret);
303 goto err1;
304 }
305
306 ret = clk_enable(phy->wkupclk);
307 if (ret) {
308 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret);
309 goto err2;
310 }
311
312 return 0;
313
314err2:
315 clk_disable(phy->optclk);
316
317err1:
318 return ret;
319}
320
321static const struct dev_pm_ops omap_usb3_pm_ops = {
322 SET_RUNTIME_PM_OPS(omap_usb3_runtime_suspend, omap_usb3_runtime_resume,
323 NULL)
324};
325
326#define DEV_PM_OPS (&omap_usb3_pm_ops)
327#else
328#define DEV_PM_OPS NULL
329#endif
330
331#ifdef CONFIG_OF
332static const struct of_device_id omap_usb3_id_table[] = {
333 { .compatible = "ti,omap-usb3" },
334 {}
335};
336MODULE_DEVICE_TABLE(of, omap_usb3_id_table);
337#endif
338
339static struct platform_driver omap_usb3_driver = {
340 .probe = omap_usb3_probe,
341 .remove = omap_usb3_remove,
342 .driver = {
343 .name = "omap-usb3",
344 .owner = THIS_MODULE,
345 .pm = DEV_PM_OPS,
346 .of_match_table = of_match_ptr(omap_usb3_id_table),
347 },
348};
349
350module_platform_driver(omap_usb3_driver);
351
352MODULE_ALIAS("platform: omap_usb3");
353MODULE_AUTHOR("Texas Instruments Inc.");
354MODULE_DESCRIPTION("OMAP USB3 phy driver");
355MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c
new file mode 100644
index 000000000000..6ea553733832
--- /dev/null
+++ b/drivers/usb/phy/samsung-usbphy.c
@@ -0,0 +1,930 @@
1/* linux/drivers/usb/phy/samsung-usbphy.c
2 *
3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Praveen Paneri <p.paneri@samsung.com>
7 *
8 * Samsung USB2.0 PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
9 * OHCI-EXYNOS controllers.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/clk.h>
24#include <linux/delay.h>
25#include <linux/device.h>
26#include <linux/err.h>
27#include <linux/io.h>
28#include <linux/of.h>
29#include <linux/of_address.h>
30#include <linux/usb/otg.h>
31#include <linux/usb/samsung_usb_phy.h>
32#include <linux/platform_data/samsung-usbphy.h>
33
34/* Register definitions */
35
36#define SAMSUNG_PHYPWR (0x00)
37
38#define PHYPWR_NORMAL_MASK (0x19 << 0)
39#define PHYPWR_OTG_DISABLE (0x1 << 4)
40#define PHYPWR_ANALOG_POWERDOWN (0x1 << 3)
41#define PHYPWR_FORCE_SUSPEND (0x1 << 1)
42/* For Exynos4 */
43#define PHYPWR_NORMAL_MASK_PHY0 (0x39 << 0)
44#define PHYPWR_SLEEP_PHY0 (0x1 << 5)
45
46#define SAMSUNG_PHYCLK (0x04)
47
48#define PHYCLK_MODE_USB11 (0x1 << 6)
49#define PHYCLK_EXT_OSC (0x1 << 5)
50#define PHYCLK_COMMON_ON_N (0x1 << 4)
51#define PHYCLK_ID_PULL (0x1 << 2)
52#define PHYCLK_CLKSEL_MASK (0x3 << 0)
53#define PHYCLK_CLKSEL_48M (0x0 << 0)
54#define PHYCLK_CLKSEL_12M (0x2 << 0)
55#define PHYCLK_CLKSEL_24M (0x3 << 0)
56
57#define SAMSUNG_RSTCON (0x08)
58
59#define RSTCON_PHYLINK_SWRST (0x1 << 2)
60#define RSTCON_HLINK_SWRST (0x1 << 1)
61#define RSTCON_SWRST (0x1 << 0)
62
63/* EXYNOS5 */
64#define EXYNOS5_PHY_HOST_CTRL0 (0x00)
65
66#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31)
67
68#define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19)
69#define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19)
70#define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19)
71#define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19)
72
73#define HOST_CTRL0_FSEL_MASK (0x7 << 16)
74#define HOST_CTRL0_FSEL(_x) ((_x) << 16)
75
76#define FSEL_CLKSEL_50M (0x7)
77#define FSEL_CLKSEL_24M (0x5)
78#define FSEL_CLKSEL_20M (0x4)
79#define FSEL_CLKSEL_19200K (0x3)
80#define FSEL_CLKSEL_12M (0x2)
81#define FSEL_CLKSEL_10M (0x1)
82#define FSEL_CLKSEL_9600K (0x0)
83
84#define HOST_CTRL0_TESTBURNIN (0x1 << 11)
85#define HOST_CTRL0_RETENABLE (0x1 << 10)
86#define HOST_CTRL0_COMMONON_N (0x1 << 9)
87#define HOST_CTRL0_SIDDQ (0x1 << 6)
88#define HOST_CTRL0_FORCESLEEP (0x1 << 5)
89#define HOST_CTRL0_FORCESUSPEND (0x1 << 4)
90#define HOST_CTRL0_WORDINTERFACE (0x1 << 3)
91#define HOST_CTRL0_UTMISWRST (0x1 << 2)
92#define HOST_CTRL0_LINKSWRST (0x1 << 1)
93#define HOST_CTRL0_PHYSWRST (0x1 << 0)
94
95#define EXYNOS5_PHY_HOST_TUNE0 (0x04)
96
97#define EXYNOS5_PHY_HSIC_CTRL1 (0x10)
98
99#define EXYNOS5_PHY_HSIC_TUNE1 (0x14)
100
101#define EXYNOS5_PHY_HSIC_CTRL2 (0x20)
102
103#define EXYNOS5_PHY_HSIC_TUNE2 (0x24)
104
105#define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23)
106#define HSIC_CTRL_REFCLKSEL (0x2 << 23)
107
108#define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16)
109#define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16)
110#define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16)
111#define HSIC_CTRL_REFCLKDIV_15 (0x1c << 16)
112#define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16)
113#define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16)
114#define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16)
115
116#define HSIC_CTRL_SIDDQ (0x1 << 6)
117#define HSIC_CTRL_FORCESLEEP (0x1 << 5)
118#define HSIC_CTRL_FORCESUSPEND (0x1 << 4)
119#define HSIC_CTRL_WORDINTERFACE (0x1 << 3)
120#define HSIC_CTRL_UTMISWRST (0x1 << 2)
121#define HSIC_CTRL_PHYSWRST (0x1 << 0)
122
123#define EXYNOS5_PHY_HOST_EHCICTRL (0x30)
124
125#define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29)
126#define HOST_EHCICTRL_ENAINCR4 (0x1 << 28)
127#define HOST_EHCICTRL_ENAINCR8 (0x1 << 27)
128#define HOST_EHCICTRL_ENAINCR16 (0x1 << 26)
129
130#define EXYNOS5_PHY_HOST_OHCICTRL (0x34)
131
132#define HOST_OHCICTRL_SUSPLGCY (0x1 << 3)
133#define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2)
134#define HOST_OHCICTRL_CNTSEL (0x1 << 1)
135#define HOST_OHCICTRL_CLKCKTRST (0x1 << 0)
136
137#define EXYNOS5_PHY_OTG_SYS (0x38)
138
139#define OTG_SYS_PHYLINK_SWRESET (0x1 << 14)
140#define OTG_SYS_LINKSWRST_UOTG (0x1 << 13)
141#define OTG_SYS_PHY0_SWRST (0x1 << 12)
142
143#define OTG_SYS_REFCLKSEL_MASK (0x3 << 9)
144#define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9)
145#define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9)
146#define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9)
147
148#define OTG_SYS_IDPULLUP_UOTG (0x1 << 8)
149#define OTG_SYS_COMMON_ON (0x1 << 7)
150
151#define OTG_SYS_FSEL_MASK (0x7 << 4)
152#define OTG_SYS_FSEL(_x) ((_x) << 4)
153
154#define OTG_SYS_FORCESLEEP (0x1 << 3)
155#define OTG_SYS_OTGDISABLE (0x1 << 2)
156#define OTG_SYS_SIDDQ_UOTG (0x1 << 1)
157#define OTG_SYS_FORCESUSPEND (0x1 << 0)
158
159#define EXYNOS5_PHY_OTG_TUNE (0x40)
160
161#ifndef MHZ
162#define MHZ (1000*1000)
163#endif
164
165#ifndef KHZ
166#define KHZ (1000)
167#endif
168
169#define EXYNOS_USBHOST_PHY_CTRL_OFFSET (0x4)
170#define S3C64XX_USBPHY_ENABLE (0x1 << 16)
171#define EXYNOS_USBPHY_ENABLE (0x1 << 0)
172#define EXYNOS_USB20PHY_CFG_HOST_LINK (0x1 << 0)
173
174enum samsung_cpu_type {
175 TYPE_S3C64XX,
176 TYPE_EXYNOS4210,
177 TYPE_EXYNOS5250,
178};
179
180/*
181 * struct samsung_usbphy_drvdata - driver data for various SoC variants
182 * @cpu_type: machine identifier
183 * @devphy_en_mask: device phy enable mask for PHY CONTROL register
184 * @hostphy_en_mask: host phy enable mask for PHY CONTROL register
185 * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from
186 * mapped address of system controller.
187 * @hostphy_reg_offset: offset to HOST PHY CONTROL register from
188 * mapped address of system controller.
189 *
190 * Here we have a separate mask for device type phy.
191 * Having different masks for host and device type phy helps
192 * in setting independent masks in case of SoCs like S5PV210,
193 * in which PHY0 and PHY1 enable bits belong to same register
194 * placed at position 0 and 1 respectively.
195 * Although for newer SoCs like exynos these bits belong to
196 * different registers altogether placed at position 0.
197 */
198struct samsung_usbphy_drvdata {
199 int cpu_type;
200 int devphy_en_mask;
201 int hostphy_en_mask;
202 u32 devphy_reg_offset;
203 u32 hostphy_reg_offset;
204};
205
206/*
207 * struct samsung_usbphy - transceiver driver state
208 * @phy: transceiver structure
209 * @plat: platform data
210 * @dev: The parent device supplied to the probe function
211 * @clk: usb phy clock
212 * @regs: usb phy controller registers memory base
213 * @pmuregs: USB device PHY_CONTROL register memory base
214 * @sysreg: USB2.0 PHY_CFG register memory base
215 * @ref_clk_freq: reference clock frequency selection
216 * @drv_data: driver data available for different SoCs
217 * @phy_type: Samsung SoCs specific phy types: #HOST
218 * #DEVICE
219 * @phy_usage: usage count for phy
220 * @lock: lock for phy operations
221 */
222struct samsung_usbphy {
223 struct usb_phy phy;
224 struct samsung_usbphy_data *plat;
225 struct device *dev;
226 struct clk *clk;
227 void __iomem *regs;
228 void __iomem *pmuregs;
229 void __iomem *sysreg;
230 int ref_clk_freq;
231 const struct samsung_usbphy_drvdata *drv_data;
232 enum samsung_usb_phy_type phy_type;
233 atomic_t phy_usage;
234 spinlock_t lock;
235};
236
237#define phy_to_sphy(x) container_of((x), struct samsung_usbphy, phy)
238
239int samsung_usbphy_set_host(struct usb_otg *otg, struct usb_bus *host)
240{
241 if (!otg)
242 return -ENODEV;
243
244 if (!otg->host)
245 otg->host = host;
246
247 return 0;
248}
249
250static int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy)
251{
252 struct device_node *usbphy_sys;
253
254 /* Getting node for system controller interface for usb-phy */
255 usbphy_sys = of_get_child_by_name(sphy->dev->of_node, "usbphy-sys");
256 if (!usbphy_sys) {
257 dev_err(sphy->dev, "No sys-controller interface for usb-phy\n");
258 return -ENODEV;
259 }
260
261 sphy->pmuregs = of_iomap(usbphy_sys, 0);
262
263 if (sphy->pmuregs == NULL) {
264 dev_err(sphy->dev, "Can't get usb-phy pmu control register\n");
265 goto err0;
266 }
267
268 sphy->sysreg = of_iomap(usbphy_sys, 1);
269
270 /*
271 * Not returning error code here, since this situation is not fatal.
272 * Few SoCs may not have this switch available
273 */
274 if (sphy->sysreg == NULL)
275 dev_warn(sphy->dev, "Can't get usb-phy sysreg cfg register\n");
276
277 of_node_put(usbphy_sys);
278
279 return 0;
280
281err0:
282 of_node_put(usbphy_sys);
283 return -ENXIO;
284}
285
286/*
287 * Set isolation here for phy.
288 * Here 'on = true' would mean USB PHY block is isolated, hence
289 * de-activated and vice-versa.
290 */
291static void samsung_usbphy_set_isolation(struct samsung_usbphy *sphy, bool on)
292{
293 void __iomem *reg = NULL;
294 u32 reg_val;
295 u32 en_mask = 0;
296
297 if (!sphy->pmuregs) {
298 dev_warn(sphy->dev, "Can't set pmu isolation\n");
299 return;
300 }
301
302 switch (sphy->drv_data->cpu_type) {
303 case TYPE_S3C64XX:
304 /*
305 * Do nothing: We will add here once S3C64xx goes for DT support
306 */
307 break;
308 case TYPE_EXYNOS4210:
309 /*
310 * Fall through since exynos4210 and exynos5250 have similar
311 * register architecture: two separate registers for host and
312 * device phy control with enable bit at position 0.
313 */
314 case TYPE_EXYNOS5250:
315 if (sphy->phy_type == USB_PHY_TYPE_DEVICE) {
316 reg = sphy->pmuregs +
317 sphy->drv_data->devphy_reg_offset;
318 en_mask = sphy->drv_data->devphy_en_mask;
319 } else if (sphy->phy_type == USB_PHY_TYPE_HOST) {
320 reg = sphy->pmuregs +
321 sphy->drv_data->hostphy_reg_offset;
322 en_mask = sphy->drv_data->hostphy_en_mask;
323 }
324 break;
325 default:
326 dev_err(sphy->dev, "Invalid SoC type\n");
327 return;
328 }
329
330 reg_val = readl(reg);
331
332 if (on)
333 reg_val &= ~en_mask;
334 else
335 reg_val |= en_mask;
336
337 writel(reg_val, reg);
338}
339
340/*
341 * Configure the mode of working of usb-phy here: HOST/DEVICE.
342 */
343static void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy)
344{
345 u32 reg;
346
347 if (!sphy->sysreg) {
348 dev_warn(sphy->dev, "Can't configure specified phy mode\n");
349 return;
350 }
351
352 reg = readl(sphy->sysreg);
353
354 if (sphy->phy_type == USB_PHY_TYPE_DEVICE)
355 reg &= ~EXYNOS_USB20PHY_CFG_HOST_LINK;
356 else if (sphy->phy_type == USB_PHY_TYPE_HOST)
357 reg |= EXYNOS_USB20PHY_CFG_HOST_LINK;
358
359 writel(reg, sphy->sysreg);
360}
361
362/*
363 * PHYs are different for USB Device and USB Host.
364 * This make sure that correct PHY type is selected before
365 * any operation on PHY.
366 */
367static int samsung_usbphy_set_type(struct usb_phy *phy,
368 enum samsung_usb_phy_type phy_type)
369{
370 struct samsung_usbphy *sphy = phy_to_sphy(phy);
371
372 sphy->phy_type = phy_type;
373
374 return 0;
375}
376
377/*
378 * Returns reference clock frequency selection value
379 */
380static int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy)
381{
382 struct clk *ref_clk;
383 int refclk_freq = 0;
384
385 /*
386 * In exynos5250 USB host and device PHY use
387 * external crystal clock XXTI
388 */
389 if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
390 ref_clk = clk_get(sphy->dev, "ext_xtal");
391 else
392 ref_clk = clk_get(sphy->dev, "xusbxti");
393 if (IS_ERR(ref_clk)) {
394 dev_err(sphy->dev, "Failed to get reference clock\n");
395 return PTR_ERR(ref_clk);
396 }
397
398 if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250) {
399 /* set clock frequency for PLL */
400 switch (clk_get_rate(ref_clk)) {
401 case 9600 * KHZ:
402 refclk_freq = FSEL_CLKSEL_9600K;
403 break;
404 case 10 * MHZ:
405 refclk_freq = FSEL_CLKSEL_10M;
406 break;
407 case 12 * MHZ:
408 refclk_freq = FSEL_CLKSEL_12M;
409 break;
410 case 19200 * KHZ:
411 refclk_freq = FSEL_CLKSEL_19200K;
412 break;
413 case 20 * MHZ:
414 refclk_freq = FSEL_CLKSEL_20M;
415 break;
416 case 50 * MHZ:
417 refclk_freq = FSEL_CLKSEL_50M;
418 break;
419 case 24 * MHZ:
420 default:
421 /* default reference clock */
422 refclk_freq = FSEL_CLKSEL_24M;
423 break;
424 }
425 } else {
426 switch (clk_get_rate(ref_clk)) {
427 case 12 * MHZ:
428 refclk_freq = PHYCLK_CLKSEL_12M;
429 break;
430 case 24 * MHZ:
431 refclk_freq = PHYCLK_CLKSEL_24M;
432 break;
433 case 48 * MHZ:
434 refclk_freq = PHYCLK_CLKSEL_48M;
435 break;
436 default:
437 if (sphy->drv_data->cpu_type == TYPE_S3C64XX)
438 refclk_freq = PHYCLK_CLKSEL_48M;
439 else
440 refclk_freq = PHYCLK_CLKSEL_24M;
441 break;
442 }
443 }
444 clk_put(ref_clk);
445
446 return refclk_freq;
447}
448
449static bool exynos5_phyhost_is_on(void *regs)
450{
451 u32 reg;
452
453 reg = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
454
455 return !(reg & HOST_CTRL0_SIDDQ);
456}
457
458static void samsung_exynos5_usbphy_enable(struct samsung_usbphy *sphy)
459{
460 void __iomem *regs = sphy->regs;
461 u32 phyclk = sphy->ref_clk_freq;
462 u32 phyhost;
463 u32 phyotg;
464 u32 phyhsic;
465 u32 ehcictrl;
466 u32 ohcictrl;
467
468 /*
469 * phy_usage helps in keeping usage count for phy
470 * so that the first consumer enabling the phy is also
471 * the last consumer to disable it.
472 */
473
474 atomic_inc(&sphy->phy_usage);
475
476 if (exynos5_phyhost_is_on(regs)) {
477 dev_info(sphy->dev, "Already power on PHY\n");
478 return;
479 }
480
481 /* Host configuration */
482 phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
483
484 /* phy reference clock configuration */
485 phyhost &= ~HOST_CTRL0_FSEL_MASK;
486 phyhost |= HOST_CTRL0_FSEL(phyclk);
487
488 /* host phy reset */
489 phyhost &= ~(HOST_CTRL0_PHYSWRST |
490 HOST_CTRL0_PHYSWRSTALL |
491 HOST_CTRL0_SIDDQ |
492 /* Enable normal mode of operation */
493 HOST_CTRL0_FORCESUSPEND |
494 HOST_CTRL0_FORCESLEEP);
495
496 /* Link reset */
497 phyhost |= (HOST_CTRL0_LINKSWRST |
498 HOST_CTRL0_UTMISWRST |
499 /* COMMON Block configuration during suspend */
500 HOST_CTRL0_COMMONON_N);
501 writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
502 udelay(10);
503 phyhost &= ~(HOST_CTRL0_LINKSWRST |
504 HOST_CTRL0_UTMISWRST);
505 writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
506
507 /* OTG configuration */
508 phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
509
510 /* phy reference clock configuration */
511 phyotg &= ~OTG_SYS_FSEL_MASK;
512 phyotg |= OTG_SYS_FSEL(phyclk);
513
514 /* Enable normal mode of operation */
515 phyotg &= ~(OTG_SYS_FORCESUSPEND |
516 OTG_SYS_SIDDQ_UOTG |
517 OTG_SYS_FORCESLEEP |
518 OTG_SYS_REFCLKSEL_MASK |
519 /* COMMON Block configuration during suspend */
520 OTG_SYS_COMMON_ON);
521
522 /* OTG phy & link reset */
523 phyotg |= (OTG_SYS_PHY0_SWRST |
524 OTG_SYS_LINKSWRST_UOTG |
525 OTG_SYS_PHYLINK_SWRESET |
526 OTG_SYS_OTGDISABLE |
527 /* Set phy refclk */
528 OTG_SYS_REFCLKSEL_CLKCORE);
529
530 writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
531 udelay(10);
532 phyotg &= ~(OTG_SYS_PHY0_SWRST |
533 OTG_SYS_LINKSWRST_UOTG |
534 OTG_SYS_PHYLINK_SWRESET);
535 writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
536
537 /* HSIC phy configuration */
538 phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
539 HSIC_CTRL_REFCLKSEL |
540 HSIC_CTRL_PHYSWRST);
541 writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
542 writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
543 udelay(10);
544 phyhsic &= ~HSIC_CTRL_PHYSWRST;
545 writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
546 writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
547
548 udelay(80);
549
550 /* enable EHCI DMA burst */
551 ehcictrl = readl(regs + EXYNOS5_PHY_HOST_EHCICTRL);
552 ehcictrl |= (HOST_EHCICTRL_ENAINCRXALIGN |
553 HOST_EHCICTRL_ENAINCR4 |
554 HOST_EHCICTRL_ENAINCR8 |
555 HOST_EHCICTRL_ENAINCR16);
556 writel(ehcictrl, regs + EXYNOS5_PHY_HOST_EHCICTRL);
557
558 /* set ohci_suspend_on_n */
559 ohcictrl = readl(regs + EXYNOS5_PHY_HOST_OHCICTRL);
560 ohcictrl |= HOST_OHCICTRL_SUSPLGCY;
561 writel(ohcictrl, regs + EXYNOS5_PHY_HOST_OHCICTRL);
562}
563
564static void samsung_usbphy_enable(struct samsung_usbphy *sphy)
565{
566 void __iomem *regs = sphy->regs;
567 u32 phypwr;
568 u32 phyclk;
569 u32 rstcon;
570
571 /* set clock frequency for PLL */
572 phyclk = sphy->ref_clk_freq;
573 phypwr = readl(regs + SAMSUNG_PHYPWR);
574 rstcon = readl(regs + SAMSUNG_RSTCON);
575
576 switch (sphy->drv_data->cpu_type) {
577 case TYPE_S3C64XX:
578 phyclk &= ~PHYCLK_COMMON_ON_N;
579 phypwr &= ~PHYPWR_NORMAL_MASK;
580 rstcon |= RSTCON_SWRST;
581 break;
582 case TYPE_EXYNOS4210:
583 phypwr &= ~PHYPWR_NORMAL_MASK_PHY0;
584 rstcon |= RSTCON_SWRST;
585 default:
586 break;
587 }
588
589 writel(phyclk, regs + SAMSUNG_PHYCLK);
590 /* Configure PHY0 for normal operation*/
591 writel(phypwr, regs + SAMSUNG_PHYPWR);
592 /* reset all ports of PHY and Link */
593 writel(rstcon, regs + SAMSUNG_RSTCON);
594 udelay(10);
595 rstcon &= ~RSTCON_SWRST;
596 writel(rstcon, regs + SAMSUNG_RSTCON);
597}
598
599static void samsung_exynos5_usbphy_disable(struct samsung_usbphy *sphy)
600{
601 void __iomem *regs = sphy->regs;
602 u32 phyhost;
603 u32 phyotg;
604 u32 phyhsic;
605
606 if (atomic_dec_return(&sphy->phy_usage) > 0) {
607 dev_info(sphy->dev, "still being used\n");
608 return;
609 }
610
611 phyhsic = (HSIC_CTRL_REFCLKDIV_12 |
612 HSIC_CTRL_REFCLKSEL |
613 HSIC_CTRL_SIDDQ |
614 HSIC_CTRL_FORCESLEEP |
615 HSIC_CTRL_FORCESUSPEND);
616 writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL1);
617 writel(phyhsic, regs + EXYNOS5_PHY_HSIC_CTRL2);
618
619 phyhost = readl(regs + EXYNOS5_PHY_HOST_CTRL0);
620 phyhost |= (HOST_CTRL0_SIDDQ |
621 HOST_CTRL0_FORCESUSPEND |
622 HOST_CTRL0_FORCESLEEP |
623 HOST_CTRL0_PHYSWRST |
624 HOST_CTRL0_PHYSWRSTALL);
625 writel(phyhost, regs + EXYNOS5_PHY_HOST_CTRL0);
626
627 phyotg = readl(regs + EXYNOS5_PHY_OTG_SYS);
628 phyotg |= (OTG_SYS_FORCESUSPEND |
629 OTG_SYS_SIDDQ_UOTG |
630 OTG_SYS_FORCESLEEP);
631 writel(phyotg, regs + EXYNOS5_PHY_OTG_SYS);
632}
633
634static void samsung_usbphy_disable(struct samsung_usbphy *sphy)
635{
636 void __iomem *regs = sphy->regs;
637 u32 phypwr;
638
639 phypwr = readl(regs + SAMSUNG_PHYPWR);
640
641 switch (sphy->drv_data->cpu_type) {
642 case TYPE_S3C64XX:
643 phypwr |= PHYPWR_NORMAL_MASK;
644 break;
645 case TYPE_EXYNOS4210:
646 phypwr |= PHYPWR_NORMAL_MASK_PHY0;
647 default:
648 break;
649 }
650
651 /* Disable analog and otg block power */
652 writel(phypwr, regs + SAMSUNG_PHYPWR);
653}
654
655/*
656 * The function passed to the usb driver for phy initialization
657 */
658static int samsung_usbphy_init(struct usb_phy *phy)
659{
660 struct samsung_usbphy *sphy;
661 struct usb_bus *host = NULL;
662 unsigned long flags;
663 int ret = 0;
664
665 sphy = phy_to_sphy(phy);
666
667 host = phy->otg->host;
668
669 /* Enable the phy clock */
670 ret = clk_prepare_enable(sphy->clk);
671 if (ret) {
672 dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
673 return ret;
674 }
675
676 spin_lock_irqsave(&sphy->lock, flags);
677
678 if (host) {
679 /* setting default phy-type for USB 2.0 */
680 if (!strstr(dev_name(host->controller), "ehci") ||
681 !strstr(dev_name(host->controller), "ohci"))
682 samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST);
683 } else {
684 samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE);
685 }
686
687 /* Disable phy isolation */
688 if (sphy->plat && sphy->plat->pmu_isolation)
689 sphy->plat->pmu_isolation(false);
690 else
691 samsung_usbphy_set_isolation(sphy, false);
692
693 /* Selecting Host/OTG mode; After reset USB2.0PHY_CFG: HOST */
694 samsung_usbphy_cfg_sel(sphy);
695
696 /* Initialize usb phy registers */
697 if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
698 samsung_exynos5_usbphy_enable(sphy);
699 else
700 samsung_usbphy_enable(sphy);
701
702 spin_unlock_irqrestore(&sphy->lock, flags);
703
704 /* Disable the phy clock */
705 clk_disable_unprepare(sphy->clk);
706
707 return ret;
708}
709
710/*
711 * The function passed to the usb driver for phy shutdown
712 */
713static void samsung_usbphy_shutdown(struct usb_phy *phy)
714{
715 struct samsung_usbphy *sphy;
716 struct usb_bus *host = NULL;
717 unsigned long flags;
718
719 sphy = phy_to_sphy(phy);
720
721 host = phy->otg->host;
722
723 if (clk_prepare_enable(sphy->clk)) {
724 dev_err(sphy->dev, "%s: clk_prepare_enable failed\n", __func__);
725 return;
726 }
727
728 spin_lock_irqsave(&sphy->lock, flags);
729
730 if (host) {
731 /* setting default phy-type for USB 2.0 */
732 if (!strstr(dev_name(host->controller), "ehci") ||
733 !strstr(dev_name(host->controller), "ohci"))
734 samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_HOST);
735 } else {
736 samsung_usbphy_set_type(&sphy->phy, USB_PHY_TYPE_DEVICE);
737 }
738
739 /* De-initialize usb phy registers */
740 if (sphy->drv_data->cpu_type == TYPE_EXYNOS5250)
741 samsung_exynos5_usbphy_disable(sphy);
742 else
743 samsung_usbphy_disable(sphy);
744
745 /* Enable phy isolation */
746 if (sphy->plat && sphy->plat->pmu_isolation)
747 sphy->plat->pmu_isolation(true);
748 else
749 samsung_usbphy_set_isolation(sphy, true);
750
751 spin_unlock_irqrestore(&sphy->lock, flags);
752
753 clk_disable_unprepare(sphy->clk);
754}
755
756static const struct of_device_id samsung_usbphy_dt_match[];
757
758static inline const struct samsung_usbphy_drvdata
759*samsung_usbphy_get_driver_data(struct platform_device *pdev)
760{
761 if (pdev->dev.of_node) {
762 const struct of_device_id *match;
763 match = of_match_node(samsung_usbphy_dt_match,
764 pdev->dev.of_node);
765 return match->data;
766 }
767
768 return (struct samsung_usbphy_drvdata *)
769 platform_get_device_id(pdev)->driver_data;
770}
771
772static int samsung_usbphy_probe(struct platform_device *pdev)
773{
774 struct samsung_usbphy *sphy;
775 struct usb_otg *otg;
776 struct samsung_usbphy_data *pdata = pdev->dev.platform_data;
777 const struct samsung_usbphy_drvdata *drv_data;
778 struct device *dev = &pdev->dev;
779 struct resource *phy_mem;
780 void __iomem *phy_base;
781 struct clk *clk;
782 int ret;
783
784 phy_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
785 if (!phy_mem) {
786 dev_err(dev, "%s: missing mem resource\n", __func__);
787 return -ENODEV;
788 }
789
790 phy_base = devm_request_and_ioremap(dev, phy_mem);
791 if (!phy_base) {
792 dev_err(dev, "%s: register mapping failed\n", __func__);
793 return -ENXIO;
794 }
795
796 sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
797 if (!sphy)
798 return -ENOMEM;
799
800 otg = devm_kzalloc(dev, sizeof(*otg), GFP_KERNEL);
801 if (!otg)
802 return -ENOMEM;
803
804 drv_data = samsung_usbphy_get_driver_data(pdev);
805
806 if (drv_data->cpu_type == TYPE_EXYNOS5250)
807 clk = devm_clk_get(dev, "usbhost");
808 else
809 clk = devm_clk_get(dev, "otg");
810
811 if (IS_ERR(clk)) {
812 dev_err(dev, "Failed to get otg clock\n");
813 return PTR_ERR(clk);
814 }
815
816 sphy->dev = dev;
817
818 if (dev->of_node) {
819 ret = samsung_usbphy_parse_dt(sphy);
820 if (ret < 0)
821 return ret;
822 } else {
823 if (!pdata) {
824 dev_err(dev, "no platform data specified\n");
825 return -EINVAL;
826 }
827 }
828
829 sphy->plat = pdata;
830 sphy->regs = phy_base;
831 sphy->clk = clk;
832 sphy->drv_data = drv_data;
833 sphy->phy.dev = sphy->dev;
834 sphy->phy.label = "samsung-usbphy";
835 sphy->phy.init = samsung_usbphy_init;
836 sphy->phy.shutdown = samsung_usbphy_shutdown;
837 sphy->ref_clk_freq = samsung_usbphy_get_refclk_freq(sphy);
838
839 sphy->phy.otg = otg;
840 sphy->phy.otg->phy = &sphy->phy;
841 sphy->phy.otg->set_host = samsung_usbphy_set_host;
842
843 spin_lock_init(&sphy->lock);
844
845 platform_set_drvdata(pdev, sphy);
846
847 return usb_add_phy(&sphy->phy, USB_PHY_TYPE_USB2);
848}
849
850static int samsung_usbphy_remove(struct platform_device *pdev)
851{
852 struct samsung_usbphy *sphy = platform_get_drvdata(pdev);
853
854 usb_remove_phy(&sphy->phy);
855
856 if (sphy->pmuregs)
857 iounmap(sphy->pmuregs);
858 if (sphy->sysreg)
859 iounmap(sphy->sysreg);
860
861 return 0;
862}
863
864static const struct samsung_usbphy_drvdata usbphy_s3c64xx = {
865 .cpu_type = TYPE_S3C64XX,
866 .devphy_en_mask = S3C64XX_USBPHY_ENABLE,
867};
868
869static const struct samsung_usbphy_drvdata usbphy_exynos4 = {
870 .cpu_type = TYPE_EXYNOS4210,
871 .devphy_en_mask = EXYNOS_USBPHY_ENABLE,
872 .hostphy_en_mask = EXYNOS_USBPHY_ENABLE,
873};
874
875static struct samsung_usbphy_drvdata usbphy_exynos5 = {
876 .cpu_type = TYPE_EXYNOS5250,
877 .hostphy_en_mask = EXYNOS_USBPHY_ENABLE,
878 .hostphy_reg_offset = EXYNOS_USBHOST_PHY_CTRL_OFFSET,
879};
880
881#ifdef CONFIG_OF
882static const struct of_device_id samsung_usbphy_dt_match[] = {
883 {
884 .compatible = "samsung,s3c64xx-usbphy",
885 .data = &usbphy_s3c64xx,
886 }, {
887 .compatible = "samsung,exynos4210-usbphy",
888 .data = &usbphy_exynos4,
889 }, {
890 .compatible = "samsung,exynos5250-usbphy",
891 .data = &usbphy_exynos5
892 },
893 {},
894};
895MODULE_DEVICE_TABLE(of, samsung_usbphy_dt_match);
896#endif
897
898static struct platform_device_id samsung_usbphy_driver_ids[] = {
899 {
900 .name = "s3c64xx-usbphy",
901 .driver_data = (unsigned long)&usbphy_s3c64xx,
902 }, {
903 .name = "exynos4210-usbphy",
904 .driver_data = (unsigned long)&usbphy_exynos4,
905 }, {
906 .name = "exynos5250-usbphy",
907 .driver_data = (unsigned long)&usbphy_exynos5,
908 },
909 {},
910};
911
912MODULE_DEVICE_TABLE(platform, samsung_usbphy_driver_ids);
913
914static struct platform_driver samsung_usbphy_driver = {
915 .probe = samsung_usbphy_probe,
916 .remove = samsung_usbphy_remove,
917 .id_table = samsung_usbphy_driver_ids,
918 .driver = {
919 .name = "samsung-usbphy",
920 .owner = THIS_MODULE,
921 .of_match_table = of_match_ptr(samsung_usbphy_dt_match),
922 },
923};
924
925module_platform_driver(samsung_usbphy_driver);
926
927MODULE_DESCRIPTION("Samsung USB phy controller");
928MODULE_AUTHOR("Praveen Paneri <p.paneri@samsung.com>");
929MODULE_LICENSE("GPL");
930MODULE_ALIAS("platform:samsung-usbphy");
diff --git a/include/linux/platform_data/samsung-usbphy.h b/include/linux/platform_data/samsung-usbphy.h
new file mode 100644
index 000000000000..1bd24cba982b
--- /dev/null
+++ b/include/linux/platform_data/samsung-usbphy.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co.Ltd
3 * http://www.samsung.com/
4 * Author: Praveen Paneri <p.paneri@samsung.com>
5 *
6 * Defines platform data for samsung usb phy driver.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#ifndef __SAMSUNG_USBPHY_PLATFORM_H
15#define __SAMSUNG_USBPHY_PLATFORM_H
16
17/**
18 * samsung_usbphy_data - Platform data for USB PHY driver.
19 * @pmu_isolation: Function to control usb phy isolation in PMU.
20 */
21struct samsung_usbphy_data {
22 void (*pmu_isolation)(int on);
23};
24
25extern void samsung_usbphy_set_pdata(struct samsung_usbphy_data *pd);
26
27#endif /* __SAMSUNG_USBPHY_PLATFORM_H */
diff --git a/include/linux/usb/omap_control_usb.h b/include/linux/usb/omap_control_usb.h
new file mode 100644
index 000000000000..f306db7149ca
--- /dev/null
+++ b/include/linux/usb/omap_control_usb.h
@@ -0,0 +1,92 @@
1/*
2 * omap_control_usb.h - Header file for the USB part of control module.
3 *
4 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * Author: Kishon Vijay Abraham I <kishon@ti.com>
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#ifndef __OMAP_CONTROL_USB_H__
20#define __OMAP_CONTROL_USB_H__
21
22struct omap_control_usb {
23 struct device *dev;
24
25 u32 __iomem *dev_conf;
26 u32 __iomem *otghs_control;
27 u32 __iomem *phy_power;
28
29 struct clk *sys_clk;
30
31 u32 type;
32};
33
34struct omap_control_usb_platform_data {
35 u8 type;
36};
37
38enum omap_control_usb_mode {
39 USB_MODE_UNDEFINED = 0,
40 USB_MODE_HOST,
41 USB_MODE_DEVICE,
42 USB_MODE_DISCONNECT,
43};
44
45/* To differentiate ctrl module IP having either mailbox or USB3 PHY power */
46#define OMAP_CTRL_DEV_TYPE1 0x1
47#define OMAP_CTRL_DEV_TYPE2 0x2
48
49#define OMAP_CTRL_DEV_PHY_PD BIT(0)
50
51#define OMAP_CTRL_DEV_AVALID BIT(0)
52#define OMAP_CTRL_DEV_BVALID BIT(1)
53#define OMAP_CTRL_DEV_VBUSVALID BIT(2)
54#define OMAP_CTRL_DEV_SESSEND BIT(3)
55#define OMAP_CTRL_DEV_IDDIG BIT(4)
56
57#define OMAP_CTRL_USB_PWRCTL_CLK_CMD_MASK 0x003FC000
58#define OMAP_CTRL_USB_PWRCTL_CLK_CMD_SHIFT 0xE
59
60#define OMAP_CTRL_USB_PWRCTL_CLK_FREQ_MASK 0xFFC00000
61#define OMAP_CTRL_USB_PWRCTL_CLK_FREQ_SHIFT 0x16
62
63#define OMAP_CTRL_USB3_PHY_TX_RX_POWERON 0x3
64#define OMAP_CTRL_USB3_PHY_TX_RX_POWEROFF 0x0
65
66#if IS_ENABLED(CONFIG_OMAP_CONTROL_USB)
67extern struct device *omap_get_control_dev(void);
68extern void omap_control_usb_phy_power(struct device *dev, int on);
69extern void omap_control_usb3_phy_power(struct device *dev, bool on);
70extern void omap_control_usb_set_mode(struct device *dev,
71 enum omap_control_usb_mode mode);
72#else
73static inline struct device *omap_get_control_dev()
74{
75 return ERR_PTR(-ENODEV);
76}
77
78static inline void omap_control_usb_phy_power(struct device *dev, int on)
79{
80}
81
82static inline void omap_control_usb3_phy_power(struct device *dev, int on)
83{
84}
85
86static inline void omap_control_usb_set_mode(struct device *dev,
87 enum omap_control_usb_mode mode)
88{
89}
90#endif
91
92#endif /* __OMAP_CONTROL_USB_H__ */
diff --git a/include/linux/usb/omap_usb.h b/include/linux/usb/omap_usb.h
index 0ea17f8ae820..6ae29360e1d2 100644
--- a/include/linux/usb/omap_usb.h
+++ b/include/linux/usb/omap_usb.h
@@ -19,19 +19,29 @@
19#ifndef __DRIVERS_OMAP_USB2_H 19#ifndef __DRIVERS_OMAP_USB2_H
20#define __DRIVERS_OMAP_USB2_H 20#define __DRIVERS_OMAP_USB2_H
21 21
22#include <linux/io.h>
22#include <linux/usb/otg.h> 23#include <linux/usb/otg.h>
23 24
25struct usb_dpll_params {
26 u16 m;
27 u8 n;
28 u8 freq:3;
29 u8 sd;
30 u32 mf;
31};
32
24struct omap_usb { 33struct omap_usb {
25 struct usb_phy phy; 34 struct usb_phy phy;
26 struct phy_companion *comparator; 35 struct phy_companion *comparator;
36 void __iomem *pll_ctrl_base;
27 struct device *dev; 37 struct device *dev;
28 u32 __iomem *control_dev; 38 struct device *control_dev;
29 struct clk *wkupclk; 39 struct clk *wkupclk;
40 struct clk *sys_clk;
41 struct clk *optclk;
30 u8 is_suspended:1; 42 u8 is_suspended:1;
31}; 43};
32 44
33#define PHY_PD 0x1
34
35#define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) 45#define phy_to_omapusb(x) container_of((x), struct omap_usb, phy)
36 46
37#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) 47#if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE)
@@ -43,4 +53,15 @@ static inline int omap_usb2_set_comparator(struct phy_companion *comparator)
43} 53}
44#endif 54#endif
45 55
56static inline u32 omap_usb_readl(void __iomem *addr, unsigned offset)
57{
58 return __raw_readl(addr + offset);
59}
60
61static inline void omap_usb_writel(void __iomem *addr, unsigned offset,
62 u32 data)
63{
64 __raw_writel(data, addr + offset);
65}
66
46#endif /* __DRIVERS_OMAP_USB_H */ 67#endif /* __DRIVERS_OMAP_USB_H */
diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h
index a29ae1eb9346..15847cbdb512 100644
--- a/include/linux/usb/phy.h
+++ b/include/linux/usb/phy.h
@@ -106,9 +106,25 @@ struct usb_phy {
106 enum usb_device_speed speed); 106 enum usb_device_speed speed);
107}; 107};
108 108
109/**
110 * struct usb_phy_bind - represent the binding for the phy
111 * @dev_name: the device name of the device that will bind to the phy
112 * @phy_dev_name: the device name of the phy
113 * @index: used if a single controller uses multiple phys
114 * @phy: reference to the phy
115 * @list: to maintain a linked list of the binding information
116 */
117struct usb_phy_bind {
118 const char *dev_name;
119 const char *phy_dev_name;
120 u8 index;
121 struct usb_phy *phy;
122 struct list_head list;
123};
109 124
110/* for board-specific init logic */ 125/* for board-specific init logic */
111extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type); 126extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type);
127extern int usb_add_phy_dev(struct usb_phy *);
112extern void usb_remove_phy(struct usb_phy *); 128extern void usb_remove_phy(struct usb_phy *);
113 129
114/* helpers for direct access thru low-level io interface */ 130/* helpers for direct access thru low-level io interface */
@@ -149,8 +165,14 @@ usb_phy_shutdown(struct usb_phy *x)
149extern struct usb_phy *usb_get_phy(enum usb_phy_type type); 165extern struct usb_phy *usb_get_phy(enum usb_phy_type type);
150extern struct usb_phy *devm_usb_get_phy(struct device *dev, 166extern struct usb_phy *devm_usb_get_phy(struct device *dev,
151 enum usb_phy_type type); 167 enum usb_phy_type type);
168extern struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index);
169extern struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index);
170extern struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
171 const char *phandle, u8 index);
152extern void usb_put_phy(struct usb_phy *); 172extern void usb_put_phy(struct usb_phy *);
153extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x); 173extern void devm_usb_put_phy(struct device *dev, struct usb_phy *x);
174extern int usb_bind_phy(const char *dev_name, u8 index,
175 const char *phy_dev_name);
154#else 176#else
155static inline struct usb_phy *usb_get_phy(enum usb_phy_type type) 177static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)
156{ 178{
@@ -163,6 +185,22 @@ static inline struct usb_phy *devm_usb_get_phy(struct device *dev,
163 return NULL; 185 return NULL;
164} 186}
165 187
188static inline struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index)
189{
190 return NULL;
191}
192
193static inline struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index)
194{
195 return NULL;
196}
197
198static inline struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev,
199 const char *phandle, u8 index)
200{
201 return NULL;
202}
203
166static inline void usb_put_phy(struct usb_phy *x) 204static inline void usb_put_phy(struct usb_phy *x)
167{ 205{
168} 206}
@@ -171,6 +209,11 @@ static inline void devm_usb_put_phy(struct device *dev, struct usb_phy *x)
171{ 209{
172} 210}
173 211
212static inline int usb_bind_phy(const char *dev_name, u8 index,
213 const char *phy_dev_name)
214{
215 return -EOPNOTSUPP;
216}
174#endif 217#endif
175 218
176static inline int 219static inline int
diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
new file mode 100644
index 000000000000..916782699f1c
--- /dev/null
+++ b/include/linux/usb/samsung_usb_phy.h
@@ -0,0 +1,16 @@
1/*
2 * Copyright (C) 2012 Samsung Electronics Co.Ltd
3 * http://www.samsung.com/
4 *
5 * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
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
13enum samsung_usb_phy_type {
14 USB_PHY_TYPE_DEVICE,
15 USB_PHY_TYPE_HOST,
16};