From e9af9229098d92145d0b894b78878bbc6ac7c910 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 17 May 2016 10:15:02 +0300 Subject: usb: dwc3: pci: add Power Management dummy hooks Allow for dwc3-pci to reach D3 and enable pm_runtime by providing dummy PM hooks. Without them, PCI subsystem won't put device to D3. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers/usb/dwc3/dwc3-pci.c') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 14196cd416b3..a7b6a1c8bc81 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -180,7 +181,11 @@ static int dwc3_pci_probe(struct pci_dev *pci, goto err; } + device_init_wakeup(dev, true); + device_set_run_wake(dev, true); pci_set_drvdata(pci, dwc3); + pm_runtime_put(dev); + return 0; err: platform_device_put(dwc3); @@ -189,6 +194,8 @@ err: static void dwc3_pci_remove(struct pci_dev *pci) { + device_init_wakeup(&pci->dev, false); + pm_runtime_get(&pci->dev); acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pci->dev)); platform_device_unregister(pci_get_drvdata(pci)); } @@ -219,11 +226,43 @@ static const struct pci_device_id dwc3_pci_id_table[] = { }; MODULE_DEVICE_TABLE(pci, dwc3_pci_id_table); +#ifdef CONFIG_PM +static int dwc3_pci_runtime_suspend(struct device *dev) +{ + if (device_run_wake(dev)) + return 0; + + return -EBUSY; +} + +static int dwc3_pci_pm_dummy(struct device *dev) +{ + /* + * There's nothing to do here. No, seriously. Everything is either taken + * care either by PCI subsystem or dwc3/core.c, so we have nothing + * missing here. + * + * So you'd think we didn't need this at all, but PCI subsystem will + * bail out if we don't have a valid callback :-s + */ + return 0; +} +#endif /* CONFIG_PM */ + +static struct dev_pm_ops dwc3_pci_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy) + SET_RUNTIME_PM_OPS(dwc3_pci_runtime_suspend, dwc3_pci_pm_dummy, + NULL) +}; + static struct pci_driver dwc3_pci_driver = { .name = "dwc3-pci", .id_table = dwc3_pci_id_table, .probe = dwc3_pci_probe, .remove = dwc3_pci_remove, + .driver = { + .pm = &dwc3_pci_dev_pm_ops, + } }; MODULE_AUTHOR("Felipe Balbi "); -- cgit v1.2.3 From cf48305de0c6b556ff6af64e93295cc54c4fe246 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Fri, 22 Apr 2016 11:17:39 +0300 Subject: usb: dwc3: pci: use build-in properties instead of platform data This should allow the core driver to drop handling of platform data and expect the platform specific details to always come from properties. Tested-by: John Youn Signed-off-by: Heikki Krogerus Cc: Huang Rui CC: John Youn Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 70 +++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 38 deletions(-) (limited to 'drivers/usb/dwc3/dwc3-pci.c') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index a7b6a1c8bc81..6bc4c2b08ac7 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -24,8 +24,7 @@ #include #include #include - -#include "platform_data.h" +#include #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI 0xabce @@ -52,33 +51,29 @@ static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3) { if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == PCI_DEVICE_ID_AMD_NL_USB) { - struct dwc3_platform_data pdata; - - memset(&pdata, 0, sizeof(pdata)); - - pdata.has_lpm_erratum = true; - pdata.lpm_nyet_threshold = 0xf; - - pdata.u2exit_lfps_quirk = true; - pdata.u2ss_inp3_quirk = true; - pdata.req_p1p2p3_quirk = true; - pdata.del_p1p2p3_quirk = true; - pdata.del_phy_power_chg_quirk = true; - pdata.lfps_filter_quirk = true; - pdata.rx_detect_poll_quirk = true; - - pdata.tx_de_emphasis_quirk = true; - pdata.tx_de_emphasis = 1; - - /* - * FIXME these quirks should be removed when AMD NL - * taps out - */ - pdata.disable_scramble_quirk = true; - pdata.dis_u3_susphy_quirk = true; - pdata.dis_u2_susphy_quirk = true; - - return platform_device_add_data(dwc3, &pdata, sizeof(pdata)); + struct property_entry properties[] = { + PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), + PROPERTY_ENTRY_U8("snps,lpm-nyet-threshold", 0xf), + PROPERTY_ENTRY_BOOL("snps,u2exit_lfps_quirk"), + PROPERTY_ENTRY_BOOL("snps,u2ss_inp3_quirk"), + PROPERTY_ENTRY_BOOL("snps,req_p1p2p3_quirk"), + PROPERTY_ENTRY_BOOL("snps,del_p1p2p3_quirk"), + PROPERTY_ENTRY_BOOL("snps,del_phy_power_chg_quirk"), + PROPERTY_ENTRY_BOOL("snps,lfps_filter_quirk"), + PROPERTY_ENTRY_BOOL("snps,rx_detect_poll_quirk"), + PROPERTY_ENTRY_BOOL("snps,tx_de_emphasis_quirk"), + PROPERTY_ENTRY_U8("snps,tx_de_emphasis", 1), + /* + * FIXME these quirks should be removed when AMD NL + * tapes out + */ + PROPERTY_ENTRY_BOOL("snps,disable_scramble_quirk"), + PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), + PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), + { }, + }; + + return platform_device_add_properties(dwc3, properties); } if (pdev->vendor == PCI_VENDOR_ID_INTEL && @@ -115,15 +110,14 @@ static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3) (pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 || pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3_AXI || pdev->device == PCI_DEVICE_ID_SYNOPSYS_HAPSUSB31)) { - - struct dwc3_platform_data pdata; - - memset(&pdata, 0, sizeof(pdata)); - pdata.usb3_lpm_capable = true; - pdata.has_lpm_erratum = true; - pdata.dis_enblslpm_quirk = true; - - return platform_device_add_data(dwc3, &pdata, sizeof(pdata)); + struct property_entry properties[] = { + PROPERTY_ENTRY_BOOL("snps,usb3_lpm_capable"), + PROPERTY_ENTRY_BOOL("snps,has-lpm-erratum"), + PROPERTY_ENTRY_BOOL("snps,dis_enblslpm_quirk"), + { }, + }; + + return platform_device_add_properties(dwc3, properties); } return 0; -- cgit v1.2.3 From e6fe66fe08cdf9c5d0eb6a6e209621f74f7ee60b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 7 Jun 2016 12:49:52 +0300 Subject: usb: dwc3: pci: add dr-mode for Intel dwc3 It's know that Intel's SoCs' dwc3 integration is peripheral-only since Intel implements its own portmux for role-swapping. In order to prevent dwc3 from ever registering and XHCI platform_device, let's just set dr-mode to peripheral-only on Intel SoCs. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-pci.c | 62 +++++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 25 deletions(-) (limited to 'drivers/usb/dwc3/dwc3-pci.c') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 6bc4c2b08ac7..45f5a232d9fb 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -76,33 +76,45 @@ static int dwc3_pci_quirks(struct pci_dev *pdev, struct platform_device *dwc3) return platform_device_add_properties(dwc3, properties); } - if (pdev->vendor == PCI_VENDOR_ID_INTEL && - pdev->device == PCI_DEVICE_ID_INTEL_BYT) { - struct gpio_desc *gpio; - - acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev), - acpi_dwc3_byt_gpios); - - /* - * These GPIOs will turn on the USB2 PHY. Note that we have to - * put the gpio descriptors again here because the phy driver - * might want to grab them, too. - */ - gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW); - if (IS_ERR(gpio)) - return PTR_ERR(gpio); - - gpiod_set_value_cansleep(gpio, 1); - gpiod_put(gpio); - - gpio = gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(gpio)) - return PTR_ERR(gpio); - - if (gpio) { + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + int ret; + + struct property_entry properties[] = { + PROPERTY_ENTRY_STRING("dr-mode", "peripheral"), + { } + }; + + ret = platform_device_add_properties(dwc3, properties); + if (ret < 0) + return ret; + + if (pdev->device == PCI_DEVICE_ID_INTEL_BYT) { + struct gpio_desc *gpio; + + acpi_dev_add_driver_gpios(ACPI_COMPANION(&pdev->dev), + acpi_dwc3_byt_gpios); + + /* + * These GPIOs will turn on the USB2 PHY. Note that we have to + * put the gpio descriptors again here because the phy driver + * might want to grab them, too. + */ + gpio = gpiod_get_optional(&pdev->dev, "cs", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + gpiod_set_value_cansleep(gpio, 1); gpiod_put(gpio); - usleep_range(10000, 11000); + + gpio = gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + + if (gpio) { + gpiod_set_value_cansleep(gpio, 1); + gpiod_put(gpio); + usleep_range(10000, 11000); + } } } -- cgit v1.2.3