|
@@ -1388,10 +1388,6 @@ static void brcmf_pcie_wowl_config(struct device *dev, bool enabled)
|
|
|
|
|
|
brcmf_dbg(PCIE, "Configuring WOWL, enabled=%d\n", enabled);
|
|
|
devinfo->wowl_enabled = enabled;
|
|
|
- if (enabled)
|
|
|
- device_set_wakeup_enable(&devinfo->pdev->dev, true);
|
|
|
- else
|
|
|
- device_set_wakeup_enable(&devinfo->pdev->dev, false);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1961,15 +1957,14 @@ brcmf_pcie_remove(struct pci_dev *pdev)
|
|
|
#ifdef CONFIG_PM
|
|
|
|
|
|
|
|
|
-static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
|
+static int brcmf_pcie_pm_enter_D3(struct device *dev)
|
|
|
{
|
|
|
struct brcmf_pciedev_info *devinfo;
|
|
|
struct brcmf_bus *bus;
|
|
|
- int err;
|
|
|
|
|
|
- brcmf_dbg(PCIE, "Enter, state=%d, pdev=%p\n", state.event, pdev);
|
|
|
+ brcmf_err("Enter\n");
|
|
|
|
|
|
- bus = dev_get_drvdata(&pdev->dev);
|
|
|
+ bus = dev_get_drvdata(dev);
|
|
|
devinfo = bus->bus_priv.pcie->devinfo;
|
|
|
|
|
|
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
|
|
@@ -1984,62 +1979,45 @@ static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
|
|
|
brcmf_err("Timeout on response for entering D3 substate\n");
|
|
|
return -EIO;
|
|
|
}
|
|
|
- brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM_IN_USE);
|
|
|
|
|
|
- err = pci_save_state(pdev);
|
|
|
- if (err)
|
|
|
- brcmf_err("pci_save_state failed, err=%d\n", err);
|
|
|
- if ((err) || (!devinfo->wowl_enabled)) {
|
|
|
- brcmf_chip_detach(devinfo->ci);
|
|
|
- devinfo->ci = NULL;
|
|
|
- brcmf_pcie_remove(pdev);
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
|
|
|
|
|
|
- return pci_prepare_to_sleep(pdev);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-static int brcmf_pcie_resume(struct pci_dev *pdev)
|
|
|
+
|
|
|
+static int brcmf_pcie_pm_leave_D3(struct device *dev)
|
|
|
{
|
|
|
struct brcmf_pciedev_info *devinfo;
|
|
|
struct brcmf_bus *bus;
|
|
|
+ struct pci_dev *pdev;
|
|
|
int err;
|
|
|
|
|
|
- bus = dev_get_drvdata(&pdev->dev);
|
|
|
- brcmf_dbg(PCIE, "Enter, pdev=%p, bus=%p\n", pdev, bus);
|
|
|
+ brcmf_err("Enter\n");
|
|
|
|
|
|
- err = pci_set_power_state(pdev, PCI_D0);
|
|
|
- if (err) {
|
|
|
- brcmf_err("pci_set_power_state failed, err=%d\n", err);
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- pci_restore_state(pdev);
|
|
|
- pci_enable_wake(pdev, PCI_D3hot, false);
|
|
|
- pci_enable_wake(pdev, PCI_D3cold, false);
|
|
|
+ bus = dev_get_drvdata(dev);
|
|
|
+ devinfo = bus->bus_priv.pcie->devinfo;
|
|
|
+ brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
|
|
|
|
|
|
/* Check if device is still up and running, if so we are ready */
|
|
|
- if (bus) {
|
|
|
- devinfo = bus->bus_priv.pcie->devinfo;
|
|
|
- if (brcmf_pcie_read_reg32(devinfo,
|
|
|
- BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
|
|
|
- if (brcmf_pcie_send_mb_data(devinfo,
|
|
|
- BRCMF_H2D_HOST_D0_INFORM))
|
|
|
- goto cleanup;
|
|
|
- brcmf_dbg(PCIE, "Hot resume, continue....\n");
|
|
|
- brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
|
|
|
- brcmf_bus_change_state(bus, BRCMF_BUS_UP);
|
|
|
- brcmf_pcie_intr_enable(devinfo);
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
|
|
|
+ brcmf_dbg(PCIE, "Try to wakeup device....\n");
|
|
|
+ if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
|
|
|
+ goto cleanup;
|
|
|
+ brcmf_dbg(PCIE, "Hot resume, continue....\n");
|
|
|
+ devinfo->state = BRCMFMAC_PCIE_STATE_UP;
|
|
|
+ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
|
|
|
+ brcmf_bus_change_state(bus, BRCMF_BUS_UP);
|
|
|
+ brcmf_pcie_intr_enable(devinfo);
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
cleanup:
|
|
|
- if (bus) {
|
|
|
- devinfo = bus->bus_priv.pcie->devinfo;
|
|
|
- brcmf_chip_detach(devinfo->ci);
|
|
|
- devinfo->ci = NULL;
|
|
|
- brcmf_pcie_remove(pdev);
|
|
|
- }
|
|
|
+ brcmf_chip_detach(devinfo->ci);
|
|
|
+ devinfo->ci = NULL;
|
|
|
+ pdev = devinfo->pdev;
|
|
|
+ brcmf_pcie_remove(pdev);
|
|
|
+
|
|
|
err = brcmf_pcie_probe(pdev, NULL);
|
|
|
if (err)
|
|
|
brcmf_err("probe after resume failed, err=%d\n", err);
|
|
@@ -2048,6 +2026,14 @@ cleanup:
|
|
|
}
|
|
|
|
|
|
|
|
|
+static const struct dev_pm_ops brcmf_pciedrvr_pm = {
|
|
|
+ .suspend = brcmf_pcie_pm_enter_D3,
|
|
|
+ .resume = brcmf_pcie_pm_leave_D3,
|
|
|
+ .freeze = brcmf_pcie_pm_enter_D3,
|
|
|
+ .restore = brcmf_pcie_pm_leave_D3,
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
#endif /* CONFIG_PM */
|
|
|
|
|
|
|
|
@@ -2086,9 +2072,8 @@ static struct pci_driver brcmf_pciedrvr = {
|
|
|
.probe = brcmf_pcie_probe,
|
|
|
.remove = brcmf_pcie_remove,
|
|
|
#ifdef CONFIG_PM
|
|
|
- .suspend = brcmf_pcie_suspend,
|
|
|
- .resume = brcmf_pcie_resume
|
|
|
-#endif /* CONFIG_PM */
|
|
|
+ .driver.pm = &brcmf_pciedrvr_pm,
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
|