1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
From 8bdade8b2e46a32aba6a44ef8814c1f902012fa8 Mon Sep 17 00:00:00 2001
From: "Lukas F. Hartmann" <lukas@mntre.com>
Date: Wed, 7 Sep 2022 06:24:04 +0200
Subject: [PATCH 4/7] mnt4002-imx-gpcv2-wake-smccc.patch
---
drivers/irqchip/irq-imx-gpcv2.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c
index b9c22f7..4f6d924 100644
--- a/drivers/irqchip/irq-imx-gpcv2.c
+++ b/drivers/irqchip/irq-imx-gpcv2.c
@@ -3,6 +3,7 @@
* Copyright (C) 2015 Freescale Semiconductor, Inc.
*/
+#include <linux/arm-smccc.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
@@ -17,6 +18,13 @@
#define GPC_IMR1_CORE2 0x1c0
#define GPC_IMR1_CORE3 0x1d0
+#define FSL_SIP_GPC 0xC2000000
+#define FSL_SIP_CONFIG_GPC_MASK 0x00
+#define FSL_SIP_CONFIG_GPC_UNMASK 0x01
+#define FSL_SIP_CONFIG_GPC_SET_WAKE 0x02
+#define FSL_SIP_CONFIG_GPC_PM_DOMAIN 0x03
+#define FSL_SIP_CONFIG_GPC_SET_AFF 0x04
+#define FSL_SIP_CONFIG_GPC_CORE_WAKE 0x05
struct gpcv2_irqchip_data {
struct raw_spinlock rlock;
@@ -76,12 +84,17 @@ static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on)
unsigned int idx = d->hwirq / 32;
unsigned long flags;
u32 mask, val;
+ struct arm_smccc_res res;
raw_spin_lock_irqsave(&cd->rlock, flags);
mask = BIT(d->hwirq % 32);
val = cd->wakeup_sources[idx];
cd->wakeup_sources[idx] = on ? (val & ~mask) : (val | mask);
+
+ // save wakeup config in vendor tf-a
+ arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_SET_WAKE, d->hwirq, on, 0, 0, 0, 0, &res);
+
raw_spin_unlock_irqrestore(&cd->rlock, flags);
/*
@@ -97,6 +110,7 @@ static void imx_gpcv2_irq_unmask(struct irq_data *d)
struct gpcv2_irqchip_data *cd = d->chip_data;
void __iomem *reg;
u32 val;
+ struct arm_smccc_res res;
raw_spin_lock(&cd->rlock);
reg = gpcv2_idx_to_reg(cd, d->hwirq / 32);
@@ -105,6 +119,10 @@ static void imx_gpcv2_irq_unmask(struct irq_data *d)
writel_relaxed(val, reg);
raw_spin_unlock(&cd->rlock);
+ // call into vendor tf-a
+ //arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_UNMASK,
+ // d->hwirq, 0, 0, 0, 0, 0, &res);
+
irq_chip_unmask_parent(d);
}
@@ -113,12 +131,18 @@ static void imx_gpcv2_irq_mask(struct irq_data *d)
struct gpcv2_irqchip_data *cd = d->chip_data;
void __iomem *reg;
u32 val;
+ struct arm_smccc_res res;
raw_spin_lock(&cd->rlock);
reg = gpcv2_idx_to_reg(cd, d->hwirq / 32);
val = readl_relaxed(reg);
val |= BIT(d->hwirq % 32);
writel_relaxed(val, reg);
+
+ // call into vendor tf-a
+ //arm_smccc_smc(FSL_SIP_GPC, FSL_SIP_CONFIG_GPC_MASK,
+ // d->hwirq, 0, 0, 0, 0, 0, &res);
+
raw_spin_unlock(&cd->rlock);
irq_chip_mask_parent(d);
--
2.37.2
|