Commit e4ac5a40 authored by Shubhrajyoti Datta's avatar Shubhrajyoti Datta Committed by Greg Kroah-Hartman
Browse files

usb: xilinx: Add suspend resume support



Add suspend resume support. In the suspend udc is suspended
and it is set to ready at resume for it to be functional.

Signed-off-by: default avatarShubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>
Link: https://lore.kernel.org/r/20211118120143.1079-1-shubhrajyoti.datta@xilinx.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4616dddc
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
@@ -2176,6 +2176,61 @@ static int xudc_remove(struct platform_device *pdev)
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int xudc_suspend(struct device *dev)
{
	struct xusb_udc *udc;
	u32 crtlreg;
	unsigned long flags;

	udc = dev_get_drvdata(dev);

	spin_lock_irqsave(&udc->lock, flags);

	crtlreg = udc->read_fn(udc->addr + XUSB_CONTROL_OFFSET);
	crtlreg &= ~XUSB_CONTROL_USB_READY_MASK;

	udc->write_fn(udc->addr, XUSB_CONTROL_OFFSET, crtlreg);

	spin_unlock_irqrestore(&udc->lock, flags);
	if (udc->driver && udc->driver->suspend)
		udc->driver->suspend(&udc->gadget);

	clk_disable(udc->clk);

	return 0;
}

static int xudc_resume(struct device *dev)
{
	struct xusb_udc *udc;
	u32 crtlreg;
	unsigned long flags;
	int ret;

	udc = dev_get_drvdata(dev);

	ret = clk_enable(udc->clk);
	if (ret < 0)
		return ret;

	spin_lock_irqsave(&udc->lock, flags);

	crtlreg = udc->read_fn(udc->addr + XUSB_CONTROL_OFFSET);
	crtlreg |= XUSB_CONTROL_USB_READY_MASK;

	udc->write_fn(udc->addr, XUSB_CONTROL_OFFSET, crtlreg);

	spin_unlock_irqrestore(&udc->lock, flags);

	return 0;
}
#endif /* CONFIG_PM_SLEEP */

static const struct dev_pm_ops xudc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(xudc_suspend, xudc_resume)
};

/* Match table for of_platform binding */
static const struct of_device_id usb_of_match[] = {
	{ .compatible = "xlnx,usb2-device-4.00.a", },
@@ -2187,6 +2242,7 @@ static struct platform_driver xudc_driver = {
	.driver = {
		.name = driver_name,
		.of_match_table = usb_of_match,
		.pm	= &xudc_pm_ops,
	},
	.probe = xudc_probe,
	.remove = xudc_remove,