diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-20 11:25:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-20 11:25:44 -0400 |
commit | af52739b922f656eb1f39016fabaabe4baeda2e2 (patch) | |
tree | 79a7aa810d0493cd0cf4adebac26d37f12e8b545 /drivers/usb/musb/sunxi.c | |
parent | 25ed6a5e97809129a1bc852b6b5c7d03baa112c4 (diff) | |
parent | 33688abb2802ff3a230bd2441f765477b94cc89e (diff) |
Merge 4.7-rc4 into staging-next
We want the fixes in here, and we can resolve a merge issue in
drivers/iio/industrialio-trigger.c
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/musb/sunxi.c')
-rw-r--r-- | drivers/usb/musb/sunxi.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c index fdab4232cfbf..76500515dd8b 100644 --- a/drivers/usb/musb/sunxi.c +++ b/drivers/usb/musb/sunxi.c | |||
@@ -80,7 +80,8 @@ static struct musb *sunxi_musb; | |||
80 | 80 | ||
81 | struct sunxi_glue { | 81 | struct sunxi_glue { |
82 | struct device *dev; | 82 | struct device *dev; |
83 | struct platform_device *musb; | 83 | struct musb *musb; |
84 | struct platform_device *musb_pdev; | ||
84 | struct clk *clk; | 85 | struct clk *clk; |
85 | struct reset_control *rst; | 86 | struct reset_control *rst; |
86 | struct phy *phy; | 87 | struct phy *phy; |
@@ -102,7 +103,7 @@ static void sunxi_musb_work(struct work_struct *work) | |||
102 | return; | 103 | return; |
103 | 104 | ||
104 | if (test_and_clear_bit(SUNXI_MUSB_FL_HOSTMODE_PEND, &glue->flags)) { | 105 | if (test_and_clear_bit(SUNXI_MUSB_FL_HOSTMODE_PEND, &glue->flags)) { |
105 | struct musb *musb = platform_get_drvdata(glue->musb); | 106 | struct musb *musb = glue->musb; |
106 | unsigned long flags; | 107 | unsigned long flags; |
107 | u8 devctl; | 108 | u8 devctl; |
108 | 109 | ||
@@ -112,7 +113,7 @@ static void sunxi_musb_work(struct work_struct *work) | |||
112 | if (test_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags)) { | 113 | if (test_bit(SUNXI_MUSB_FL_HOSTMODE, &glue->flags)) { |
113 | set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); | 114 | set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); |
114 | musb->xceiv->otg->default_a = 1; | 115 | musb->xceiv->otg->default_a = 1; |
115 | musb->xceiv->otg->state = OTG_STATE_A_IDLE; | 116 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
116 | MUSB_HST_MODE(musb); | 117 | MUSB_HST_MODE(musb); |
117 | devctl |= MUSB_DEVCTL_SESSION; | 118 | devctl |= MUSB_DEVCTL_SESSION; |
118 | } else { | 119 | } else { |
@@ -145,10 +146,12 @@ static void sunxi_musb_set_vbus(struct musb *musb, int is_on) | |||
145 | { | 146 | { |
146 | struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); | 147 | struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); |
147 | 148 | ||
148 | if (is_on) | 149 | if (is_on) { |
149 | set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); | 150 | set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); |
150 | else | 151 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; |
152 | } else { | ||
151 | clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); | 153 | clear_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); |
154 | } | ||
152 | 155 | ||
153 | schedule_work(&glue->work); | 156 | schedule_work(&glue->work); |
154 | } | 157 | } |
@@ -264,15 +267,6 @@ static int sunxi_musb_init(struct musb *musb) | |||
264 | if (ret) | 267 | if (ret) |
265 | goto error_unregister_notifier; | 268 | goto error_unregister_notifier; |
266 | 269 | ||
267 | if (musb->port_mode == MUSB_PORT_MODE_HOST) { | ||
268 | ret = phy_power_on(glue->phy); | ||
269 | if (ret) | ||
270 | goto error_phy_exit; | ||
271 | set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags); | ||
272 | /* Stop musb work from turning vbus off again */ | ||
273 | set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); | ||
274 | } | ||
275 | |||
276 | musb->isr = sunxi_musb_interrupt; | 270 | musb->isr = sunxi_musb_interrupt; |
277 | 271 | ||
278 | /* Stop the musb-core from doing runtime pm (not supported on sunxi) */ | 272 | /* Stop the musb-core from doing runtime pm (not supported on sunxi) */ |
@@ -280,8 +274,6 @@ static int sunxi_musb_init(struct musb *musb) | |||
280 | 274 | ||
281 | return 0; | 275 | return 0; |
282 | 276 | ||
283 | error_phy_exit: | ||
284 | phy_exit(glue->phy); | ||
285 | error_unregister_notifier: | 277 | error_unregister_notifier: |
286 | if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) | 278 | if (musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) |
287 | extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, | 279 | extcon_unregister_notifier(glue->extcon, EXTCON_USB_HOST, |
@@ -323,10 +315,31 @@ static int sunxi_musb_exit(struct musb *musb) | |||
323 | return 0; | 315 | return 0; |
324 | } | 316 | } |
325 | 317 | ||
318 | static int sunxi_set_mode(struct musb *musb, u8 mode) | ||
319 | { | ||
320 | struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
321 | int ret; | ||
322 | |||
323 | if (mode == MUSB_HOST) { | ||
324 | ret = phy_power_on(glue->phy); | ||
325 | if (ret) | ||
326 | return ret; | ||
327 | |||
328 | set_bit(SUNXI_MUSB_FL_PHY_ON, &glue->flags); | ||
329 | /* Stop musb work from turning vbus off again */ | ||
330 | set_bit(SUNXI_MUSB_FL_VBUS_ON, &glue->flags); | ||
331 | musb->xceiv->otg->state = OTG_STATE_A_WAIT_VRISE; | ||
332 | } | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
326 | static void sunxi_musb_enable(struct musb *musb) | 337 | static void sunxi_musb_enable(struct musb *musb) |
327 | { | 338 | { |
328 | struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); | 339 | struct sunxi_glue *glue = dev_get_drvdata(musb->controller->parent); |
329 | 340 | ||
341 | glue->musb = musb; | ||
342 | |||
330 | /* musb_core does not call us in a balanced manner */ | 343 | /* musb_core does not call us in a balanced manner */ |
331 | if (test_and_set_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags)) | 344 | if (test_and_set_bit(SUNXI_MUSB_FL_ENABLED, &glue->flags)) |
332 | return; | 345 | return; |
@@ -569,6 +582,7 @@ static const struct musb_platform_ops sunxi_musb_ops = { | |||
569 | .exit = sunxi_musb_exit, | 582 | .exit = sunxi_musb_exit, |
570 | .enable = sunxi_musb_enable, | 583 | .enable = sunxi_musb_enable, |
571 | .disable = sunxi_musb_disable, | 584 | .disable = sunxi_musb_disable, |
585 | .set_mode = sunxi_set_mode, | ||
572 | .fifo_offset = sunxi_musb_fifo_offset, | 586 | .fifo_offset = sunxi_musb_fifo_offset, |
573 | .ep_offset = sunxi_musb_ep_offset, | 587 | .ep_offset = sunxi_musb_ep_offset, |
574 | .busctl_offset = sunxi_musb_busctl_offset, | 588 | .busctl_offset = sunxi_musb_busctl_offset, |
@@ -721,9 +735,9 @@ static int sunxi_musb_probe(struct platform_device *pdev) | |||
721 | pinfo.data = &pdata; | 735 | pinfo.data = &pdata; |
722 | pinfo.size_data = sizeof(pdata); | 736 | pinfo.size_data = sizeof(pdata); |
723 | 737 | ||
724 | glue->musb = platform_device_register_full(&pinfo); | 738 | glue->musb_pdev = platform_device_register_full(&pinfo); |
725 | if (IS_ERR(glue->musb)) { | 739 | if (IS_ERR(glue->musb_pdev)) { |
726 | ret = PTR_ERR(glue->musb); | 740 | ret = PTR_ERR(glue->musb_pdev); |
727 | dev_err(&pdev->dev, "Error registering musb dev: %d\n", ret); | 741 | dev_err(&pdev->dev, "Error registering musb dev: %d\n", ret); |
728 | goto err_unregister_usb_phy; | 742 | goto err_unregister_usb_phy; |
729 | } | 743 | } |
@@ -740,7 +754,7 @@ static int sunxi_musb_remove(struct platform_device *pdev) | |||
740 | struct sunxi_glue *glue = platform_get_drvdata(pdev); | 754 | struct sunxi_glue *glue = platform_get_drvdata(pdev); |
741 | struct platform_device *usb_phy = glue->usb_phy; | 755 | struct platform_device *usb_phy = glue->usb_phy; |
742 | 756 | ||
743 | platform_device_unregister(glue->musb); /* Frees glue ! */ | 757 | platform_device_unregister(glue->musb_pdev); |
744 | usb_phy_generic_unregister(usb_phy); | 758 | usb_phy_generic_unregister(usb_phy); |
745 | 759 | ||
746 | return 0; | 760 | return 0; |