From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jingoo Han Subject: RE: [PATCH 4/4 v2] USB: ohci-exynos: Add phy driver support Date: Mon, 15 Oct 2012 14:52:46 +0900 Message-ID: <009001cdaa99$4d4ad340$e7e079c0$%han@samsung.com> References: <1349865780-7701-1-git-send-email-gautam.vivek@samsung.com> <1349865780-7701-5-git-send-email-gautam.vivek@samsung.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Return-path: In-reply-to: <1349865780-7701-5-git-send-email-gautam.vivek@samsung.com> Content-language: ko Sender: linux-samsung-soc-owner@vger.kernel.org To: 'Vivek Gautam' , linux-usb@vger.kernel.org Cc: linux-samsung-soc@vger.kernel.org, devicetree-discuss@lists.ozlabs.org, gregkh@linuxfoundation.org, stern@rowland.harvard.edu, balbi@ti.com, rob.herring@calxeda.com, kgene.kim@samsung.com, thomas.abraham@linaro.org, kishon@ti.com, p.paneri@samsung.com, yulgon.kim@samsung.com, 'Jingoo Han' List-Id: devicetree@vger.kernel.org On Wednesday, October 10, 2012 7:43 PM Vivek Gautam wrote > > Adding the transceiver to ohci driver. Keeping the platform data > for continuing the smooth operation for boards which still uses it > > Signed-off-by: Vivek Gautam It looks good. I have tested this patch with Exynos5250. Acked-by: Jingoo Han Best regards, Jingoo Han > --- > drivers/usb/host/ohci-exynos.c | 65 +++++++++++++++++++++++++++------------ > 1 files changed, 45 insertions(+), 20 deletions(-) > > diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c > index 20a5008..a1c4eb3 100644 > --- a/drivers/usb/host/ohci-exynos.c > +++ b/drivers/usb/host/ohci-exynos.c > @@ -15,14 +15,37 @@ > #include > #include > #include > +#include > #include > > struct exynos_ohci_hcd { > struct device *dev; > struct usb_hcd *hcd; > struct clk *clk; > + struct usb_phy *phy; > + struct exynos4_ohci_platdata *pdata; > }; > > +static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) > +{ > + struct platform_device *pdev = to_platform_device(exynos_ohci->dev); > + > + if (exynos_ohci->phy) > + usb_phy_init(exynos_ohci->phy); > + else if (exynos_ohci->pdata->phy_init) > + exynos_ohci->pdata->phy_init(pdev, S5P_USB_PHY_HOST); > +} > + > +static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) > +{ > + struct platform_device *pdev = to_platform_device(exynos_ohci->dev); > + > + if (exynos_ohci->phy) > + usb_phy_shutdown(exynos_ohci->phy); > + else if (exynos_ohci->pdata->phy_exit) > + exynos_ohci->pdata->phy_exit(pdev, S5P_USB_PHY_HOST); > +} > + > static int ohci_exynos_start(struct usb_hcd *hcd) > { > struct ohci_hcd *ohci = hcd_to_ohci(hcd); > @@ -81,15 +104,10 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) > struct usb_hcd *hcd; > struct ohci_hcd *ohci; > struct resource *res; > + struct usb_phy *phy; > int irq; > int err; > > - pdata = pdev->dev.platform_data; > - if (!pdata) { > - dev_err(&pdev->dev, "No platform data defined\n"); > - return -EINVAL; > - } > - > /* > * Right now device-tree probed devices don't get dma_mask set. > * Since shared usb code relies on it, set it here for now. > @@ -105,6 +123,20 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) > if (!exynos_ohci) > return -ENOMEM; > > + pdata = pdev->dev.platform_data; > + if (!pdata) { > + /* Fallback to Phy transceiver */ > + phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); > + if (IS_ERR_OR_NULL(phy)) { > + dev_err(&pdev->dev, "no platform data or transceiver defined\n"); > + return -EPROBE_DEFER; > + } else { > + exynos_ohci->phy = phy; > + } > + } else { > + exynos_ohci->pdata = pdata; > + } > + > exynos_ohci->dev = &pdev->dev; > > hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, > @@ -150,8 +182,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) > goto fail_io; > } > > - if (pdata->phy_init) > - pdata->phy_init(pdev, S5P_USB_PHY_HOST); > + exynos_ohci_phy_enable(exynos_ohci); > > ohci = hcd_to_ohci(hcd); > ohci_hcd_init(ohci); > @@ -159,13 +190,15 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) > err = usb_add_hcd(hcd, irq, IRQF_SHARED); > if (err) { > dev_err(&pdev->dev, "Failed to add USB HCD\n"); > - goto fail_io; > + goto fail_add_hcd; > } > > platform_set_drvdata(pdev, exynos_ohci); > > return 0; > > +fail_add_hcd: > + exynos_ohci_phy_disable(exynos_ohci); > fail_io: > clk_disable(exynos_ohci->clk); > fail_clken: > @@ -177,14 +210,12 @@ fail_clk: > > static int __devexit exynos_ohci_remove(struct platform_device *pdev) > { > - struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; > struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); > struct usb_hcd *hcd = exynos_ohci->hcd; > > usb_remove_hcd(hcd); > > - if (pdata && pdata->phy_exit) > - pdata->phy_exit(pdev, S5P_USB_PHY_HOST); > + exynos_ohci_phy_disable(exynos_ohci); > > clk_disable(exynos_ohci->clk); > clk_put(exynos_ohci->clk); > @@ -209,8 +240,6 @@ static int exynos_ohci_suspend(struct device *dev) > struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); > struct usb_hcd *hcd = exynos_ohci->hcd; > struct ohci_hcd *ohci = hcd_to_ohci(hcd); > - struct platform_device *pdev = to_platform_device(dev); > - struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; > unsigned long flags; > int rc = 0; > > @@ -229,8 +258,7 @@ static int exynos_ohci_suspend(struct device *dev) > > clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); > > - if (pdata && pdata->phy_exit) > - pdata->phy_exit(pdev, S5P_USB_PHY_HOST); > + exynos_ohci_phy_disable(exynos_ohci); > > clk_disable(exynos_ohci->clk); > > @@ -244,13 +272,10 @@ static int exynos_ohci_resume(struct device *dev) > { > struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); > struct usb_hcd *hcd = exynos_ohci->hcd; > - struct platform_device *pdev = to_platform_device(dev); > - struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; > > clk_enable(exynos_ohci->clk); > > - if (pdata && pdata->phy_init) > - pdata->phy_init(pdev, S5P_USB_PHY_HOST); > + exynos_ohci_phy_enable(exynos_ohci); > > /* Mark hardware accessible again as we are out of D3 state by now */ > set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); > -- > 1.7.6.5