usb: gadget: udc-xilinx: Add clock support

Currently the driver depends on the  bootloader to enable the clocks.
Add support for clocking. The patch enables the clock at  probe and
disables them at remove.

Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Acked-by: Felipe Balbi <balbi@kernel.org>
Link: https://lore.kernel.org/r/054de6deeab81020eaf0399add2839c36b64275f.1632805672.git.shubhrajyoti.datta@xilinx.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Shubhrajyoti Datta 2021-09-28 10:57:11 +05:30 committed by Greg Kroah-Hartman
parent 01b5415044
commit 2474922921

View file

@ -11,6 +11,7 @@
* USB peripheral controller (at91_udc.c).
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
@ -171,6 +172,7 @@ struct xusb_ep {
* @addr: the usb device base address
* @lock: instance of spinlock
* @dma_enabled: flag indicating whether the dma is included in the system
* @clk: pointer to struct clk
* @read_fn: function pointer to read device registers
* @write_fn: function pointer to write to device registers
*/
@ -188,6 +190,7 @@ struct xusb_udc {
void __iomem *addr;
spinlock_t lock;
bool dma_enabled;
struct clk *clk;
unsigned int (*read_fn)(void __iomem *);
void (*write_fn)(void __iomem *, u32, u32);
@ -2092,6 +2095,27 @@ static int xudc_probe(struct platform_device *pdev)
udc->gadget.ep0 = &udc->ep[XUSB_EP_NUMBER_ZERO].ep_usb;
udc->gadget.name = driver_name;
udc->clk = devm_clk_get(&pdev->dev, "s_axi_aclk");
if (IS_ERR(udc->clk)) {
if (PTR_ERR(udc->clk) != -ENOENT) {
ret = PTR_ERR(udc->clk);
goto fail;
}
/*
* Clock framework support is optional, continue on,
* anyways if we don't find a matching clock
*/
dev_warn(&pdev->dev, "s_axi_aclk clock property is not found\n");
udc->clk = NULL;
}
ret = clk_prepare_enable(udc->clk);
if (ret) {
dev_err(&pdev->dev, "Unable to enable clock.\n");
return ret;
}
spin_lock_init(&udc->lock);
/* Check for IP endianness */
@ -2147,6 +2171,7 @@ static int xudc_remove(struct platform_device *pdev)
struct xusb_udc *udc = platform_get_drvdata(pdev);
usb_del_gadget_udc(&udc->gadget);
clk_disable_unprepare(udc->clk);
return 0;
}