diff options
35 files changed, 152 insertions, 57 deletions
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index cf5ffc4d104..6bd6f1c4196 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c @@ -2688,7 +2688,7 @@ static int __devinit ab8500_charger_probe(struct platform_device *pdev)  		goto free_ac;  	} -	di->usb_phy = usb_get_phy(); +	di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!di->usb_phy) {  		dev_err(di->dev, "failed to get usb transceiver\n");  		ret = -EINVAL; diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 50773ae6f72..090e5f9e72c 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -415,7 +415,7 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev)  	if (!isp)  		return -ENOMEM; -	isp->phy = usb_get_phy(); +	isp->phy = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!isp->phy)  		goto fail0; diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index e0f206b0775..7602d49e4d8 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -321,7 +321,7 @@ static int pda_power_probe(struct platform_device *pdev)  	}  #ifdef CONFIG_USB_OTG_UTILS -	transceiver = usb_get_phy(); +	transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  	if (transceiver && !pdata->is_usb_online) {  		pdata->is_usb_online = otg_is_usb_online;  	} diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index fcddd115cc0..13f9db2e853 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -479,7 +479,7 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)  	INIT_WORK(&bci->work, twl4030_bci_usb_work); -	bci->transceiver = usb_get_phy(); +	bci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  	if (bci->transceiver != NULL) {  		bci->usb_nb.notifier_call = twl4030_bci_usb_ncb;  		usb_register_notifier(bci->transceiver, &bci->usb_nb); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 4468f2c2ddd..a06d28b119f 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1687,7 +1687,7 @@ static int udc_start(struct ci13xxx *udc)  	udc->gadget.ep0 = &udc->ep0in->ep; -	udc->transceiver = usb_get_phy(); +	udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  	if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {  		if (udc->transceiver == NULL) { diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index d7038509b95..0808820ba49 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2455,7 +2455,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)  #ifdef CONFIG_USB_OTG  	if (pdata->operating_mode == FSL_USB2_DR_OTG) { -		udc_controller->transceiver = usb_get_phy(); +		udc_controller->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  		if (!udc_controller->transceiver) {  			ERR("Can't find OTG driver!\n");  			ret = -ENODEV; diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 5d779955d5a..75ff41a5c95 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2180,7 +2180,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev)  #ifdef CONFIG_USB_OTG_UTILS  	if (pdata->mode == MV_USB_MODE_OTG) -		udc->transceiver = usb_get_phy(); +		udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  #endif  	udc->clknum = pdata->clknum; diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 74b9bb8099e..cf8bf26f12e 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2865,7 +2865,7 @@ static int __init omap_udc_probe(struct platform_device *pdev)  		 * use it.  Except for OTG, we don't _need_ to talk to one;  		 * but not having one probably means no VBUS detection.  		 */ -		xceiv = usb_get_phy(); +		xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  		if (xceiv)  			type = xceiv->label;  		else if (config->otg) { diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index a658e446cab..cc0b1e63dca 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -2159,7 +2159,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)  	dev->dev = &pdev->dev;  	dev->mach = pdev->dev.platform_data; -	dev->transceiver = usb_get_phy(); +	dev->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  	if (gpio_is_valid(dev->mach->gpio_pullup)) {  		if ((retval = gpio_request(dev->mach->gpio_pullup, diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index b982304a49c..8f744aab962 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -2464,7 +2464,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev)  	udc->dev = &pdev->dev;  	udc->mach = pdev->dev.platform_data; -	udc->transceiver = usb_get_phy(); +	udc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  	gpio = udc->mach->gpio_pullup;  	if (gpio_is_valid(gpio)) { diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 9ad33395f56..22326f27446 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1282,7 +1282,7 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev)  	hsudc->dev = dev;  	hsudc->pd = pdev->dev.platform_data; -	hsudc->transceiver = usb_get_phy(); +	hsudc->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  	for (i = 0; i < ARRAY_SIZE(hsudc->supplies); i++)  		hsudc->supplies[i].supply = s3c_hsudc_supply_names[i]; diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 0e8976a0ed5..ba290589d85 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -142,7 +142,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,  	if (pdata->operating_mode == FSL_USB2_DR_OTG) {  		struct ehci_hcd *ehci = hcd_to_ehci(hcd); -		ehci->transceiver = usb_get_phy(); +		ehci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  		dev_dbg(&pdev->dev, "hcd=0x%p  ehci=0x%p, transceiver=0x%p\n",  			hcd, ehci, ehci->transceiver); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 7badd5db398..c7615fb93db 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -145,7 +145,7 @@ static int ehci_msm_probe(struct platform_device *pdev)  	 * powering up VBUS, mapping of registers address space and power  	 * management.  	 */ -	phy = usb_get_phy(); +	phy = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!phy) {  		dev_err(&pdev->dev, "unable to find transceiver\n");  		ret = -ENODEV; diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 24f838fe25a..ef7aa0df40a 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -253,7 +253,7 @@ static int mv_ehci_probe(struct platform_device *pdev)  	ehci_mv->mode = pdata->mode;  	if (ehci_mv->mode == MV_USB_MODE_OTG) {  #ifdef CONFIG_USB_OTG_UTILS -		ehci_mv->otg = usb_get_phy(); +		ehci_mv->otg = usb_get_phy(USB_PHY_TYPE_USB2);  		if (!ehci_mv->otg) {  			dev_err(&pdev->dev,  				"unable to find transceiver\n"); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index ee17d19b1b8..14df2f5cf6a 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -749,7 +749,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)  #ifdef CONFIG_USB_OTG_UTILS  	if (pdata->operating_mode == TEGRA_USB_OTG) { -		tegra->transceiver = usb_get_phy(); +		tegra->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  		if (tegra->transceiver)  			otg_set_host(tegra->transceiver->otg, &hcd->self);  	} diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index c2c1f55889a..92a77dfd193 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -211,7 +211,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)  #ifdef	CONFIG_USB_OTG  	if (need_transceiver) { -		ohci->transceiver = usb_get_phy(); +		ohci->transceiver = usb_get_phy(USB_PHY_TYPE_USB2);  		if (ohci->transceiver) {  			int	status = otg_set_host(ohci->transceiver->otg,  						&ohci_to_hcd(ohci)->self); diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index a75989bbb3d..4a8cbf0e8d5 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -364,7 +364,7 @@ static int am35x_musb_init(struct musb *musb)  		return -ENODEV;  	usb_nop_xceiv_register(); -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv)  		return -ENODEV; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 522a4a263df..452940986d6 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -415,7 +415,7 @@ static int bfin_musb_init(struct musb *musb)  	gpio_direction_output(musb->config->gpio_vrsel, 0);  	usb_nop_xceiv_register(); -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv) {  		gpio_free(musb->config->gpio_vrsel);  		return -ENODEV; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 61868d604b2..d731c80c4fe 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -425,7 +425,7 @@ static int da8xx_musb_init(struct musb *musb)  		goto fail;  	usb_nop_xceiv_register(); -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv)  		goto fail; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 441f776366f..582268de3fa 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -384,7 +384,7 @@ static int davinci_musb_init(struct musb *musb)  	u32		revision;  	usb_nop_xceiv_register(); -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv)  		goto unregister; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 716c113608f..92603e498e6 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -376,7 +376,7 @@ static int dsps_musb_init(struct musb *musb)  	/* NOP driver needs change if supporting dual instance */  	usb_nop_xceiv_register(); -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv)  		return -ENODEV; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index e16dbbf7f30..e279cf32772 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -292,7 +292,7 @@ static int omap2430_musb_init(struct musb *musb)  	 * up through ULPI.  TWL4030-family PMICs include one,  	 * which needs a driver, drivers aren't always needed.  	 */ -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv) {  		pr_err("HS USB OTG: no transceiver configured\n");  		return -ENODEV; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index a004736186f..8ddf3d5f7cd 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1078,7 +1078,7 @@ static int tusb_musb_init(struct musb *musb)  	int			ret;  	usb_nop_xceiv_register(); -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv)  		return -ENODEV; diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 53006b113b1..46cf80a8cac 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -37,7 +37,7 @@ struct ux500_glue {  static int ux500_musb_init(struct musb *musb)  { -	musb->xceiv = usb_get_phy(); +	musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2);  	if (!musb->xceiv) {  		pr_err("HS USB OTG: no transceiver configured\n");  		return -ENODEV; diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index 672e28c8143..ae8ad561f08 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)  	if (err < 0)  		goto fail0; -	err = usb_add_phy(&ab->phy); +	err = usb_add_phy(&ab->phy, USB_PHY_TYPE_USB2);  	if (err) {  		dev_err(&pdev->dev, "Can't register transceiver\n");  		goto fail1; @@ -556,7 +556,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev)  	cancel_work_sync(&ab->phy_dis_work); -	usb_add_phy(NULL); +	usb_remove_phy(&ab->phy);  	ab8500_usb_host_phy_dis(ab);  	ab8500_usb_peri_phy_dis(ab); diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 73561edd81d..23c798cb2d7 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)  	fsl_otg_dev = fsl_otg_tc;  	/* Store the otg transceiver */ -	status = usb_add_phy(&fsl_otg_tc->phy); +	status = usb_add_phy(&fsl_otg_tc->phy, USB_PHY_TYPE_USB2);  	if (status) {  		pr_warn(FSL_OTG_NAME ": unable to register OTG transceiver.\n");  		goto err; @@ -824,7 +824,7 @@ err:  int usb_otg_start(struct platform_device *pdev)  {  	struct fsl_otg *p_otg; -	struct usb_phy *otg_trans = usb_get_phy(); +	struct usb_phy *otg_trans = usb_get_phy(USB_PHY_TYPE_USB2);  	struct otg_fsm *fsm;  	int status;  	struct resource *res; @@ -1134,7 +1134,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev)  {  	struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; -	usb_add_phy(NULL); +	usb_remove_phy(&fsl_otg_dev->phy);  	free_irq(fsl_otg_dev->irq, fsl_otg_dev);  	iounmap((void *)usb_dr_regs); diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 9b3c264cdb5..a67ffe22179 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)  	}  	/* only active when a gadget is registered */ -	err = usb_add_phy(&gpio_vbus->phy); +	err = usb_add_phy(&gpio_vbus->phy, USB_PHY_TYPE_USB2);  	if (err) {  		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",  			err); @@ -354,7 +354,7 @@ static int __exit gpio_vbus_remove(struct platform_device *pdev)  	cancel_delayed_work_sync(&gpio_vbus->work);  	regulator_put(gpio_vbus->vbus_draw); -	usb_add_phy(NULL); +	usb_remove_phy(&gpio_vbus->phy);  	free_irq(gpio_vbus->irq, pdev);  	if (gpio_is_valid(pdata->gpio_pullup)) diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index b74df3fec56..75cea4ab098 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1611,7 +1611,7 @@ isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id)  	dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES);  #endif -	status = usb_add_phy(&isp->phy); +	status = usb_add_phy(&isp->phy, USB_PHY_TYPE_USB2);  	if (status < 0)  		dev_err(&i2c->dev, "can't register transceiver, %d\n",  			status); @@ -1650,7 +1650,7 @@ subsys_initcall(isp_init);  static void __exit isp_exit(void)  {  	if (the_transceiver) -		usb_add_phy(NULL); +		usb_remove_phy(&the_transceiver->phy);  	i2c_del_driver(&isp1301_driver);  }  module_exit(isp_exit); diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index dd606c01003..9f5fc906041 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -1555,7 +1555,7 @@ static int __init msm_otg_probe(struct platform_device *pdev)  	phy->otg->set_host = msm_otg_set_host;  	phy->otg->set_peripheral = msm_otg_set_peripheral; -	ret = usb_add_phy(&motg->phy); +	ret = usb_add_phy(&motg->phy, USB_PHY_TYPE_USB2);  	if (ret) {  		dev_err(&pdev->dev, "usb_add_phy failed\n");  		goto free_irq; @@ -1624,7 +1624,7 @@ static int __devexit msm_otg_remove(struct platform_device *pdev)  	device_init_wakeup(&pdev->dev, 0);  	pm_runtime_disable(&pdev->dev); -	usb_add_phy(NULL); +	usb_remove_phy(phy);  	free_irq(motg->irq, motg);  	/* diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c index 18e90fe1fbd..3f124e8f579 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)  	for (clk_i = 0; clk_i <= mvotg->clknum; clk_i++)  		clk_put(mvotg->clk[clk_i]); -	usb_add_phy(NULL); +	usb_remove_phy(&mvotg->phy);  	platform_set_drvdata(pdev, NULL);  	kfree(mvotg->phy.otg); @@ -853,7 +853,7 @@ static int mv_otg_probe(struct platform_device *pdev)  		goto err_disable_clk;  	} -	retval = usb_add_phy(&mvotg->phy); +	retval = usb_add_phy(&mvotg->phy, USB_PHY_TYPE_USB2);  	if (retval < 0) {  		dev_err(&pdev->dev, "can't register transceiver, %d\n",  			retval); @@ -880,7 +880,7 @@ static int mv_otg_probe(struct platform_device *pdev)  	return 0;  err_set_transceiver: -	usb_add_phy(NULL); +	usb_remove_phy(&mvotg->phy);  err_free_irq:  	free_irq(mvotg->irq, mvotg);  err_disable_clk: diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 33000dae720..803f958f413 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)  	nop->phy.otg->set_host		= nop_set_host;  	nop->phy.otg->set_peripheral	= nop_set_peripheral; -	err = usb_add_phy(&nop->phy); +	err = usb_add_phy(&nop->phy, USB_PHY_TYPE_USB2);  	if (err) {  		dev_err(&pdev->dev, "can't register transceiver, err: %d\n",  			err); @@ -139,7 +139,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev)  {  	struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); -	usb_add_phy(NULL); +	usb_remove_phy(&nop->phy);  	platform_set_drvdata(pdev, NULL);  	kfree(nop->phy.otg); diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index 300a995cfdb..a23065820ea 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -11,14 +11,32 @@  #include <linux/kernel.h>  #include <linux/export.h> +#include <linux/err.h>  #include <linux/device.h>  #include <linux/usb/otg.h> -static struct usb_phy *phy; +static LIST_HEAD(phy_list); +static DEFINE_SPINLOCK(phy_lock); + +static struct usb_phy *__usb_find_phy(struct list_head *list, +	enum usb_phy_type type) +{ +	struct usb_phy  *phy = NULL; + +	list_for_each_entry(phy, list, head) { +		if (phy->type != type) +			continue; + +		return phy; +	} + +	return ERR_PTR(-ENODEV); +}  /** - * usb_get_phy - find the (single) USB PHY + * usb_get_phy - find the USB PHY + * @type - the type of the phy the controller requires   *   * Returns the phy driver, after getting a refcount to it; or   * null if there is no such phy.  The caller is responsible for @@ -26,16 +44,30 @@ static struct usb_phy *phy;   *   * For use by USB host and peripheral drivers.   */ -struct usb_phy *usb_get_phy(void) +struct usb_phy *usb_get_phy(enum usb_phy_type type)  { -	if (phy) -		get_device(phy->dev); +	struct usb_phy	*phy = NULL; +	unsigned long	flags; + +	spin_lock_irqsave(&phy_lock, flags); + +	phy = __usb_find_phy(&phy_list, type); +	if (IS_ERR(phy)) { +		pr_err("unable to find transceiver of type %s\n", +			usb_phy_type_string(type)); +		return phy; +	} + +	get_device(phy->dev); + +	spin_unlock_irqrestore(&phy_lock, flags); +  	return phy;  }  EXPORT_SYMBOL(usb_get_phy);  /** - * usb_put_phy - release the (single) USB PHY + * usb_put_phy - release the USB PHY   * @x: the phy returned by usb_get_phy()   *   * Releases a refcount the caller received from usb_get_phy(). @@ -50,22 +82,62 @@ void usb_put_phy(struct usb_phy *x)  EXPORT_SYMBOL(usb_put_phy);  /** - * usb_add_phy - declare the (single) USB PHY + * usb_add_phy - declare the USB PHY   * @x: the USB phy to be used; or NULL + * @type - the type of this PHY   *   * This call is exclusively for use by phy drivers, which   * coordinate the activities of drivers for host and peripheral   * controllers, and in some cases for VBUS current regulation.   */ -int usb_add_phy(struct usb_phy *x) +int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)  { -	if (phy && x) -		return -EBUSY; -	phy = x; -	return 0; +	int		ret = 0; +	unsigned long	flags; +	struct usb_phy	*phy; + +	if (x && x->type != USB_PHY_TYPE_UNDEFINED) { +		dev_err(x->dev, "not accepting initialized PHY %s\n", x->label); +		return -EINVAL; +	} + +	spin_lock_irqsave(&phy_lock, flags); + +	list_for_each_entry(phy, &phy_list, head) { +		if (phy->type == type) { +			ret = -EBUSY; +			dev_err(x->dev, "transceiver type %s already exists\n", +						usb_phy_type_string(type)); +			goto out; +		} +	} + +	x->type = type; +	list_add_tail(&x->head, &phy_list); + +out: +	spin_unlock_irqrestore(&phy_lock, flags); +	return ret;  }  EXPORT_SYMBOL(usb_add_phy); +/** + * usb_remove_phy - remove the OTG PHY + * @x: the USB OTG PHY to be removed; + * + * This reverts the effects of usb_add_phy + */ +void usb_remove_phy(struct usb_phy *x) +{ +	unsigned long	flags; + +	spin_lock_irqsave(&phy_lock, flags); +	if (x) +		list_del(&x->head); +	spin_unlock_irqrestore(&phy_lock, flags); +} +EXPORT_SYMBOL(usb_remove_phy); +  const char *otg_state_string(enum usb_otg_state state)  {  	switch (state) { diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 01022c891e2..25a09fabbe3 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -633,7 +633,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev)  		kfree(twl);  		return err;  	} -	usb_add_phy(&twl->phy); +	usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);  	platform_set_drvdata(pdev, twl);  	if (device_create_file(&pdev->dev, &dev_attr_vbus)) diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index a8be20878eb..dbee00aea75 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -443,7 +443,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)  		kfree(twl);  		return err;  	} -	usb_add_phy(&twl->phy); +	usb_add_phy(&twl->phy, USB_PHY_TYPE_USB2);  	platform_set_drvdata(pdev, twl);  	if (device_create_file(&pdev->dev, &dev_attr_vbus)) diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 0e739c81052..1def65fb57d 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -43,6 +43,13 @@ enum usb_phy_events {  	USB_EVENT_ENUMERATED,   /* gadget driver enumerated */  }; +/* associate a type with PHY */ +enum usb_phy_type { +	USB_PHY_TYPE_UNDEFINED, +	USB_PHY_TYPE_USB2, +	USB_PHY_TYPE_USB3, +}; +  struct usb_phy;  /* for transceivers connected thru an ULPI interface, the user must @@ -89,6 +96,7 @@ struct usb_phy {  	const char		*label;  	unsigned int		 flags; +	enum usb_phy_type	type;  	enum usb_otg_state	state;  	enum usb_phy_events	last_event; @@ -105,6 +113,9 @@ struct usb_phy {  	u16			port_status;  	u16			port_change; +	/* to support controllers that have multiple transceivers */ +	struct list_head	head; +  	/* initialize/shutdown the OTG controller */  	int	(*init)(struct usb_phy *x);  	void	(*shutdown)(struct usb_phy *x); @@ -121,7 +132,8 @@ struct usb_phy {  /* for board-specific init logic */ -extern int usb_add_phy(struct usb_phy *); +extern int usb_add_phy(struct usb_phy *, enum usb_phy_type type); +extern void usb_remove_phy(struct usb_phy *);  #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))  /* sometimes transceivers are accessed only through e.g. ULPI */ @@ -172,11 +184,11 @@ usb_phy_shutdown(struct usb_phy *x)  /* for usb host and peripheral controller drivers */  #ifdef CONFIG_USB_OTG_UTILS -extern struct usb_phy *usb_get_phy(void); +extern struct usb_phy *usb_get_phy(enum usb_phy_type type);  extern void usb_put_phy(struct usb_phy *);  extern const char *otg_state_string(enum usb_otg_state state);  #else -static inline struct usb_phy *usb_get_phy(void) +static inline struct usb_phy *usb_get_phy(enum usb_phy_type type)  {  	return NULL;  } @@ -276,4 +288,15 @@ usb_unregister_notifier(struct usb_phy *x, struct notifier_block *nb)  /* for OTG controller drivers (and maybe other stuff) */  extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num); +static inline const char *usb_phy_type_string(enum usb_phy_type type) +{ +	switch (type) { +	case USB_PHY_TYPE_USB2: +		return "USB2 PHY"; +	case USB_PHY_TYPE_USB3: +		return "USB3 PHY"; +	default: +		return "UNKNOWN PHY TYPE"; +	} +}  #endif /* __LINUX_USB_OTG_H */  |