Skip to content

Commit f274e16

Browse files
bijudasgregkh
authored andcommitted
irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
[ Upstream commit 0a9d6ef ] The ICU block on the RZ/G3E SoC is almost identical to the one found on the RZ/V2H SoC, with the following differences: - The TINT register base offset is 0x800 instead of zero. - The number of GPIO interrupts for TINT selection is 141 instead of 86. - The pin index and TINT selection index are not in the 1:1 map - The number of TSSR registers is 16 instead of 8 - Each TSSR register can program 2 TINTs instead of 4 TINTs Introduce struct rzv2h_hw_info to describe the SoC properties and refactor the code by moving rzv2h_icu_init() into rzv2h_icu_init_common() and pass the variable containing hw difference to support both these SoCs. As a first step add t_offs to the new struct and replace the hardcoded constants in the code. Signed-off-by: Biju Das <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Fabrizio Castro <[email protected]> Reviewed-by: Tommaso Merciai <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Link: https://lore.kernel.org/all/[email protected] Stable-dep-of: 28e89cd ("irqchip/renesas-rzv2h: Prevent TINT spurious interrupt") Signed-off-by: Sasha Levin <[email protected]>
1 parent a127329 commit f274e16

File tree

1 file changed

+34
-12
lines changed

1 file changed

+34
-12
lines changed

drivers/irqchip/irq-renesas-rzv2h.c

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,28 @@
8080
#define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x))
8181
#define ICU_PB5_TINT 0x55
8282

83+
/**
84+
* struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
85+
* @t_offs: TINT offset
86+
*/
87+
struct rzv2h_hw_info {
88+
u16 t_offs;
89+
};
90+
8391
/**
8492
* struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
8593
* @base: Controller's base address
8694
* @irqchip: Pointer to struct irq_chip
8795
* @fwspec: IRQ firmware specific data
8896
* @lock: Lock to serialize access to hardware registers
97+
* @info: Pointer to struct rzv2h_hw_info
8998
*/
9099
struct rzv2h_icu_priv {
91100
void __iomem *base;
92101
const struct irq_chip *irqchip;
93102
struct irq_fwspec fwspec[ICU_NUM_IRQ];
94103
raw_spinlock_t lock;
104+
const struct rzv2h_hw_info *info;
95105
};
96106

97107
static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
@@ -111,7 +121,7 @@ static void rzv2h_icu_eoi(struct irq_data *d)
111121
tintirq_nr = hw_irq - ICU_TINT_START;
112122
bit = BIT(tintirq_nr);
113123
if (!irqd_is_level_type(d))
114-
writel_relaxed(bit, priv->base + ICU_TSCLR);
124+
writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR);
115125
} else if (hw_irq >= ICU_IRQ_START) {
116126
tintirq_nr = hw_irq - ICU_IRQ_START;
117127
bit = BIT(tintirq_nr);
@@ -139,12 +149,12 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
139149
tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
140150

141151
guard(raw_spinlock)(&priv->lock);
142-
tssr = readl_relaxed(priv->base + ICU_TSSR(k));
152+
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k));
143153
if (enable)
144154
tssr |= ICU_TSSR_TIEN(tssel_n);
145155
else
146156
tssr &= ~ICU_TSSR_TIEN(tssel_n);
147-
writel_relaxed(tssr, priv->base + ICU_TSSR(k));
157+
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
148158
}
149159

150160
static void rzv2h_icu_irq_disable(struct irq_data *d)
@@ -247,8 +257,8 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
247257
u32 bit = BIT(tint_nr);
248258
int k = tint_nr / 16;
249259

250-
tsctr = readl_relaxed(priv->base + ICU_TSCTR);
251-
titsr = readl_relaxed(priv->base + ICU_TITSR(k));
260+
tsctr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSCTR);
261+
titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(k));
252262
titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n);
253263

254264
/*
@@ -257,7 +267,7 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
257267
*/
258268
if ((tsctr & bit) && ((titsel == ICU_TINT_EDGE_RISING) ||
259269
(titsel == ICU_TINT_EDGE_FALLING)))
260-
writel_relaxed(bit, priv->base + ICU_TSCLR);
270+
writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR);
261271
}
262272

263273
static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
@@ -308,21 +318,21 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
308318

309319
guard(raw_spinlock)(&priv->lock);
310320

311-
tssr = readl_relaxed(priv->base + ICU_TSSR(tssr_k));
321+
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
312322
tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n) | tien);
313323
tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n);
314324

315-
writel_relaxed(tssr, priv->base + ICU_TSSR(tssr_k));
325+
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
316326

317-
titsr = readl_relaxed(priv->base + ICU_TITSR(titsr_k));
327+
titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
318328
titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n);
319329
titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n);
320330

321-
writel_relaxed(titsr, priv->base + ICU_TITSR(titsr_k));
331+
writel_relaxed(titsr, priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
322332

323333
rzv2h_clear_tint_int(priv, hwirq);
324334

325-
writel_relaxed(tssr | tien, priv->base + ICU_TSSR(tssr_k));
335+
writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
326336

327337
return 0;
328338
}
@@ -426,7 +436,8 @@ static void rzv2h_icu_put_device(void *data)
426436
put_device(data);
427437
}
428438

429-
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
439+
static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent,
440+
const struct rzv2h_hw_info *hw_info)
430441
{
431442
struct irq_domain *irq_domain, *parent_domain;
432443
struct rzv2h_icu_priv *rzv2h_icu_data;
@@ -492,6 +503,8 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
492503
goto pm_put;
493504
}
494505

506+
rzv2h_icu_data->info = hw_info;
507+
495508
/*
496509
* coccicheck complains about a missing put_device call before returning, but it's a false
497510
* positive. We still need &pdev->dev after successfully returning from this function.
@@ -507,6 +520,15 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
507520
return ret;
508521
}
509522

523+
static const struct rzv2h_hw_info rzv2h_hw_params = {
524+
.t_offs = 0,
525+
};
526+
527+
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
528+
{
529+
return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params);
530+
}
531+
510532
IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu)
511533
IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)
512534
IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)

0 commit comments

Comments
 (0)