aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/host/ehci-sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-sh.c')
-rw-r--r--drivers/usb/host/ehci-sh.c79
1 files changed, 21 insertions, 58 deletions
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c
index 595f70f42b5..9b9b9f5b016 100644
--- a/drivers/usb/host/ehci-sh.c
+++ b/drivers/usb/host/ehci-sh.c
@@ -11,6 +11,7 @@
*/
#include <linux/platform_device.h>
#include <linux/clk.h>
+#include <linux/platform_data/ehci-sh.h>
struct ehci_sh_priv {
struct clk *iclk, *fclk;
@@ -20,31 +21,10 @@ struct ehci_sh_priv {
static int ehci_sh_reset(struct usb_hcd *hcd)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int ret;
ehci->caps = hcd->regs;
- ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci,
- &ehci->caps->hc_capbase));
- dbg_hcs_params(ehci, "reset");
- dbg_hcc_params(ehci, "reset");
-
- ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
-
- ret = ehci_halt(ehci);
- if (unlikely(ret))
- return ret;
-
- ret = ehci_init(hcd);
- if (unlikely(ret))
- return ret;
-
- ehci->sbrn = 0x20;
-
- ehci_reset(ehci);
- ehci_port_power(ehci, 0);
-
- return ret;
+ return ehci_setup(hcd);
}
static const struct hc_driver ehci_sh_hc_driver = {
@@ -56,7 +36,7 @@ static const struct hc_driver ehci_sh_hc_driver = {
* generic hardware linkage
*/
.irq = ehci_irq,
- .flags = HCD_USB2 | HCD_MEMORY,
+ .flags = HCD_USB2 | HCD_MEMORY | HCD_BH,
/*
* basic lifecycle operations
@@ -97,9 +77,9 @@ static const struct hc_driver ehci_sh_hc_driver = {
static int ehci_hcd_sh_probe(struct platform_device *pdev)
{
- const struct hc_driver *driver = &ehci_sh_hc_driver;
struct resource *res;
struct ehci_sh_priv *priv;
+ struct ehci_sh_platdata *pdata;
struct usb_hcd *hcd;
int irq, ret;
@@ -124,6 +104,8 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
goto fail_create_hcd;
}
+ pdata = dev_get_platdata(&pdev->dev);
+
/* initialize hcd */
hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev,
dev_name(&pdev->dev));
@@ -135,44 +117,41 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)
hcd->rsrc_start = res->start;
hcd->rsrc_len = resource_size(res);
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
- driver->description)) {
- dev_dbg(&pdev->dev, "controller already in use\n");
- ret = -EBUSY;
+ hcd->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(hcd->regs)) {
+ ret = PTR_ERR(hcd->regs);
goto fail_request_resource;
}
- hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
- if (hcd->regs == NULL) {
- dev_dbg(&pdev->dev, "error mapping memory\n");
- ret = -ENXIO;
- goto fail_ioremap;
- }
-
- priv = kmalloc(sizeof(struct ehci_sh_priv), GFP_KERNEL);
+ priv = devm_kzalloc(&pdev->dev, sizeof(struct ehci_sh_priv),
+ GFP_KERNEL);
if (!priv) {
dev_dbg(&pdev->dev, "error allocating priv data\n");
ret = -ENOMEM;
- goto fail_alloc;
+ goto fail_request_resource;
}
/* These are optional, we don't care if they fail */
- priv->fclk = clk_get(&pdev->dev, "usb_fck");
+ priv->fclk = devm_clk_get(&pdev->dev, "usb_fck");
if (IS_ERR(priv->fclk))
priv->fclk = NULL;
- priv->iclk = clk_get(&pdev->dev, "usb_ick");
+ priv->iclk = devm_clk_get(&pdev->dev, "usb_ick");
if (IS_ERR(priv->iclk))
priv->iclk = NULL;
clk_enable(priv->fclk);
clk_enable(priv->iclk);
- ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+ if (pdata && pdata->phy_init)
+ pdata->phy_init();
+
+ ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to add hcd");
goto fail_add_hcd;
}
+ device_wakeup_enable(hcd->self.controller);
priv->hcd = hcd;
platform_set_drvdata(pdev, priv);
@@ -183,14 +162,6 @@ fail_add_hcd:
clk_disable(priv->iclk);
clk_disable(priv->fclk);
- clk_put(priv->iclk);
- clk_put(priv->fclk);
-
- kfree(priv);
-fail_alloc:
- iounmap(hcd->regs);
-fail_ioremap:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
fail_request_resource:
usb_put_hcd(hcd);
fail_create_hcd:
@@ -199,25 +170,17 @@ fail_create_hcd:
return ret;
}
-static int __exit ehci_hcd_sh_remove(struct platform_device *pdev)
+static int ehci_hcd_sh_remove(struct platform_device *pdev)
{
struct ehci_sh_priv *priv = platform_get_drvdata(pdev);
struct usb_hcd *hcd = priv->hcd;
usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
- platform_set_drvdata(pdev, NULL);
clk_disable(priv->fclk);
clk_disable(priv->iclk);
- clk_put(priv->fclk);
- clk_put(priv->iclk);
-
- kfree(priv);
-
return 0;
}
@@ -232,7 +195,7 @@ static void ehci_hcd_sh_shutdown(struct platform_device *pdev)
static struct platform_driver ehci_hcd_sh_driver = {
.probe = ehci_hcd_sh_probe,
- .remove = __exit_p(ehci_hcd_sh_remove),
+ .remove = ehci_hcd_sh_remove,
.shutdown = ehci_hcd_sh_shutdown,
.driver = {
.name = "sh_ehci",