qcom_wcnss.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Qualcomm Wireless Connectivity Subsystem Peripheral Image Loader
  4. *
  5. * Copyright (C) 2016 Linaro Ltd
  6. * Copyright (C) 2014 Sony Mobile Communications AB
  7. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/delay.h>
  11. #include <linux/firmware.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/io.h>
  16. #include <linux/of.h>
  17. #include <linux/of_reserved_mem.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/pm_domain.h>
  20. #include <linux/pm_runtime.h>
  21. #include <linux/firmware/qcom/qcom_scm.h>
  22. #include <linux/regulator/consumer.h>
  23. #include <linux/remoteproc.h>
  24. #include <linux/soc/qcom/mdt_loader.h>
  25. #include <linux/soc/qcom/smem.h>
  26. #include <linux/soc/qcom/smem_state.h>
  27. #include "qcom_common.h"
  28. #include "remoteproc_internal.h"
  29. #include "qcom_pil_info.h"
  30. #include "qcom_wcnss.h"
  31. #define WCNSS_CRASH_REASON_SMEM 422
  32. #define WCNSS_FIRMWARE_NAME "wcnss.mdt"
  33. #define WCNSS_PAS_ID 6
  34. #define WCNSS_SSCTL_ID 0x13
  35. #define WCNSS_SPARE_NVBIN_DLND BIT(25)
  36. #define WCNSS_PMU_IRIS_XO_CFG BIT(3)
  37. #define WCNSS_PMU_IRIS_XO_EN BIT(4)
  38. #define WCNSS_PMU_GC_BUS_MUX_SEL_TOP BIT(5)
  39. #define WCNSS_PMU_IRIS_XO_CFG_STS BIT(6) /* 1: in progress, 0: done */
  40. #define WCNSS_PMU_IRIS_RESET BIT(7)
  41. #define WCNSS_PMU_IRIS_RESET_STS BIT(8) /* 1: in progress, 0: done */
  42. #define WCNSS_PMU_IRIS_XO_READ BIT(9)
  43. #define WCNSS_PMU_IRIS_XO_READ_STS BIT(10)
  44. #define WCNSS_PMU_XO_MODE_MASK GENMASK(2, 1)
  45. #define WCNSS_PMU_XO_MODE_19p2 0
  46. #define WCNSS_PMU_XO_MODE_48 3
  47. #define WCNSS_MAX_PDS 2
  48. struct wcnss_data {
  49. size_t pmu_offset;
  50. size_t spare_offset;
  51. const char *pd_names[WCNSS_MAX_PDS];
  52. const struct wcnss_vreg_info *vregs;
  53. size_t num_vregs, num_pd_vregs;
  54. };
  55. struct qcom_wcnss {
  56. struct device *dev;
  57. struct rproc *rproc;
  58. void __iomem *pmu_cfg;
  59. void __iomem *spare_out;
  60. bool use_48mhz_xo;
  61. int wdog_irq;
  62. int fatal_irq;
  63. int ready_irq;
  64. int handover_irq;
  65. int stop_ack_irq;
  66. struct qcom_smem_state *state;
  67. unsigned stop_bit;
  68. struct mutex iris_lock;
  69. struct qcom_iris *iris;
  70. struct device *pds[WCNSS_MAX_PDS];
  71. size_t num_pds;
  72. struct regulator_bulk_data *vregs;
  73. size_t num_vregs;
  74. struct completion start_done;
  75. struct completion stop_done;
  76. phys_addr_t mem_phys;
  77. phys_addr_t mem_reloc;
  78. void *mem_region;
  79. size_t mem_size;
  80. struct qcom_rproc_subdev smd_subdev;
  81. struct qcom_sysmon *sysmon;
  82. };
  83. static const struct wcnss_data riva_data = {
  84. .pmu_offset = 0x28,
  85. .spare_offset = 0xb4,
  86. .vregs = (struct wcnss_vreg_info[]) {
  87. { "vddmx", 1050000, 1150000, 0 },
  88. { "vddcx", 1050000, 1150000, 0 },
  89. { "vddpx", 1800000, 1800000, 0 },
  90. },
  91. .num_vregs = 3,
  92. };
  93. static const struct wcnss_data pronto_v1_data = {
  94. .pmu_offset = 0x1004,
  95. .spare_offset = 0x1088,
  96. .pd_names = { "cx", "mx" },
  97. .vregs = (struct wcnss_vreg_info[]) {
  98. { "vddcx", .super_turbo = true},
  99. { "vddmx", 950000, 1150000, 0 },
  100. { "vddpx", 1800000, 1800000, 0 },
  101. },
  102. .num_pd_vregs = 2,
  103. .num_vregs = 1,
  104. };
  105. static const struct wcnss_data pronto_v2_data = {
  106. .pmu_offset = 0x1004,
  107. .spare_offset = 0x1088,
  108. .pd_names = { "cx", "mx" },
  109. .vregs = (struct wcnss_vreg_info[]) {
  110. { "vddcx", .super_turbo = true },
  111. { "vddmx", 1287500, 1287500, 0 },
  112. { "vddpx", 1800000, 1800000, 0 },
  113. },
  114. .num_pd_vregs = 2,
  115. .num_vregs = 1,
  116. };
  117. static const struct wcnss_data pronto_v3_data = {
  118. .pmu_offset = 0x1004,
  119. .spare_offset = 0x1088,
  120. .pd_names = { "mx", "cx" },
  121. .vregs = (struct wcnss_vreg_info[]) {
  122. { "vddpx", 1800000, 1800000, 0 },
  123. },
  124. .num_vregs = 1,
  125. };
  126. static int wcnss_load(struct rproc *rproc, const struct firmware *fw)
  127. {
  128. struct qcom_wcnss *wcnss = rproc->priv;
  129. int ret;
  130. ret = qcom_mdt_load(wcnss->dev, fw, rproc->firmware, WCNSS_PAS_ID,
  131. wcnss->mem_region, wcnss->mem_phys,
  132. wcnss->mem_size, &wcnss->mem_reloc);
  133. if (ret)
  134. return ret;
  135. qcom_pil_info_store("wcnss", wcnss->mem_phys, wcnss->mem_size);
  136. return 0;
  137. }
  138. static void wcnss_indicate_nv_download(struct qcom_wcnss *wcnss)
  139. {
  140. u32 val;
  141. /* Indicate NV download capability */
  142. val = readl(wcnss->spare_out);
  143. val |= WCNSS_SPARE_NVBIN_DLND;
  144. writel(val, wcnss->spare_out);
  145. }
  146. static void wcnss_configure_iris(struct qcom_wcnss *wcnss)
  147. {
  148. u32 val;
  149. /* Clear PMU cfg register */
  150. writel(0, wcnss->pmu_cfg);
  151. val = WCNSS_PMU_GC_BUS_MUX_SEL_TOP | WCNSS_PMU_IRIS_XO_EN;
  152. writel(val, wcnss->pmu_cfg);
  153. /* Clear XO_MODE */
  154. val &= ~WCNSS_PMU_XO_MODE_MASK;
  155. if (wcnss->use_48mhz_xo)
  156. val |= WCNSS_PMU_XO_MODE_48 << 1;
  157. else
  158. val |= WCNSS_PMU_XO_MODE_19p2 << 1;
  159. writel(val, wcnss->pmu_cfg);
  160. /* Reset IRIS */
  161. val |= WCNSS_PMU_IRIS_RESET;
  162. writel(val, wcnss->pmu_cfg);
  163. /* Wait for PMU.iris_reg_reset_sts */
  164. while (readl(wcnss->pmu_cfg) & WCNSS_PMU_IRIS_RESET_STS)
  165. cpu_relax();
  166. /* Clear IRIS reset */
  167. val &= ~WCNSS_PMU_IRIS_RESET;
  168. writel(val, wcnss->pmu_cfg);
  169. /* Start IRIS XO configuration */
  170. val |= WCNSS_PMU_IRIS_XO_CFG;
  171. writel(val, wcnss->pmu_cfg);
  172. /* Wait for XO configuration to finish */
  173. while (readl(wcnss->pmu_cfg) & WCNSS_PMU_IRIS_XO_CFG_STS)
  174. cpu_relax();
  175. /* Stop IRIS XO configuration */
  176. val &= ~WCNSS_PMU_GC_BUS_MUX_SEL_TOP;
  177. val &= ~WCNSS_PMU_IRIS_XO_CFG;
  178. writel(val, wcnss->pmu_cfg);
  179. /* Add some delay for XO to settle */
  180. msleep(20);
  181. }
  182. static int wcnss_start(struct rproc *rproc)
  183. {
  184. struct qcom_wcnss *wcnss = rproc->priv;
  185. int ret, i;
  186. mutex_lock(&wcnss->iris_lock);
  187. if (!wcnss->iris) {
  188. dev_err(wcnss->dev, "no iris registered\n");
  189. ret = -EINVAL;
  190. goto release_iris_lock;
  191. }
  192. for (i = 0; i < wcnss->num_pds; i++) {
  193. dev_pm_genpd_set_performance_state(wcnss->pds[i], INT_MAX);
  194. ret = pm_runtime_get_sync(wcnss->pds[i]);
  195. if (ret < 0) {
  196. pm_runtime_put_noidle(wcnss->pds[i]);
  197. goto disable_pds;
  198. }
  199. }
  200. ret = regulator_bulk_enable(wcnss->num_vregs, wcnss->vregs);
  201. if (ret)
  202. goto disable_pds;
  203. ret = qcom_iris_enable(wcnss->iris);
  204. if (ret)
  205. goto disable_regulators;
  206. wcnss_indicate_nv_download(wcnss);
  207. wcnss_configure_iris(wcnss);
  208. ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
  209. if (ret) {
  210. dev_err(wcnss->dev,
  211. "failed to authenticate image and release reset\n");
  212. goto disable_iris;
  213. }
  214. ret = wait_for_completion_timeout(&wcnss->start_done,
  215. msecs_to_jiffies(5000));
  216. if (wcnss->ready_irq > 0 && ret == 0) {
  217. /* We have a ready_irq, but it didn't fire in time. */
  218. dev_err(wcnss->dev, "start timed out\n");
  219. qcom_scm_pas_shutdown(WCNSS_PAS_ID);
  220. ret = -ETIMEDOUT;
  221. goto disable_iris;
  222. }
  223. ret = 0;
  224. disable_iris:
  225. qcom_iris_disable(wcnss->iris);
  226. disable_regulators:
  227. regulator_bulk_disable(wcnss->num_vregs, wcnss->vregs);
  228. disable_pds:
  229. for (i--; i >= 0; i--) {
  230. pm_runtime_put(wcnss->pds[i]);
  231. dev_pm_genpd_set_performance_state(wcnss->pds[i], 0);
  232. }
  233. release_iris_lock:
  234. mutex_unlock(&wcnss->iris_lock);
  235. return ret;
  236. }
  237. static int wcnss_stop(struct rproc *rproc)
  238. {
  239. struct qcom_wcnss *wcnss = rproc->priv;
  240. int ret;
  241. if (wcnss->state) {
  242. qcom_smem_state_update_bits(wcnss->state,
  243. BIT(wcnss->stop_bit),
  244. BIT(wcnss->stop_bit));
  245. ret = wait_for_completion_timeout(&wcnss->stop_done,
  246. msecs_to_jiffies(5000));
  247. if (ret == 0)
  248. dev_err(wcnss->dev, "timed out on wait\n");
  249. qcom_smem_state_update_bits(wcnss->state,
  250. BIT(wcnss->stop_bit),
  251. 0);
  252. }
  253. ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
  254. if (ret)
  255. dev_err(wcnss->dev, "failed to shutdown: %d\n", ret);
  256. return ret;
  257. }
  258. static void *wcnss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
  259. {
  260. struct qcom_wcnss *wcnss = rproc->priv;
  261. int offset;
  262. offset = da - wcnss->mem_reloc;
  263. if (offset < 0 || offset + len > wcnss->mem_size)
  264. return NULL;
  265. return wcnss->mem_region + offset;
  266. }
  267. static const struct rproc_ops wcnss_ops = {
  268. .start = wcnss_start,
  269. .stop = wcnss_stop,
  270. .da_to_va = wcnss_da_to_va,
  271. .parse_fw = qcom_register_dump_segments,
  272. .load = wcnss_load,
  273. };
  274. static irqreturn_t wcnss_wdog_interrupt(int irq, void *dev)
  275. {
  276. struct qcom_wcnss *wcnss = dev;
  277. rproc_report_crash(wcnss->rproc, RPROC_WATCHDOG);
  278. return IRQ_HANDLED;
  279. }
  280. static irqreturn_t wcnss_fatal_interrupt(int irq, void *dev)
  281. {
  282. struct qcom_wcnss *wcnss = dev;
  283. size_t len;
  284. char *msg;
  285. msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, WCNSS_CRASH_REASON_SMEM, &len);
  286. if (!IS_ERR(msg) && len > 0 && msg[0])
  287. dev_err(wcnss->dev, "fatal error received: %s\n", msg);
  288. rproc_report_crash(wcnss->rproc, RPROC_FATAL_ERROR);
  289. return IRQ_HANDLED;
  290. }
  291. static irqreturn_t wcnss_ready_interrupt(int irq, void *dev)
  292. {
  293. struct qcom_wcnss *wcnss = dev;
  294. complete(&wcnss->start_done);
  295. return IRQ_HANDLED;
  296. }
  297. static irqreturn_t wcnss_handover_interrupt(int irq, void *dev)
  298. {
  299. /*
  300. * XXX: At this point we're supposed to release the resources that we
  301. * have been holding on behalf of the WCNSS. Unfortunately this
  302. * interrupt comes way before the other side seems to be done.
  303. *
  304. * So we're currently relying on the ready interrupt firing later then
  305. * this and we just disable the resources at the end of wcnss_start().
  306. */
  307. return IRQ_HANDLED;
  308. }
  309. static irqreturn_t wcnss_stop_ack_interrupt(int irq, void *dev)
  310. {
  311. struct qcom_wcnss *wcnss = dev;
  312. complete(&wcnss->stop_done);
  313. return IRQ_HANDLED;
  314. }
  315. static int wcnss_init_pds(struct qcom_wcnss *wcnss,
  316. const char * const pd_names[WCNSS_MAX_PDS])
  317. {
  318. struct device *dev = wcnss->dev;
  319. int i, ret;
  320. /* Handle single power domain */
  321. if (dev->pm_domain) {
  322. wcnss->pds[0] = dev;
  323. wcnss->num_pds = 1;
  324. pm_runtime_enable(dev);
  325. return 0;
  326. }
  327. for (i = 0; i < WCNSS_MAX_PDS; i++) {
  328. if (!pd_names[i])
  329. break;
  330. wcnss->pds[i] = dev_pm_domain_attach_by_name(wcnss->dev, pd_names[i]);
  331. if (IS_ERR_OR_NULL(wcnss->pds[i])) {
  332. ret = PTR_ERR(wcnss->pds[i]) ? : -ENODATA;
  333. for (i--; i >= 0; i--)
  334. dev_pm_domain_detach(wcnss->pds[i], false);
  335. return ret;
  336. }
  337. }
  338. wcnss->num_pds = i;
  339. return 0;
  340. }
  341. static void wcnss_release_pds(struct qcom_wcnss *wcnss)
  342. {
  343. struct device *dev = wcnss->dev;
  344. int i;
  345. /* Handle single power domain */
  346. if (wcnss->num_pds == 1 && dev->pm_domain) {
  347. pm_runtime_disable(dev);
  348. return;
  349. }
  350. for (i = 0; i < wcnss->num_pds; i++)
  351. dev_pm_domain_detach(wcnss->pds[i], false);
  352. }
  353. static int wcnss_init_regulators(struct qcom_wcnss *wcnss,
  354. const struct wcnss_vreg_info *info,
  355. int num_vregs, int num_pd_vregs)
  356. {
  357. struct regulator_bulk_data *bulk;
  358. int ret;
  359. int i;
  360. /*
  361. * If attaching the power domains suceeded we can skip requesting
  362. * the regulators for the power domains. For old device trees we need to
  363. * reserve extra space to manage them through the regulator interface.
  364. */
  365. if (wcnss->num_pds) {
  366. info += wcnss->num_pds;
  367. /* Handle single power domain case */
  368. if (wcnss->num_pds < num_pd_vregs)
  369. num_vregs += num_pd_vregs - wcnss->num_pds;
  370. } else {
  371. num_vregs += num_pd_vregs;
  372. }
  373. bulk = devm_kcalloc(wcnss->dev,
  374. num_vregs, sizeof(struct regulator_bulk_data),
  375. GFP_KERNEL);
  376. if (!bulk)
  377. return -ENOMEM;
  378. for (i = 0; i < num_vregs; i++)
  379. bulk[i].supply = info[i].name;
  380. ret = devm_regulator_bulk_get(wcnss->dev, num_vregs, bulk);
  381. if (ret)
  382. return ret;
  383. for (i = 0; i < num_vregs; i++) {
  384. if (info[i].max_voltage)
  385. regulator_set_voltage(bulk[i].consumer,
  386. info[i].min_voltage,
  387. info[i].max_voltage);
  388. if (info[i].load_uA)
  389. regulator_set_load(bulk[i].consumer, info[i].load_uA);
  390. }
  391. wcnss->vregs = bulk;
  392. wcnss->num_vregs = num_vregs;
  393. return 0;
  394. }
  395. static int wcnss_request_irq(struct qcom_wcnss *wcnss,
  396. struct platform_device *pdev,
  397. const char *name,
  398. bool optional,
  399. irq_handler_t thread_fn)
  400. {
  401. int ret;
  402. int irq_number;
  403. ret = platform_get_irq_byname(pdev, name);
  404. if (ret < 0 && optional) {
  405. dev_dbg(&pdev->dev, "no %s IRQ defined, ignoring\n", name);
  406. return 0;
  407. } else if (ret < 0) {
  408. dev_err(&pdev->dev, "no %s IRQ defined\n", name);
  409. return ret;
  410. }
  411. irq_number = ret;
  412. ret = devm_request_threaded_irq(&pdev->dev, ret,
  413. NULL, thread_fn,
  414. IRQF_TRIGGER_RISING | IRQF_ONESHOT,
  415. "wcnss", wcnss);
  416. if (ret) {
  417. dev_err(&pdev->dev, "request %s IRQ failed\n", name);
  418. return ret;
  419. }
  420. /* Return the IRQ number if the IRQ was successfully acquired */
  421. return irq_number;
  422. }
  423. static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss)
  424. {
  425. struct resource res;
  426. int ret;
  427. ret = of_reserved_mem_region_to_resource(wcnss->dev->of_node, 0, &res);
  428. if (ret) {
  429. dev_err(wcnss->dev, "unable to resolve memory-region\n");
  430. return ret;
  431. }
  432. wcnss->mem_phys = wcnss->mem_reloc = res.start;
  433. wcnss->mem_size = resource_size(&res);
  434. wcnss->mem_region = devm_ioremap_wc(wcnss->dev, wcnss->mem_phys, wcnss->mem_size);
  435. if (IS_ERR(wcnss->mem_region)) {
  436. dev_err(wcnss->dev, "unable to map memory region: %pR\n", &res);
  437. return PTR_ERR(wcnss->mem_region);
  438. }
  439. return 0;
  440. }
  441. static int wcnss_probe(struct platform_device *pdev)
  442. {
  443. const char *fw_name = WCNSS_FIRMWARE_NAME;
  444. const struct wcnss_data *data;
  445. struct qcom_wcnss *wcnss;
  446. struct rproc *rproc;
  447. void __iomem *mmio;
  448. int ret;
  449. data = of_device_get_match_data(&pdev->dev);
  450. if (!qcom_scm_is_available())
  451. return -EPROBE_DEFER;
  452. if (!qcom_scm_pas_supported(WCNSS_PAS_ID)) {
  453. dev_err(&pdev->dev, "PAS is not available for WCNSS\n");
  454. return -ENXIO;
  455. }
  456. ret = of_property_read_string(pdev->dev.of_node, "firmware-name",
  457. &fw_name);
  458. if (ret < 0 && ret != -EINVAL)
  459. return ret;
  460. rproc = devm_rproc_alloc(&pdev->dev, pdev->name, &wcnss_ops,
  461. fw_name, sizeof(*wcnss));
  462. if (!rproc) {
  463. dev_err(&pdev->dev, "unable to allocate remoteproc\n");
  464. return -ENOMEM;
  465. }
  466. rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_NONE);
  467. wcnss = rproc->priv;
  468. wcnss->dev = &pdev->dev;
  469. wcnss->rproc = rproc;
  470. platform_set_drvdata(pdev, wcnss);
  471. init_completion(&wcnss->start_done);
  472. init_completion(&wcnss->stop_done);
  473. mutex_init(&wcnss->iris_lock);
  474. mmio = devm_platform_ioremap_resource_byname(pdev, "pmu");
  475. if (IS_ERR(mmio))
  476. return PTR_ERR(mmio);
  477. ret = wcnss_alloc_memory_region(wcnss);
  478. if (ret)
  479. return ret;
  480. wcnss->pmu_cfg = mmio + data->pmu_offset;
  481. wcnss->spare_out = mmio + data->spare_offset;
  482. /*
  483. * We might need to fallback to regulators instead of power domains
  484. * for old device trees. Don't report an error in that case.
  485. */
  486. ret = wcnss_init_pds(wcnss, data->pd_names);
  487. if (ret && (ret != -ENODATA || !data->num_pd_vregs))
  488. return ret;
  489. ret = wcnss_init_regulators(wcnss, data->vregs, data->num_vregs,
  490. data->num_pd_vregs);
  491. if (ret)
  492. goto detach_pds;
  493. ret = wcnss_request_irq(wcnss, pdev, "wdog", false, wcnss_wdog_interrupt);
  494. if (ret < 0)
  495. goto detach_pds;
  496. wcnss->wdog_irq = ret;
  497. ret = wcnss_request_irq(wcnss, pdev, "fatal", false, wcnss_fatal_interrupt);
  498. if (ret < 0)
  499. goto detach_pds;
  500. wcnss->fatal_irq = ret;
  501. ret = wcnss_request_irq(wcnss, pdev, "ready", true, wcnss_ready_interrupt);
  502. if (ret < 0)
  503. goto detach_pds;
  504. wcnss->ready_irq = ret;
  505. ret = wcnss_request_irq(wcnss, pdev, "handover", true, wcnss_handover_interrupt);
  506. if (ret < 0)
  507. goto detach_pds;
  508. wcnss->handover_irq = ret;
  509. ret = wcnss_request_irq(wcnss, pdev, "stop-ack", true, wcnss_stop_ack_interrupt);
  510. if (ret < 0)
  511. goto detach_pds;
  512. wcnss->stop_ack_irq = ret;
  513. if (wcnss->stop_ack_irq) {
  514. wcnss->state = devm_qcom_smem_state_get(&pdev->dev, "stop",
  515. &wcnss->stop_bit);
  516. if (IS_ERR(wcnss->state)) {
  517. ret = PTR_ERR(wcnss->state);
  518. goto detach_pds;
  519. }
  520. }
  521. qcom_add_smd_subdev(rproc, &wcnss->smd_subdev);
  522. wcnss->sysmon = qcom_add_sysmon_subdev(rproc, "wcnss", WCNSS_SSCTL_ID);
  523. if (IS_ERR(wcnss->sysmon)) {
  524. ret = PTR_ERR(wcnss->sysmon);
  525. goto detach_pds;
  526. }
  527. wcnss->iris = qcom_iris_probe(&pdev->dev, &wcnss->use_48mhz_xo);
  528. if (IS_ERR(wcnss->iris)) {
  529. ret = PTR_ERR(wcnss->iris);
  530. goto detach_pds;
  531. }
  532. ret = rproc_add(rproc);
  533. if (ret)
  534. goto remove_iris;
  535. return 0;
  536. remove_iris:
  537. qcom_iris_remove(wcnss->iris);
  538. detach_pds:
  539. wcnss_release_pds(wcnss);
  540. return ret;
  541. }
  542. static void wcnss_remove(struct platform_device *pdev)
  543. {
  544. struct qcom_wcnss *wcnss = platform_get_drvdata(pdev);
  545. qcom_iris_remove(wcnss->iris);
  546. rproc_del(wcnss->rproc);
  547. qcom_remove_sysmon_subdev(wcnss->sysmon);
  548. qcom_remove_smd_subdev(wcnss->rproc, &wcnss->smd_subdev);
  549. wcnss_release_pds(wcnss);
  550. }
  551. static const struct of_device_id wcnss_of_match[] = {
  552. { .compatible = "qcom,riva-pil", &riva_data },
  553. { .compatible = "qcom,pronto-v1-pil", &pronto_v1_data },
  554. { .compatible = "qcom,pronto-v2-pil", &pronto_v2_data },
  555. { .compatible = "qcom,pronto-v3-pil", &pronto_v3_data },
  556. { },
  557. };
  558. MODULE_DEVICE_TABLE(of, wcnss_of_match);
  559. static struct platform_driver wcnss_driver = {
  560. .probe = wcnss_probe,
  561. .remove = wcnss_remove,
  562. .driver = {
  563. .name = "qcom-wcnss-pil",
  564. .of_match_table = wcnss_of_match,
  565. },
  566. };
  567. module_platform_driver(wcnss_driver);
  568. MODULE_DESCRIPTION("Qualcomm Peripheral Image Loader for Wireless Subsystem");
  569. MODULE_LICENSE("GPL v2");