diff options
Diffstat (limited to 'drivers/usb/otg')
-rw-r--r-- | drivers/usb/otg/ab8500-usb.c | 4 | ||||
-rw-r--r-- | drivers/usb/otg/fsl_otg.c | 6 | ||||
-rw-r--r-- | drivers/usb/otg/gpio_vbus.c | 4 | ||||
-rw-r--r-- | drivers/usb/otg/isp1301_omap.c | 19 | ||||
-rw-r--r-- | drivers/usb/otg/msm_otg.c | 6 | ||||
-rw-r--r-- | drivers/usb/otg/mv_otg.c | 6 | ||||
-rw-r--r-- | drivers/usb/otg/nop-usb-xceiv.c | 4 | ||||
-rw-r--r-- | drivers/usb/otg/otg.c | 181 | ||||
-rw-r--r-- | drivers/usb/otg/twl4030-usb.c | 73 | ||||
-rw-r--r-- | drivers/usb/otg/twl6030-usb.c | 69 |
10 files changed, 236 insertions, 136 deletions
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index a84af677dc59..ae8ad561f083 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c | |||
@@ -529,7 +529,7 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev) | |||
529 | if (err < 0) | 529 | if (err < 0) |
530 | goto fail0; | 530 | goto fail0; |
531 | 531 | ||
532 | err = usb_set_transceiver(&ab->phy); | 532 | err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2); |
533 | if (err) { | 533 | if (err) { |
534 | dev_err(&pdev->dev, "Can't register transceiver\n"); | 534 | dev_err(&pdev->dev, "Can't register transceiver\n"); |
535 | goto fail1; | 535 | goto fail1; |
@@ -556,7 +556,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev) | |||
556 | 556 | ||
557 | cancel_work_sync(&ab->phy_dis_work); | 557 | cancel_work_sync(&ab->phy_dis_work); |
558 | 558 | ||
559 | usb_set_transceiver(NULL); | 559 | usb_remove_phy(&ab->phy); |
560 | 560 | ||
561 | ab8500_usb_host_phy_dis(ab); | 561 | ab8500_usb_host_phy_dis(ab); |
562 | ab8500_usb_peri_phy_dis(ab); | 562 | ab8500_usb_peri_phy_dis(ab); |
diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index be4a63e8302f..23c798cb2d7f 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c | |||
@@ -806,7 +806,7 @@ static int fsl_otg_conf(struct platform_device *pdev) | |||
806 | fsl_otg_dev = fsl_otg_tc; | 806 | fsl_otg_dev = fsl_otg_tc; |
807 | 807 | ||
808 | /* Store the otg transceiver */ | 808 | /* Store the otg transceiver */ |
809 | status = usb_set_transceiver(&fsl_otg_tc->phy); | 809 | status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2); |
810 | if (status) { | 810 | if (status) { |
811 | pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); | 811 | pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n"); |
812 | goto err; | 812 | goto err; |
@@ -824,7 +824,7 @@ err: | |||
824 | int usb_otg_start(struct platform_device *pdev) | 824 | int usb_otg_start(struct platform_device *pdev) |
825 | { | 825 | { |
826 | struct fsl_otg *p_otg; | 826 | struct fsl_otg *p_otg; |
827 | struct usb_phy *otg_trans = usb_get_transceiver(); | 827 | struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2); |
828 | struct otg_fsm *fsm; | 828 | struct otg_fsm *fsm; |
829 | int status; | 829 | int status; |
830 | struct resource *res; | 830 | struct resource *res; |
@@ -1134,7 +1134,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev) | |||
1134 | { | 1134 | { |
1135 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | 1135 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; |
1136 | 1136 | ||
1137 | usb_set_transceiver(NULL); | 1137 | usb_remove_phy(&fsl_otg_dev->phy); |
1138 | free_irq(fsl_otg_dev->irq, fsl_otg_dev); | 1138 | free_irq(fsl_otg_dev->irq, fsl_otg_dev); |
1139 | 1139 | ||
1140 | iounmap((void *)usb_dr_regs); | 1140 | iounmap((void *)usb_dr_regs); |
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index bde6298a9693..a67ffe22179a 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c | |||
@@ -320,7 +320,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) | |||
320 | } | 320 | } |
321 | 321 | ||
322 | /* only active when a gadget is registered */ | 322 | /* only active when a gadget is registered */ |
323 | err = usb_set_transceiver(&gpio_vbus->phy); | 323 | err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2); |
324 | if (err) { | 324 | if (err) { |
325 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | 325 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", |
326 | err); | 326 | err); |
@@ -354,7 +354,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev) | |||
354 | cancel_delayed_work_sync(&gpio_vbus->work); | 354 | cancel_delayed_work_sync(&gpio_vbus->work); |
355 | regulator_put(gpio_vbus->vbus_draw); | 355 | regulator_put(gpio_vbus->vbus_draw); |
356 | 356 | ||
357 | usb_set_transceiver(NULL); | 357 | usb_remove_phy(&gpio_vbus->phy); |
358 | 358 | ||
359 | free_irq(gpio_vbus->irq, pdev); | 359 | free_irq(gpio_vbus->irq, pdev); |
360 | if (gpio_is_valid(pdata->gpio_pullup)) | 360 | if (gpio_is_valid(pdata->gpio_pullup)) |
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 70cf5d7bca48..75cea4ab0985 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c | |||
@@ -1336,9 +1336,6 @@ static int | |||
1336 | isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) | 1336 | isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) |
1337 | { | 1337 | { |
1338 | struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); | 1338 | struct isp1301 *isp = container_of(otg->phy, struct isp1301, phy); |
1339 | #ifndef CONFIG_USB_OTG | ||
1340 | u32 l; | ||
1341 | #endif | ||
1342 | 1339 | ||
1343 | if (!otg || isp != the_transceiver) | 1340 | if (!otg || isp != the_transceiver) |
1344 | return -ENODEV; | 1341 | return -ENODEV; |
@@ -1365,10 +1362,14 @@ isp1301_set_peripheral(struct usb_otg *otg, struct usb_gadget *gadget) | |||
1365 | otg->gadget = gadget; | 1362 | otg->gadget = gadget; |
1366 | // FIXME update its refcount | 1363 | // FIXME update its refcount |
1367 | 1364 | ||
1368 | l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; | 1365 | { |
1369 | l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); | 1366 | u32 l; |
1370 | l |= OTG_ID; | 1367 | |
1371 | omap_writel(l, OTG_CTRL); | 1368 | l = omap_readl(OTG_CTRL) & OTG_CTRL_MASK; |
1369 | l &= ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS); | ||
1370 | l |= OTG_ID; | ||
1371 | omap_writel(l, OTG_CTRL); | ||
1372 | } | ||
1372 | 1373 | ||
1373 | power_up(isp); | 1374 | power_up(isp); |
1374 | isp->phy.state = OTG_STATE_B_IDLE; | 1375 | isp->phy.state = OTG_STATE_B_IDLE; |
@@ -1610,7 +1611,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
1610 | dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); | 1611 | dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES); |
1611 | #endif | 1612 | #endif |
1612 | 1613 | ||
1613 | status = usb_set_transceiver(&isp->phy); | 1614 | status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2); |
1614 | if (status < 0) | 1615 | if (status < 0) |
1615 | dev_err(&i2c->dev, "can't register transceiver, %d\n", | 1616 | dev_err(&i2c->dev, "can't register transceiver, %d\n", |
1616 | status); | 1617 | status); |
@@ -1649,7 +1650,7 @@ subsys_initcall(isp_init); | |||
1649 | static void __exit isp_exit(void) | 1650 | static void __exit isp_exit(void) |
1650 | { | 1651 | { |
1651 | if (the_transceiver) | 1652 | if (the_transceiver) |
1652 | usb_set_transceiver(NULL); | 1653 | usb_remove_phy(&the_transceiver->phy); |
1653 | i2c_del_driver(&isp1301_driver); | 1654 | i2c_del_driver(&isp1301_driver); |
1654 | } | 1655 | } |
1655 | module_exit(isp_exit); | 1656 | module_exit(isp_exit); |
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index 1d0347c247d1..9f5fc906041a 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c | |||
@@ -1555,9 +1555,9 @@ static int __init msm_otg_probe(struct platform_device *pdev) | |||
1555 | phy->otg->set_host = msm_otg_set_host; | 1555 | phy->otg->set_host = msm_otg_set_host; |
1556 | phy->otg->set_peripheral = msm_otg_set_peripheral; | 1556 | phy->otg->set_peripheral = msm_otg_set_peripheral; |
1557 | 1557 | ||
1558 | ret = usb_set_transceiver(&motg->phy); | 1558 | ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2); |
1559 | if (ret) { | 1559 | if (ret) { |
1560 | dev_err(&pdev->dev, "usb_set_transceiver failed\n"); | 1560 | dev_err(&pdev->dev, "usb_add_phy failed\n"); |
1561 | goto free_irq; | 1561 | goto free_irq; |
1562 | } | 1562 | } |
1563 | 1563 | ||
@@ -1624,7 +1624,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev) | |||
1624 | device_init_wakeup(&pdev->dev, 0); | 1624 | device_init_wakeup(&pdev->dev, 0); |
1625 | pm_runtime_disable(&pdev->dev); | 1625 | pm_runtime_disable(&pdev->dev); |
1626 | 1626 | ||
1627 | usb_set_transceiver(NULL); | 1627 | usb_remove_phy(phy); |
1628 | free_irq(motg->irq, motg); | 1628 | free_irq(motg->irq, motg); |
1629 | 1629 | ||
1630 | /* | 1630 | /* |
diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c index 6cc6c3ffbb83..3f124e8f5792 100644 --- a/drivers/usb/otg/mv_otg.c +++ b/drivers/usb/otg/mv_otg.c | |||
@@ -690,7 +690,7 @@ int mv_otg_remove(struct platform_device *pdev) | |||
690 | for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++) | 690 | for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++) |
691 | clk_put(mvotg->clk[clk_i]); | 691 | clk_put(mvotg->clk[clk_i]); |
692 | 692 | ||
693 | usb_set_transceiver(NULL); | 693 | usb_remove_phy(&mvotg->phy); |
694 | platform_set_drvdata(pdev, NULL); | 694 | platform_set_drvdata(pdev, NULL); |
695 | 695 | ||
696 | kfree(mvotg->phy.otg); | 696 | kfree(mvotg->phy.otg); |
@@ -853,7 +853,7 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
853 | goto err_disable_clk; | 853 | goto err_disable_clk; |
854 | } | 854 | } |
855 | 855 | ||
856 | retval = usb_set_transceiver(&mvotg->phy); | 856 | retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2); |
857 | if (retval < 0) { | 857 | if (retval < 0) { |
858 | dev_err(&pdev->dev, "can't register transceiver, %d\n", | 858 | dev_err(&pdev->dev, "can't register transceiver, %d\n", |
859 | retval); | 859 | retval); |
@@ -880,7 +880,7 @@ static int mv_otg_probe(struct platform_device *pdev) | |||
880 | return 0; | 880 | return 0; |
881 | 881 | ||
882 | err_set_transceiver: | 882 | err_set_transceiver: |
883 | usb_set_transceiver(NULL); | 883 | usb_remove_phy(&mvotg->phy); |
884 | err_free_irq: | 884 | err_free_irq: |
885 | free_irq(mvotg->irq, mvotg); | 885 | free_irq(mvotg->irq, mvotg); |
886 | err_disable_clk: | 886 | err_disable_clk: |
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 58b26df6afd1..803f958f4133 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
@@ -117,7 +117,7 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) | |||
117 | nop->phy.otg->set_host = nop_set_host; | 117 | nop->phy.otg->set_host = nop_set_host; |
118 | nop->phy.otg->set_peripheral = nop_set_peripheral; | 118 | nop->phy.otg->set_peripheral = nop_set_peripheral; |
119 | 119 | ||
120 | err = usb_set_transceiver(&nop->phy); | 120 | err = usb_add_phy(&nop->phy, USB_PHY_TYPE_USB2); |
121 | if (err) { | 121 | if (err) { |
122 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | 122 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", |
123 | err); | 123 | err); |
@@ -139,7 +139,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) | |||
139 | { | 139 | { |
140 | struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); | 140 | struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); |
141 | 141 | ||
142 | usb_set_transceiver(NULL); | 142 | usb_remove_phy(&nop->phy); |
143 | 143 | ||
144 | platform_set_drvdata(pdev, NULL); | 144 | platform_set_drvdata(pdev, NULL); |
145 | kfree(nop->phy.otg); | 145 | kfree(nop->phy.otg); |
diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 801e597a1541..1bf60a22595c 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c | |||
@@ -11,60 +11,195 @@ | |||
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
14 | #include <linux/err.h> | ||
14 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/slab.h> | ||
15 | 17 | ||
16 | #include <linux/usb/otg.h> | 18 | #include <linux/usb/otg.h> |
17 | 19 | ||
18 | static struct usb_phy *phy; | 20 | static LIST_HEAD(phy_list); |
21 | static DEFINE_SPINLOCK(phy_lock); | ||
22 | |||
23 | static struct usb_phy *__usb_find_phy(struct list_head *list, | ||
24 | enum usb_phy_type type) | ||
25 | { | ||
26 | struct usb_phy *phy = NULL; | ||
27 | |||
28 | list_for_each_entry(phy, list, head) { | ||
29 | if (phy->type != type) | ||
30 | continue; | ||
31 | |||
32 | return phy; | ||
33 | } | ||
34 | |||
35 | return ERR_PTR(-ENODEV); | ||
36 | } | ||
37 | |||
38 | static void devm_usb_phy_release(struct device *dev, void *res) | ||
39 | { | ||
40 | struct usb_phy *phy = *(struct usb_phy **)res; | ||
41 | |||
42 | usb_put_phy(phy); | ||
43 | } | ||
44 | |||
45 | static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) | ||
46 | { | ||
47 | return res == match_data; | ||
48 | } | ||
19 | 49 | ||
20 | /** | 50 | /** |
21 | * usb_get_transceiver - find the (single) USB transceiver | 51 | * devm_usb_get_phy - find the USB PHY |
52 | * @dev - device that requests this phy | ||
53 | * @type - the type of the phy the controller requires | ||
22 | * | 54 | * |
23 | * Returns the transceiver driver, after getting a refcount to it; or | 55 | * Gets the phy using usb_get_phy(), and associates a device with it using |
24 | * null if there is no such transceiver. The caller is responsible for | 56 | * devres. On driver detach, release function is invoked on the devres data, |
25 | * calling usb_put_transceiver() to release that count. | 57 | * then, devres data is freed. |
26 | * | 58 | * |
27 | * For use by USB host and peripheral drivers. | 59 | * For use by USB host and peripheral drivers. |
28 | */ | 60 | */ |
29 | struct usb_phy *usb_get_transceiver(void) | 61 | struct usb_phy *devm_usb_get_phy(struct device *dev, enum usb_phy_type type) |
30 | { | 62 | { |
31 | if (phy) | 63 | struct usb_phy **ptr, *phy; |
32 | get_device(phy->dev); | 64 | |
65 | ptr = devres_alloc(devm_usb_phy_release, sizeof(*ptr), GFP_KERNEL); | ||
66 | if (!ptr) | ||
67 | return NULL; | ||
68 | |||
69 | phy = usb_get_phy(type); | ||
70 | if (!IS_ERR(phy)) { | ||
71 | *ptr = phy; | ||
72 | devres_add(dev, ptr); | ||
73 | } else | ||
74 | devres_free(ptr); | ||
75 | |||
76 | return phy; | ||
77 | } | ||
78 | EXPORT_SYMBOL(devm_usb_get_phy); | ||
79 | |||
80 | /** | ||
81 | * usb_get_phy - find the USB PHY | ||
82 | * @type - the type of the phy the controller requires | ||
83 | * | ||
84 | * Returns the phy driver, after getting a refcount to it; or | ||
85 | * -ENODEV if there is no such phy. The caller is responsible for | ||
86 | * calling usb_put_phy() to release that count. | ||
87 | * | ||
88 | * For use by USB host and peripheral drivers. | ||
89 | */ | ||
90 | struct usb_phy *usb_get_phy(enum usb_phy_type type) | ||
91 | { | ||
92 | struct usb_phy *phy = NULL; | ||
93 | unsigned long flags; | ||
94 | |||
95 | spin_lock_irqsave(&phy_lock, flags); | ||
96 | |||
97 | phy = __usb_find_phy(&phy_list, type); | ||
98 | if (IS_ERR(phy)) { | ||
99 | pr_err("unable to find transceiver of type %s\n", | ||
100 | usb_phy_type_string(type)); | ||
101 | goto err0; | ||
102 | } | ||
103 | |||
104 | get_device(phy->dev); | ||
105 | |||
106 | err0: | ||
107 | spin_unlock_irqrestore(&phy_lock, flags); | ||
108 | |||
33 | return phy; | 109 | return phy; |
34 | } | 110 | } |
35 | EXPORT_SYMBOL(usb_get_transceiver); | 111 | EXPORT_SYMBOL(usb_get_phy); |
112 | |||
113 | /** | ||
114 | * devm_usb_put_phy - release the USB PHY | ||
115 | * @dev - device that wants to release this phy | ||
116 | * @phy - the phy returned by devm_usb_get_phy() | ||
117 | * | ||
118 | * destroys the devres associated with this phy and invokes usb_put_phy | ||
119 | * to release the phy. | ||
120 | * | ||
121 | * For use by USB host and peripheral drivers. | ||
122 | */ | ||
123 | void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) | ||
124 | { | ||
125 | int r; | ||
126 | |||
127 | r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); | ||
128 | dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); | ||
129 | } | ||
130 | EXPORT_SYMBOL(devm_usb_put_phy); | ||
36 | 131 | ||
37 | /** | 132 | /** |
38 | * usb_put_transceiver - release the (single) USB transceiver | 133 | * usb_put_phy - release the USB PHY |
39 | * @x: the transceiver returned by usb_get_transceiver() | 134 | * @x: the phy returned by usb_get_phy() |
40 | * | 135 | * |
41 | * Releases a refcount the caller received from usb_get_transceiver(). | 136 | * Releases a refcount the caller received from usb_get_phy(). |
42 | * | 137 | * |
43 | * For use by USB host and peripheral drivers. | 138 | * For use by USB host and peripheral drivers. |
44 | */ | 139 | */ |
45 | void usb_put_transceiver(struct usb_phy *x) | 140 | void usb_put_phy(struct usb_phy *x) |
46 | { | 141 | { |
47 | if (x) | 142 | if (x) |
48 | put_device(x->dev); | 143 | put_device(x->dev); |
49 | } | 144 | } |
50 | EXPORT_SYMBOL(usb_put_transceiver); | 145 | EXPORT_SYMBOL(usb_put_phy); |
51 | 146 | ||
52 | /** | 147 | /** |
53 | * usb_set_transceiver - declare the (single) USB transceiver | 148 | * usb_add_phy - declare the USB PHY |
54 | * @x: the USB transceiver to be used; or NULL | 149 | * @x: the USB phy to be used; or NULL |
150 | * @type - the type of this PHY | ||
55 | * | 151 | * |
56 | * This call is exclusively for use by transceiver drivers, which | 152 | * This call is exclusively for use by phy drivers, which |
57 | * coordinate the activities of drivers for host and peripheral | 153 | * coordinate the activities of drivers for host and peripheral |
58 | * controllers, and in some cases for VBUS current regulation. | 154 | * controllers, and in some cases for VBUS current regulation. |
59 | */ | 155 | */ |
60 | int usb_set_transceiver(struct usb_phy *x) | 156 | int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) |
157 | { | ||
158 | int ret = 0; | ||
159 | unsigned long flags; | ||
160 | struct usb_phy *phy; | ||
161 | |||
162 | if (x && x->type != USB_PHY_TYPE_UNDEFINED) { | ||
163 | dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | spin_lock_irqsave(&phy_lock, flags); | ||
168 | |||
169 | list_for_each_entry(phy, &phy_list, head) { | ||
170 | if (phy->type == type) { | ||
171 | ret = -EBUSY; | ||
172 | dev_err(x->dev, "transceiver type %s already exists\n", | ||
173 | usb_phy_type_string(type)); | ||
174 | goto out; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | x->type = type; | ||
179 | list_add_tail(&x->head, &phy_list); | ||
180 | |||
181 | out: | ||
182 | spin_unlock_irqrestore(&phy_lock, flags); | ||
183 | return ret; | ||
184 | } | ||
185 | EXPORT_SYMBOL(usb_add_phy); | ||
186 | |||
187 | /** | ||
188 | * usb_remove_phy - remove the OTG PHY | ||
189 | * @x: the USB OTG PHY to be removed; | ||
190 | * | ||
191 | * This reverts the effects of usb_add_phy | ||
192 | */ | ||
193 | void usb_remove_phy(struct usb_phy *x) | ||
61 | { | 194 | { |
62 | if (phy && x) | 195 | unsigned long flags; |
63 | return -EBUSY; | 196 | |
64 | phy = x; | 197 | spin_lock_irqsave(&phy_lock, flags); |
65 | return 0; | 198 | if (x) |
199 | list_del(&x->head); | ||
200 | spin_unlock_irqrestore(&phy_lock, flags); | ||
66 | } | 201 | } |
67 | EXPORT_SYMBOL(usb_set_transceiver); | 202 | EXPORT_SYMBOL(usb_remove_phy); |
68 | 203 | ||
69 | const char *otg_state_string(enum usb_otg_state state) | 204 | const char *otg_state_string(enum usb_otg_state state) |
70 | { | 205 | { |
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index c4a86da858e2..523cad5bfea9 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -33,11 +33,11 @@ | |||
33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
36 | #include <linux/usb/musb-omap.h> | ||
36 | #include <linux/usb/ulpi.h> | 37 | #include <linux/usb/ulpi.h> |
37 | #include <linux/i2c/twl.h> | 38 | #include <linux/i2c/twl.h> |
38 | #include <linux/regulator/consumer.h> | 39 | #include <linux/regulator/consumer.h> |
39 | #include <linux/err.h> | 40 | #include <linux/err.h> |
40 | #include <linux/notifier.h> | ||
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | 42 | ||
43 | /* Register defines */ | 43 | /* Register defines */ |
@@ -159,7 +159,7 @@ struct twl4030_usb { | |||
159 | enum twl4030_usb_mode usb_mode; | 159 | enum twl4030_usb_mode usb_mode; |
160 | 160 | ||
161 | int irq; | 161 | int irq; |
162 | u8 linkstat; | 162 | enum omap_musb_vbus_id_status linkstat; |
163 | bool vbus_supplied; | 163 | bool vbus_supplied; |
164 | u8 asleep; | 164 | u8 asleep; |
165 | bool irq_enabled; | 165 | bool irq_enabled; |
@@ -246,11 +246,11 @@ twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) | |||
246 | 246 | ||
247 | /*-------------------------------------------------------------------------*/ | 247 | /*-------------------------------------------------------------------------*/ |
248 | 248 | ||
249 | static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl) | 249 | static enum omap_musb_vbus_id_status |
250 | twl4030_usb_linkstat(struct twl4030_usb *twl) | ||
250 | { | 251 | { |
251 | int status; | 252 | int status; |
252 | int linkstat = USB_EVENT_NONE; | 253 | enum omap_musb_vbus_id_status linkstat = OMAP_MUSB_UNKNOWN; |
253 | struct usb_otg *otg = twl->phy.otg; | ||
254 | 254 | ||
255 | twl->vbus_supplied = false; | 255 | twl->vbus_supplied = false; |
256 | 256 | ||
@@ -273,30 +273,23 @@ static enum usb_phy_events twl4030_usb_linkstat(struct twl4030_usb *twl) | |||
273 | twl->vbus_supplied = true; | 273 | twl->vbus_supplied = true; |
274 | 274 | ||
275 | if (status & BIT(2)) | 275 | if (status & BIT(2)) |
276 | linkstat = USB_EVENT_ID; | 276 | linkstat = OMAP_MUSB_ID_GROUND; |
277 | else | 277 | else |
278 | linkstat = USB_EVENT_VBUS; | 278 | linkstat = OMAP_MUSB_VBUS_VALID; |
279 | } else | 279 | } else { |
280 | linkstat = USB_EVENT_NONE; | 280 | if (twl->linkstat != OMAP_MUSB_UNKNOWN) |
281 | linkstat = OMAP_MUSB_VBUS_OFF; | ||
282 | } | ||
281 | 283 | ||
282 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", | 284 | dev_dbg(twl->dev, "HW_CONDITIONS 0x%02x/%d; link %d\n", |
283 | status, status, linkstat); | 285 | status, status, linkstat); |
284 | 286 | ||
285 | twl->phy.last_event = linkstat; | ||
286 | |||
287 | /* REVISIT this assumes host and peripheral controllers | 287 | /* REVISIT this assumes host and peripheral controllers |
288 | * are registered, and that both are active... | 288 | * are registered, and that both are active... |
289 | */ | 289 | */ |
290 | 290 | ||
291 | spin_lock_irq(&twl->lock); | 291 | spin_lock_irq(&twl->lock); |
292 | twl->linkstat = linkstat; | 292 | twl->linkstat = linkstat; |
293 | if (linkstat == USB_EVENT_ID) { | ||
294 | otg->default_a = true; | ||
295 | twl->phy.state = OTG_STATE_A_IDLE; | ||
296 | } else { | ||
297 | otg->default_a = false; | ||
298 | twl->phy.state = OTG_STATE_B_IDLE; | ||
299 | } | ||
300 | spin_unlock_irq(&twl->lock); | 293 | spin_unlock_irq(&twl->lock); |
301 | 294 | ||
302 | return linkstat; | 295 | return linkstat; |
@@ -501,10 +494,10 @@ static DEVICE_ATTR(vbus, 0444, twl4030_usb_vbus_show, NULL); | |||
501 | static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | 494 | static irqreturn_t twl4030_usb_irq(int irq, void *_twl) |
502 | { | 495 | { |
503 | struct twl4030_usb *twl = _twl; | 496 | struct twl4030_usb *twl = _twl; |
504 | int status; | 497 | enum omap_musb_vbus_id_status status; |
505 | 498 | ||
506 | status = twl4030_usb_linkstat(twl); | 499 | status = twl4030_usb_linkstat(twl); |
507 | if (status >= 0) { | 500 | if (status > 0) { |
508 | /* FIXME add a set_power() method so that B-devices can | 501 | /* FIXME add a set_power() method so that B-devices can |
509 | * configure the charger appropriately. It's not always | 502 | * configure the charger appropriately. It's not always |
510 | * correct to consume VBUS power, and how much current to | 503 | * correct to consume VBUS power, and how much current to |
@@ -516,13 +509,13 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
516 | * USB_LINK_VBUS state. musb_hdrc won't care until it | 509 | * USB_LINK_VBUS state. musb_hdrc won't care until it |
517 | * starts to handle softconnect right. | 510 | * starts to handle softconnect right. |
518 | */ | 511 | */ |
519 | if (status == USB_EVENT_NONE) | 512 | if (status == OMAP_MUSB_VBUS_OFF || |
513 | status == OMAP_MUSB_ID_FLOAT) | ||
520 | twl4030_phy_suspend(twl, 0); | 514 | twl4030_phy_suspend(twl, 0); |
521 | else | 515 | else |
522 | twl4030_phy_resume(twl); | 516 | twl4030_phy_resume(twl); |
523 | 517 | ||
524 | atomic_notifier_call_chain(&twl->phy.notifier, status, | 518 | omap_musb_mailbox(twl->linkstat); |
525 | twl->phy.otg->gadget); | ||
526 | } | 519 | } |
527 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 520 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
528 | 521 | ||
@@ -531,11 +524,12 @@ static irqreturn_t twl4030_usb_irq(int irq, void *_twl) | |||
531 | 524 | ||
532 | static void twl4030_usb_phy_init(struct twl4030_usb *twl) | 525 | static void twl4030_usb_phy_init(struct twl4030_usb *twl) |
533 | { | 526 | { |
534 | int status; | 527 | enum omap_musb_vbus_id_status status; |
535 | 528 | ||
536 | status = twl4030_usb_linkstat(twl); | 529 | status = twl4030_usb_linkstat(twl); |
537 | if (status >= 0) { | 530 | if (status > 0) { |
538 | if (status == USB_EVENT_NONE) { | 531 | if (status == OMAP_MUSB_VBUS_OFF || |
532 | status == OMAP_MUSB_ID_FLOAT) { | ||
539 | __twl4030_phy_power(twl, 0); | 533 | __twl4030_phy_power(twl, 0); |
540 | twl->asleep = 1; | 534 | twl->asleep = 1; |
541 | } else { | 535 | } else { |
@@ -543,8 +537,7 @@ static void twl4030_usb_phy_init(struct twl4030_usb *twl) | |||
543 | twl->asleep = 0; | 537 | twl->asleep = 0; |
544 | } | 538 | } |
545 | 539 | ||
546 | atomic_notifier_call_chain(&twl->phy.notifier, status, | 540 | omap_musb_mailbox(twl->linkstat); |
547 | twl->phy.otg->gadget); | ||
548 | } | 541 | } |
549 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | 542 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); |
550 | } | 543 | } |
@@ -598,21 +591,20 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
598 | return -EINVAL; | 591 | return -EINVAL; |
599 | } | 592 | } |
600 | 593 | ||
601 | twl = kzalloc(sizeof *twl, GFP_KERNEL); | 594 | twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL); |
602 | if (!twl) | 595 | if (!twl) |
603 | return -ENOMEM; | 596 | return -ENOMEM; |
604 | 597 | ||
605 | otg = kzalloc(sizeof *otg, GFP_KERNEL); | 598 | otg = devm_kzalloc(&pdev->dev, sizeof *otg, GFP_KERNEL); |
606 | if (!otg) { | 599 | if (!otg) |
607 | kfree(twl); | ||
608 | return -ENOMEM; | 600 | return -ENOMEM; |
609 | } | ||
610 | 601 | ||
611 | twl->dev = &pdev->dev; | 602 | twl->dev = &pdev->dev; |
612 | twl->irq = platform_get_irq(pdev, 0); | 603 | twl->irq = platform_get_irq(pdev, 0); |
613 | twl->usb_mode = pdata->usb_mode; | 604 | twl->usb_mode = pdata->usb_mode; |
614 | twl->vbus_supplied = false; | 605 | twl->vbus_supplied = false; |
615 | twl->asleep = 1; | 606 | twl->asleep = 1; |
607 | twl->linkstat = OMAP_MUSB_UNKNOWN; | ||
616 | 608 | ||
617 | twl->phy.dev = twl->dev; | 609 | twl->phy.dev = twl->dev; |
618 | twl->phy.label = "twl4030"; | 610 | twl->phy.label = "twl4030"; |
@@ -629,18 +621,14 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
629 | err = twl4030_usb_ldo_init(twl); | 621 | err = twl4030_usb_ldo_init(twl); |
630 | if (err) { | 622 | if (err) { |
631 | dev_err(&pdev->dev, "ldo init failed\n"); | 623 | dev_err(&pdev->dev, "ldo init failed\n"); |
632 | kfree(otg); | ||
633 | kfree(twl); | ||
634 | return err; | 624 | return err; |
635 | } | 625 | } |
636 | usb_set_transceiver(&twl->phy); | 626 | usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); |
637 | 627 | ||
638 | platform_set_drvdata(pdev, twl); | 628 | platform_set_drvdata(pdev, twl); |
639 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 629 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
640 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 630 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
641 | 631 | ||
642 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); | ||
643 | |||
644 | /* Our job is to use irqs and status from the power module | 632 | /* Our job is to use irqs and status from the power module |
645 | * to keep the transceiver disabled when nothing's connected. | 633 | * to keep the transceiver disabled when nothing's connected. |
646 | * | 634 | * |
@@ -651,13 +639,11 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
651 | */ | 639 | */ |
652 | twl->irq_enabled = true; | 640 | twl->irq_enabled = true; |
653 | status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, | 641 | status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq, |
654 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 642 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | |
655 | "twl4030_usb", twl); | 643 | IRQF_ONESHOT, "twl4030_usb", twl); |
656 | if (status < 0) { | 644 | if (status < 0) { |
657 | dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", | 645 | dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n", |
658 | twl->irq, status); | 646 | twl->irq, status); |
659 | kfree(otg); | ||
660 | kfree(twl); | ||
661 | return status; | 647 | return status; |
662 | } | 648 | } |
663 | 649 | ||
@@ -701,9 +687,6 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) | |||
701 | regulator_put(twl->usb1v8); | 687 | regulator_put(twl->usb1v8); |
702 | regulator_put(twl->usb3v1); | 688 | regulator_put(twl->usb3v1); |
703 | 689 | ||
704 | kfree(twl->phy.otg); | ||
705 | kfree(twl); | ||
706 | |||
707 | return 0; | 690 | return 0; |
708 | } | 691 | } |
709 | 692 | ||
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index 0eabb049b6a9..a3d0c0405cca 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c | |||
@@ -26,10 +26,10 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
28 | #include <linux/usb/otg.h> | 28 | #include <linux/usb/otg.h> |
29 | #include <linux/usb/musb-omap.h> | ||
29 | #include <linux/i2c/twl.h> | 30 | #include <linux/i2c/twl.h> |
30 | #include <linux/regulator/consumer.h> | 31 | #include <linux/regulator/consumer.h> |
31 | #include <linux/err.h> | 32 | #include <linux/err.h> |
32 | #include <linux/notifier.h> | ||
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
35 | 35 | ||
@@ -100,7 +100,7 @@ struct twl6030_usb { | |||
100 | 100 | ||
101 | int irq1; | 101 | int irq1; |
102 | int irq2; | 102 | int irq2; |
103 | u8 linkstat; | 103 | enum omap_musb_vbus_id_status linkstat; |
104 | u8 asleep; | 104 | u8 asleep; |
105 | bool irq_enabled; | 105 | bool irq_enabled; |
106 | bool vbus_enable; | 106 | bool vbus_enable; |
@@ -147,7 +147,7 @@ static int twl6030_phy_init(struct usb_phy *x) | |||
147 | dev = twl->dev; | 147 | dev = twl->dev; |
148 | pdata = dev->platform_data; | 148 | pdata = dev->platform_data; |
149 | 149 | ||
150 | if (twl->linkstat == USB_EVENT_ID) | 150 | if (twl->linkstat == OMAP_MUSB_ID_GROUND) |
151 | pdata->phy_power(twl->dev, 1, 1); | 151 | pdata->phy_power(twl->dev, 1, 1); |
152 | else | 152 | else |
153 | pdata->phy_power(twl->dev, 0, 1); | 153 | pdata->phy_power(twl->dev, 0, 1); |
@@ -235,13 +235,13 @@ static ssize_t twl6030_usb_vbus_show(struct device *dev, | |||
235 | spin_lock_irqsave(&twl->lock, flags); | 235 | spin_lock_irqsave(&twl->lock, flags); |
236 | 236 | ||
237 | switch (twl->linkstat) { | 237 | switch (twl->linkstat) { |
238 | case USB_EVENT_VBUS: | 238 | case OMAP_MUSB_VBUS_VALID: |
239 | ret = snprintf(buf, PAGE_SIZE, "vbus\n"); | 239 | ret = snprintf(buf, PAGE_SIZE, "vbus\n"); |
240 | break; | 240 | break; |
241 | case USB_EVENT_ID: | 241 | case OMAP_MUSB_ID_GROUND: |
242 | ret = snprintf(buf, PAGE_SIZE, "id\n"); | 242 | ret = snprintf(buf, PAGE_SIZE, "id\n"); |
243 | break; | 243 | break; |
244 | case USB_EVENT_NONE: | 244 | case OMAP_MUSB_VBUS_OFF: |
245 | ret = snprintf(buf, PAGE_SIZE, "none\n"); | 245 | ret = snprintf(buf, PAGE_SIZE, "none\n"); |
246 | break; | 246 | break; |
247 | default: | 247 | default: |
@@ -256,8 +256,7 @@ static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); | |||
256 | static irqreturn_t twl6030_usb_irq(int irq, void *_twl) | 256 | static irqreturn_t twl6030_usb_irq(int irq, void *_twl) |
257 | { | 257 | { |
258 | struct twl6030_usb *twl = _twl; | 258 | struct twl6030_usb *twl = _twl; |
259 | struct usb_otg *otg = twl->phy.otg; | 259 | enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; |
260 | int status; | ||
261 | u8 vbus_state, hw_state; | 260 | u8 vbus_state, hw_state; |
262 | 261 | ||
263 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); | 262 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); |
@@ -268,22 +267,18 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) | |||
268 | if (vbus_state & VBUS_DET) { | 267 | if (vbus_state & VBUS_DET) { |
269 | regulator_enable(twl->usb3v3); | 268 | regulator_enable(twl->usb3v3); |
270 | twl->asleep = 1; | 269 | twl->asleep = 1; |
271 | status = USB_EVENT_VBUS; | 270 | status = OMAP_MUSB_VBUS_VALID; |
272 | otg->default_a = false; | ||
273 | twl->phy.state = OTG_STATE_B_IDLE; | ||
274 | twl->linkstat = status; | 271 | twl->linkstat = status; |
275 | twl->phy.last_event = status; | 272 | omap_musb_mailbox(status); |
276 | atomic_notifier_call_chain(&twl->phy.notifier, | ||
277 | status, otg->gadget); | ||
278 | } else { | 273 | } else { |
279 | status = USB_EVENT_NONE; | 274 | if (twl->linkstat != OMAP_MUSB_UNKNOWN) { |
280 | twl->linkstat = status; | 275 | status = OMAP_MUSB_VBUS_OFF; |
281 | twl->phy.last_event = status; | 276 | twl->linkstat = status; |
282 | atomic_notifier_call_chain(&twl->phy.notifier, | 277 | omap_musb_mailbox(status); |
283 | status, otg->gadget); | 278 | if (twl->asleep) { |
284 | if (twl->asleep) { | 279 | regulator_disable(twl->usb3v3); |
285 | regulator_disable(twl->usb3v3); | 280 | twl->asleep = 0; |
286 | twl->asleep = 0; | 281 | } |
287 | } | 282 | } |
288 | } | 283 | } |
289 | } | 284 | } |
@@ -295,8 +290,7 @@ static irqreturn_t twl6030_usb_irq(int irq, void *_twl) | |||
295 | static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) | 290 | static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) |
296 | { | 291 | { |
297 | struct twl6030_usb *twl = _twl; | 292 | struct twl6030_usb *twl = _twl; |
298 | struct usb_otg *otg = twl->phy.otg; | 293 | enum omap_musb_vbus_id_status status = OMAP_MUSB_UNKNOWN; |
299 | int status = USB_EVENT_NONE; | ||
300 | u8 hw_state; | 294 | u8 hw_state; |
301 | 295 | ||
302 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); | 296 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); |
@@ -307,13 +301,11 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) | |||
307 | twl->asleep = 1; | 301 | twl->asleep = 1; |
308 | twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); | 302 | twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); |
309 | twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); | 303 | twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); |
310 | status = USB_EVENT_ID; | 304 | status = OMAP_MUSB_ID_GROUND; |
311 | otg->default_a = true; | 305 | otg->default_a = true; |
312 | twl->phy.state = OTG_STATE_A_IDLE; | 306 | twl->phy.state = OTG_STATE_A_IDLE; |
313 | twl->linkstat = status; | 307 | twl->linkstat = status; |
314 | twl->phy.last_event = status; | 308 | omap_musb_mailbox(status); |
315 | atomic_notifier_call_chain(&twl->phy.notifier, status, | ||
316 | otg->gadget); | ||
317 | } else { | 309 | } else { |
318 | twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); | 310 | twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); |
319 | twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); | 311 | twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); |
@@ -402,20 +394,19 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) | |||
402 | struct device *dev = &pdev->dev; | 394 | struct device *dev = &pdev->dev; |
403 | pdata = dev->platform_data; | 395 | pdata = dev->platform_data; |
404 | 396 | ||
405 | twl = kzalloc(sizeof *twl, GFP_KERNEL); | 397 | twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL); |
406 | if (!twl) | 398 | if (!twl) |
407 | return -ENOMEM; | 399 | return -ENOMEM; |
408 | 400 | ||
409 | otg = kzalloc(sizeof *otg, GFP_KERNEL); | 401 | otg = devm_kzalloc(dev, sizeof *otg, GFP_KERNEL); |
410 | if (!otg) { | 402 | if (!otg) |
411 | kfree(twl); | ||
412 | return -ENOMEM; | 403 | return -ENOMEM; |
413 | } | ||
414 | 404 | ||
415 | twl->dev = &pdev->dev; | 405 | twl->dev = &pdev->dev; |
416 | twl->irq1 = platform_get_irq(pdev, 0); | 406 | twl->irq1 = platform_get_irq(pdev, 0); |
417 | twl->irq2 = platform_get_irq(pdev, 1); | 407 | twl->irq2 = platform_get_irq(pdev, 1); |
418 | twl->features = pdata->features; | 408 | twl->features = pdata->features; |
409 | twl->linkstat = OMAP_MUSB_UNKNOWN; | ||
419 | 410 | ||
420 | twl->phy.dev = twl->dev; | 411 | twl->phy.dev = twl->dev; |
421 | twl->phy.label = "twl6030"; | 412 | twl->phy.label = "twl6030"; |
@@ -436,18 +427,14 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) | |||
436 | err = twl6030_usb_ldo_init(twl); | 427 | err = twl6030_usb_ldo_init(twl); |
437 | if (err) { | 428 | if (err) { |
438 | dev_err(&pdev->dev, "ldo init failed\n"); | 429 | dev_err(&pdev->dev, "ldo init failed\n"); |
439 | kfree(otg); | ||
440 | kfree(twl); | ||
441 | return err; | 430 | return err; |
442 | } | 431 | } |
443 | usb_set_transceiver(&twl->phy); | 432 | usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2); |
444 | 433 | ||
445 | platform_set_drvdata(pdev, twl); | 434 | platform_set_drvdata(pdev, twl); |
446 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | 435 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) |
447 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | 436 | dev_warn(&pdev->dev, "could not create sysfs file\n"); |
448 | 437 | ||
449 | ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier); | ||
450 | |||
451 | INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); | 438 | INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work); |
452 | 439 | ||
453 | twl->irq_enabled = true; | 440 | twl->irq_enabled = true; |
@@ -458,8 +445,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) | |||
458 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | 445 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", |
459 | twl->irq1, status); | 446 | twl->irq1, status); |
460 | device_remove_file(twl->dev, &dev_attr_vbus); | 447 | device_remove_file(twl->dev, &dev_attr_vbus); |
461 | kfree(otg); | ||
462 | kfree(twl); | ||
463 | return status; | 448 | return status; |
464 | } | 449 | } |
465 | 450 | ||
@@ -471,8 +456,6 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) | |||
471 | twl->irq2, status); | 456 | twl->irq2, status); |
472 | free_irq(twl->irq1, twl); | 457 | free_irq(twl->irq1, twl); |
473 | device_remove_file(twl->dev, &dev_attr_vbus); | 458 | device_remove_file(twl->dev, &dev_attr_vbus); |
474 | kfree(otg); | ||
475 | kfree(twl); | ||
476 | return status; | 459 | return status; |
477 | } | 460 | } |
478 | 461 | ||
@@ -503,8 +486,6 @@ static int __exit twl6030_usb_remove(struct platform_device *pdev) | |||
503 | pdata->phy_exit(twl->dev); | 486 | pdata->phy_exit(twl->dev); |
504 | device_remove_file(twl->dev, &dev_attr_vbus); | 487 | device_remove_file(twl->dev, &dev_attr_vbus); |
505 | cancel_work_sync(&twl->set_vbus_work); | 488 | cancel_work_sync(&twl->set_vbus_work); |
506 | kfree(twl->phy.otg); | ||
507 | kfree(twl); | ||
508 | 489 | ||
509 | return 0; | 490 | return 0; |
510 | } | 491 | } |