1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Thu, 29 Oct 2015 20:33:18 +0100
3 Subject: [PATCH] brcmfmac: Use new methods for pcie Power Management.
5 Currently the legacy methods suspend and resume are used for pcie
6 devices. This is not the preferable method and is also causing
7 issues with some setups when doing hibernate. Changing this to
8 use the new PM methods.
10 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
11 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
13 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
18 --- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
19 +++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
20 @@ -1388,10 +1388,6 @@ static void brcmf_pcie_wowl_config(struc
22 brcmf_dbg(PCIE, "Configuring WOWL, enabled=%d\n", enabled);
23 devinfo->wowl_enabled = enabled;
25 - device_set_wakeup_enable(&devinfo->pdev->dev, true);
27 - device_set_wakeup_enable(&devinfo->pdev->dev, false);
31 @@ -1961,15 +1957,14 @@ brcmf_pcie_remove(struct pci_dev *pdev)
35 -static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
36 +static int brcmf_pcie_pm_enter_D3(struct device *dev)
38 struct brcmf_pciedev_info *devinfo;
39 struct brcmf_bus *bus;
42 - brcmf_dbg(PCIE, "Enter, state=%d, pdev=%p\n", state.event, pdev);
43 + brcmf_err("Enter\n");
45 - bus = dev_get_drvdata(&pdev->dev);
46 + bus = dev_get_drvdata(dev);
47 devinfo = bus->bus_priv.pcie->devinfo;
49 brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
50 @@ -1984,62 +1979,45 @@ static int brcmf_pcie_suspend(struct pci
51 brcmf_err("Timeout on response for entering D3 substate\n");
54 - brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM_IN_USE);
56 - err = pci_save_state(pdev);
58 - brcmf_err("pci_save_state failed, err=%d\n", err);
59 - if ((err) || (!devinfo->wowl_enabled)) {
60 - brcmf_chip_detach(devinfo->ci);
62 - brcmf_pcie_remove(pdev);
65 + devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
67 - return pci_prepare_to_sleep(pdev);
71 -static int brcmf_pcie_resume(struct pci_dev *pdev)
73 +static int brcmf_pcie_pm_leave_D3(struct device *dev)
75 struct brcmf_pciedev_info *devinfo;
76 struct brcmf_bus *bus;
77 + struct pci_dev *pdev;
80 - bus = dev_get_drvdata(&pdev->dev);
81 - brcmf_dbg(PCIE, "Enter, pdev=%p, bus=%p\n", pdev, bus);
82 + brcmf_err("Enter\n");
84 - err = pci_set_power_state(pdev, PCI_D0);
86 - brcmf_err("pci_set_power_state failed, err=%d\n", err);
89 - pci_restore_state(pdev);
90 - pci_enable_wake(pdev, PCI_D3hot, false);
91 - pci_enable_wake(pdev, PCI_D3cold, false);
92 + bus = dev_get_drvdata(dev);
93 + devinfo = bus->bus_priv.pcie->devinfo;
94 + brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
96 /* Check if device is still up and running, if so we are ready */
98 - devinfo = bus->bus_priv.pcie->devinfo;
99 - if (brcmf_pcie_read_reg32(devinfo,
100 - BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
101 - if (brcmf_pcie_send_mb_data(devinfo,
102 - BRCMF_H2D_HOST_D0_INFORM))
104 - brcmf_dbg(PCIE, "Hot resume, continue....\n");
105 - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
106 - brcmf_bus_change_state(bus, BRCMF_BUS_UP);
107 - brcmf_pcie_intr_enable(devinfo);
110 + if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
111 + brcmf_dbg(PCIE, "Try to wakeup device....\n");
112 + if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
114 + brcmf_dbg(PCIE, "Hot resume, continue....\n");
115 + devinfo->state = BRCMFMAC_PCIE_STATE_UP;
116 + brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
117 + brcmf_bus_change_state(bus, BRCMF_BUS_UP);
118 + brcmf_pcie_intr_enable(devinfo);
124 - devinfo = bus->bus_priv.pcie->devinfo;
125 - brcmf_chip_detach(devinfo->ci);
126 - devinfo->ci = NULL;
127 - brcmf_pcie_remove(pdev);
129 + brcmf_chip_detach(devinfo->ci);
130 + devinfo->ci = NULL;
131 + pdev = devinfo->pdev;
132 + brcmf_pcie_remove(pdev);
134 err = brcmf_pcie_probe(pdev, NULL);
136 brcmf_err("probe after resume failed, err=%d\n", err);
137 @@ -2048,6 +2026,14 @@ cleanup:
141 +static const struct dev_pm_ops brcmf_pciedrvr_pm = {
142 + .suspend = brcmf_pcie_pm_enter_D3,
143 + .resume = brcmf_pcie_pm_leave_D3,
144 + .freeze = brcmf_pcie_pm_enter_D3,
145 + .restore = brcmf_pcie_pm_leave_D3,
149 #endif /* CONFIG_PM */
152 @@ -2086,9 +2072,8 @@ static struct pci_driver brcmf_pciedrvr
153 .probe = brcmf_pcie_probe,
154 .remove = brcmf_pcie_remove,
156 - .suspend = brcmf_pcie_suspend,
157 - .resume = brcmf_pcie_resume
158 -#endif /* CONFIG_PM */
159 + .driver.pm = &brcmf_pciedrvr_pm,