diff options
Diffstat (limited to 'drivers/usb/host/ehci-platform.c')
| -rw-r--r-- | drivers/usb/host/ehci-platform.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index fe497c876d76..f61f095cedab 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -27,6 +27,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/reset.h> #include <linux/sys_soc.h> @@ -111,8 +112,7 @@ static void ehci_platform_power_off(struct platform_device *dev) int clk; for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) - if (priv->clks[clk]) - clk_disable_unprepare(priv->clks[clk]); + clk_disable_unprepare(priv->clks[clk]); } static struct hc_driver __read_mostly ehci_platform_hc_driver; @@ -198,7 +198,8 @@ static void quirk_poll_work(struct work_struct *work) static void quirk_poll_timer(struct timer_list *t) { - struct ehci_platform_priv *priv = from_timer(priv, t, poll_timer); + struct ehci_platform_priv *priv = timer_container_of(priv, t, + poll_timer); struct ehci_hcd *ehci = container_of((void *)priv, struct ehci_hcd, priv); @@ -224,7 +225,7 @@ static void quirk_poll_init(struct ehci_platform_priv *priv) static void quirk_poll_end(struct ehci_platform_priv *priv) { - del_timer_sync(&priv->poll_timer); + timer_delete_sync(&priv->poll_timer); cancel_delayed_work(&priv->poll_work); } @@ -238,9 +239,11 @@ static int ehci_platform_probe(struct platform_device *dev) struct usb_hcd *hcd; struct resource *res_mem; struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); + const struct of_device_id *match; struct ehci_platform_priv *priv; struct ehci_hcd *ehci; int err, irq, clk = 0; + bool dma_mask_64; if (usb_disabled()) return -ENODEV; @@ -252,8 +255,13 @@ static int ehci_platform_probe(struct platform_device *dev) if (!pdata) pdata = &ehci_platform_defaults; + dma_mask_64 = pdata->dma_mask_64; + match = of_match_device(dev->dev.driver->of_match_table, &dev->dev); + if (match && match->data) + dma_mask_64 = true; + err = dma_coerce_mask_and_coherent(&dev->dev, - pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); + dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32)); if (err) { dev_err(&dev->dev, "Error: DMA mask configuration failed\n"); return err; @@ -297,7 +305,9 @@ static int ehci_platform_probe(struct platform_device *dev) if (of_device_is_compatible(dev->dev.of_node, "aspeed,ast2500-ehci") || of_device_is_compatible(dev->dev.of_node, - "aspeed,ast2600-ehci")) + "aspeed,ast2600-ehci") || + of_device_is_compatible(dev->dev.of_node, + "aspeed,ast2700-ehci")) ehci->is_aspeed = 1; if (soc_device_match(quirk_poll_match)) @@ -359,8 +369,7 @@ static int ehci_platform_probe(struct platform_device *dev) goto err_reset; } - res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); - hcd->regs = devm_ioremap_resource(&dev->dev, res_mem); + hcd->regs = devm_platform_get_and_ioremap_resource(dev, 0, &res_mem); if (IS_ERR(hcd->regs)) { err = PTR_ERR(hcd->regs); goto err_power; @@ -400,7 +409,7 @@ err_put_clks: return err; } -static int ehci_platform_remove(struct platform_device *dev) +static void ehci_platform_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); @@ -424,8 +433,6 @@ static int ehci_platform_remove(struct platform_device *dev) if (pdata == &ehci_platform_defaults) dev->dev.platform_data = NULL; - - return 0; } static int __maybe_unused ehci_platform_suspend(struct device *dev) @@ -447,6 +454,17 @@ static int __maybe_unused ehci_platform_suspend(struct device *dev) if (pdata->power_suspend) pdata->power_suspend(pdev); + ret = reset_control_assert(priv->rsts); + if (ret) { + if (pdata->power_on) + pdata->power_on(pdev); + + ehci_resume(hcd, false); + + if (priv->quirk_poll) + quirk_poll_init(priv); + } + return ret; } @@ -457,11 +475,18 @@ static int __maybe_unused ehci_platform_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); struct device *companion_dev; + int err; + + err = reset_control_deassert(priv->rsts); + if (err) + return err; if (pdata->power_on) { - int err = pdata->power_on(pdev); - if (err < 0) + err = pdata->power_on(pdev); + if (err < 0) { + reset_control_assert(priv->rsts); return err; + } } companion_dev = usb_of_get_companion_dev(hcd->self.controller); @@ -487,6 +512,7 @@ static const struct of_device_id vt8500_ehci_ids[] = { { .compatible = "wm,prizm-ehci", }, { .compatible = "generic-ehci", }, { .compatible = "cavium,octeon-6335-ehci", }, + { .compatible = "aspeed,ast2700-ehci", .data = (void *)1 }, {} }; MODULE_DEVICE_TABLE(of, vt8500_ehci_ids); |
