Skip to content

Commit

Permalink
usb: host: xhci-plat: add clock support
Browse files Browse the repository at this point in the history
Some platforms (such as the Armada 38x ones) can gate the clock of
their USB controller. This patch adds the support for one clock in
xhci-plat, by enabling it during probe and disabling it on remove.

To achieve this, it adds a 'struct clk *' member in xhci_hcd. While
only used for now in xhci-plat, it might be used by other drivers in
the future. Moreover, the xhci_hcd structure already holds other
members such as msix_count and msix_entries, which are MSI-X specific,
and therefore only used by xhci-pci.

Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Acked-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Gregory CLEMENT authored and Greg Kroah-Hartman committed May 27, 2014
1 parent 48157bb commit 4718c17
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
24 changes: 23 additions & 1 deletion drivers/usb/host/xhci-plat.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* version 2 as published by the Free Software Foundation.
*/

#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <linux/of.h>
Expand Down Expand Up @@ -91,6 +92,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
struct xhci_hcd *xhci;
struct resource *res;
struct usb_hcd *hcd;
struct clk *clk;
int ret;
int irq;

Expand Down Expand Up @@ -137,14 +139,27 @@ static int xhci_plat_probe(struct platform_device *pdev)
goto release_mem_region;
}

/*
* Not all platforms have a clk so it is not an error if the
* clock does not exists.
*/
clk = devm_clk_get(&pdev->dev, NULL);
if (!IS_ERR(clk)) {
ret = clk_prepare_enable(clk);
if (ret)
goto unmap_registers;
}

ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (ret)
goto unmap_registers;
goto disable_clk;

device_wakeup_enable(hcd->self.controller);

/* USB 2.0 roothub is stored in the platform_device now. */
hcd = platform_get_drvdata(pdev);
xhci = hcd_to_xhci(hcd);
xhci->clk = clk;
xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,
dev_name(&pdev->dev), hcd);
if (!xhci->shared_hcd) {
Expand Down Expand Up @@ -173,6 +188,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
dealloc_usb2_hcd:
usb_remove_hcd(hcd);

disable_clk:
if (!IS_ERR(clk))
clk_disable_unprepare(clk);

unmap_registers:
iounmap(hcd->regs);

Expand All @@ -189,11 +208,14 @@ static int xhci_plat_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct clk *clk = xhci->clk;

usb_remove_hcd(xhci->shared_hcd);
usb_put_hcd(xhci->shared_hcd);

usb_remove_hcd(hcd);
if (!IS_ERR(clk))
clk_disable_unprepare(clk);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -1472,6 +1472,8 @@ struct xhci_hcd {
/* msi-x vectors */
int msix_count;
struct msix_entry *msix_entries;
/* optional clock */
struct clk *clk;
/* data structures */
struct xhci_device_context_array *dcbaa;
struct xhci_ring *cmd_ring;
Expand Down

0 comments on commit 4718c17

Please sign in to comment.