diff options
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index de80fa644b5a..c26564f29a2c 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 { | |||
153 | struct s3c_hsotg { | 156 | struct 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 | ||
@@ -3055,7 +3064,7 @@ static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | |||
3055 | return 0; | 3064 | return 0; |
3056 | } | 3065 | } |
3057 | 3066 | ||
3058 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { | 3067 | static const struct usb_gadget_ops s3c_hsotg_gadget_ops = { |
3059 | .get_frame = s3c_hsotg_gadget_getframe, | 3068 | .get_frame = s3c_hsotg_gadget_getframe, |
3060 | .udc_start = s3c_hsotg_udc_start, | 3069 | .udc_start = s3c_hsotg_udc_start, |
3061 | .udc_stop = s3c_hsotg_udc_stop, | 3070 | .udc_stop = s3c_hsotg_udc_stop, |
@@ -3492,6 +3501,7 @@ static void s3c_hsotg_release(struct device *dev) | |||
3492 | static int s3c_hsotg_probe(struct platform_device *pdev) | 3501 | static 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)) { |
@@ -3571,7 +3588,7 @@ static int s3c_hsotg_probe(struct platform_device *pdev) | |||
3571 | for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) | 3588 | for (i = 0; i < ARRAY_SIZE(hsotg->supplies); i++) |
3572 | hsotg->supplies[i].supply = s3c_hsotg_supply_names[i]; | 3589 | hsotg->supplies[i].supply = s3c_hsotg_supply_names[i]; |
3573 | 3590 | ||
3574 | ret = regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), | 3591 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hsotg->supplies), |
3575 | hsotg->supplies); | 3592 | hsotg->supplies); |
3576 | if (ret) { | 3593 | if (ret) { |
3577 | dev_err(dev, "failed to request supplies: %d\n", ret); | 3594 | dev_err(dev, "failed to request supplies: %d\n", ret); |
@@ -3661,8 +3678,6 @@ err_ep_mem: | |||
3661 | kfree(eps); | 3678 | kfree(eps); |
3662 | err_supplies: | 3679 | err_supplies: |
3663 | s3c_hsotg_phy_disable(hsotg); | 3680 | s3c_hsotg_phy_disable(hsotg); |
3664 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | ||
3665 | |||
3666 | err_clk: | 3681 | err_clk: |
3667 | clk_disable_unprepare(hsotg->clk); | 3682 | clk_disable_unprepare(hsotg->clk); |
3668 | 3683 | ||
@@ -3687,7 +3702,6 @@ static int s3c_hsotg_remove(struct platform_device *pdev) | |||
3687 | } | 3702 | } |
3688 | 3703 | ||
3689 | s3c_hsotg_phy_disable(hsotg); | 3704 | s3c_hsotg_phy_disable(hsotg); |
3690 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | ||
3691 | 3705 | ||
3692 | clk_disable_unprepare(hsotg->clk); | 3706 | clk_disable_unprepare(hsotg->clk); |
3693 | 3707 | ||