usb: host: xhci-plat: Fix clock resource by adding a register clock
On Armada 7K/8K we need to explicitly enable the register clock. This clock is optional because not all the SoCs using this IP need it but at least for Armada 7K/8K it is actually mandatory. The change was done at xhci-plat level and not at a xhci-mvebu.c because, it is expected that other SoC would have this kind of constraint. The binding documentation is updating accordingly. Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
3e29109f51
Коммит
0fd2060ad4
|
@ -28,7 +28,10 @@ Required properties:
|
||||||
- interrupts: one XHCI interrupt should be described here.
|
- interrupts: one XHCI interrupt should be described here.
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- clocks: reference to a clock
|
- clocks: reference to the clocks
|
||||||
|
- clock-names: mandatory if there is a second clock, in this case
|
||||||
|
the name must be "core" for the first clock and "reg" for the
|
||||||
|
second one
|
||||||
- usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
|
- usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM
|
||||||
- usb3-lpm-capable: determines if platform is USB3 LPM capable
|
- usb3-lpm-capable: determines if platform is USB3 LPM capable
|
||||||
- quirk-broken-port-ped: set if the controller has broken port disable mechanism
|
- quirk-broken-port-ped: set if the controller has broken port disable mechanism
|
||||||
|
|
|
@ -157,6 +157,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct usb_hcd *hcd;
|
struct usb_hcd *hcd;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
struct clk *reg_clk;
|
||||||
int ret;
|
int ret;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
@ -226,17 +227,27 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||||
hcd->rsrc_len = resource_size(res);
|
hcd->rsrc_len = resource_size(res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not all platforms have a clk so it is not an error if the
|
* Not all platforms have clks so it is not an error if the
|
||||||
* clock does not exists.
|
* clock do not exist.
|
||||||
*/
|
*/
|
||||||
|
reg_clk = devm_clk_get(&pdev->dev, "reg");
|
||||||
|
if (!IS_ERR(reg_clk)) {
|
||||||
|
ret = clk_prepare_enable(reg_clk);
|
||||||
|
if (ret)
|
||||||
|
goto put_hcd;
|
||||||
|
} else if (PTR_ERR(reg_clk) == -EPROBE_DEFER) {
|
||||||
|
ret = -EPROBE_DEFER;
|
||||||
|
goto put_hcd;
|
||||||
|
}
|
||||||
|
|
||||||
clk = devm_clk_get(&pdev->dev, NULL);
|
clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (!IS_ERR(clk)) {
|
if (!IS_ERR(clk)) {
|
||||||
ret = clk_prepare_enable(clk);
|
ret = clk_prepare_enable(clk);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto put_hcd;
|
goto disable_reg_clk;
|
||||||
} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
|
} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
|
||||||
ret = -EPROBE_DEFER;
|
ret = -EPROBE_DEFER;
|
||||||
goto put_hcd;
|
goto disable_reg_clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
xhci = hcd_to_xhci(hcd);
|
xhci = hcd_to_xhci(hcd);
|
||||||
|
@ -252,6 +263,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
|
||||||
device_wakeup_enable(hcd->self.controller);
|
device_wakeup_enable(hcd->self.controller);
|
||||||
|
|
||||||
xhci->clk = clk;
|
xhci->clk = clk;
|
||||||
|
xhci->reg_clk = reg_clk;
|
||||||
xhci->main_hcd = hcd;
|
xhci->main_hcd = hcd;
|
||||||
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
|
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
|
||||||
dev_name(&pdev->dev), hcd);
|
dev_name(&pdev->dev), hcd);
|
||||||
|
@ -322,6 +334,9 @@ put_usb3_hcd:
|
||||||
disable_clk:
|
disable_clk:
|
||||||
clk_disable_unprepare(clk);
|
clk_disable_unprepare(clk);
|
||||||
|
|
||||||
|
disable_reg_clk:
|
||||||
|
clk_disable_unprepare(reg_clk);
|
||||||
|
|
||||||
put_hcd:
|
put_hcd:
|
||||||
usb_put_hcd(hcd);
|
usb_put_hcd(hcd);
|
||||||
|
|
||||||
|
@ -337,6 +352,7 @@ static int xhci_plat_remove(struct platform_device *dev)
|
||||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||||
struct clk *clk = xhci->clk;
|
struct clk *clk = xhci->clk;
|
||||||
|
struct clk *reg_clk = xhci->reg_clk;
|
||||||
|
|
||||||
xhci->xhc_state |= XHCI_STATE_REMOVING;
|
xhci->xhc_state |= XHCI_STATE_REMOVING;
|
||||||
|
|
||||||
|
@ -347,6 +363,7 @@ static int xhci_plat_remove(struct platform_device *dev)
|
||||||
usb_put_hcd(xhci->shared_hcd);
|
usb_put_hcd(xhci->shared_hcd);
|
||||||
|
|
||||||
clk_disable_unprepare(clk);
|
clk_disable_unprepare(clk);
|
||||||
|
clk_disable_unprepare(reg_clk);
|
||||||
usb_put_hcd(hcd);
|
usb_put_hcd(hcd);
|
||||||
|
|
||||||
pm_runtime_set_suspended(&dev->dev);
|
pm_runtime_set_suspended(&dev->dev);
|
||||||
|
|
|
@ -1729,8 +1729,9 @@ struct xhci_hcd {
|
||||||
int page_shift;
|
int page_shift;
|
||||||
/* msi-x vectors */
|
/* msi-x vectors */
|
||||||
int msix_count;
|
int msix_count;
|
||||||
/* optional clock */
|
/* optional clocks */
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
|
struct clk *reg_clk;
|
||||||
/* data structures */
|
/* data structures */
|
||||||
struct xhci_device_context_array *dcbaa;
|
struct xhci_device_context_array *dcbaa;
|
||||||
struct xhci_ring *cmd_ring;
|
struct xhci_ring *cmd_ring;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче