mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02:00
irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
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 <biju.das.jz@bp.renesas.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com> Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Link: https://lore.kernel.org/all/20250224131253.134199-8-biju.das.jz@bp.renesas.com
This commit is contained in:
parent
5ec8cabc3b
commit
0a9d6ef64e
|
|
@ -80,16 +80,26 @@
|
|||
#define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x))
|
||||
#define ICU_PB5_TINT 0x55
|
||||
|
||||
/**
|
||||
* struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
|
||||
* @t_offs: TINT offset
|
||||
*/
|
||||
struct rzv2h_hw_info {
|
||||
u16 t_offs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
|
||||
* @base: Controller's base address
|
||||
* @fwspec: IRQ firmware specific data
|
||||
* @lock: Lock to serialize access to hardware registers
|
||||
* @info: Pointer to struct rzv2h_hw_info
|
||||
*/
|
||||
struct rzv2h_icu_priv {
|
||||
void __iomem *base;
|
||||
struct irq_fwspec fwspec[ICU_NUM_IRQ];
|
||||
raw_spinlock_t lock;
|
||||
const struct rzv2h_hw_info *info;
|
||||
};
|
||||
|
||||
static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
|
||||
|
|
@ -109,7 +119,7 @@ static void rzv2h_icu_eoi(struct irq_data *d)
|
|||
tintirq_nr = hw_irq - ICU_TINT_START;
|
||||
bit = BIT(tintirq_nr);
|
||||
if (!irqd_is_level_type(d))
|
||||
writel_relaxed(bit, priv->base + ICU_TSCLR);
|
||||
writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR);
|
||||
} else if (hw_irq >= ICU_IRQ_START) {
|
||||
tintirq_nr = hw_irq - ICU_IRQ_START;
|
||||
bit = BIT(tintirq_nr);
|
||||
|
|
@ -137,12 +147,12 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
|
|||
tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
|
||||
|
||||
guard(raw_spinlock)(&priv->lock);
|
||||
tssr = readl_relaxed(priv->base + ICU_TSSR(k));
|
||||
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k));
|
||||
if (enable)
|
||||
tssr |= ICU_TSSR_TIEN(tssel_n);
|
||||
else
|
||||
tssr &= ~ICU_TSSR_TIEN(tssel_n);
|
||||
writel_relaxed(tssr, priv->base + ICU_TSSR(k));
|
||||
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
|
||||
}
|
||||
|
||||
static void rzv2h_icu_irq_disable(struct irq_data *d)
|
||||
|
|
@ -245,8 +255,8 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
|
|||
u32 bit = BIT(tint_nr);
|
||||
int k = tint_nr / 16;
|
||||
|
||||
tsctr = readl_relaxed(priv->base + ICU_TSCTR);
|
||||
titsr = readl_relaxed(priv->base + ICU_TITSR(k));
|
||||
tsctr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSCTR);
|
||||
titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(k));
|
||||
titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n);
|
||||
|
||||
/*
|
||||
|
|
@ -255,7 +265,7 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
|
|||
*/
|
||||
if ((tsctr & bit) && ((titsel == ICU_TINT_EDGE_RISING) ||
|
||||
(titsel == ICU_TINT_EDGE_FALLING)))
|
||||
writel_relaxed(bit, priv->base + ICU_TSCLR);
|
||||
writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR);
|
||||
}
|
||||
|
||||
static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
|
||||
|
|
@ -306,21 +316,21 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
|
|||
|
||||
guard(raw_spinlock)(&priv->lock);
|
||||
|
||||
tssr = readl_relaxed(priv->base + ICU_TSSR(tssr_k));
|
||||
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
|
||||
tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n) | tien);
|
||||
tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n);
|
||||
|
||||
writel_relaxed(tssr, priv->base + ICU_TSSR(tssr_k));
|
||||
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
|
||||
|
||||
titsr = readl_relaxed(priv->base + ICU_TITSR(titsr_k));
|
||||
titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
|
||||
titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n);
|
||||
titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n);
|
||||
|
||||
writel_relaxed(titsr, priv->base + ICU_TITSR(titsr_k));
|
||||
writel_relaxed(titsr, priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
|
||||
|
||||
rzv2h_clear_tint_int(priv, hwirq);
|
||||
|
||||
writel_relaxed(tssr | tien, priv->base + ICU_TSSR(tssr_k));
|
||||
writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -424,7 +434,8 @@ static void rzv2h_icu_put_device(void *data)
|
|||
put_device(data);
|
||||
}
|
||||
|
||||
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
|
||||
static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent,
|
||||
const struct rzv2h_hw_info *hw_info)
|
||||
{
|
||||
struct irq_domain *irq_domain, *parent_domain;
|
||||
struct rzv2h_icu_priv *rzv2h_icu_data;
|
||||
|
|
@ -490,6 +501,8 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
|
|||
goto pm_put;
|
||||
}
|
||||
|
||||
rzv2h_icu_data->info = hw_info;
|
||||
|
||||
/*
|
||||
* coccicheck complains about a missing put_device call before returning, but it's a false
|
||||
* positive. We still need &pdev->dev after successfully returning from this function.
|
||||
|
|
@ -502,6 +515,15 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct rzv2h_hw_info rzv2h_hw_params = {
|
||||
.t_offs = 0,
|
||||
};
|
||||
|
||||
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params);
|
||||
}
|
||||
|
||||
IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu)
|
||||
IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)
|
||||
IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user