16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC 26c92544dSBjoern A. Zeeb /* Copyright (C) 2021 MediaTek Inc. 36c92544dSBjoern A. Zeeb * 46c92544dSBjoern A. Zeeb */ 56c92544dSBjoern A. Zeeb 66c92544dSBjoern A. Zeeb #include <linux/kernel.h> 76c92544dSBjoern A. Zeeb #include <linux/iopoll.h> 86c92544dSBjoern A. Zeeb #include <linux/module.h> 96c92544dSBjoern A. Zeeb 106c92544dSBjoern A. Zeeb #include <linux/mmc/host.h> 116c92544dSBjoern A. Zeeb #include <linux/mmc/sdio_ids.h> 126c92544dSBjoern A. Zeeb #include <linux/mmc/sdio_func.h> 136c92544dSBjoern A. Zeeb 146c92544dSBjoern A. Zeeb #include "mt7921.h" 156c92544dSBjoern A. Zeeb #include "../sdio.h" 16*cbb3ec25SBjoern A. Zeeb #include "../mt76_connac2_mac.h" 176c92544dSBjoern A. Zeeb #include "mcu.h" 186c92544dSBjoern A. Zeeb 196c92544dSBjoern A. Zeeb static const struct sdio_device_id mt7921s_table[] = { 20*cbb3ec25SBjoern A. Zeeb { SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7901), 21*cbb3ec25SBjoern A. Zeeb .driver_data = (kernel_ulong_t)MT7921_FIRMWARE_WM }, 226c92544dSBjoern A. Zeeb { } /* Terminating entry */ 236c92544dSBjoern A. Zeeb }; 246c92544dSBjoern A. Zeeb 256c92544dSBjoern A. Zeeb static void mt7921s_txrx_worker(struct mt76_worker *w) 266c92544dSBjoern A. Zeeb { 276c92544dSBjoern A. Zeeb struct mt76_sdio *sdio = container_of(w, struct mt76_sdio, 286c92544dSBjoern A. Zeeb txrx_worker); 296c92544dSBjoern A. Zeeb struct mt76_dev *mdev = container_of(sdio, struct mt76_dev, sdio); 30*cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); 316c92544dSBjoern A. Zeeb 326c92544dSBjoern A. Zeeb if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) { 336c92544dSBjoern A. Zeeb queue_work(mdev->wq, &dev->pm.wake_work); 346c92544dSBjoern A. Zeeb return; 356c92544dSBjoern A. Zeeb } 366c92544dSBjoern A. Zeeb 376c92544dSBjoern A. Zeeb mt76s_txrx_worker(sdio); 386c92544dSBjoern A. Zeeb mt76_connac_pm_unref(&dev->mphy, &dev->pm); 396c92544dSBjoern A. Zeeb } 406c92544dSBjoern A. Zeeb 41*cbb3ec25SBjoern A. Zeeb static void mt7921s_unregister_device(struct mt792x_dev *dev) 426c92544dSBjoern A. Zeeb { 436c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm; 446c92544dSBjoern A. Zeeb 456c92544dSBjoern A. Zeeb cancel_work_sync(&dev->init_work); 466c92544dSBjoern A. Zeeb mt76_unregister_device(&dev->mt76); 476c92544dSBjoern A. Zeeb cancel_delayed_work_sync(&pm->ps_work); 486c92544dSBjoern A. Zeeb cancel_work_sync(&pm->wake_work); 496c92544dSBjoern A. Zeeb 506c92544dSBjoern A. Zeeb mt76s_deinit(&dev->mt76); 516c92544dSBjoern A. Zeeb mt7921s_wfsys_reset(dev); 526c92544dSBjoern A. Zeeb skb_queue_purge(&dev->mt76.mcu.res_q); 536c92544dSBjoern A. Zeeb 546c92544dSBjoern A. Zeeb mt76_free_device(&dev->mt76); 556c92544dSBjoern A. Zeeb } 566c92544dSBjoern A. Zeeb 576c92544dSBjoern A. Zeeb static int mt7921s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr) 586c92544dSBjoern A. Zeeb { 596c92544dSBjoern A. Zeeb struct mt76_sdio *sdio = &dev->sdio; 606c92544dSBjoern A. Zeeb struct mt7921_sdio_intr *irq_data = sdio->intr_data; 616c92544dSBjoern A. Zeeb int i, err; 626c92544dSBjoern A. Zeeb 636c92544dSBjoern A. Zeeb sdio_claim_host(sdio->func); 646c92544dSBjoern A. Zeeb err = sdio_readsb(sdio->func, irq_data, MCR_WHISR, sizeof(*irq_data)); 656c92544dSBjoern A. Zeeb sdio_release_host(sdio->func); 666c92544dSBjoern A. Zeeb 676c92544dSBjoern A. Zeeb if (err < 0) 686c92544dSBjoern A. Zeeb return err; 696c92544dSBjoern A. Zeeb 706c92544dSBjoern A. Zeeb if (irq_data->rx.num[0] > 16 || 716c92544dSBjoern A. Zeeb irq_data->rx.num[1] > 128) 726c92544dSBjoern A. Zeeb return -EINVAL; 736c92544dSBjoern A. Zeeb 746c92544dSBjoern A. Zeeb intr->isr = irq_data->isr; 756c92544dSBjoern A. Zeeb intr->rec_mb = irq_data->rec_mb; 766c92544dSBjoern A. Zeeb intr->tx.wtqcr = irq_data->tx.wtqcr; 776c92544dSBjoern A. Zeeb intr->rx.num = irq_data->rx.num; 786c92544dSBjoern A. Zeeb for (i = 0; i < 2 ; i++) { 796c92544dSBjoern A. Zeeb if (!i) 806c92544dSBjoern A. Zeeb intr->rx.len[0] = irq_data->rx.len0; 816c92544dSBjoern A. Zeeb else 826c92544dSBjoern A. Zeeb intr->rx.len[1] = irq_data->rx.len1; 836c92544dSBjoern A. Zeeb } 846c92544dSBjoern A. Zeeb 856c92544dSBjoern A. Zeeb return 0; 866c92544dSBjoern A. Zeeb } 876c92544dSBjoern A. Zeeb 886c92544dSBjoern A. Zeeb static int mt7921s_probe(struct sdio_func *func, 896c92544dSBjoern A. Zeeb const struct sdio_device_id *id) 906c92544dSBjoern A. Zeeb { 916c92544dSBjoern A. Zeeb static const struct mt76_driver_ops drv_ops = { 926c92544dSBjoern A. Zeeb .txwi_size = MT_SDIO_TXD_SIZE, 93*cbb3ec25SBjoern A. Zeeb .drv_flags = MT_DRV_AMSDU_OFFLOAD, 946c92544dSBjoern A. Zeeb .survey_flags = SURVEY_INFO_TIME_TX | 956c92544dSBjoern A. Zeeb SURVEY_INFO_TIME_RX | 966c92544dSBjoern A. Zeeb SURVEY_INFO_TIME_BSS_RX, 976c92544dSBjoern A. Zeeb .tx_prepare_skb = mt7921_usb_sdio_tx_prepare_skb, 986c92544dSBjoern A. Zeeb .tx_complete_skb = mt7921_usb_sdio_tx_complete_skb, 996c92544dSBjoern A. Zeeb .tx_status_data = mt7921_usb_sdio_tx_status_data, 1006c92544dSBjoern A. Zeeb .rx_skb = mt7921_queue_rx_skb, 1016c92544dSBjoern A. Zeeb .rx_check = mt7921_rx_check, 1026c92544dSBjoern A. Zeeb .sta_add = mt7921_mac_sta_add, 1036c92544dSBjoern A. Zeeb .sta_assoc = mt7921_mac_sta_assoc, 1046c92544dSBjoern A. Zeeb .sta_remove = mt7921_mac_sta_remove, 105*cbb3ec25SBjoern A. Zeeb .update_survey = mt792x_update_channel, 1066c92544dSBjoern A. Zeeb }; 1076c92544dSBjoern A. Zeeb static const struct mt76_bus_ops mt7921s_ops = { 1086c92544dSBjoern A. Zeeb .rr = mt76s_rr, 1096c92544dSBjoern A. Zeeb .rmw = mt76s_rmw, 1106c92544dSBjoern A. Zeeb .wr = mt76s_wr, 1116c92544dSBjoern A. Zeeb .write_copy = mt76s_write_copy, 1126c92544dSBjoern A. Zeeb .read_copy = mt76s_read_copy, 1136c92544dSBjoern A. Zeeb .wr_rp = mt76s_wr_rp, 1146c92544dSBjoern A. Zeeb .rd_rp = mt76s_rd_rp, 1156c92544dSBjoern A. Zeeb .type = MT76_BUS_SDIO, 1166c92544dSBjoern A. Zeeb }; 117*cbb3ec25SBjoern A. Zeeb static const struct mt792x_hif_ops mt7921_sdio_ops = { 1186c92544dSBjoern A. Zeeb .init_reset = mt7921s_init_reset, 1196c92544dSBjoern A. Zeeb .reset = mt7921s_mac_reset, 1206c92544dSBjoern A. Zeeb .mcu_init = mt7921s_mcu_init, 1216c92544dSBjoern A. Zeeb .drv_own = mt7921s_mcu_drv_pmctrl, 1226c92544dSBjoern A. Zeeb .fw_own = mt7921s_mcu_fw_pmctrl, 1236c92544dSBjoern A. Zeeb }; 124*cbb3ec25SBjoern A. Zeeb struct ieee80211_ops *ops; 125*cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev; 1266c92544dSBjoern A. Zeeb struct mt76_dev *mdev; 127*cbb3ec25SBjoern A. Zeeb u8 features; 1286c92544dSBjoern A. Zeeb int ret; 1296c92544dSBjoern A. Zeeb 130*cbb3ec25SBjoern A. Zeeb ops = mt792x_get_mac80211_ops(&func->dev, &mt7921_ops, 131*cbb3ec25SBjoern A. Zeeb (void *)id->driver_data, &features); 132*cbb3ec25SBjoern A. Zeeb if (!ops) 133*cbb3ec25SBjoern A. Zeeb return -ENOMEM; 134*cbb3ec25SBjoern A. Zeeb 135*cbb3ec25SBjoern A. Zeeb mdev = mt76_alloc_device(&func->dev, sizeof(*dev), ops, &drv_ops); 1366c92544dSBjoern A. Zeeb if (!mdev) 1376c92544dSBjoern A. Zeeb return -ENOMEM; 1386c92544dSBjoern A. Zeeb 139*cbb3ec25SBjoern A. Zeeb dev = container_of(mdev, struct mt792x_dev, mt76); 140*cbb3ec25SBjoern A. Zeeb dev->fw_features = features; 1416c92544dSBjoern A. Zeeb dev->hif_ops = &mt7921_sdio_ops; 1426c92544dSBjoern A. Zeeb sdio_set_drvdata(func, dev); 1436c92544dSBjoern A. Zeeb 1446c92544dSBjoern A. Zeeb ret = mt76s_init(mdev, func, &mt7921s_ops); 1456c92544dSBjoern A. Zeeb if (ret < 0) 1466c92544dSBjoern A. Zeeb goto error; 1476c92544dSBjoern A. Zeeb 1486c92544dSBjoern A. Zeeb ret = mt76s_hw_init(mdev, func, MT76_CONNAC2_SDIO); 1496c92544dSBjoern A. Zeeb if (ret) 1506c92544dSBjoern A. Zeeb goto error; 1516c92544dSBjoern A. Zeeb 1526c92544dSBjoern A. Zeeb mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) | 1536c92544dSBjoern A. Zeeb (mt76_rr(dev, MT_HW_REV) & 0xff); 1546c92544dSBjoern A. Zeeb dev_dbg(mdev->dev, "ASIC revision: %04x\n", mdev->rev); 1556c92544dSBjoern A. Zeeb 1566c92544dSBjoern A. Zeeb mdev->sdio.parse_irq = mt7921s_parse_intr; 1576c92544dSBjoern A. Zeeb mdev->sdio.intr_data = devm_kmalloc(mdev->dev, 1586c92544dSBjoern A. Zeeb sizeof(struct mt7921_sdio_intr), 1596c92544dSBjoern A. Zeeb GFP_KERNEL); 1606c92544dSBjoern A. Zeeb if (!mdev->sdio.intr_data) { 1616c92544dSBjoern A. Zeeb ret = -ENOMEM; 1626c92544dSBjoern A. Zeeb goto error; 1636c92544dSBjoern A. Zeeb } 1646c92544dSBjoern A. Zeeb 1656c92544dSBjoern A. Zeeb ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MAIN); 1666c92544dSBjoern A. Zeeb if (ret) 1676c92544dSBjoern A. Zeeb goto error; 1686c92544dSBjoern A. Zeeb 1696c92544dSBjoern A. Zeeb ret = mt76s_alloc_rx_queue(mdev, MT_RXQ_MCU); 1706c92544dSBjoern A. Zeeb if (ret) 1716c92544dSBjoern A. Zeeb goto error; 1726c92544dSBjoern A. Zeeb 1736c92544dSBjoern A. Zeeb ret = mt76s_alloc_tx(mdev); 1746c92544dSBjoern A. Zeeb if (ret) 1756c92544dSBjoern A. Zeeb goto error; 1766c92544dSBjoern A. Zeeb 1776c92544dSBjoern A. Zeeb ret = mt76_worker_setup(mt76_hw(dev), &mdev->sdio.txrx_worker, 1786c92544dSBjoern A. Zeeb mt7921s_txrx_worker, "sdio-txrx"); 1796c92544dSBjoern A. Zeeb if (ret) 1806c92544dSBjoern A. Zeeb goto error; 1816c92544dSBjoern A. Zeeb 1826c92544dSBjoern A. Zeeb sched_set_fifo_low(mdev->sdio.txrx_worker.task); 1836c92544dSBjoern A. Zeeb 1846c92544dSBjoern A. Zeeb ret = mt7921_register_device(dev); 1856c92544dSBjoern A. Zeeb if (ret) 1866c92544dSBjoern A. Zeeb goto error; 1876c92544dSBjoern A. Zeeb 1886c92544dSBjoern A. Zeeb return 0; 1896c92544dSBjoern A. Zeeb 1906c92544dSBjoern A. Zeeb error: 1916c92544dSBjoern A. Zeeb mt76s_deinit(&dev->mt76); 1926c92544dSBjoern A. Zeeb mt76_free_device(&dev->mt76); 1936c92544dSBjoern A. Zeeb 1946c92544dSBjoern A. Zeeb return ret; 1956c92544dSBjoern A. Zeeb } 1966c92544dSBjoern A. Zeeb 1976c92544dSBjoern A. Zeeb static void mt7921s_remove(struct sdio_func *func) 1986c92544dSBjoern A. Zeeb { 199*cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = sdio_get_drvdata(func); 2006c92544dSBjoern A. Zeeb 2016c92544dSBjoern A. Zeeb mt7921s_unregister_device(dev); 2026c92544dSBjoern A. Zeeb } 2036c92544dSBjoern A. Zeeb 2046c92544dSBjoern A. Zeeb static int mt7921s_suspend(struct device *__dev) 2056c92544dSBjoern A. Zeeb { 2066c92544dSBjoern A. Zeeb struct sdio_func *func = dev_to_sdio_func(__dev); 207*cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = sdio_get_drvdata(func); 2086c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm; 2096c92544dSBjoern A. Zeeb struct mt76_dev *mdev = &dev->mt76; 2106c92544dSBjoern A. Zeeb int err; 2116c92544dSBjoern A. Zeeb 2126c92544dSBjoern A. Zeeb pm->suspended = true; 2136c92544dSBjoern A. Zeeb set_bit(MT76_STATE_SUSPEND, &mdev->phy.state); 2146c92544dSBjoern A. Zeeb 2156c92544dSBjoern A. Zeeb flush_work(&dev->reset_work); 2166c92544dSBjoern A. Zeeb cancel_delayed_work_sync(&pm->ps_work); 2176c92544dSBjoern A. Zeeb cancel_work_sync(&pm->wake_work); 2186c92544dSBjoern A. Zeeb 219*cbb3ec25SBjoern A. Zeeb err = mt792x_mcu_drv_pmctrl(dev); 2206c92544dSBjoern A. Zeeb if (err < 0) 2216c92544dSBjoern A. Zeeb goto restore_suspend; 2226c92544dSBjoern A. Zeeb 2236c92544dSBjoern A. Zeeb /* always enable deep sleep during suspend to reduce 2246c92544dSBjoern A. Zeeb * power consumption 2256c92544dSBjoern A. Zeeb */ 2266c92544dSBjoern A. Zeeb mt76_connac_mcu_set_deep_sleep(mdev, true); 2276c92544dSBjoern A. Zeeb 2286c92544dSBjoern A. Zeeb mt76_txq_schedule_all(&dev->mphy); 2296c92544dSBjoern A. Zeeb mt76_worker_disable(&mdev->tx_worker); 2306c92544dSBjoern A. Zeeb mt76_worker_disable(&mdev->sdio.status_worker); 2316c92544dSBjoern A. Zeeb cancel_work_sync(&mdev->sdio.stat_work); 2326c92544dSBjoern A. Zeeb clear_bit(MT76_READING_STATS, &dev->mphy.state); 2336c92544dSBjoern A. Zeeb mt76_tx_status_check(mdev, true); 2346c92544dSBjoern A. Zeeb 2356c92544dSBjoern A. Zeeb mt76_worker_schedule(&mdev->sdio.txrx_worker); 2366c92544dSBjoern A. Zeeb wait_event_timeout(dev->mt76.sdio.wait, 2376c92544dSBjoern A. Zeeb mt76s_txqs_empty(&dev->mt76), 5 * HZ); 2386c92544dSBjoern A. Zeeb 2396c92544dSBjoern A. Zeeb /* It is supposed that SDIO bus is idle at the point */ 2406c92544dSBjoern A. Zeeb err = mt76_connac_mcu_set_hif_suspend(mdev, true); 2416c92544dSBjoern A. Zeeb if (err) 2426c92544dSBjoern A. Zeeb goto restore_worker; 2436c92544dSBjoern A. Zeeb 2446c92544dSBjoern A. Zeeb mt76_worker_disable(&mdev->sdio.txrx_worker); 2456c92544dSBjoern A. Zeeb mt76_worker_disable(&mdev->sdio.net_worker); 2466c92544dSBjoern A. Zeeb 247*cbb3ec25SBjoern A. Zeeb err = mt792x_mcu_fw_pmctrl(dev); 2486c92544dSBjoern A. Zeeb if (err) 2496c92544dSBjoern A. Zeeb goto restore_txrx_worker; 2506c92544dSBjoern A. Zeeb 2516c92544dSBjoern A. Zeeb sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); 2526c92544dSBjoern A. Zeeb 2536c92544dSBjoern A. Zeeb return 0; 2546c92544dSBjoern A. Zeeb 2556c92544dSBjoern A. Zeeb restore_txrx_worker: 2566c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->sdio.net_worker); 2576c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->sdio.txrx_worker); 2586c92544dSBjoern A. Zeeb mt76_connac_mcu_set_hif_suspend(mdev, false); 2596c92544dSBjoern A. Zeeb 2606c92544dSBjoern A. Zeeb restore_worker: 2616c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->tx_worker); 2626c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->sdio.status_worker); 2636c92544dSBjoern A. Zeeb 2646c92544dSBjoern A. Zeeb if (!pm->ds_enable) 2656c92544dSBjoern A. Zeeb mt76_connac_mcu_set_deep_sleep(mdev, false); 2666c92544dSBjoern A. Zeeb 2676c92544dSBjoern A. Zeeb restore_suspend: 2686c92544dSBjoern A. Zeeb clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state); 2696c92544dSBjoern A. Zeeb pm->suspended = false; 2706c92544dSBjoern A. Zeeb 2716c92544dSBjoern A. Zeeb if (err < 0) 272*cbb3ec25SBjoern A. Zeeb mt792x_reset(&dev->mt76); 2736c92544dSBjoern A. Zeeb 2746c92544dSBjoern A. Zeeb return err; 2756c92544dSBjoern A. Zeeb } 2766c92544dSBjoern A. Zeeb 2776c92544dSBjoern A. Zeeb static int mt7921s_resume(struct device *__dev) 2786c92544dSBjoern A. Zeeb { 2796c92544dSBjoern A. Zeeb struct sdio_func *func = dev_to_sdio_func(__dev); 280*cbb3ec25SBjoern A. Zeeb struct mt792x_dev *dev = sdio_get_drvdata(func); 2816c92544dSBjoern A. Zeeb struct mt76_connac_pm *pm = &dev->pm; 2826c92544dSBjoern A. Zeeb struct mt76_dev *mdev = &dev->mt76; 2836c92544dSBjoern A. Zeeb int err; 2846c92544dSBjoern A. Zeeb 2856c92544dSBjoern A. Zeeb clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state); 2866c92544dSBjoern A. Zeeb 287*cbb3ec25SBjoern A. Zeeb err = mt792x_mcu_drv_pmctrl(dev); 2886c92544dSBjoern A. Zeeb if (err < 0) 2896c92544dSBjoern A. Zeeb goto failed; 2906c92544dSBjoern A. Zeeb 2916c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->tx_worker); 2926c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->sdio.txrx_worker); 2936c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->sdio.status_worker); 2946c92544dSBjoern A. Zeeb mt76_worker_enable(&mdev->sdio.net_worker); 2956c92544dSBjoern A. Zeeb 2966c92544dSBjoern A. Zeeb /* restore previous ds setting */ 2976c92544dSBjoern A. Zeeb if (!pm->ds_enable) 2986c92544dSBjoern A. Zeeb mt76_connac_mcu_set_deep_sleep(mdev, false); 2996c92544dSBjoern A. Zeeb 3006c92544dSBjoern A. Zeeb err = mt76_connac_mcu_set_hif_suspend(mdev, false); 3016c92544dSBjoern A. Zeeb failed: 3026c92544dSBjoern A. Zeeb pm->suspended = false; 3036c92544dSBjoern A. Zeeb 3046c92544dSBjoern A. Zeeb if (err < 0) 305*cbb3ec25SBjoern A. Zeeb mt792x_reset(&dev->mt76); 3066c92544dSBjoern A. Zeeb 3076c92544dSBjoern A. Zeeb return err; 3086c92544dSBjoern A. Zeeb } 3096c92544dSBjoern A. Zeeb 3106c92544dSBjoern A. Zeeb MODULE_DEVICE_TABLE(sdio, mt7921s_table); 3116c92544dSBjoern A. Zeeb MODULE_FIRMWARE(MT7921_FIRMWARE_WM); 3126c92544dSBjoern A. Zeeb MODULE_FIRMWARE(MT7921_ROM_PATCH); 3136c92544dSBjoern A. Zeeb 3146c92544dSBjoern A. Zeeb static DEFINE_SIMPLE_DEV_PM_OPS(mt7921s_pm_ops, mt7921s_suspend, mt7921s_resume); 3156c92544dSBjoern A. Zeeb 3166c92544dSBjoern A. Zeeb static struct sdio_driver mt7921s_driver = { 3176c92544dSBjoern A. Zeeb .name = KBUILD_MODNAME, 3186c92544dSBjoern A. Zeeb .probe = mt7921s_probe, 3196c92544dSBjoern A. Zeeb .remove = mt7921s_remove, 3206c92544dSBjoern A. Zeeb .id_table = mt7921s_table, 3216c92544dSBjoern A. Zeeb .drv.pm = pm_sleep_ptr(&mt7921s_pm_ops), 3226c92544dSBjoern A. Zeeb }; 3236c92544dSBjoern A. Zeeb module_sdio_driver(mt7921s_driver); 3246c92544dSBjoern A. Zeeb MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 3256c92544dSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL"); 326