snoc.c (188de5dd80b2b7986e75821374efb67081049b6e) | snoc.c (ba94c753ccb471bafe8bd824b744fda6fee0001e) |
---|---|
1/* 2 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --- 53 unchanged lines hidden (view full) --- 62static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state); 63static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state); 64static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state); 65static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state); 66 67static const struct ath10k_snoc_drv_priv drv_priv = { 68 .hw_rev = ATH10K_HW_WCN3990, 69 .dma_mask = DMA_BIT_MASK(37), | 1/* 2 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --- 53 unchanged lines hidden (view full) --- 62static void ath10k_snoc_htc_rx_cb(struct ath10k_ce_pipe *ce_state); 63static void ath10k_snoc_htt_rx_cb(struct ath10k_ce_pipe *ce_state); 64static void ath10k_snoc_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state); 65static void ath10k_snoc_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state); 66 67static const struct ath10k_snoc_drv_priv drv_priv = { 68 .hw_rev = ATH10K_HW_WCN3990, 69 .dma_mask = DMA_BIT_MASK(37), |
70 .msa_size = 0x100000, |
|
70}; 71 | 71}; 72 |
73#define WCN3990_SRC_WR_IDX_OFFSET 0x3C 74#define WCN3990_DST_WR_IDX_OFFSET 0x40 75 76static struct ath10k_shadow_reg_cfg target_shadow_reg_cfg_map[] = { 77 { 78 .ce_id = __cpu_to_le16(0), 79 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), 80 }, 81 82 { 83 .ce_id = __cpu_to_le16(3), 84 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), 85 }, 86 87 { 88 .ce_id = __cpu_to_le16(4), 89 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), 90 }, 91 92 { 93 .ce_id = __cpu_to_le16(5), 94 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), 95 }, 96 97 { 98 .ce_id = __cpu_to_le16(7), 99 .reg_offset = __cpu_to_le16(WCN3990_SRC_WR_IDX_OFFSET), 100 }, 101 102 { 103 .ce_id = __cpu_to_le16(1), 104 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 105 }, 106 107 { 108 .ce_id = __cpu_to_le16(2), 109 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 110 }, 111 112 { 113 .ce_id = __cpu_to_le16(7), 114 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 115 }, 116 117 { 118 .ce_id = __cpu_to_le16(8), 119 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 120 }, 121 122 { 123 .ce_id = __cpu_to_le16(9), 124 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 125 }, 126 127 { 128 .ce_id = __cpu_to_le16(10), 129 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 130 }, 131 132 { 133 .ce_id = __cpu_to_le16(11), 134 .reg_offset = __cpu_to_le16(WCN3990_DST_WR_IDX_OFFSET), 135 }, 136}; 137 |
|
72static struct ce_attr host_ce_config_wlan[] = { 73 /* CE0: host->target HTC control streams */ 74 { 75 .flags = CE_ATTR_FLAGS, 76 .src_nentries = 16, 77 .src_sz_max = 2048, 78 .dest_nentries = 0, 79 .send_cb = ath10k_snoc_htc_tx_cb, --- 91 unchanged lines hidden (view full) --- 171 .flags = CE_ATTR_FLAGS, 172 .src_nentries = 0, 173 .src_sz_max = 2048, 174 .dest_nentries = 512, 175 .recv_cb = ath10k_snoc_pktlog_rx_cb, 176 }, 177}; 178 | 138static struct ce_attr host_ce_config_wlan[] = { 139 /* CE0: host->target HTC control streams */ 140 { 141 .flags = CE_ATTR_FLAGS, 142 .src_nentries = 16, 143 .src_sz_max = 2048, 144 .dest_nentries = 0, 145 .send_cb = ath10k_snoc_htc_tx_cb, --- 91 unchanged lines hidden (view full) --- 237 .flags = CE_ATTR_FLAGS, 238 .src_nentries = 0, 239 .src_sz_max = 2048, 240 .dest_nentries = 512, 241 .recv_cb = ath10k_snoc_pktlog_rx_cb, 242 }, 243}; 244 |
245static struct ce_pipe_config target_ce_config_wlan[] = { 246 /* CE0: host->target HTC control and raw streams */ 247 { 248 .pipenum = __cpu_to_le32(0), 249 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 250 .nentries = __cpu_to_le32(32), 251 .nbytes_max = __cpu_to_le32(2048), 252 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 253 .reserved = __cpu_to_le32(0), 254 }, 255 256 /* CE1: target->host HTT + HTC control */ 257 { 258 .pipenum = __cpu_to_le32(1), 259 .pipedir = __cpu_to_le32(PIPEDIR_IN), 260 .nentries = __cpu_to_le32(32), 261 .nbytes_max = __cpu_to_le32(2048), 262 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 263 .reserved = __cpu_to_le32(0), 264 }, 265 266 /* CE2: target->host WMI */ 267 { 268 .pipenum = __cpu_to_le32(2), 269 .pipedir = __cpu_to_le32(PIPEDIR_IN), 270 .nentries = __cpu_to_le32(64), 271 .nbytes_max = __cpu_to_le32(2048), 272 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 273 .reserved = __cpu_to_le32(0), 274 }, 275 276 /* CE3: host->target WMI */ 277 { 278 .pipenum = __cpu_to_le32(3), 279 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 280 .nentries = __cpu_to_le32(32), 281 .nbytes_max = __cpu_to_le32(2048), 282 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 283 .reserved = __cpu_to_le32(0), 284 }, 285 286 /* CE4: host->target HTT */ 287 { 288 .pipenum = __cpu_to_le32(4), 289 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 290 .nentries = __cpu_to_le32(256), 291 .nbytes_max = __cpu_to_le32(256), 292 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), 293 .reserved = __cpu_to_le32(0), 294 }, 295 296 /* CE5: target->host HTT (HIF->HTT) */ 297 { 298 .pipenum = __cpu_to_le32(5), 299 .pipedir = __cpu_to_le32(PIPEDIR_OUT), 300 .nentries = __cpu_to_le32(1024), 301 .nbytes_max = __cpu_to_le32(64), 302 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), 303 .reserved = __cpu_to_le32(0), 304 }, 305 306 /* CE6: Reserved for target autonomous hif_memcpy */ 307 { 308 .pipenum = __cpu_to_le32(6), 309 .pipedir = __cpu_to_le32(PIPEDIR_INOUT), 310 .nentries = __cpu_to_le32(32), 311 .nbytes_max = __cpu_to_le32(16384), 312 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 313 .reserved = __cpu_to_le32(0), 314 }, 315 316 /* CE7 used only by Host */ 317 { 318 .pipenum = __cpu_to_le32(7), 319 .pipedir = __cpu_to_le32(4), 320 .nentries = __cpu_to_le32(0), 321 .nbytes_max = __cpu_to_le32(0), 322 .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR), 323 .reserved = __cpu_to_le32(0), 324 }, 325 326 /* CE8 Target to uMC */ 327 { 328 .pipenum = __cpu_to_le32(8), 329 .pipedir = __cpu_to_le32(PIPEDIR_IN), 330 .nentries = __cpu_to_le32(32), 331 .nbytes_max = __cpu_to_le32(2048), 332 .flags = __cpu_to_le32(0), 333 .reserved = __cpu_to_le32(0), 334 }, 335 336 /* CE9 target->host HTT */ 337 { 338 .pipenum = __cpu_to_le32(9), 339 .pipedir = __cpu_to_le32(PIPEDIR_IN), 340 .nentries = __cpu_to_le32(32), 341 .nbytes_max = __cpu_to_le32(2048), 342 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 343 .reserved = __cpu_to_le32(0), 344 }, 345 346 /* CE10 target->host HTT */ 347 { 348 .pipenum = __cpu_to_le32(10), 349 .pipedir = __cpu_to_le32(PIPEDIR_IN), 350 .nentries = __cpu_to_le32(32), 351 .nbytes_max = __cpu_to_le32(2048), 352 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 353 .reserved = __cpu_to_le32(0), 354 }, 355 356 /* CE11 target autonomous qcache memcpy */ 357 { 358 .pipenum = __cpu_to_le32(11), 359 .pipedir = __cpu_to_le32(PIPEDIR_IN), 360 .nentries = __cpu_to_le32(32), 361 .nbytes_max = __cpu_to_le32(2048), 362 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 363 .reserved = __cpu_to_le32(0), 364 }, 365}; 366 |
|
179static struct service_to_pipe target_service_to_ce_map_wlan[] = { 180 { 181 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), 182 __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 183 __cpu_to_le32(3), 184 }, 185 { 186 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), --- 574 unchanged lines hidden (view full) --- 761 } 762 } 763 764 return 0; 765} 766 767static int ath10k_snoc_wlan_enable(struct ath10k *ar) 768{ | 367static struct service_to_pipe target_service_to_ce_map_wlan[] = { 368 { 369 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), 370 __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ 371 __cpu_to_le32(3), 372 }, 373 { 374 __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), --- 574 unchanged lines hidden (view full) --- 949 } 950 } 951 952 return 0; 953} 954 955static int ath10k_snoc_wlan_enable(struct ath10k *ar) 956{ |
769 return 0; | 957 struct ath10k_tgt_pipe_cfg tgt_cfg[CE_COUNT_MAX]; 958 struct ath10k_qmi_wlan_enable_cfg cfg; 959 enum wlfw_driver_mode_enum_v01 mode; 960 int pipe_num; 961 962 for (pipe_num = 0; pipe_num < CE_COUNT_MAX; pipe_num++) { 963 tgt_cfg[pipe_num].pipe_num = 964 target_ce_config_wlan[pipe_num].pipenum; 965 tgt_cfg[pipe_num].pipe_dir = 966 target_ce_config_wlan[pipe_num].pipedir; 967 tgt_cfg[pipe_num].nentries = 968 target_ce_config_wlan[pipe_num].nentries; 969 tgt_cfg[pipe_num].nbytes_max = 970 target_ce_config_wlan[pipe_num].nbytes_max; 971 tgt_cfg[pipe_num].flags = 972 target_ce_config_wlan[pipe_num].flags; 973 tgt_cfg[pipe_num].reserved = 0; 974 } 975 976 cfg.num_ce_tgt_cfg = sizeof(target_ce_config_wlan) / 977 sizeof(struct ath10k_tgt_pipe_cfg); 978 cfg.ce_tgt_cfg = (struct ath10k_tgt_pipe_cfg *) 979 &tgt_cfg; 980 cfg.num_ce_svc_pipe_cfg = sizeof(target_service_to_ce_map_wlan) / 981 sizeof(struct ath10k_svc_pipe_cfg); 982 cfg.ce_svc_cfg = (struct ath10k_svc_pipe_cfg *) 983 &target_service_to_ce_map_wlan; 984 cfg.num_shadow_reg_cfg = sizeof(target_shadow_reg_cfg_map) / 985 sizeof(struct ath10k_shadow_reg_cfg); 986 cfg.shadow_reg_cfg = (struct ath10k_shadow_reg_cfg *) 987 &target_shadow_reg_cfg_map; 988 989 mode = QMI_WLFW_MISSION_V01; 990 991 return ath10k_qmi_wlan_enable(ar, &cfg, mode, 992 NULL); |
770} 771 772static void ath10k_snoc_wlan_disable(struct ath10k *ar) 773{ | 993} 994 995static void ath10k_snoc_wlan_disable(struct ath10k *ar) 996{ |
997 ath10k_qmi_wlan_disable(ar); |
|
774} 775 776static void ath10k_snoc_hif_power_down(struct ath10k *ar) 777{ 778 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); 779 780 ath10k_snoc_wlan_disable(ar); 781 ath10k_ce_free_rri(ar); --- 170 unchanged lines hidden (view full) --- 952 } 953 ar_snoc->ce_irqs[i].irq_line = res->start; 954 } 955 956out: 957 return ret; 958} 959 | 998} 999 1000static void ath10k_snoc_hif_power_down(struct ath10k *ar) 1001{ 1002 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); 1003 1004 ath10k_snoc_wlan_disable(ar); 1005 ath10k_ce_free_rri(ar); --- 170 unchanged lines hidden (view full) --- 1176 } 1177 ar_snoc->ce_irqs[i].irq_line = res->start; 1178 } 1179 1180out: 1181 return ret; 1182} 1183 |
1184int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type) 1185{ 1186 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1187 struct ath10k_bus_params bus_params; 1188 int ret; 1189 1190 switch (type) { 1191 case ATH10K_QMI_EVENT_FW_READY_IND: 1192 bus_params.dev_type = ATH10K_DEV_TYPE_LL; 1193 bus_params.chip_id = ar_snoc->target_info.soc_version; 1194 ret = ath10k_core_register(ar, &bus_params); 1195 if (ret) { 1196 ath10k_err(ar, "failed to register driver core: %d\n", 1197 ret); 1198 } 1199 break; 1200 case ATH10K_QMI_EVENT_FW_DOWN_IND: 1201 break; 1202 default: 1203 ath10k_err(ar, "invalid fw indication: %llx\n", type); 1204 return -EINVAL; 1205 } 1206 1207 return 0; 1208} 1209 |
|
960static int ath10k_snoc_setup_resource(struct ath10k *ar) 961{ 962 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 963 struct ath10k_ce *ce = ath10k_ce_priv(ar); 964 struct ath10k_snoc_pipe *pipe; 965 int i, ret; 966 967 timer_setup(&ar_snoc->rx_post_retry, ath10k_snoc_rx_replenish_retry, 0); --- 308 unchanged lines hidden (view full) --- 1276 1277static int ath10k_snoc_probe(struct platform_device *pdev) 1278{ 1279 const struct ath10k_snoc_drv_priv *drv_data; 1280 const struct of_device_id *of_id; 1281 struct ath10k_snoc *ar_snoc; 1282 struct device *dev; 1283 struct ath10k *ar; | 1210static int ath10k_snoc_setup_resource(struct ath10k *ar) 1211{ 1212 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1213 struct ath10k_ce *ce = ath10k_ce_priv(ar); 1214 struct ath10k_snoc_pipe *pipe; 1215 int i, ret; 1216 1217 timer_setup(&ar_snoc->rx_post_retry, ath10k_snoc_rx_replenish_retry, 0); --- 308 unchanged lines hidden (view full) --- 1526 1527static int ath10k_snoc_probe(struct platform_device *pdev) 1528{ 1529 const struct ath10k_snoc_drv_priv *drv_data; 1530 const struct of_device_id *of_id; 1531 struct ath10k_snoc *ar_snoc; 1532 struct device *dev; 1533 struct ath10k *ar; |
1534 u32 msa_size; |
|
1284 int ret; 1285 u32 i; | 1535 int ret; 1536 u32 i; |
1286 struct ath10k_bus_params bus_params; | |
1287 1288 of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev); 1289 if (!of_id) { 1290 dev_err(&pdev->dev, "failed to find matching device tree id\n"); 1291 return -EINVAL; 1292 } 1293 1294 drv_data = of_id->data; --- 13 unchanged lines hidden (view full) --- 1308 } 1309 1310 ar_snoc = ath10k_snoc_priv(ar); 1311 ar_snoc->dev = pdev; 1312 platform_set_drvdata(pdev, ar); 1313 ar_snoc->ar = ar; 1314 ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops; 1315 ar->ce_priv = &ar_snoc->ce; | 1537 1538 of_id = of_match_device(ath10k_snoc_dt_match, &pdev->dev); 1539 if (!of_id) { 1540 dev_err(&pdev->dev, "failed to find matching device tree id\n"); 1541 return -EINVAL; 1542 } 1543 1544 drv_data = of_id->data; --- 13 unchanged lines hidden (view full) --- 1558 } 1559 1560 ar_snoc = ath10k_snoc_priv(ar); 1561 ar_snoc->dev = pdev; 1562 platform_set_drvdata(pdev, ar); 1563 ar_snoc->ar = ar; 1564 ar_snoc->ce.bus_ops = &ath10k_snoc_bus_ops; 1565 ar->ce_priv = &ar_snoc->ce; |
1566 msa_size = drv_data->msa_size; |
|
1316 1317 ret = ath10k_snoc_resource_init(ar); 1318 if (ret) { 1319 ath10k_warn(ar, "failed to initialize resource: %d\n", ret); 1320 goto err_core_destroy; 1321 } 1322 1323 ret = ath10k_snoc_setup_resource(ar); --- 22 unchanged lines hidden (view full) --- 1346 } 1347 1348 ret = ath10k_hw_power_on(ar); 1349 if (ret) { 1350 ath10k_err(ar, "failed to power on device: %d\n", ret); 1351 goto err_free_irq; 1352 } 1353 | 1567 1568 ret = ath10k_snoc_resource_init(ar); 1569 if (ret) { 1570 ath10k_warn(ar, "failed to initialize resource: %d\n", ret); 1571 goto err_core_destroy; 1572 } 1573 1574 ret = ath10k_snoc_setup_resource(ar); --- 22 unchanged lines hidden (view full) --- 1597 } 1598 1599 ret = ath10k_hw_power_on(ar); 1600 if (ret) { 1601 ath10k_err(ar, "failed to power on device: %d\n", ret); 1602 goto err_free_irq; 1603 } 1604 |
1354 bus_params.dev_type = ATH10K_DEV_TYPE_LL; 1355 bus_params.chip_id = drv_data->hw_rev; 1356 ret = ath10k_core_register(ar, &bus_params); | 1605 ret = ath10k_qmi_init(ar, msa_size); |
1357 if (ret) { | 1606 if (ret) { |
1358 ath10k_err(ar, "failed to register driver core: %d\n", ret); 1359 goto err_hw_power_off; | 1607 ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret); 1608 goto err_core_destroy; |
1360 } 1361 1362 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n"); 1363 ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!"); 1364 1365 return 0; 1366 | 1609 } 1610 1611 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n"); 1612 ath10k_warn(ar, "Warning: SNOC support is still work-in-progress, it will not work properly!"); 1613 1614 return 0; 1615 |
1367err_hw_power_off: 1368 ath10k_hw_power_off(ar); 1369 | |
1370err_free_irq: 1371 ath10k_snoc_free_irq(ar); 1372 1373err_release_resource: 1374 ath10k_snoc_release_resource(ar); 1375 1376err_core_destroy: 1377 ath10k_core_destroy(ar); --- 5 unchanged lines hidden (view full) --- 1383{ 1384 struct ath10k *ar = platform_get_drvdata(pdev); 1385 1386 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n"); 1387 ath10k_core_unregister(ar); 1388 ath10k_hw_power_off(ar); 1389 ath10k_snoc_free_irq(ar); 1390 ath10k_snoc_release_resource(ar); | 1616err_free_irq: 1617 ath10k_snoc_free_irq(ar); 1618 1619err_release_resource: 1620 ath10k_snoc_release_resource(ar); 1621 1622err_core_destroy: 1623 ath10k_core_destroy(ar); --- 5 unchanged lines hidden (view full) --- 1629{ 1630 struct ath10k *ar = platform_get_drvdata(pdev); 1631 1632 ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc remove\n"); 1633 ath10k_core_unregister(ar); 1634 ath10k_hw_power_off(ar); 1635 ath10k_snoc_free_irq(ar); 1636 ath10k_snoc_release_resource(ar); |
1637 ath10k_qmi_deinit(ar); |
|
1391 ath10k_core_destroy(ar); 1392 1393 return 0; 1394} 1395 1396static struct platform_driver ath10k_snoc_driver = { 1397 .probe = ath10k_snoc_probe, 1398 .remove = ath10k_snoc_remove, 1399 .driver = { 1400 .name = "ath10k_snoc", 1401 .of_match_table = ath10k_snoc_dt_match, 1402 }, 1403}; 1404module_platform_driver(ath10k_snoc_driver); 1405 1406MODULE_AUTHOR("Qualcomm"); 1407MODULE_LICENSE("Dual BSD/GPL"); 1408MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices"); | 1638 ath10k_core_destroy(ar); 1639 1640 return 0; 1641} 1642 1643static struct platform_driver ath10k_snoc_driver = { 1644 .probe = ath10k_snoc_probe, 1645 .remove = ath10k_snoc_remove, 1646 .driver = { 1647 .name = "ath10k_snoc", 1648 .of_match_table = ath10k_snoc_dt_match, 1649 }, 1650}; 1651module_platform_driver(ath10k_snoc_driver); 1652 1653MODULE_AUTHOR("Qualcomm"); 1654MODULE_LICENSE("Dual BSD/GPL"); 1655MODULE_DESCRIPTION("Driver support for Atheros WCN3990 SNOC devices"); |