--- zzzz-none-000/linux-5.4.213/drivers/soc/qcom/smp2p.c 2022-09-15 10:04:56.000000000 +0000 +++ miami-7690-761/linux-5.4.213/drivers/soc/qcom/smp2p.c 2024-05-29 11:20:02.000000000 +0000 @@ -43,6 +43,9 @@ #define SMP2P_MAGIC 0x504d5324 +#define GLOBAL_TIMER_LO 0x0 +#define GLOBAL_TIMER_HI 0x4 + /** * struct smp2p_smem_item - in memory communication structure * @magic: magic number @@ -123,6 +126,7 @@ * @mbox_chan: apcs ipc mailbox channel handle * @inbound: list of inbound entries * @outbound: list of outbound entries + * @need_ssr_ack fw expects ack for irq */ struct qcom_smp2p { struct device *dev; @@ -146,8 +150,22 @@ struct list_head inbound; struct list_head outbound; + bool need_ssr_ack; }; +#define SMP2PLOG_SIZE 256 +static void __iomem *global_timer_base; + +struct smp2p_log { + u64 timestamp; + unsigned int global_timer_lo; + unsigned int global_timer_hi; + u32 value; + u32 last_value; + u32 status; +} smp2pintr[SMP2PLOG_SIZE]; +unsigned int smp2pintrindex; + static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) { /* Make sure any updated data is written before the kick */ @@ -218,6 +236,19 @@ val = readl(entry->value); status = val ^ entry->last_value; + smp2pintr[smp2pintrindex].timestamp = + ktime_to_us(ktime_get()); + if (global_timer_base) { + smp2pintr[smp2pintrindex].global_timer_lo = + readl_relaxed(global_timer_base + GLOBAL_TIMER_LO) - 0x13; + smp2pintr[smp2pintrindex].global_timer_hi = + readl_relaxed(global_timer_base + GLOBAL_TIMER_HI); + } + smp2pintr[smp2pintrindex].value = val; + smp2pintr[smp2pintrindex].last_value = entry->last_value; + smp2pintr[smp2pintrindex++].status = status; + smp2pintrindex &= (SMP2PLOG_SIZE - 1); + entry->last_value = val; /* No changes of this entry? */ @@ -236,6 +267,9 @@ } } + if (smp2p->need_ssr_ack) + qcom_smp2p_kick(smp2p); + return IRQ_HANDLED; } @@ -352,6 +386,8 @@ /* Make the logical entry reference the physical value */ entry->value = &out->entries[out->valid_entries].value; + smp2p->need_ssr_ack = of_property_read_bool(node, + "qcom,smp2p-feature-ssr-ack"); out->valid_entries++; @@ -448,6 +484,7 @@ const char *key; int irq; int ret; + unsigned int global_timer; smp2p = devm_kzalloc(&pdev->dev, sizeof(*smp2p), GFP_KERNEL); if (!smp2p) @@ -540,6 +577,15 @@ goto unwind_interfaces; } + /* Get the global timer base and remap it + * to the kernel address space + */ + ret = of_property_read_u32(pdev->dev.of_node, "global_timer", + &global_timer); + if (!ret) + global_timer_base = ioremap_nocache(global_timer, 8); + else + pr_info("global timer is null\n"); return 0; @@ -576,7 +622,10 @@ mbox_free_channel(smp2p->mbox_chan); smp2p->out->valid_entries = 0; - + memset(smp2pintr, 0, sizeof(struct smp2p_log) * SMP2PLOG_SIZE); + smp2pintrindex = 0; + iounmap(global_timer_base); + global_timer_base = NULL; return 0; }