@@ -20,6 +20,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/usb/role.h>
+#include <linux/power_supply.h>
/* register definition */
#define DUAL_ROLE_CFG0 0x68
@@ -37,6 +38,7 @@
struct intel_xhci_usb_data {
struct usb_role_switch *role_sw;
void __iomem *base;
+ enum usb_role role;
};
static int intel_xhci_usb_set_role(struct device *dev, enum usb_role role)
@@ -167,6 +169,29 @@ static int intel_xhci_usb_remove(struct platform_device *pdev)
return 0;
}
+static int intel_xhci_usb_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ struct intel_xhci_usb_data *data = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+
+ data->role = intel_xhci_usb_get_role(dev);
+
+ return 0;
+}
+
+static int intel_xhci_usb_resume(struct platform_device *pdev)
+{
+ struct intel_xhci_usb_data *data = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+
+ if (intel_xhci_usb_get_role(dev) == USB_ROLE_NONE &&
+ power_supply_is_system_supplied())
+ intel_xhci_usb_set_role(dev, data->role);
+
+ return 0;
+}
+
static const struct platform_device_id intel_xhci_usb_table[] = {
{ .name = DRV_NAME },
{}
@@ -180,6 +205,8 @@ static struct platform_driver intel_xhci_usb_driver = {
.id_table = intel_xhci_usb_table,
.probe = intel_xhci_usb_probe,
.remove = intel_xhci_usb_remove,
+ .suspend = intel_xhci_usb_suspend,
+ .resume = intel_xhci_usb_resume,
};
module_platform_driver(intel_xhci_usb_driver);