mt76: mt7921u: add suspend/resume support
Introduce suspend/resume callbacks for mt7921u driver. Tested-by: Deren Wu <deren.wu@mediatek.com> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
committed by
Felix Fietkau
parent
b619e01380
commit
df3e4143ba
@@ -467,7 +467,7 @@ bool mt7921_usb_sdio_tx_status_data(struct mt76_dev *mdev, u8 *update);
|
|||||||
|
|
||||||
int mt7921u_mcu_power_on(struct mt7921_dev *dev);
|
int mt7921u_mcu_power_on(struct mt7921_dev *dev);
|
||||||
int mt7921u_wfsys_reset(struct mt7921_dev *dev);
|
int mt7921u_wfsys_reset(struct mt7921_dev *dev);
|
||||||
int mt7921u_dma_init(struct mt7921_dev *dev);
|
int mt7921u_dma_init(struct mt7921_dev *dev, bool resume);
|
||||||
int mt7921u_init_reset(struct mt7921_dev *dev);
|
int mt7921u_init_reset(struct mt7921_dev *dev);
|
||||||
int mt7921u_mac_reset(struct mt7921_dev *dev);
|
int mt7921u_mac_reset(struct mt7921_dev *dev);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -516,4 +516,9 @@
|
|||||||
#define MT_TOP_MISC2_FW_PWR_ON BIT(0)
|
#define MT_TOP_MISC2_FW_PWR_ON BIT(0)
|
||||||
#define MT_TOP_MISC2_FW_N9_RDY GENMASK(1, 0)
|
#define MT_TOP_MISC2_FW_N9_RDY GENMASK(1, 0)
|
||||||
|
|
||||||
|
#define MT_WF_SW_DEF_CR(ofs) (0x401a00 + (ofs))
|
||||||
|
#define MT_WF_SW_DEF_CR_USB_MCU_EVENT MT_WF_SW_DEF_CR(0x028)
|
||||||
|
#define MT_WF_SW_SER_TRIGGER_SUSPEND BIT(6)
|
||||||
|
#define MT_WF_SW_SER_DONE_SUSPEND BIT(7)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ static int mt7921u_probe(struct usb_interface *usb_intf,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ret = mt7921u_dma_init(dev);
|
ret = mt7921u_dma_init(dev, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -288,6 +288,61 @@ static void mt7921u_disconnect(struct usb_interface *usb_intf)
|
|||||||
mt76_free_device(&dev->mt76);
|
mt76_free_device(&dev->mt76);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
static int mt7921u_suspend(struct usb_interface *intf, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct mt7921_dev *dev = usb_get_intfdata(intf);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
mt76u_stop_rx(&dev->mt76);
|
||||||
|
mt76u_stop_tx(&dev->mt76);
|
||||||
|
|
||||||
|
set_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mt7921u_resume(struct usb_interface *intf)
|
||||||
|
{
|
||||||
|
struct mt7921_dev *dev = usb_get_intfdata(intf);
|
||||||
|
bool reinit = true;
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
u32 val = mt76_rr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT);
|
||||||
|
|
||||||
|
if (!(val & MT_WF_SW_SER_TRIGGER_SUSPEND)) {
|
||||||
|
reinit = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val & MT_WF_SW_SER_DONE_SUSPEND) {
|
||||||
|
mt76_wr(dev, MT_WF_SW_DEF_CR_USB_MCU_EVENT, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
msleep(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reinit || mt7921_dma_need_reinit(dev)) {
|
||||||
|
err = mt7921u_dma_init(dev, true);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
|
||||||
|
|
||||||
|
err = mt76u_resume_rx(&dev->mt76);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(usb, mt7921u_device_table);
|
MODULE_DEVICE_TABLE(usb, mt7921u_device_table);
|
||||||
MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
|
MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
|
||||||
MODULE_FIRMWARE(MT7921_ROM_PATCH);
|
MODULE_FIRMWARE(MT7921_ROM_PATCH);
|
||||||
@@ -297,6 +352,11 @@ static struct usb_driver mt7921u_driver = {
|
|||||||
.id_table = mt7921u_device_table,
|
.id_table = mt7921u_device_table,
|
||||||
.probe = mt7921u_probe,
|
.probe = mt7921u_probe,
|
||||||
.disconnect = mt7921u_disconnect,
|
.disconnect = mt7921u_disconnect,
|
||||||
|
#ifdef CONFIG_PM
|
||||||
|
.suspend = mt7921u_suspend,
|
||||||
|
.resume = mt7921u_resume,
|
||||||
|
.reset_resume = mt7921u_resume,
|
||||||
|
#endif /* CONFIG_PM */
|
||||||
.soft_unbind = 1,
|
.soft_unbind = 1,
|
||||||
.disable_hub_initiated_lpm = 1,
|
.disable_hub_initiated_lpm = 1,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ static void mt7921u_epctl_rst_opt(struct mt7921_dev *dev, bool reset)
|
|||||||
mt7921u_uhw_wr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT, val);
|
mt7921u_uhw_wr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mt7921u_dma_init(struct mt7921_dev *dev)
|
int mt7921u_dma_init(struct mt7921_dev *dev, bool resume)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@@ -136,6 +136,9 @@ int mt7921u_dma_init(struct mt7921_dev *dev)
|
|||||||
MT_WL_RX_AGG_TO | MT_WL_RX_AGG_LMT);
|
MT_WL_RX_AGG_TO | MT_WL_RX_AGG_LMT);
|
||||||
mt76_clear(dev, MT_UDMA_WLCFG_1, MT_WL_RX_AGG_PKT_LMT);
|
mt76_clear(dev, MT_UDMA_WLCFG_1, MT_WL_RX_AGG_PKT_LMT);
|
||||||
|
|
||||||
|
if (resume)
|
||||||
|
return 0;
|
||||||
|
|
||||||
err = mt7921u_dma_rx_evt_ep4(dev);
|
err = mt7921u_dma_rx_evt_ep4(dev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@@ -221,7 +224,7 @@ int mt7921u_mac_reset(struct mt7921_dev *dev)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = mt7921u_dma_init(dev);
|
err = mt7921u_dma_init(dev, false);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user