diff options
| author | Yuanyuan Liu <yuanliu@codeaurora.org> | 2016-04-13 17:14:48 -0700 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-04-28 16:40:11 -0700 |
| commit | f02bb95a6ee8c2159885dca9d9ae981451f0a9f0 (patch) | |
| tree | ffdbc103f9e9e59859e16484d2edb00fabd6b3ca | |
| parent | 53c1ac8bc76c1a34064392f237638b6a3f55561a (diff) | |
icnss: Reset Adrastea before executing cold boot
Program MPM_CONFIG bit 0 to release reset to Adrastea before
executing cold boot.
CRs-Fixed: 986579
Change-Id: Ic9605be675c10ea2973e57ea5aae0e8ee2f893f2
Signed-off-by: Yuanyuan Liu <yuanliu@codeaurora.org>
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmcobalt.dtsi | 5 | ||||
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 54 |
2 files changed, 52 insertions, 7 deletions
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi index 7c0eb08547a2..78c99ee81a12 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi @@ -2141,8 +2141,9 @@ qcom,icnss@18800000 { compatible = "qcom,icnss"; - reg = <0x18800000 0x800000>; - reg-names = "membase"; + reg = <0x18800000 0x800000>, + <0x10AC000 0x20>; + reg-names = "membase", "mpm_config"; interrupts = <0 413 0 /* CE0 */ >, <0 414 0 /* CE1 */ >, <0 415 0 /* CE2 */ >, diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 84b47f789214..887e49e3beb6 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -68,6 +68,8 @@ struct icnss_qmi_event { } while (0) #endif +#define MPM2_MPM_WCSSAON_CONFIG_OFFSET 0x18 + struct ce_irq_list { int irq; irqreturn_t (*handler)(int, void *); @@ -80,6 +82,8 @@ static struct { u32 ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS]; phys_addr_t mem_base_pa; void __iomem *mem_base_va; + phys_addr_t mpm_config_pa; + void __iomem *mpm_config_va; struct qmi_handle *wlfw_clnt; struct list_head qmi_event_list; spinlock_t qmi_event_lock; @@ -163,11 +167,26 @@ out: } +static void icnss_adrastea_reset(void) +{ + uint32_t rdata = 0; + + if (penv->mpm_config_va) { + writel_relaxed(0x1, + penv->mpm_config_va + + MPM2_MPM_WCSSAON_CONFIG_OFFSET); + while (rdata != 0x1) + rdata = readl_relaxed(penv->mpm_config_va + + MPM2_MPM_WCSSAON_CONFIG_OFFSET); + } +} + static int icnss_adrastea_power_on(void) { int ret = 0; - /* TZ API of power on adrastea */ + /* Top level adrastea reset */ + icnss_adrastea_reset(); return ret; } @@ -1176,17 +1195,32 @@ static int icnss_probe(struct platform_device *pdev) penv->mem_base_pa = res->start; penv->mem_base_va = ioremap(penv->mem_base_pa, resource_size(res)); if (!penv->mem_base_va) { - pr_err("icnss: ioremap failed\n"); + pr_err("%s: mem_base ioremap failed\n", __func__); ret = -EINVAL; goto out; } + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "mpm_config"); + if (!res) { + pr_err("%s: mpm_config not found\n", __func__); + ret = -EINVAL; + goto unmap_mem_base; + } + penv->mpm_config_pa = res->start; + penv->mpm_config_va = ioremap(penv->mpm_config_pa, resource_size(res)); + if (!penv->mpm_config_va) { + pr_err("%s: mpm_config ioremap failed\n", __func__); + ret = -EINVAL; + goto unmap_mem_base; + } + for (i = 0; i < ICNSS_MAX_IRQ_REGISTRATIONS; i++) { res = platform_get_resource(pdev, IORESOURCE_IRQ, i); if (!res) { pr_err("icnss: Fail to get IRQ-%d\n", i); ret = -ENODEV; - goto out; + goto unmap_mpm_config; } else { penv->ce_irqs[i] = res->start; } @@ -1202,7 +1236,7 @@ static int icnss_probe(struct platform_device *pdev) if (!penv->msa_va) { pr_err("%s: DMA alloc failed\n", __func__); ret = -EINVAL; - goto out; + goto unmap_mpm_config; } pr_debug("%s: MAS va: %p, MSA pa: %pa\n", __func__, penv->msa_va, &penv->msa_pa); @@ -1210,7 +1244,7 @@ static int icnss_probe(struct platform_device *pdev) } else { pr_err("%s: Fail to get MSA Memory Size\n", __func__); ret = -ENODEV; - goto out; + goto unmap_mpm_config; } penv->skip_qmi = of_property_read_bool(dev->of_node, @@ -1258,6 +1292,12 @@ err_wlan_mode: if (penv->msa_va) dma_free_coherent(&pdev->dev, penv->msa_mem_size, penv->msa_va, penv->msa_pa); +unmap_mpm_config: + if (penv->mpm_config_va) + iounmap(penv->mpm_config_va); +unmap_mem_base: + if (penv->mem_base_va) + iounmap(penv->mem_base_va); out: return ret; } @@ -1274,6 +1314,10 @@ static int icnss_remove(struct platform_device *pdev) if (penv->msa_va) dma_free_coherent(&pdev->dev, penv->msa_mem_size, penv->msa_va, penv->msa_pa); + if (penv->mpm_config_va) + iounmap(penv->mpm_config_va); + if (penv->mem_base_va) + iounmap(penv->mem_base_va); return 0; } |
