* [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
@ 2025-07-04 9:07 Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 01/18] reset: replace boolean parameters with flags parameter Tommaso Merciai
` (19 more replies)
0 siblings, 20 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
Dear All,
This series adds support for the RZ/G3E ICU driver into linux 6.12.y-cip.
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 supported 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
This series applies on top of [1]
[1] https://patchwork.kernel.org/project/cip-dev/list/?series=978150&state=%2A&archive=both
Thanks & Regards,
Tommaso
Biju Das (14):
dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E
SoC
irqchip/renesas-rzv2h: Fix wrong variable usage in
rzv2h_tint_set_type()
irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv
irqchip/renesas-rzv2h: Simplify rzv2h_icu_init()
irqchip/renesas-rzv2h: Use
devm_reset_control_get_exclusive_deasserted()
irqchip/renesas-rzv2h: Use devm_pm_runtime_enable()
irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info
irqchip/renesas-rzv2h: Add field_width to struct rzv2h_hw_info
irqchip/renesas-rzv2h: Update TSSR_TIEN macro
irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP}
irqchip/renesas-rzv2h: Add RZ/G3E support
irqchip/renesas-rzv2h: Prevent TINT spurious interrupt
arm64: dts: renesas: r9a09g047: Add ICU node
Fabrizio Castro (2):
dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt
Controller
irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver
Philipp Zabel (2):
reset: replace boolean parameters with flags parameter
reset: Add devres helpers to request pre-deasserted reset controls
.../renesas,rzv2h-icu.yaml | 280 ++++++++
arch/arm64/boot/dts/renesas/r9a09g047.dtsi | 90 +++
drivers/irqchip/Kconfig | 7 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-renesas-rzv2h.c | 601 ++++++++++++++++++
drivers/reset/core.c | 119 +++-
drivers/soc/renesas/Kconfig | 1 +
include/linux/reset.h | 274 ++++++--
8 files changed, 1278 insertions(+), 95 deletions(-)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
create mode 100644 drivers/irqchip/irq-renesas-rzv2h.c
--
2.43.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 01/18] reset: replace boolean parameters with flags parameter
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 02/18] reset: Add devres helpers to request pre-deasserted reset controls Tommaso Merciai
` (18 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Philipp Zabel <p.zabel@pengutronix.de>
commit dad35f7d2fc14e446669d4cab100597a6798eae5 upstream.
Introduce enum reset_control_flags and replace the list of boolean
parameters to the internal reset_control_get functions with a single
flags parameter, before adding more boolean options.
The separate boolean parameters have been shown to be error prone in
the past. See for example commit a57f68ddc886 ("reset: Fix devm bulk
optional exclusive control getter").
Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/20240925-reset-get-deasserted-v2-1-b3601bbd0458@pengutronix.de
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/reset/core.c | 71 +++++++++++--------
include/linux/reset.h | 161 ++++++++++++++++++++++++++----------------
2 files changed, 139 insertions(+), 93 deletions(-)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 4d509d41456a..682d61812852 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -773,12 +773,19 @@ EXPORT_SYMBOL_GPL(reset_control_bulk_release);
static struct reset_control *
__reset_control_get_internal(struct reset_controller_dev *rcdev,
- unsigned int index, bool shared, bool acquired)
+ unsigned int index, enum reset_control_flags flags)
{
+ bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED;
+ bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED;
struct reset_control *rstc;
lockdep_assert_held(&reset_list_mutex);
+ /* Expect callers to filter out OPTIONAL and DEASSERTED bits */
+ if (WARN_ON(flags & ~(RESET_CONTROL_FLAGS_BIT_SHARED |
+ RESET_CONTROL_FLAGS_BIT_ACQUIRED)))
+ return ERR_PTR(-EINVAL);
+
list_for_each_entry(rstc, &rcdev->reset_control_head, list) {
if (rstc->id == index) {
/*
@@ -994,8 +1001,9 @@ static struct reset_controller_dev *__reset_find_rcdev(const struct of_phandle_a
struct reset_control *
__of_reset_control_get(struct device_node *node, const char *id, int index,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
bool gpio_fallback = false;
struct reset_control *rstc;
struct reset_controller_dev *rcdev;
@@ -1059,8 +1067,10 @@ __of_reset_control_get(struct device_node *node, const char *id, int index,
goto out_unlock;
}
+ flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
/* reset_list_mutex also protects the rcdev's reset_control list */
- rstc = __reset_control_get_internal(rcdev, rstc_id, shared, acquired);
+ rstc = __reset_control_get_internal(rcdev, rstc_id, flags);
out_unlock:
mutex_unlock(&reset_list_mutex);
@@ -1091,8 +1101,9 @@ __reset_controller_by_name(const char *name)
static struct reset_control *
__reset_control_get_from_lookup(struct device *dev, const char *con_id,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
const struct reset_control_lookup *lookup;
struct reset_controller_dev *rcdev;
const char *dev_id = dev_name(dev);
@@ -1116,9 +1127,11 @@ __reset_control_get_from_lookup(struct device *dev, const char *con_id,
return ERR_PTR(-EPROBE_DEFER);
}
+ flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
rstc = __reset_control_get_internal(rcdev,
lookup->index,
- shared, acquired);
+ flags);
mutex_unlock(&reset_list_mutex);
break;
}
@@ -1133,30 +1146,29 @@ __reset_control_get_from_lookup(struct device *dev, const char *con_id,
}
struct reset_control *__reset_control_get(struct device *dev, const char *id,
- int index, bool shared, bool optional,
- bool acquired)
+ int index, enum reset_control_flags flags)
{
+ bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED;
+ bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED;
+
if (WARN_ON(shared && acquired))
return ERR_PTR(-EINVAL);
if (dev->of_node)
- return __of_reset_control_get(dev->of_node, id, index, shared,
- optional, acquired);
+ return __of_reset_control_get(dev->of_node, id, index, flags);
- return __reset_control_get_from_lookup(dev, id, shared, optional,
- acquired);
+ return __reset_control_get_from_lookup(dev, id, flags);
}
EXPORT_SYMBOL_GPL(__reset_control_get);
int __reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
int ret, i;
for (i = 0; i < num_rstcs; i++) {
- rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0,
- shared, optional, acquired);
+ rstcs[i].rstc = __reset_control_get(dev, rstcs[i].id, 0, flags);
if (IS_ERR(rstcs[i].rstc)) {
ret = PTR_ERR(rstcs[i].rstc);
goto err;
@@ -1226,7 +1238,7 @@ static void devm_reset_control_release(struct device *dev, void *res)
struct reset_control *
__devm_reset_control_get(struct device *dev, const char *id, int index,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
struct reset_control **ptr, *rstc;
@@ -1235,7 +1247,7 @@ __devm_reset_control_get(struct device *dev, const char *id, int index,
if (!ptr)
return ERR_PTR(-ENOMEM);
- rstc = __reset_control_get(dev, id, index, shared, optional, acquired);
+ rstc = __reset_control_get(dev, id, index, flags);
if (IS_ERR_OR_NULL(rstc)) {
devres_free(ptr);
return rstc;
@@ -1262,7 +1274,7 @@ static void devm_reset_control_bulk_release(struct device *dev, void *res)
int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
struct reset_control_bulk_devres *ptr;
int ret;
@@ -1272,7 +1284,7 @@ int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
if (!ptr)
return -ENOMEM;
- ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, shared, optional, acquired);
+ ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, flags);
if (ret < 0) {
devres_free(ptr);
return ret;
@@ -1298,6 +1310,7 @@ EXPORT_SYMBOL_GPL(__devm_reset_control_bulk_get);
*/
int __device_reset(struct device *dev, bool optional)
{
+ enum reset_control_flags flags;
struct reset_control *rstc;
int ret;
@@ -1313,7 +1326,8 @@ int __device_reset(struct device *dev, bool optional)
}
#endif
- rstc = __reset_control_get(dev, NULL, 0, 0, optional, true);
+ flags = optional ? RESET_CONTROL_OPTIONAL_EXCLUSIVE : RESET_CONTROL_EXCLUSIVE;
+ rstc = __reset_control_get(dev, NULL, 0, flags);
if (IS_ERR(rstc))
return PTR_ERR(rstc);
@@ -1356,17 +1370,14 @@ static int of_reset_control_get_count(struct device_node *node)
* device node.
*
* @np: device node for the device that requests the reset controls array
- * @shared: whether reset controls are shared or not
- * @optional: whether it is optional to get the reset controls
- * @acquired: only one reset control may be acquired for a given controller
- * and ID
+ * @flags: whether reset controls are shared, optional, acquired
*
* Returns pointer to allocated reset_control on success or error on failure
*/
struct reset_control *
-of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
- bool acquired)
+of_reset_control_array_get(struct device_node *np, enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
struct reset_control_array *resets;
struct reset_control *rstc;
int num, i;
@@ -1381,8 +1392,7 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
resets->num_rstcs = num;
for (i = 0; i < num; i++) {
- rstc = __of_reset_control_get(np, NULL, i, shared, optional,
- acquired);
+ rstc = __of_reset_control_get(np, NULL, i, flags);
if (IS_ERR(rstc))
goto err_rst;
resets->rstc[i] = rstc;
@@ -1407,8 +1417,7 @@ EXPORT_SYMBOL_GPL(of_reset_control_array_get);
* devm_reset_control_array_get - Resource managed reset control array get
*
* @dev: device that requests the list of reset controls
- * @shared: whether reset controls are shared or not
- * @optional: whether it is optional to get the reset controls
+ * @flags: whether reset controls are shared, optional, acquired
*
* The reset control array APIs are intended for a list of resets
* that just have to be asserted or deasserted, without any
@@ -1417,7 +1426,7 @@ EXPORT_SYMBOL_GPL(of_reset_control_array_get);
* Returns pointer to allocated reset_control on success or error on failure
*/
struct reset_control *
-devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
+devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags)
{
struct reset_control **ptr, *rstc;
@@ -1426,7 +1435,7 @@ devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
if (!ptr)
return ERR_PTR(-ENOMEM);
- rstc = of_reset_control_array_get(dev->of_node, shared, optional, true);
+ rstc = of_reset_control_array_get(dev->of_node, flags);
if (IS_ERR_OR_NULL(rstc)) {
devres_free(ptr);
return rstc;
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 514ddf003efc..99296af98f81 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -25,6 +25,33 @@ struct reset_control_bulk_data {
struct reset_control *rstc;
};
+#define RESET_CONTROL_FLAGS_BIT_SHARED BIT(0) /* not exclusive */
+#define RESET_CONTROL_FLAGS_BIT_OPTIONAL BIT(1)
+#define RESET_CONTROL_FLAGS_BIT_ACQUIRED BIT(2) /* iff exclusive, not released */
+
+/**
+ * enum reset_control_flags - Flags that can be passed to the reset_control_get functions
+ * to determine the type of reset control.
+ * These values cannot be OR'd.
+ *
+ * @RESET_CONTROL_EXCLUSIVE: exclusive, acquired,
+ * @RESET_CONTROL_EXCLUSIVE_RELEASED: exclusive, released,
+ * @RESET_CONTROL_SHARED: shared
+ * @RESET_CONTROL_OPTIONAL_EXCLUSIVE: optional, exclusive, acquired
+ * @RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED: optional, exclusive, released
+ * @RESET_CONTROL_OPTIONAL_SHARED: optional, shared
+ */
+enum reset_control_flags {
+ RESET_CONTROL_EXCLUSIVE = RESET_CONTROL_FLAGS_BIT_ACQUIRED,
+ RESET_CONTROL_EXCLUSIVE_RELEASED = 0,
+ RESET_CONTROL_SHARED = RESET_CONTROL_FLAGS_BIT_SHARED,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
+ RESET_CONTROL_FLAGS_BIT_ACQUIRED,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED = RESET_CONTROL_FLAGS_BIT_OPTIONAL,
+ RESET_CONTROL_OPTIONAL_SHARED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
+ RESET_CONTROL_FLAGS_BIT_SHARED,
+};
+
#ifdef CONFIG_RESET_CONTROLLER
int reset_control_reset(struct reset_control *rstc);
@@ -42,30 +69,25 @@ int reset_control_bulk_acquire(int num_rstcs, struct reset_control_bulk_data *rs
void reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs);
struct reset_control *__of_reset_control_get(struct device_node *node,
- const char *id, int index, bool shared,
- bool optional, bool acquired);
+ const char *id, int index, enum reset_control_flags flags);
struct reset_control *__reset_control_get(struct device *dev, const char *id,
- int index, bool shared,
- bool optional, bool acquired);
+ int index, enum reset_control_flags flags);
void reset_control_put(struct reset_control *rstc);
int __reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
- bool shared, bool optional, bool acquired);
+ enum reset_control_flags flags);
void reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs);
int __device_reset(struct device *dev, bool optional);
struct reset_control *__devm_reset_control_get(struct device *dev,
- const char *id, int index, bool shared,
- bool optional, bool acquired);
+ const char *id, int index, enum reset_control_flags flags);
int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
- bool shared, bool optional, bool acquired);
+ enum reset_control_flags flags);
struct reset_control *devm_reset_control_array_get(struct device *dev,
- bool shared, bool optional);
-struct reset_control *of_reset_control_array_get(struct device_node *np,
- bool shared, bool optional,
- bool acquired);
+ enum reset_control_flags flags);
+struct reset_control *of_reset_control_array_get(struct device_node *np, enum reset_control_flags);
int reset_control_get_count(struct device *dev);
@@ -116,17 +138,19 @@ static inline int __device_reset(struct device *dev, bool optional)
static inline struct reset_control *__of_reset_control_get(
struct device_node *node,
- const char *id, int index, bool shared,
- bool optional, bool acquired)
+ const char *id, int index, enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
static inline struct reset_control *__reset_control_get(
struct device *dev, const char *id,
- int index, bool shared, bool optional,
- bool acquired)
+ int index, enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
@@ -162,8 +186,10 @@ reset_control_bulk_release(int num_rstcs, struct reset_control_bulk_data *rstcs)
static inline int
__reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? 0 : -EOPNOTSUPP;
}
@@ -174,30 +200,36 @@ reset_control_bulk_put(int num_rstcs, struct reset_control_bulk_data *rstcs)
static inline struct reset_control *__devm_reset_control_get(
struct device *dev, const char *id,
- int index, bool shared, bool optional,
- bool acquired)
+ int index, enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
static inline int
__devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
- bool shared, bool optional, bool acquired)
+ enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? 0 : -EOPNOTSUPP;
}
static inline struct reset_control *
-devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
+devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
static inline struct reset_control *
-of_reset_control_array_get(struct device_node *np, bool shared, bool optional,
- bool acquired)
+of_reset_control_array_get(struct device_node *np, enum reset_control_flags flags)
{
+ bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL;
+
return optional ? NULL : ERR_PTR(-ENOTSUPP);
}
@@ -236,7 +268,7 @@ static inline int device_reset_optional(struct device *dev)
static inline struct reset_control *
__must_check reset_control_get_exclusive(struct device *dev, const char *id)
{
- return __reset_control_get(dev, id, 0, false, false, true);
+ return __reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -253,7 +285,7 @@ static inline int __must_check
reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -274,7 +306,7 @@ static inline struct reset_control *
__must_check reset_control_get_exclusive_released(struct device *dev,
const char *id)
{
- return __reset_control_get(dev, id, 0, false, false, false);
+ return __reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE_RELEASED);
}
/**
@@ -295,7 +327,7 @@ static inline int __must_check
reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_EXCLUSIVE_RELEASED);
}
/**
@@ -316,7 +348,8 @@ static inline int __must_check
reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED);
}
/**
@@ -344,7 +377,7 @@ reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_r
static inline struct reset_control *reset_control_get_shared(
struct device *dev, const char *id)
{
- return __reset_control_get(dev, id, 0, true, false, false);
+ return __reset_control_get(dev, id, 0, RESET_CONTROL_SHARED);
}
/**
@@ -361,7 +394,7 @@ static inline int __must_check
reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_SHARED);
}
/**
@@ -378,7 +411,7 @@ reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
static inline struct reset_control *reset_control_get_optional_exclusive(
struct device *dev, const char *id)
{
- return __reset_control_get(dev, id, 0, false, true, true);
+ return __reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
/**
@@ -398,7 +431,7 @@ static inline int __must_check
reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, true);
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
/**
@@ -415,7 +448,7 @@ reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
static inline struct reset_control *reset_control_get_optional_shared(
struct device *dev, const char *id)
{
- return __reset_control_get(dev, id, 0, true, true, false);
+ return __reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_SHARED);
}
/**
@@ -435,7 +468,7 @@ static inline int __must_check
reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
+ return __reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_OPTIONAL_SHARED);
}
/**
@@ -451,7 +484,7 @@ reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
static inline struct reset_control *of_reset_control_get_exclusive(
struct device_node *node, const char *id)
{
- return __of_reset_control_get(node, id, 0, false, false, true);
+ return __of_reset_control_get(node, id, 0, RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -471,7 +504,7 @@ static inline struct reset_control *of_reset_control_get_exclusive(
static inline struct reset_control *of_reset_control_get_optional_exclusive(
struct device_node *node, const char *id)
{
- return __of_reset_control_get(node, id, 0, false, true, true);
+ return __of_reset_control_get(node, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
/**
@@ -496,7 +529,7 @@ static inline struct reset_control *of_reset_control_get_optional_exclusive(
static inline struct reset_control *of_reset_control_get_shared(
struct device_node *node, const char *id)
{
- return __of_reset_control_get(node, id, 0, true, false, false);
+ return __of_reset_control_get(node, id, 0, RESET_CONTROL_SHARED);
}
/**
@@ -513,7 +546,7 @@ static inline struct reset_control *of_reset_control_get_shared(
static inline struct reset_control *of_reset_control_get_exclusive_by_index(
struct device_node *node, int index)
{
- return __of_reset_control_get(node, NULL, index, false, false, true);
+ return __of_reset_control_get(node, NULL, index, RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -541,7 +574,7 @@ static inline struct reset_control *of_reset_control_get_exclusive_by_index(
static inline struct reset_control *of_reset_control_get_shared_by_index(
struct device_node *node, int index)
{
- return __of_reset_control_get(node, NULL, index, true, false, false);
+ return __of_reset_control_get(node, NULL, index, RESET_CONTROL_SHARED);
}
/**
@@ -560,7 +593,7 @@ static inline struct reset_control *
__must_check devm_reset_control_get_exclusive(struct device *dev,
const char *id)
{
- return __devm_reset_control_get(dev, id, 0, false, false, true);
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -580,7 +613,8 @@ static inline int __must_check
devm_reset_control_bulk_get_exclusive(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, true);
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs,
+ RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -599,7 +633,7 @@ static inline struct reset_control *
__must_check devm_reset_control_get_exclusive_released(struct device *dev,
const char *id)
{
- return __devm_reset_control_get(dev, id, 0, false, false, false);
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE_RELEASED);
}
/**
@@ -619,7 +653,8 @@ static inline int __must_check
devm_reset_control_bulk_get_exclusive_released(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, false, false);
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs,
+ RESET_CONTROL_EXCLUSIVE_RELEASED);
}
/**
@@ -638,7 +673,7 @@ static inline struct reset_control *
__must_check devm_reset_control_get_optional_exclusive_released(struct device *dev,
const char *id)
{
- return __devm_reset_control_get(dev, id, 0, false, true, false);
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED);
}
/**
@@ -658,7 +693,8 @@ static inline int __must_check
devm_reset_control_bulk_get_optional_exclusive_released(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, false);
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED);
}
/**
@@ -673,7 +709,7 @@ devm_reset_control_bulk_get_optional_exclusive_released(struct device *dev, int
static inline struct reset_control *devm_reset_control_get_shared(
struct device *dev, const char *id)
{
- return __devm_reset_control_get(dev, id, 0, true, false, false);
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_SHARED);
}
/**
@@ -693,7 +729,7 @@ static inline int __must_check
devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, false, false);
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_SHARED);
}
/**
@@ -711,7 +747,7 @@ devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
static inline struct reset_control *devm_reset_control_get_optional_exclusive(
struct device *dev, const char *id)
{
- return __devm_reset_control_get(dev, id, 0, false, true, true);
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
/**
@@ -731,7 +767,8 @@ static inline int __must_check
devm_reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, false, true, true);
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
/**
@@ -749,7 +786,7 @@ devm_reset_control_bulk_get_optional_exclusive(struct device *dev, int num_rstcs
static inline struct reset_control *devm_reset_control_get_optional_shared(
struct device *dev, const char *id)
{
- return __devm_reset_control_get(dev, id, 0, true, true, false);
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_SHARED);
}
/**
@@ -769,7 +806,7 @@ static inline int __must_check
devm_reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs)
{
- return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, true, true, false);
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_OPTIONAL_SHARED);
}
/**
@@ -787,7 +824,7 @@ devm_reset_control_bulk_get_optional_shared(struct device *dev, int num_rstcs,
static inline struct reset_control *
devm_reset_control_get_exclusive_by_index(struct device *dev, int index)
{
- return __devm_reset_control_get(dev, NULL, index, false, false, true);
+ return __devm_reset_control_get(dev, NULL, index, RESET_CONTROL_EXCLUSIVE);
}
/**
@@ -803,7 +840,7 @@ devm_reset_control_get_exclusive_by_index(struct device *dev, int index)
static inline struct reset_control *
devm_reset_control_get_shared_by_index(struct device *dev, int index)
{
- return __devm_reset_control_get(dev, NULL, index, true, false, false);
+ return __devm_reset_control_get(dev, NULL, index, RESET_CONTROL_SHARED);
}
/*
@@ -851,54 +888,54 @@ static inline struct reset_control *devm_reset_control_get_by_index(
static inline struct reset_control *
devm_reset_control_array_get_exclusive(struct device *dev)
{
- return devm_reset_control_array_get(dev, false, false);
+ return devm_reset_control_array_get(dev, RESET_CONTROL_EXCLUSIVE);
}
static inline struct reset_control *
devm_reset_control_array_get_shared(struct device *dev)
{
- return devm_reset_control_array_get(dev, true, false);
+ return devm_reset_control_array_get(dev, RESET_CONTROL_SHARED);
}
static inline struct reset_control *
devm_reset_control_array_get_optional_exclusive(struct device *dev)
{
- return devm_reset_control_array_get(dev, false, true);
+ return devm_reset_control_array_get(dev, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
static inline struct reset_control *
devm_reset_control_array_get_optional_shared(struct device *dev)
{
- return devm_reset_control_array_get(dev, true, true);
+ return devm_reset_control_array_get(dev, RESET_CONTROL_OPTIONAL_SHARED);
}
static inline struct reset_control *
of_reset_control_array_get_exclusive(struct device_node *node)
{
- return of_reset_control_array_get(node, false, false, true);
+ return of_reset_control_array_get(node, RESET_CONTROL_EXCLUSIVE);
}
static inline struct reset_control *
of_reset_control_array_get_exclusive_released(struct device_node *node)
{
- return of_reset_control_array_get(node, false, false, false);
+ return of_reset_control_array_get(node, RESET_CONTROL_EXCLUSIVE_RELEASED);
}
static inline struct reset_control *
of_reset_control_array_get_shared(struct device_node *node)
{
- return of_reset_control_array_get(node, true, false, true);
+ return of_reset_control_array_get(node, RESET_CONTROL_SHARED);
}
static inline struct reset_control *
of_reset_control_array_get_optional_exclusive(struct device_node *node)
{
- return of_reset_control_array_get(node, false, true, true);
+ return of_reset_control_array_get(node, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
static inline struct reset_control *
of_reset_control_array_get_optional_shared(struct device_node *node)
{
- return of_reset_control_array_get(node, true, true, true);
+ return of_reset_control_array_get(node, RESET_CONTROL_OPTIONAL_SHARED);
}
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 02/18] reset: Add devres helpers to request pre-deasserted reset controls
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 01/18] reset: replace boolean parameters with flags parameter Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 03/18] dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt Controller Tommaso Merciai
` (17 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Philipp Zabel <p.zabel@pengutronix.de>
commit d872bed85036f5e60c66b0dd0994346b4ea6470c upstream.
Add devres helpers
- devm_reset_control_bulk_get_exclusive_deasserted
- devm_reset_control_bulk_get_optional_exclusive_deasserted
- devm_reset_control_bulk_get_optional_shared_deasserted
- devm_reset_control_bulk_get_shared_deasserted
- devm_reset_control_get_exclusive_deasserted
- devm_reset_control_get_optional_exclusive_deasserted
- devm_reset_control_get_optional_shared_deasserted
- devm_reset_control_get_shared_deasserted
to request and immediately deassert reset controls. During cleanup,
reset_control_assert() will be called automatically on the returned
reset controls.
Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/20240925-reset-get-deasserted-v2-2-b3601bbd0458@pengutronix.de
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/reset/core.c | 48 +++++++++++++++++-
include/linux/reset.h | 113 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 159 insertions(+), 2 deletions(-)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 682d61812852..22f67fc77ae5 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -1236,23 +1236,46 @@ static void devm_reset_control_release(struct device *dev, void *res)
reset_control_put(*(struct reset_control **)res);
}
+static void devm_reset_control_release_deasserted(struct device *dev, void *res)
+{
+ struct reset_control *rstc = *(struct reset_control **)res;
+
+ reset_control_assert(rstc);
+ reset_control_put(rstc);
+}
+
struct reset_control *
__devm_reset_control_get(struct device *dev, const char *id, int index,
enum reset_control_flags flags)
{
struct reset_control **ptr, *rstc;
+ bool deasserted = flags & RESET_CONTROL_FLAGS_BIT_DEASSERTED;
- ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr),
+ ptr = devres_alloc(deasserted ? devm_reset_control_release_deasserted :
+ devm_reset_control_release, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return ERR_PTR(-ENOMEM);
+ flags &= ~RESET_CONTROL_FLAGS_BIT_DEASSERTED;
+
rstc = __reset_control_get(dev, id, index, flags);
if (IS_ERR_OR_NULL(rstc)) {
devres_free(ptr);
return rstc;
}
+ if (deasserted) {
+ int ret;
+
+ ret = reset_control_deassert(rstc);
+ if (ret) {
+ reset_control_put(rstc);
+ devres_free(ptr);
+ return ERR_PTR(ret);
+ }
+ }
+
*ptr = rstc;
devres_add(dev, ptr);
@@ -1272,24 +1295,45 @@ static void devm_reset_control_bulk_release(struct device *dev, void *res)
reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
}
+static void devm_reset_control_bulk_release_deasserted(struct device *dev, void *res)
+{
+ struct reset_control_bulk_devres *devres = res;
+
+ reset_control_bulk_assert(devres->num_rstcs, devres->rstcs);
+ reset_control_bulk_put(devres->num_rstcs, devres->rstcs);
+}
+
int __devm_reset_control_bulk_get(struct device *dev, int num_rstcs,
struct reset_control_bulk_data *rstcs,
enum reset_control_flags flags)
{
struct reset_control_bulk_devres *ptr;
+ bool deasserted = flags & RESET_CONTROL_FLAGS_BIT_DEASSERTED;
int ret;
- ptr = devres_alloc(devm_reset_control_bulk_release, sizeof(*ptr),
+ ptr = devres_alloc(deasserted ? devm_reset_control_bulk_release_deasserted :
+ devm_reset_control_bulk_release, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return -ENOMEM;
+ flags &= ~RESET_CONTROL_FLAGS_BIT_DEASSERTED;
+
ret = __reset_control_bulk_get(dev, num_rstcs, rstcs, flags);
if (ret < 0) {
devres_free(ptr);
return ret;
}
+ if (deasserted) {
+ ret = reset_control_bulk_deassert(num_rstcs, rstcs);
+ if (ret) {
+ reset_control_bulk_put(num_rstcs, rstcs);
+ devres_free(ptr);
+ return ret;
+ }
+ }
+
ptr->num_rstcs = num_rstcs;
ptr->rstcs = rstcs;
devres_add(dev, ptr);
diff --git a/include/linux/reset.h b/include/linux/reset.h
index 99296af98f81..2986ced69a02 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -28,6 +28,7 @@ struct reset_control_bulk_data {
#define RESET_CONTROL_FLAGS_BIT_SHARED BIT(0) /* not exclusive */
#define RESET_CONTROL_FLAGS_BIT_OPTIONAL BIT(1)
#define RESET_CONTROL_FLAGS_BIT_ACQUIRED BIT(2) /* iff exclusive, not released */
+#define RESET_CONTROL_FLAGS_BIT_DEASSERTED BIT(3)
/**
* enum reset_control_flags - Flags that can be passed to the reset_control_get functions
@@ -35,21 +36,35 @@ struct reset_control_bulk_data {
* These values cannot be OR'd.
*
* @RESET_CONTROL_EXCLUSIVE: exclusive, acquired,
+ * @RESET_CONTROL_EXCLUSIVE_DEASSERTED: exclusive, acquired, deasserted
* @RESET_CONTROL_EXCLUSIVE_RELEASED: exclusive, released,
* @RESET_CONTROL_SHARED: shared
+ * @RESET_CONTROL_SHARED_DEASSERTED: shared, deasserted
* @RESET_CONTROL_OPTIONAL_EXCLUSIVE: optional, exclusive, acquired
+ * @RESET_CONTROL_OPTIONAL_EXCLUSIVE_DEASSERTED: optional, exclusive, acquired, deasserted
* @RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED: optional, exclusive, released
* @RESET_CONTROL_OPTIONAL_SHARED: optional, shared
+ * @RESET_CONTROL_OPTIONAL_SHARED_DEASSERTED: optional, shared, deasserted
*/
enum reset_control_flags {
RESET_CONTROL_EXCLUSIVE = RESET_CONTROL_FLAGS_BIT_ACQUIRED,
+ RESET_CONTROL_EXCLUSIVE_DEASSERTED = RESET_CONTROL_FLAGS_BIT_ACQUIRED |
+ RESET_CONTROL_FLAGS_BIT_DEASSERTED,
RESET_CONTROL_EXCLUSIVE_RELEASED = 0,
RESET_CONTROL_SHARED = RESET_CONTROL_FLAGS_BIT_SHARED,
+ RESET_CONTROL_SHARED_DEASSERTED = RESET_CONTROL_FLAGS_BIT_SHARED |
+ RESET_CONTROL_FLAGS_BIT_DEASSERTED,
RESET_CONTROL_OPTIONAL_EXCLUSIVE = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
RESET_CONTROL_FLAGS_BIT_ACQUIRED,
+ RESET_CONTROL_OPTIONAL_EXCLUSIVE_DEASSERTED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
+ RESET_CONTROL_FLAGS_BIT_ACQUIRED |
+ RESET_CONTROL_FLAGS_BIT_DEASSERTED,
RESET_CONTROL_OPTIONAL_EXCLUSIVE_RELEASED = RESET_CONTROL_FLAGS_BIT_OPTIONAL,
RESET_CONTROL_OPTIONAL_SHARED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
RESET_CONTROL_FLAGS_BIT_SHARED,
+ RESET_CONTROL_OPTIONAL_SHARED_DEASSERTED = RESET_CONTROL_FLAGS_BIT_OPTIONAL |
+ RESET_CONTROL_FLAGS_BIT_SHARED |
+ RESET_CONTROL_FLAGS_BIT_DEASSERTED,
};
#ifdef CONFIG_RESET_CONTROLLER
@@ -596,6 +611,25 @@ __must_check devm_reset_control_get_exclusive(struct device *dev,
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE);
}
+/**
+ * devm_reset_control_get_exclusive_deasserted - resource managed
+ * reset_control_get_exclusive() +
+ * reset_control_deassert()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get_exclusive() + reset_control_deassert(). For reset
+ * controllers returned from this function, reset_control_assert() +
+ * reset_control_put() is called automatically on driver detach.
+ *
+ * See reset_control_get_exclusive() for more information.
+ */
+static inline struct reset_control * __must_check
+devm_reset_control_get_exclusive_deasserted(struct device *dev, const char *id)
+{
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_EXCLUSIVE_DEASSERTED);
+}
+
/**
* devm_reset_control_bulk_get_exclusive - resource managed
* reset_control_bulk_get_exclusive()
@@ -712,6 +746,25 @@ static inline struct reset_control *devm_reset_control_get_shared(
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_SHARED);
}
+/**
+ * devm_reset_control_get_shared_deasserted - resource managed
+ * reset_control_get_shared() +
+ * reset_control_deassert()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get_shared() + reset_control_deassert(). For reset
+ * controllers returned from this function, reset_control_assert() +
+ * reset_control_put() is called automatically on driver detach.
+ *
+ * See devm_reset_control_get_shared() for more information.
+ */
+static inline struct reset_control * __must_check
+devm_reset_control_get_shared_deasserted(struct device *dev, const char *id)
+{
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_SHARED_DEASSERTED);
+}
+
/**
* devm_reset_control_bulk_get_shared - resource managed
* reset_control_bulk_get_shared()
@@ -732,6 +785,28 @@ devm_reset_control_bulk_get_shared(struct device *dev, int num_rstcs,
return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs, RESET_CONTROL_SHARED);
}
+/**
+ * devm_reset_control_bulk_get_shared_deasserted - resource managed
+ * reset_control_bulk_get_shared() +
+ * reset_control_bulk_deassert()
+ * @dev: device to be reset by the controller
+ * @num_rstcs: number of entries in rstcs array
+ * @rstcs: array of struct reset_control_bulk_data with reset line names set
+ *
+ * Managed reset_control_bulk_get_shared() + reset_control_bulk_deassert(). For
+ * reset controllers returned from this function, reset_control_bulk_assert() +
+ * reset_control_bulk_put() are called automatically on driver detach.
+ *
+ * See devm_reset_control_bulk_get_shared() for more information.
+ */
+static inline int __must_check
+devm_reset_control_bulk_get_shared_deasserted(struct device *dev, int num_rstcs,
+ struct reset_control_bulk_data *rstcs)
+{
+ return __devm_reset_control_bulk_get(dev, num_rstcs, rstcs,
+ RESET_CONTROL_SHARED_DEASSERTED);
+}
+
/**
* devm_reset_control_get_optional_exclusive - resource managed
* reset_control_get_optional_exclusive()
@@ -750,6 +825,25 @@ static inline struct reset_control *devm_reset_control_get_optional_exclusive(
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE);
}
+/**
+ * devm_reset_control_get_optional_exclusive_deasserted - resource managed
+ * reset_control_get_optional_exclusive() +
+ * reset_control_deassert()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get_optional_exclusive() + reset_control_deassert().
+ * For reset controllers returned from this function, reset_control_assert() +
+ * reset_control_put() is called automatically on driver detach.
+ *
+ * See devm_reset_control_get_optional_exclusive() for more information.
+ */
+static inline struct reset_control *
+devm_reset_control_get_optional_exclusive_deasserted(struct device *dev, const char *id)
+{
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_EXCLUSIVE_DEASSERTED);
+}
+
/**
* devm_reset_control_bulk_get_optional_exclusive - resource managed
* reset_control_bulk_get_optional_exclusive()
@@ -789,6 +883,25 @@ static inline struct reset_control *devm_reset_control_get_optional_shared(
return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_SHARED);
}
+/**
+ * devm_reset_control_get_optional_shared_deasserted - resource managed
+ * reset_control_get_optional_shared() +
+ * reset_control_deassert()
+ * @dev: device to be reset by the controller
+ * @id: reset line name
+ *
+ * Managed reset_control_get_optional_shared() + reset_control_deassert(). For
+ * reset controllers returned from this function, reset_control_assert() +
+ * reset_control_put() is called automatically on driver detach.
+ *
+ * See devm_reset_control_get_optional_shared() for more information.
+ */
+static inline struct reset_control *
+devm_reset_control_get_optional_shared_deasserted(struct device *dev, const char *id)
+{
+ return __devm_reset_control_get(dev, id, 0, RESET_CONTROL_OPTIONAL_SHARED_DEASSERTED);
+}
+
/**
* devm_reset_control_bulk_get_optional_shared - resource managed
* reset_control_bulk_get_optional_shared()
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 03/18] dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt Controller
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 01/18] reset: replace boolean parameters with flags parameter Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 02/18] reset: Add devres helpers to request pre-deasserted reset controls Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-07 9:35 ` Pavel Machek
2025-07-04 9:07 ` [PATCH 6.12.y-cip 04/18] dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E SoC Tommaso Merciai
` (16 subsequent siblings)
19 siblings, 1 reply; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
commit 3d5fb05e829682fd7d0d08cfcf6415aa50d4cb22 upstream.
Add DT bindings for the Renesas RZ/V2H(P) Interrupt Controller.
Also add macros for the NMI and IRQ0-15 interrupts which map the
SPI0-16 interrupts on the RZ/V2H(P) SoC so that they can be
used in the first cell of the interrupt specifiers.
For the second cell of the interrupt specifier, since NMI, IRQn
and TINTn support different types of interrupts between themselves,
add helper macros to make it easier for the user to work out what's
available.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Link: https://lore.kernel.org/all/20241009230817.798582-2-fabrizio.castro.jz@renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
.../renesas,rzv2h-icu.yaml | 278 ++++++++++++++++++
1 file changed, 278 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
new file mode 100644
index 000000000000..d7ef4f1323a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
@@ -0,0 +1,278 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/renesas,rzv2h-icu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/V2H(P) Interrupt Control Unit
+
+maintainers:
+ - Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+ - Geert Uytterhoeven <geert+renesas@glider.be>
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+
+description:
+ The Interrupt Control Unit (ICU) handles external interrupts (NMI, IRQ, and
+ TINT), error interrupts, DMAC requests, GPT interrupts, and internal
+ interrupts.
+
+properties:
+ compatible:
+ const: renesas,r9a09g057-icu # RZ/V2H(P)
+
+ '#interrupt-cells':
+ description: The first cell is the SPI number of the NMI or the
+ PORT_IRQ[0-15] interrupt, as per user manual. The second cell is used to
+ specify the flag.
+ const: 2
+
+ '#address-cells':
+ const: 0
+
+ interrupt-controller: true
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ minItems: 58
+ items:
+ - description: NMI interrupt
+ - description: PORT_IRQ0 interrupt
+ - description: PORT_IRQ1 interrupt
+ - description: PORT_IRQ2 interrupt
+ - description: PORT_IRQ3 interrupt
+ - description: PORT_IRQ4 interrupt
+ - description: PORT_IRQ5 interrupt
+ - description: PORT_IRQ6 interrupt
+ - description: PORT_IRQ7 interrupt
+ - description: PORT_IRQ8 interrupt
+ - description: PORT_IRQ9 interrupt
+ - description: PORT_IRQ10 interrupt
+ - description: PORT_IRQ11 interrupt
+ - description: PORT_IRQ12 interrupt
+ - description: PORT_IRQ13 interrupt
+ - description: PORT_IRQ14 interrupt
+ - description: PORT_IRQ15 interrupt
+ - description: GPIO interrupt, TINT0
+ - description: GPIO interrupt, TINT1
+ - description: GPIO interrupt, TINT2
+ - description: GPIO interrupt, TINT3
+ - description: GPIO interrupt, TINT4
+ - description: GPIO interrupt, TINT5
+ - description: GPIO interrupt, TINT6
+ - description: GPIO interrupt, TINT7
+ - description: GPIO interrupt, TINT8
+ - description: GPIO interrupt, TINT9
+ - description: GPIO interrupt, TINT10
+ - description: GPIO interrupt, TINT11
+ - description: GPIO interrupt, TINT12
+ - description: GPIO interrupt, TINT13
+ - description: GPIO interrupt, TINT14
+ - description: GPIO interrupt, TINT15
+ - description: GPIO interrupt, TINT16
+ - description: GPIO interrupt, TINT17
+ - description: GPIO interrupt, TINT18
+ - description: GPIO interrupt, TINT19
+ - description: GPIO interrupt, TINT20
+ - description: GPIO interrupt, TINT21
+ - description: GPIO interrupt, TINT22
+ - description: GPIO interrupt, TINT23
+ - description: GPIO interrupt, TINT24
+ - description: GPIO interrupt, TINT25
+ - description: GPIO interrupt, TINT26
+ - description: GPIO interrupt, TINT27
+ - description: GPIO interrupt, TINT28
+ - description: GPIO interrupt, TINT29
+ - description: GPIO interrupt, TINT30
+ - description: GPIO interrupt, TINT31
+ - description: Software interrupt, INTA55_0
+ - description: Software interrupt, INTA55_1
+ - description: Software interrupt, INTA55_2
+ - description: Software interrupt, INTA55_3
+ - description: Error interrupt to CA55
+ - description: GTCCRA compare match/input capture (U0)
+ - description: GTCCRB compare match/input capture (U0)
+ - description: GTCCRA compare match/input capture (U1)
+ - description: GTCCRB compare match/input capture (U1)
+
+ interrupt-names:
+ minItems: 58
+ items:
+ - const: nmi
+ - const: port_irq0
+ - const: port_irq1
+ - const: port_irq2
+ - const: port_irq3
+ - const: port_irq4
+ - const: port_irq5
+ - const: port_irq6
+ - const: port_irq7
+ - const: port_irq8
+ - const: port_irq9
+ - const: port_irq10
+ - const: port_irq11
+ - const: port_irq12
+ - const: port_irq13
+ - const: port_irq14
+ - const: port_irq15
+ - const: tint0
+ - const: tint1
+ - const: tint2
+ - const: tint3
+ - const: tint4
+ - const: tint5
+ - const: tint6
+ - const: tint7
+ - const: tint8
+ - const: tint9
+ - const: tint10
+ - const: tint11
+ - const: tint12
+ - const: tint13
+ - const: tint14
+ - const: tint15
+ - const: tint16
+ - const: tint17
+ - const: tint18
+ - const: tint19
+ - const: tint20
+ - const: tint21
+ - const: tint22
+ - const: tint23
+ - const: tint24
+ - const: tint25
+ - const: tint26
+ - const: tint27
+ - const: tint28
+ - const: tint29
+ - const: tint30
+ - const: tint31
+ - const: int-ca55-0
+ - const: int-ca55-1
+ - const: int-ca55-2
+ - const: int-ca55-3
+ - const: icu-error-ca55
+ - const: gpt-u0-gtciada
+ - const: gpt-u0-gtciadb
+ - const: gpt-u1-gtciada
+ - const: gpt-u1-gtciadb
+
+ clocks:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - '#interrupt-cells'
+ - '#address-cells'
+ - interrupt-controller
+ - interrupts
+ - interrupt-names
+ - clocks
+ - power-domains
+ - resets
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/renesas-cpg-mssr.h>
+
+ icu: interrupt-controller@10400000 {
+ compatible = "renesas,r9a09g057-icu";
+ reg = <0x10400000 0x10000>;
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 263 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 264 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 265 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "nmi",
+ "port_irq0", "port_irq1", "port_irq2",
+ "port_irq3", "port_irq4", "port_irq5",
+ "port_irq6", "port_irq7", "port_irq8",
+ "port_irq9", "port_irq10", "port_irq11",
+ "port_irq12", "port_irq13", "port_irq14",
+ "port_irq15",
+ "tint0", "tint1", "tint2", "tint3",
+ "tint4", "tint5", "tint6", "tint7",
+ "tint8", "tint9", "tint10", "tint11",
+ "tint12", "tint13", "tint14", "tint15",
+ "tint16", "tint17", "tint18", "tint19",
+ "tint20", "tint21", "tint22", "tint23",
+ "tint24", "tint25", "tint26", "tint27",
+ "tint28", "tint29", "tint30", "tint31",
+ "int-ca55-0", "int-ca55-1",
+ "int-ca55-2", "int-ca55-3",
+ "icu-error-ca55",
+ "gpt-u0-gtciada", "gpt-u0-gtciadb",
+ "gpt-u1-gtciada", "gpt-u1-gtciadb";
+ clocks = <&cpg CPG_MOD 0x5>;
+ power-domains = <&cpg>;
+ resets = <&cpg 0x36>;
+ };
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 04/18] dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E SoC
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (2 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 03/18] dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt Controller Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 05/18] irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver Tommaso Merciai
` (15 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 9d245214b683e9e4fe2d5c588691337b22c48841 upstream.
Document RZ/G3E (R9A09G047) ICU bindings. 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 supported 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
Hence add the new compatible string "renesas,r9a09g047-icu" for RZ/G3E SoC.
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>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
Link: https://lore.kernel.org/all/20250224131253.134199-2-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
.../bindings/interrupt-controller/renesas,rzv2h-icu.yaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
index d7ef4f1323a7..3f99c8645767 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/interrupt-controller/renesas,rzv2h-icu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Renesas RZ/V2H(P) Interrupt Control Unit
+title: Renesas RZ/{G3E,V2H(P)} Interrupt Control Unit
maintainers:
- Fabrizio Castro <fabrizio.castro.jz@renesas.com>
@@ -20,7 +20,9 @@ description:
properties:
compatible:
- const: renesas,r9a09g057-icu # RZ/V2H(P)
+ enum:
+ - renesas,r9a09g047-icu # RZ/G3E
+ - renesas,r9a09g057-icu # RZ/V2H(P)
'#interrupt-cells':
description: The first cell is the SPI number of the NMI or the
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 05/18] irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (3 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 04/18] dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E SoC Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-07 9:37 ` Pavel Machek
2025-07-04 9:07 ` [PATCH 6.12.y-cip 06/18] irqchip/renesas-rzv2h: Fix wrong variable usage in rzv2h_tint_set_type() Tommaso Merciai
` (14 subsequent siblings)
19 siblings, 1 reply; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
commit 0d7605e75ac2d8620929148f932cde54746c485f upstream.
Add driver for the Renesas RZ/V2H(P) Interrupt Control Unit (ICU).
This driver supports the external interrupts NMI, IRQn, and TINTn.
Signed-off-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20241009230817.798582-3-fabrizio.castro.jz@renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/Kconfig | 7 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-renesas-rzv2h.c | 513 ++++++++++++++++++++++++++++
drivers/soc/renesas/Kconfig | 1 +
4 files changed, 522 insertions(+)
create mode 100644 drivers/irqchip/irq-renesas-rzv2h.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index c1f304836008..6bdcf4517d17 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -259,6 +259,13 @@ config RENESAS_RZG2L_IRQC
Enable support for the Renesas RZ/G2L (and alike SoC) Interrupt Controller
for external devices.
+config RENESAS_RZV2H_ICU
+ bool "Renesas RZ/V2H(P) ICU support" if COMPILE_TEST
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN_HIERARCHY
+ help
+ Enable support for the Renesas RZ/V2H(P) Interrupt Control Unit (ICU)
+
config SL28CPLD_INTC
bool "Kontron sl28cpld IRQ controller"
depends on MFD_SL28CPLD=y || COMPILE_TEST
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index e3679ec2b9f7..94ecaebff37f 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_RENESAS_INTC_IRQPIN) += irq-renesas-intc-irqpin.o
obj-$(CONFIG_RENESAS_IRQC) += irq-renesas-irqc.o
obj-$(CONFIG_RENESAS_RZA1_IRQC) += irq-renesas-rza1.o
obj-$(CONFIG_RENESAS_RZG2L_IRQC) += irq-renesas-rzg2l.o
+obj-$(CONFIG_RENESAS_RZV2H_ICU) += irq-renesas-rzv2h.o
obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
obj-$(CONFIG_ARCH_NSPIRE) += irq-zevio.o
obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
new file mode 100644
index 000000000000..fe2d29e91026
--- /dev/null
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -0,0 +1,513 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Renesas RZ/V2H(P) ICU Driver
+ *
+ * Based on irq-renesas-rzg2l.c
+ *
+ * Copyright (C) 2024 Renesas Electronics Corporation.
+ *
+ * Author: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/cleanup.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
+
+/* DT "interrupts" indexes */
+#define ICU_IRQ_START 1
+#define ICU_IRQ_COUNT 16
+#define ICU_TINT_START (ICU_IRQ_START + ICU_IRQ_COUNT)
+#define ICU_TINT_COUNT 32
+#define ICU_NUM_IRQ (ICU_TINT_START + ICU_TINT_COUNT)
+
+/* Registers */
+#define ICU_NSCNT 0x00
+#define ICU_NSCLR 0x04
+#define ICU_NITSR 0x08
+#define ICU_ISCTR 0x10
+#define ICU_ISCLR 0x14
+#define ICU_IITSR 0x18
+#define ICU_TSCTR 0x20
+#define ICU_TSCLR 0x24
+#define ICU_TITSR(k) (0x28 + (k) * 4)
+#define ICU_TSSR(k) (0x30 + (k) * 4)
+
+/* NMI */
+#define ICU_NMI_EDGE_FALLING 0
+#define ICU_NMI_EDGE_RISING 1
+
+#define ICU_NSCLR_NCLR BIT(0)
+
+/* IRQ */
+#define ICU_IRQ_LEVEL_LOW 0
+#define ICU_IRQ_EDGE_FALLING 1
+#define ICU_IRQ_EDGE_RISING 2
+#define ICU_IRQ_EDGE_BOTH 3
+
+#define ICU_IITSR_IITSEL_PREP(iitsel, n) ((iitsel) << ((n) * 2))
+#define ICU_IITSR_IITSEL_GET(iitsr, n) (((iitsr) >> ((n) * 2)) & 0x03)
+#define ICU_IITSR_IITSEL_MASK(n) ICU_IITSR_IITSEL_PREP(0x03, n)
+
+/* TINT */
+#define ICU_TINT_EDGE_RISING 0
+#define ICU_TINT_EDGE_FALLING 1
+#define ICU_TINT_LEVEL_HIGH 2
+#define ICU_TINT_LEVEL_LOW 3
+
+#define ICU_TSSR_K(tint_nr) ((tint_nr) / 4)
+#define ICU_TSSR_TSSEL_N(tint_nr) ((tint_nr) % 4)
+#define ICU_TSSR_TSSEL_PREP(tssel, n) ((tssel) << ((n) * 8))
+#define ICU_TSSR_TSSEL_MASK(n) ICU_TSSR_TSSEL_PREP(0x7F, n)
+#define ICU_TSSR_TIEN(n) (BIT(7) << ((n) * 8))
+
+#define ICU_TITSR_K(tint_nr) ((tint_nr) / 16)
+#define ICU_TITSR_TITSEL_N(tint_nr) ((tint_nr) % 16)
+#define ICU_TITSR_TITSEL_PREP(titsel, n) ICU_IITSR_IITSEL_PREP(titsel, n)
+#define ICU_TITSR_TITSEL_MASK(n) ICU_IITSR_IITSEL_MASK(n)
+#define ICU_TITSR_TITSEL_GET(titsr, n) ICU_IITSR_IITSEL_GET(titsr, n)
+
+#define ICU_TINT_EXTRACT_HWIRQ(x) FIELD_GET(GENMASK(15, 0), (x))
+#define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x))
+#define ICU_PB5_TINT 0x55
+
+/**
+ * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
+ * @base: Controller's base address
+ * @irqchip: Pointer to struct irq_chip
+ * @fwspec: IRQ firmware specific data
+ * @lock: Lock to serialize access to hardware registers
+ */
+struct rzv2h_icu_priv {
+ void __iomem *base;
+ const struct irq_chip *irqchip;
+ struct irq_fwspec fwspec[ICU_NUM_IRQ];
+ raw_spinlock_t lock;
+};
+
+static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data)
+{
+ return data->domain->host_data;
+}
+
+static void rzv2h_icu_eoi(struct irq_data *d)
+{
+ struct rzv2h_icu_priv *priv = irq_data_to_priv(d);
+ unsigned int hw_irq = irqd_to_hwirq(d);
+ unsigned int tintirq_nr;
+ u32 bit;
+
+ scoped_guard(raw_spinlock, &priv->lock) {
+ if (hw_irq >= ICU_TINT_START) {
+ tintirq_nr = hw_irq - ICU_TINT_START;
+ bit = BIT(tintirq_nr);
+ if (!irqd_is_level_type(d))
+ writel_relaxed(bit, priv->base + ICU_TSCLR);
+ } else if (hw_irq >= ICU_IRQ_START) {
+ tintirq_nr = hw_irq - ICU_IRQ_START;
+ bit = BIT(tintirq_nr);
+ if (!irqd_is_level_type(d))
+ writel_relaxed(bit, priv->base + ICU_ISCLR);
+ } else {
+ writel_relaxed(ICU_NSCLR_NCLR, priv->base + ICU_NSCLR);
+ }
+ }
+
+ irq_chip_eoi_parent(d);
+}
+
+static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
+{
+ struct rzv2h_icu_priv *priv = irq_data_to_priv(d);
+ unsigned int hw_irq = irqd_to_hwirq(d);
+ u32 tint_nr, tssel_n, k, tssr;
+
+ if (hw_irq < ICU_TINT_START)
+ return;
+
+ tint_nr = hw_irq - ICU_TINT_START;
+ k = ICU_TSSR_K(tint_nr);
+ tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
+
+ guard(raw_spinlock)(&priv->lock);
+ tssr = readl_relaxed(priv->base + 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));
+}
+
+static void rzv2h_icu_irq_disable(struct irq_data *d)
+{
+ irq_chip_disable_parent(d);
+ rzv2h_tint_irq_endisable(d, false);
+}
+
+static void rzv2h_icu_irq_enable(struct irq_data *d)
+{
+ rzv2h_tint_irq_endisable(d, true);
+ irq_chip_enable_parent(d);
+}
+
+static int rzv2h_nmi_set_type(struct irq_data *d, unsigned int type)
+{
+ struct rzv2h_icu_priv *priv = irq_data_to_priv(d);
+ u32 sense;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_FALLING:
+ sense = ICU_NMI_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ sense = ICU_NMI_EDGE_RISING;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ writel_relaxed(sense, priv->base + ICU_NITSR);
+
+ return 0;
+}
+
+static void rzv2h_clear_irq_int(struct rzv2h_icu_priv *priv, unsigned int hwirq)
+{
+ unsigned int irq_nr = hwirq - ICU_IRQ_START;
+ u32 isctr, iitsr, iitsel;
+ u32 bit = BIT(irq_nr);
+
+ isctr = readl_relaxed(priv->base + ICU_ISCTR);
+ iitsr = readl_relaxed(priv->base + ICU_IITSR);
+ iitsel = ICU_IITSR_IITSEL_GET(iitsr, irq_nr);
+
+ /*
+ * When level sensing is used, the interrupt flag gets automatically cleared when the
+ * interrupt signal is de-asserted by the source of the interrupt request, therefore clear
+ * the interrupt only for edge triggered interrupts.
+ */
+ if ((isctr & bit) && (iitsel != ICU_IRQ_LEVEL_LOW))
+ writel_relaxed(bit, priv->base + ICU_ISCLR);
+}
+
+static int rzv2h_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ struct rzv2h_icu_priv *priv = irq_data_to_priv(d);
+ unsigned int hwirq = irqd_to_hwirq(d);
+ u32 irq_nr = hwirq - ICU_IRQ_START;
+ u32 iitsr, sense;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_LEVEL_LOW:
+ sense = ICU_IRQ_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ sense = ICU_IRQ_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ sense = ICU_IRQ_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ sense = ICU_IRQ_EDGE_BOTH;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ guard(raw_spinlock)(&priv->lock);
+ iitsr = readl_relaxed(priv->base + ICU_IITSR);
+ iitsr &= ~ICU_IITSR_IITSEL_MASK(irq_nr);
+ iitsr |= ICU_IITSR_IITSEL_PREP(sense, irq_nr);
+ rzv2h_clear_irq_int(priv, hwirq);
+ writel_relaxed(iitsr, priv->base + ICU_IITSR);
+
+ return 0;
+}
+
+static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq)
+{
+ unsigned int tint_nr = hwirq - ICU_TINT_START;
+ int titsel_n = ICU_TITSR_TITSEL_N(tint_nr);
+ u32 tsctr, titsr, titsel;
+ 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));
+ titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n);
+
+ /*
+ * Writing 1 to the corresponding flag from register ICU_TSCTR only has effect if
+ * TSTATn = 1b and if it's a rising edge or a falling edge interrupt.
+ */
+ if ((tsctr & bit) && ((titsel == ICU_TINT_EDGE_RISING) ||
+ (titsel == ICU_TINT_EDGE_FALLING)))
+ writel_relaxed(bit, priv->base + ICU_TSCLR);
+}
+
+static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
+{
+ u32 titsr, titsr_k, titsel_n, tien;
+ struct rzv2h_icu_priv *priv;
+ u32 tssr, tssr_k, tssel_n;
+ unsigned int hwirq;
+ u32 tint, sense;
+ int tint_nr;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_LEVEL_LOW:
+ sense = ICU_TINT_LEVEL_LOW;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ sense = ICU_TINT_LEVEL_HIGH;
+ break;
+
+ case IRQ_TYPE_EDGE_RISING:
+ sense = ICU_TINT_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ sense = ICU_TINT_EDGE_FALLING;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
+ if (tint > ICU_PB5_TINT)
+ return -EINVAL;
+
+ priv = irq_data_to_priv(d);
+ hwirq = irqd_to_hwirq(d);
+
+ tint_nr = hwirq - ICU_TINT_START;
+
+ tssr_k = ICU_TSSR_K(tint_nr);
+ tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
+
+ titsr_k = ICU_TITSR_K(tint_nr);
+ titsel_n = ICU_TITSR_TITSEL_N(tint_nr);
+ tien = ICU_TSSR_TIEN(titsel_n);
+
+ guard(raw_spinlock)(&priv->lock);
+
+ tssr = readl_relaxed(priv->base + 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));
+
+ titsr = readl_relaxed(priv->base + 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));
+
+ rzv2h_clear_tint_int(priv, hwirq);
+
+ writel_relaxed(tssr | tien, priv->base + ICU_TSSR(tssr_k));
+
+ return 0;
+}
+
+static int rzv2h_icu_set_type(struct irq_data *d, unsigned int type)
+{
+ unsigned int hw_irq = irqd_to_hwirq(d);
+ int ret;
+
+ if (hw_irq >= ICU_TINT_START)
+ ret = rzv2h_tint_set_type(d, type);
+ else if (hw_irq >= ICU_IRQ_START)
+ ret = rzv2h_irq_set_type(d, type);
+ else
+ ret = rzv2h_nmi_set_type(d, type);
+
+ if (ret)
+ return ret;
+
+ return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
+}
+
+static const struct irq_chip rzv2h_icu_chip = {
+ .name = "rzv2h-icu",
+ .irq_eoi = rzv2h_icu_eoi,
+ .irq_mask = irq_chip_mask_parent,
+ .irq_unmask = irq_chip_unmask_parent,
+ .irq_disable = rzv2h_icu_irq_disable,
+ .irq_enable = rzv2h_icu_irq_enable,
+ .irq_get_irqchip_state = irq_chip_get_parent_state,
+ .irq_set_irqchip_state = irq_chip_set_parent_state,
+ .irq_retrigger = irq_chip_retrigger_hierarchy,
+ .irq_set_type = rzv2h_icu_set_type,
+ .irq_set_affinity = irq_chip_set_affinity_parent,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static int rzv2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs,
+ void *arg)
+{
+ struct rzv2h_icu_priv *priv = domain->host_data;
+ unsigned long tint = 0;
+ irq_hw_number_t hwirq;
+ unsigned int type;
+ int ret;
+
+ ret = irq_domain_translate_twocell(domain, arg, &hwirq, &type);
+ if (ret)
+ return ret;
+
+ /*
+ * For TINT interrupts the hwirq and TINT are encoded in
+ * fwspec->param[0].
+ * hwirq is embedded in bits 0-15.
+ * TINT is embedded in bits 16-31.
+ */
+ if (hwirq >= ICU_TINT_START) {
+ tint = ICU_TINT_EXTRACT_GPIOINT(hwirq);
+ hwirq = ICU_TINT_EXTRACT_HWIRQ(hwirq);
+
+ if (hwirq < ICU_TINT_START)
+ return -EINVAL;
+ }
+
+ if (hwirq > (ICU_NUM_IRQ - 1))
+ return -EINVAL;
+
+ ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, priv->irqchip,
+ (void *)(uintptr_t)tint);
+ if (ret)
+ return ret;
+
+ return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, &priv->fwspec[hwirq]);
+}
+
+static const struct irq_domain_ops rzv2h_icu_domain_ops = {
+ .alloc = rzv2h_icu_alloc,
+ .free = irq_domain_free_irqs_common,
+ .translate = irq_domain_translate_twocell,
+};
+
+static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device_node *np)
+{
+ struct of_phandle_args map;
+ unsigned int i;
+ int ret;
+
+ for (i = 0; i < ICU_NUM_IRQ; i++) {
+ ret = of_irq_parse_one(np, i, &map);
+ if (ret)
+ return ret;
+
+ of_phandle_args_to_fwspec(np, map.args, map.args_count, &priv->fwspec[i]);
+ }
+
+ return 0;
+}
+
+static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
+{
+ struct irq_domain *irq_domain, *parent_domain;
+ struct rzv2h_icu_priv *rzv2h_icu_data;
+ struct platform_device *pdev;
+ struct reset_control *resetn;
+ int ret;
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev)
+ return -ENODEV;
+
+ parent_domain = irq_find_host(parent);
+ if (!parent_domain) {
+ dev_err(&pdev->dev, "cannot find parent domain\n");
+ ret = -ENODEV;
+ goto put_dev;
+ }
+
+ rzv2h_icu_data = devm_kzalloc(&pdev->dev, sizeof(*rzv2h_icu_data), GFP_KERNEL);
+ if (!rzv2h_icu_data) {
+ ret = -ENOMEM;
+ goto put_dev;
+ }
+
+ rzv2h_icu_data->irqchip = &rzv2h_icu_chip;
+
+ rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
+ if (IS_ERR(rzv2h_icu_data->base)) {
+ ret = PTR_ERR(rzv2h_icu_data->base);
+ goto put_dev;
+ }
+
+ ret = rzv2h_icu_parse_interrupts(rzv2h_icu_data, node);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret);
+ goto put_dev;
+ }
+
+ resetn = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+ if (IS_ERR(resetn)) {
+ ret = PTR_ERR(resetn);
+ goto put_dev;
+ }
+
+ ret = reset_control_deassert(resetn);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to deassert resetn pin, %d\n", ret);
+ goto put_dev;
+ }
+
+ pm_runtime_enable(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "pm_runtime_resume_and_get failed: %d\n", ret);
+ goto pm_disable;
+ }
+
+ raw_spin_lock_init(&rzv2h_icu_data->lock);
+
+ irq_domain = irq_domain_add_hierarchy(parent_domain, 0, ICU_NUM_IRQ, node,
+ &rzv2h_icu_domain_ops, rzv2h_icu_data);
+ if (!irq_domain) {
+ dev_err(&pdev->dev, "failed to add irq domain\n");
+ ret = -ENOMEM;
+ goto pm_put;
+ }
+
+ /*
+ * 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.
+ */
+ return 0;
+
+pm_put:
+ pm_runtime_put(&pdev->dev);
+pm_disable:
+ pm_runtime_disable(&pdev->dev);
+ reset_control_assert(resetn);
+put_dev:
+ put_device(&pdev->dev);
+
+ return ret;
+}
+
+IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu)
+IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)
+IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)
+MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
+MODULE_DESCRIPTION("Renesas RZ/V2H(P) ICU Driver");
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index 9dc97c0a1a6a..49648cf28bd2 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -354,6 +354,7 @@ config ARCH_R9A09G047
config ARCH_R9A09G057
bool "ARM64 Platform support for RZ/V2H(P)"
+ select RENESAS_RZV2H_ICU
select SYS_R9A09G057
help
This enables support for the Renesas RZ/V2H(P) SoC variants.
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 06/18] irqchip/renesas-rzv2h: Fix wrong variable usage in rzv2h_tint_set_type()
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (4 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 05/18] irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 07/18] irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv Tommaso Merciai
` (13 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 72310650788ad3d3afe3810735656dd291fea885 upstream.
The variable tssel_n is used for selecting TINT source and titsel_n for
setting the interrupt type. The variable titsel_n is wrongly used for
enabling the TINT interrupt in rzv2h_tint_set_type(). Fix this issue by
using the correct variable tssel_n.
While at it, move the tien variable assignment near to tssr.
Fixes: 0d7605e75ac2 ("irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver")
Reported-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20250224131253.134199-3-biju.das.jz@bp.renesas.com
Closes: https://lore.kernel.org/CAMuHMdU3xJpz-jh=j7t4JreBat2of2ksP_OR3+nKAoZBr4pSxg@mail.gmail.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index fe2d29e91026..f6363246a71a 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -301,10 +301,10 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
tssr_k = ICU_TSSR_K(tint_nr);
tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
+ tien = ICU_TSSR_TIEN(tssel_n);
titsr_k = ICU_TITSR_K(tint_nr);
titsel_n = ICU_TITSR_TITSEL_N(tint_nr);
- tien = ICU_TSSR_TIEN(titsel_n);
guard(raw_spinlock)(&priv->lock);
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 07/18] irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (5 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 06/18] irqchip/renesas-rzv2h: Fix wrong variable usage in rzv2h_tint_set_type() Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 08/18] irqchip/renesas-rzv2h: Simplify rzv2h_icu_init() Tommaso Merciai
` (12 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit c56cab0c3ee063f30d1e53cca7614574e3c2cbd5 upstream.
Use rzv2h_icu_chip directly on irq_domain_set_hwirq_and_chip() and drop
the global variable irqchip from struct rzv2h_icu_priv.
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-4-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index f6363246a71a..0573062c89c4 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -83,13 +83,11 @@
/**
* struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure.
* @base: Controller's base address
- * @irqchip: Pointer to struct irq_chip
* @fwspec: IRQ firmware specific data
* @lock: Lock to serialize access to hardware registers
*/
struct rzv2h_icu_priv {
void __iomem *base;
- const struct irq_chip *irqchip;
struct irq_fwspec fwspec[ICU_NUM_IRQ];
raw_spinlock_t lock;
};
@@ -390,7 +388,7 @@ static int rzv2h_icu_alloc(struct irq_domain *domain, unsigned int virq, unsigne
if (hwirq > (ICU_NUM_IRQ - 1))
return -EINVAL;
- ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, priv->irqchip,
+ ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &rzv2h_icu_chip,
(void *)(uintptr_t)tint);
if (ret)
return ret;
@@ -446,8 +444,6 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
goto put_dev;
}
- rzv2h_icu_data->irqchip = &rzv2h_icu_chip;
-
rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
if (IS_ERR(rzv2h_icu_data->base)) {
ret = PTR_ERR(rzv2h_icu_data->base);
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 08/18] irqchip/renesas-rzv2h: Simplify rzv2h_icu_init()
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (6 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 07/18] irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 09/18] irqchip/renesas-rzv2h: Use devm_reset_control_get_exclusive_deasserted() Tommaso Merciai
` (11 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit f5de95438834a3bc3ad747f67c9da93cd08e5008 upstream.
Use devm_add_action_or_reset() for calling put_device in error path of
rzv2h_icu_init() to simplify the code by using the recently added devm_*
helpers.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://lore.kernel.org/all/20250224131253.134199-5-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 37 +++++++++++++++--------------
1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 0573062c89c4..d724f32dde8f 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -419,6 +419,11 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device
return 0;
}
+static void rzv2h_icu_put_device(void *data)
+{
+ put_device(data);
+}
+
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
{
struct irq_domain *irq_domain, *parent_domain;
@@ -431,41 +436,39 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
if (!pdev)
return -ENODEV;
+ ret = devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device,
+ &pdev->dev);
+ if (ret < 0)
+ return ret;
+
parent_domain = irq_find_host(parent);
if (!parent_domain) {
dev_err(&pdev->dev, "cannot find parent domain\n");
- ret = -ENODEV;
- goto put_dev;
+ return -ENODEV;
}
rzv2h_icu_data = devm_kzalloc(&pdev->dev, sizeof(*rzv2h_icu_data), GFP_KERNEL);
- if (!rzv2h_icu_data) {
- ret = -ENOMEM;
- goto put_dev;
- }
+ if (!rzv2h_icu_data)
+ return -ENOMEM;
rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL);
- if (IS_ERR(rzv2h_icu_data->base)) {
- ret = PTR_ERR(rzv2h_icu_data->base);
- goto put_dev;
- }
+ if (IS_ERR(rzv2h_icu_data->base))
+ return PTR_ERR(rzv2h_icu_data->base);
ret = rzv2h_icu_parse_interrupts(rzv2h_icu_data, node);
if (ret) {
dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret);
- goto put_dev;
+ return ret;
}
resetn = devm_reset_control_get_exclusive(&pdev->dev, NULL);
- if (IS_ERR(resetn)) {
- ret = PTR_ERR(resetn);
- goto put_dev;
- }
+ if (IS_ERR(resetn))
+ return PTR_ERR(resetn);
ret = reset_control_deassert(resetn);
if (ret) {
dev_err(&pdev->dev, "failed to deassert resetn pin, %d\n", ret);
- goto put_dev;
+ return ret;
}
pm_runtime_enable(&pdev->dev);
@@ -496,8 +499,6 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
pm_disable:
pm_runtime_disable(&pdev->dev);
reset_control_assert(resetn);
-put_dev:
- put_device(&pdev->dev);
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 09/18] irqchip/renesas-rzv2h: Use devm_reset_control_get_exclusive_deasserted()
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (7 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 08/18] irqchip/renesas-rzv2h: Simplify rzv2h_icu_init() Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 10/18] irqchip/renesas-rzv2h: Use devm_pm_runtime_enable() Tommaso Merciai
` (10 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit ad773ebc6e41f0004487726e432b86795ae426d9 upstream.
Use devm_reset_control_get_exclusive_deasserted() to simplify
rzv2h_icu_init().
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://lore.kernel.org/all/20250224131253.134199-6-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index d724f32dde8f..edae54f9f5da 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -461,13 +461,10 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
return ret;
}
- resetn = devm_reset_control_get_exclusive(&pdev->dev, NULL);
- if (IS_ERR(resetn))
- return PTR_ERR(resetn);
-
- ret = reset_control_deassert(resetn);
- if (ret) {
- dev_err(&pdev->dev, "failed to deassert resetn pin, %d\n", ret);
+ resetn = devm_reset_control_get_exclusive_deasserted(&pdev->dev, NULL);
+ if (IS_ERR(resetn)) {
+ ret = PTR_ERR(resetn);
+ dev_err(&pdev->dev, "failed to acquire deasserted reset: %d\n", ret);
return ret;
}
@@ -498,7 +495,6 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
pm_runtime_put(&pdev->dev);
pm_disable:
pm_runtime_disable(&pdev->dev);
- reset_control_assert(resetn);
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 10/18] irqchip/renesas-rzv2h: Use devm_pm_runtime_enable()
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (8 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 09/18] irqchip/renesas-rzv2h: Use devm_reset_control_get_exclusive_deasserted() Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 11/18] irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable Tommaso Merciai
` (9 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 5ec8cabc3b8622f95de973c1a245245c65e3337b upstream.
Simplify rzv2h_icu_init() by using devm_pm_runtime_enable().
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/all/20250224131253.134199-7-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index edae54f9f5da..10b9b63a1f09 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -468,11 +468,16 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
return ret;
}
- pm_runtime_enable(&pdev->dev);
+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "devm_pm_runtime_enable failed, %d\n", ret);
+ return ret;
+ }
+
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "pm_runtime_resume_and_get failed: %d\n", ret);
- goto pm_disable;
+ return ret;
}
raw_spin_lock_init(&rzv2h_icu_data->lock);
@@ -493,8 +498,6 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
pm_put:
pm_runtime_put(&pdev->dev);
-pm_disable:
- pm_runtime_disable(&pdev->dev);
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 11/18] irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (9 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 10/18] irqchip/renesas-rzv2h: Use devm_pm_runtime_enable() Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 12/18] irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info Tommaso Merciai
` (8 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 0a9d6ef64e5e917f93db98935cd09bac38507ebf upstream.
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
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 46 +++++++++++++++++++++--------
1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 10b9b63a1f09..43b805b6df94 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -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)
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 12/18] irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (10 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 11/18] irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 13/18] irqchip/renesas-rzv2h: Add field_width " Tommaso Merciai
` (7 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit eb23d23d082d097e2a8154a57da72061cb7e33b3 upstream.
The number of GPIO interrupts on RZ/G3E for TINT selection is 141 compared
to 86 on RZ/V2H. Rename the macro ICU_PB5_TINT->ICU_RZV2H_TSSEL_MAX_VAL to
hold this difference for RZ/V2H.
Add max_tssel to struct rzv2h_hw_info 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-9-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 43b805b6df94..2fae3274c015 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -78,14 +78,16 @@
#define ICU_TINT_EXTRACT_HWIRQ(x) FIELD_GET(GENMASK(15, 0), (x))
#define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x))
-#define ICU_PB5_TINT 0x55
+#define ICU_RZV2H_TSSEL_MAX_VAL 0x55
/**
* struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
* @t_offs: TINT offset
+ * @max_tssel: TSSEL max value
*/
struct rzv2h_hw_info {
u16 t_offs;
+ u8 max_tssel;
};
/**
@@ -298,13 +300,12 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
+ priv = irq_data_to_priv(d);
tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
- if (tint > ICU_PB5_TINT)
+ if (tint > priv->info->max_tssel)
return -EINVAL;
- priv = irq_data_to_priv(d);
hwirq = irqd_to_hwirq(d);
-
tint_nr = hwirq - ICU_TINT_START;
tssr_k = ICU_TSSR_K(tint_nr);
@@ -517,6 +518,7 @@ static int rzv2h_icu_init_common(struct device_node *node, struct device_node *p
static const struct rzv2h_hw_info rzv2h_hw_params = {
.t_offs = 0,
+ .max_tssel = ICU_RZV2H_TSSEL_MAX_VAL,
};
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 13/18] irqchip/renesas-rzv2h: Add field_width to struct rzv2h_hw_info
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (11 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 12/18] irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 14/18] irqchip/renesas-rzv2h: Update TSSR_TIEN macro Tommaso Merciai
` (6 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 1a6ebcc10b138a6c55f8df2cf6cc630ddabe3cab upstream.
On RZ/G3E the field width for TSSR register for a TINT is 16 compared to 8
on the RZ/V2H.
Add field_width to struct rzv2h_hw_info and replace the macros ICU_TSSR_K
and ICU_TSSR_TSSEL_N by a runtime evaluation:
(32 / field_width) provides the number of tints in the TSSR register.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/all/20250224131253.134199-10-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 2fae3274c015..98a6a7cd3611 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -64,8 +64,6 @@
#define ICU_TINT_LEVEL_HIGH 2
#define ICU_TINT_LEVEL_LOW 3
-#define ICU_TSSR_K(tint_nr) ((tint_nr) / 4)
-#define ICU_TSSR_TSSEL_N(tint_nr) ((tint_nr) % 4)
#define ICU_TSSR_TSSEL_PREP(tssel, n) ((tssel) << ((n) * 8))
#define ICU_TSSR_TSSEL_MASK(n) ICU_TSSR_TSSEL_PREP(0x7F, n)
#define ICU_TSSR_TIEN(n) (BIT(7) << ((n) * 8))
@@ -84,10 +82,12 @@
* struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
* @t_offs: TINT offset
* @max_tssel: TSSEL max value
+ * @field_width: TSSR field width
*/
struct rzv2h_hw_info {
u16 t_offs;
u8 max_tssel;
+ u8 field_width;
};
/**
@@ -140,13 +140,15 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
struct rzv2h_icu_priv *priv = irq_data_to_priv(d);
unsigned int hw_irq = irqd_to_hwirq(d);
u32 tint_nr, tssel_n, k, tssr;
+ u8 nr_tint;
if (hw_irq < ICU_TINT_START)
return;
tint_nr = hw_irq - ICU_TINT_START;
- k = ICU_TSSR_K(tint_nr);
- tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
+ nr_tint = 32 / priv->info->field_width;
+ k = tint_nr / nr_tint;
+ tssel_n = tint_nr % nr_tint;
guard(raw_spinlock)(&priv->lock);
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k));
@@ -278,6 +280,7 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
unsigned int hwirq;
u32 tint, sense;
int tint_nr;
+ u8 nr_tint;
switch (type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_LEVEL_LOW:
@@ -308,8 +311,9 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
hwirq = irqd_to_hwirq(d);
tint_nr = hwirq - ICU_TINT_START;
- tssr_k = ICU_TSSR_K(tint_nr);
- tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
+ nr_tint = 32 / priv->info->field_width;
+ tssr_k = tint_nr / nr_tint;
+ tssel_n = tint_nr % nr_tint;
tien = ICU_TSSR_TIEN(tssel_n);
titsr_k = ICU_TITSR_K(tint_nr);
@@ -519,6 +523,7 @@ static int rzv2h_icu_init_common(struct device_node *node, struct device_node *p
static const struct rzv2h_hw_info rzv2h_hw_params = {
.t_offs = 0,
.max_tssel = ICU_RZV2H_TSSEL_MAX_VAL,
+ .field_width = 8,
};
static int rzv2h_icu_init(struct device_node *node, struct device_node *parent)
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 14/18] irqchip/renesas-rzv2h: Update TSSR_TIEN macro
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (12 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 13/18] irqchip/renesas-rzv2h: Add field_width " Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 15/18] irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP} Tommaso Merciai
` (5 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 76c3b774734feb8224b78721e0c67a54760a75c5 upstream.
On RZ/G3E, TIEN bit position is at 15 compared to 7 on RZ/V2H. Replace the
macro ICU_TSSR_TIEN(n)->ICU_TSSR_TIEN(n, _field_width) for supporting both
these SoCs.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/all/20250224131253.134199-11-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 98a6a7cd3611..8d0bd4d69de2 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -66,7 +66,11 @@
#define ICU_TSSR_TSSEL_PREP(tssel, n) ((tssel) << ((n) * 8))
#define ICU_TSSR_TSSEL_MASK(n) ICU_TSSR_TSSEL_PREP(0x7F, n)
-#define ICU_TSSR_TIEN(n) (BIT(7) << ((n) * 8))
+#define ICU_TSSR_TIEN(n, field_width) \
+({\
+ typeof(field_width) (_field_width) = (field_width); \
+ BIT((_field_width) - 1) << ((n) * (_field_width)); \
+})
#define ICU_TITSR_K(tint_nr) ((tint_nr) / 16)
#define ICU_TITSR_TITSEL_N(tint_nr) ((tint_nr) % 16)
@@ -153,9 +157,9 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
guard(raw_spinlock)(&priv->lock);
tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k));
if (enable)
- tssr |= ICU_TSSR_TIEN(tssel_n);
+ tssr |= ICU_TSSR_TIEN(tssel_n, priv->info->field_width);
else
- tssr &= ~ICU_TSSR_TIEN(tssel_n);
+ tssr &= ~ICU_TSSR_TIEN(tssel_n, priv->info->field_width);
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
}
@@ -314,7 +318,7 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
nr_tint = 32 / priv->info->field_width;
tssr_k = tint_nr / nr_tint;
tssel_n = tint_nr % nr_tint;
- tien = ICU_TSSR_TIEN(tssel_n);
+ tien = ICU_TSSR_TIEN(tssel_n, priv->info->field_width);
titsr_k = ICU_TITSR_K(tint_nr);
titsel_n = ICU_TITSR_TITSEL_N(tint_nr);
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 15/18] irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP}
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (13 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 14/18] irqchip/renesas-rzv2h: Update TSSR_TIEN macro Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 16/18] irqchip/renesas-rzv2h: Add RZ/G3E support Tommaso Merciai
` (4 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit e3a16c33db69ffd1369ebfdf93f93a93a785896a upstream.
On RZ/G3E, TSSEL register field is 8 bits wide compared to 7 on RZ/V2H.
Also bits 8..14 is reserved on RZ/G3E and any writes on these reserved
bits is ignored.
Use bitmask GENMASK(field_width - 2, 0) on both SoCs for extracting TSSEL
and then update the macros ICU_TSSR_TSSEL_PREP and ICU_TSSR_TSSEL_MASK for
supporting both SoCs.
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/all/20250224131253.134199-12-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 8d0bd4d69de2..7bc4397ec149 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -64,8 +64,13 @@
#define ICU_TINT_LEVEL_HIGH 2
#define ICU_TINT_LEVEL_LOW 3
-#define ICU_TSSR_TSSEL_PREP(tssel, n) ((tssel) << ((n) * 8))
-#define ICU_TSSR_TSSEL_MASK(n) ICU_TSSR_TSSEL_PREP(0x7F, n)
+#define ICU_TSSR_TSSEL_PREP(tssel, n, field_width) ((tssel) << ((n) * (field_width)))
+#define ICU_TSSR_TSSEL_MASK(n, field_width) \
+({\
+ typeof(field_width) (_field_width) = (field_width); \
+ ICU_TSSR_TSSEL_PREP((GENMASK(((_field_width) - 2), 0)), (n), _field_width); \
+})
+
#define ICU_TSSR_TIEN(n, field_width) \
({\
typeof(field_width) (_field_width) = (field_width); \
@@ -326,8 +331,8 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
guard(raw_spinlock)(&priv->lock);
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);
+ tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width) | tien);
+ tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n, priv->info->field_width);
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 16/18] irqchip/renesas-rzv2h: Add RZ/G3E support
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (14 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 15/18] irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP} Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 17/18] irqchip/renesas-rzv2h: Prevent TINT spurious interrupt Tommaso Merciai
` (3 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 399b2799985237cf5c3656b7cfc87cdaa489efd1 upstream.
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.
Add support for the RZ/G3E driver by filling the rzv2h_hw_info table and
adding LUT for mapping between pin index and TINT selection index.
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-13-biju.das.jz@bp.renesas.com
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 46 +++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 7bc4397ec149..3d5b5fdf9bde 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -85,15 +85,19 @@
#define ICU_TINT_EXTRACT_HWIRQ(x) FIELD_GET(GENMASK(15, 0), (x))
#define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x))
+#define ICU_RZG3E_TINT_OFFSET 0x800
+#define ICU_RZG3E_TSSEL_MAX_VAL 0x8c
#define ICU_RZV2H_TSSEL_MAX_VAL 0x55
/**
* struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure.
+ * @tssel_lut: TINT lookup table
* @t_offs: TINT offset
* @max_tssel: TSSEL max value
* @field_width: TSSR field width
*/
struct rzv2h_hw_info {
+ const u8 *tssel_lut;
u16 t_offs;
u8 max_tssel;
u8 field_width;
@@ -317,6 +321,9 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
if (tint > priv->info->max_tssel)
return -EINVAL;
+ if (priv->info->tssel_lut)
+ tint = priv->info->tssel_lut[tint];
+
hwirq = irqd_to_hwirq(d);
tint_nr = hwirq - ICU_TINT_START;
@@ -529,18 +536,57 @@ static int rzv2h_icu_init_common(struct device_node *node, struct device_node *p
return ret;
}
+/* Mapping based on port index on Table 4.2-6 and TSSEL bits on Table 4.6-4 */
+static const u8 rzg3e_tssel_lut[] = {
+ 81, 82, 83, 84, 85, 86, 87, 88, /* P00-P07 */
+ 89, 90, 91, 92, 93, 94, 95, 96, /* P10-P17 */
+ 111, 112, /* P20-P21 */
+ 97, 98, 99, 100, 101, 102, 103, 104, /* P30-P37 */
+ 105, 106, 107, 108, 109, 110, /* P40-P45 */
+ 113, 114, 115, 116, 117, 118, 119, /* P50-P56 */
+ 120, 121, 122, 123, 124, 125, 126, /* P60-P66 */
+ 127, 128, 129, 130, 131, 132, 133, 134, /* P70-P77 */
+ 135, 136, 137, 138, 139, 140, /* P80-P85 */
+ 43, 44, 45, 46, 47, 48, 49, 50, /* PA0-PA7 */
+ 51, 52, 53, 54, 55, 56, 57, 58, /* PB0-PB7 */
+ 59, 60, 61, /* PC0-PC2 */
+ 62, 63, 64, 65, 66, 67, 68, 69, /* PD0-PD7 */
+ 70, 71, 72, 73, 74, 75, 76, 77, /* PE0-PE7 */
+ 78, 79, 80, /* PF0-PF2 */
+ 25, 26, 27, 28, 29, 30, 31, 32, /* PG0-PG7 */
+ 33, 34, 35, 36, 37, 38, /* PH0-PH5 */
+ 4, 5, 6, 7, 8, /* PJ0-PJ4 */
+ 39, 40, 41, 42, /* PK0-PK3 */
+ 9, 10, 11, 12, 21, 22, 23, 24, /* PL0-PL7 */
+ 13, 14, 15, 16, 17, 18, 19, 20, /* PM0-PM7 */
+ 0, 1, 2, 3 /* PS0-PS3 */
+};
+
+static const struct rzv2h_hw_info rzg3e_hw_params = {
+ .tssel_lut = rzg3e_tssel_lut,
+ .t_offs = ICU_RZG3E_TINT_OFFSET,
+ .max_tssel = ICU_RZG3E_TSSEL_MAX_VAL,
+ .field_width = 16,
+};
+
static const struct rzv2h_hw_info rzv2h_hw_params = {
.t_offs = 0,
.max_tssel = ICU_RZV2H_TSSEL_MAX_VAL,
.field_width = 8,
};
+static int rzg3e_icu_init(struct device_node *node, struct device_node *parent)
+{
+ return rzv2h_icu_init_common(node, parent, &rzg3e_hw_params);
+}
+
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,r9a09g047-icu", rzg3e_icu_init)
IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init)
IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)
MODULE_AUTHOR("Fabrizio Castro <fabrizio.castro.jz@renesas.com>");
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 17/18] irqchip/renesas-rzv2h: Prevent TINT spurious interrupt
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (15 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 16/18] irqchip/renesas-rzv2h: Add RZ/G3E support Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 18/18] arm64: dts: renesas: r9a09g047: Add ICU node Tommaso Merciai
` (2 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit 28e89cdac6482f3c980df3e2e245db7366269124 upstream.
A spurious TINT interrupt is seen during boot on RZ/G3E SMARC EVK.
A glitch in the edge detection circuit can cause a spurious interrupt.
Clear the status flag after setting the ICU_TSSRk registers, which is
recommended in the hardware manual as a countermeasure.
Fixes: 0d7605e75ac2 ("irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
drivers/irqchip/irq-renesas-rzv2h.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index 3d5b5fdf9bde..0f0fd7d4dfdf 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -170,6 +170,14 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable)
else
tssr &= ~ICU_TSSR_TIEN(tssel_n, priv->info->field_width);
writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k));
+
+ /*
+ * A glitch in the edge detection circuit can cause a spurious
+ * interrupt. Clear the status flag after setting the ICU_TSSRk
+ * registers, which is recommended by the hardware manual as a
+ * countermeasure.
+ */
+ writel_relaxed(BIT(tint_nr), priv->base + priv->info->t_offs + ICU_TSCLR);
}
static void rzv2h_icu_irq_disable(struct irq_data *d)
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 6.12.y-cip 18/18] arm64: dts: renesas: r9a09g047: Add ICU node
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (16 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 17/18] irqchip/renesas-rzv2h: Prevent TINT spurious interrupt Tommaso Merciai
@ 2025-07-04 9:07 ` Tommaso Merciai
2025-07-04 18:12 ` [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Pavel Machek
2025-07-07 5:00 ` nobuhiro1.iwamatsu
19 siblings, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-04 9:07 UTC (permalink / raw)
To: cip-dev, Nobuhiro Iwamatsu, Pavel Machek
Cc: Biju Das, Lad Prabhakar, tomm.merciai
From: Biju Das <biju.das.jz@bp.renesas.com>
commit b7509775670d69999096b55c0e90a4e03a373bae upstream.
Add interrupt control node to RZ/G3E ("R9A09G047") SoC DTSI
and add icu as interrupt-parent of pincontrol.
Reviewed-by: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
Reviewed-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/20250207113653.21641-13-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
---
arch/arm64/boot/dts/renesas/r9a09g047.dtsi | 90 ++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
index b742e57f40b4..5b413d31b8cd 100644
--- a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
+++ b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
@@ -160,6 +160,95 @@ soc: soc {
#size-cells = <2>;
ranges;
+ icu: interrupt-controller@10400000 {
+ compatible = "renesas,r9a09g047-icu";
+ reg = <0 0x10400000 0 0x10000>;
+ #interrupt-cells = <2>;
+ #address-cells = <0>;
+ interrupt-controller;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 263 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 264 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 265 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "nmi",
+ "port_irq0", "port_irq1", "port_irq2",
+ "port_irq3", "port_irq4", "port_irq5",
+ "port_irq6", "port_irq7", "port_irq8",
+ "port_irq9", "port_irq10", "port_irq11",
+ "port_irq12", "port_irq13", "port_irq14",
+ "port_irq15",
+ "tint0", "tint1", "tint2", "tint3",
+ "tint4", "tint5", "tint6", "tint7",
+ "tint8", "tint9", "tint10", "tint11",
+ "tint12", "tint13", "tint14", "tint15",
+ "tint16", "tint17", "tint18", "tint19",
+ "tint20", "tint21", "tint22", "tint23",
+ "tint24", "tint25", "tint26", "tint27",
+ "tint28", "tint29", "tint30", "tint31",
+ "int-ca55-0", "int-ca55-1",
+ "int-ca55-2", "int-ca55-3",
+ "icu-error-ca55",
+ "gpt-u0-gtciada", "gpt-u0-gtciadb",
+ "gpt-u1-gtciada", "gpt-u1-gtciadb";
+ clocks = <&cpg CPG_MOD 0x5>;
+ power-domains = <&cpg>;
+ resets = <&cpg 0x36>;
+ };
+
pinctrl: pinctrl@10410000 {
compatible = "renesas,r9a09g047-pinctrl";
reg = <0 0x10410000 0 0x10000>;
@@ -169,6 +258,7 @@ pinctrl: pinctrl@10410000 {
gpio-ranges = <&pinctrl 0 0 232>;
#interrupt-cells = <2>;
interrupt-controller;
+ interrupt-parent = <&icu>;
power-domains = <&cpg>;
resets = <&cpg 0xa5>, <&cpg 0xa6>;
};
--
2.43.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (17 preceding siblings ...)
2025-07-04 9:07 ` [PATCH 6.12.y-cip 18/18] arm64: dts: renesas: r9a09g047: Add ICU node Tommaso Merciai
@ 2025-07-04 18:12 ` Pavel Machek
2025-07-07 8:49 ` Tommaso Merciai
2025-07-07 5:00 ` nobuhiro1.iwamatsu
19 siblings, 1 reply; 27+ messages in thread
From: Pavel Machek @ 2025-07-04 18:12 UTC (permalink / raw)
To: Tommaso Merciai
Cc: cip-dev, Nobuhiro Iwamatsu, Biju Das, Lad Prabhakar, tomm.merciai
[-- Attachment #1: Type: text/plain, Size: 1149 bytes --]
Hi!
> This series adds support for the RZ/G3E ICU driver into linux 6.12.y-cip.
>
> 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 supported 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
>
> This series applies on top of [1]
>
> [1] https://patchwork.kernel.org/project/cip-dev/list/?series=978150&state=%2A&archive=both
Series looks ok to me.
I'll have some minor comments but nothing that should prevent
merge... so I can merge this if it passes testing and there are no
other comments.
One thing: "Signed-off-by:" section should not have empty lines in
that. I guess we can fix that up doing merge.
Best regards,
Pavel
--
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich,
Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* RE: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
` (18 preceding siblings ...)
2025-07-04 18:12 ` [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Pavel Machek
@ 2025-07-07 5:00 ` nobuhiro1.iwamatsu
2025-07-07 9:00 ` Tommaso Merciai
2025-07-07 10:44 ` Pavel Machek
19 siblings, 2 replies; 27+ messages in thread
From: nobuhiro1.iwamatsu @ 2025-07-07 5:00 UTC (permalink / raw)
To: tommaso.merciai.xr, cip-dev, pavel
Cc: biju.das.jz, prabhakar.mahadev-lad.rj, tomm.merciai
Hi all,
> -----Original Message-----
> From: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> Sent: Friday, July 4, 2025 6:07 PM
> To: cip-dev@lists.cip-project.org; iwamatsu nobuhiro(岩松 信洋 □DITC○
> CPT) <nobuhiro1.iwamatsu@toshiba.co.jp>; Pavel Machek
> <pavel@denx.de>
> Cc: Biju Das <biju.das.jz@bp.renesas.com>; Lad Prabhakar
> <prabhakar.mahadev-lad.rj@bp.renesas.com>; tomm.merciai@gmail.com
> Subject: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
>
> Dear All,
>
> This series adds support for the RZ/G3E ICU driver into linux 6.12.y-cip.
>
> 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 supported 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
>
> This series applies on top of [1]
>
> [1]
> https://patchwork.kernel.org/project/cip-dev/list/?series=978150&state=%2
> A&archive=both
>
> Thanks & Regards,
> Tommaso
>
> Biju Das (14):
> dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E
> SoC
> irqchip/renesas-rzv2h: Fix wrong variable usage in
> rzv2h_tint_set_type()
> irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv
> irqchip/renesas-rzv2h: Simplify rzv2h_icu_init()
> irqchip/renesas-rzv2h: Use
> devm_reset_control_get_exclusive_deasserted()
> irqchip/renesas-rzv2h: Use devm_pm_runtime_enable()
> irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
> irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info
> irqchip/renesas-rzv2h: Add field_width to struct rzv2h_hw_info
> irqchip/renesas-rzv2h: Update TSSR_TIEN macro
> irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP}
> irqchip/renesas-rzv2h: Add RZ/G3E support
> irqchip/renesas-rzv2h: Prevent TINT spurious interrupt
> arm64: dts: renesas: r9a09g047: Add ICU node
>
> Fabrizio Castro (2):
> dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt
> Controller
> irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver
>
> Philipp Zabel (2):
> reset: replace boolean parameters with flags parameter
> reset: Add devres helpers to request pre-deasserted reset controls
>
> .../renesas,rzv2h-icu.yaml | 280 ++++++++
> arch/arm64/boot/dts/renesas/r9a09g047.dtsi | 90 +++
> drivers/irqchip/Kconfig | 7 +
> drivers/irqchip/Makefile | 1 +
> drivers/irqchip/irq-renesas-rzv2h.c | 601
> ++++++++++++++++++
> drivers/reset/core.c | 119 +++-
> drivers/soc/renesas/Kconfig | 1 +
> include/linux/reset.h | 274 ++++++--
> 8 files changed, 1278 insertions(+), 95 deletions(-) create mode 100644
> Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.y
> aml
> create mode 100644 drivers/irqchip/irq-renesas-rzv2h.c
>
I reviewed this series, looks good to me. I can apply, if there are no other comments and test was OK.
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Best regards,
Nobuhiro
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
2025-07-04 18:12 ` [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Pavel Machek
@ 2025-07-07 8:49 ` Tommaso Merciai
2025-07-07 9:33 ` Pavel Machek
0 siblings, 1 reply; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-07 8:49 UTC (permalink / raw)
To: Pavel Machek
Cc: cip-dev, Nobuhiro Iwamatsu, Biju Das, Lad Prabhakar, tomm.merciai
Hi Pavel,
Thanks for your work!
On Fri, Jul 04, 2025 at 08:12:56PM +0200, Pavel Machek wrote:
> Hi!
>
> > This series adds support for the RZ/G3E ICU driver into linux 6.12.y-cip.
> >
> > 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 supported 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
> >
> > This series applies on top of [1]
> >
> > [1] https://patchwork.kernel.org/project/cip-dev/list/?series=978150&state=%2A&archive=both
>
> Series looks ok to me.
>
> I'll have some minor comments but nothing that should prevent
> merge... so I can merge this if it passes testing and there are no
> other comments.
>
> One thing: "Signed-off-by:" section should not have empty lines in
> that. I guess we can fix that up doing merge.
Sorry for that and thanks for taking care of this.
Tbh I'm just using "git commit -s" to apply upstream patches.
Any suggestion? Thanks in advance.
Maybe I have somenthing wrong in my configuration :'(
Thanks again,
Tommaso
>
> Best regards,
> Pavel
> --
> In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich,
> Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
2025-07-07 5:00 ` nobuhiro1.iwamatsu
@ 2025-07-07 9:00 ` Tommaso Merciai
2025-07-07 10:44 ` Pavel Machek
1 sibling, 0 replies; 27+ messages in thread
From: Tommaso Merciai @ 2025-07-07 9:00 UTC (permalink / raw)
To: nobuhiro1.iwamatsu
Cc: cip-dev, pavel, biju.das.jz, prabhakar.mahadev-lad.rj,
tomm.merciai
Hi Nobuhiro,
On Mon, Jul 07, 2025 at 05:00:34AM +0000, nobuhiro1.iwamatsu@toshiba.co.jp wrote:
> Hi all,
>
> > -----Original Message-----
> > From: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
> > Sent: Friday, July 4, 2025 6:07 PM
> > To: cip-dev@lists.cip-project.org; iwamatsu nobuhiro(岩松 信洋 □DITC○
> > CPT) <nobuhiro1.iwamatsu@toshiba.co.jp>; Pavel Machek
> > <pavel@denx.de>
> > Cc: Biju Das <biju.das.jz@bp.renesas.com>; Lad Prabhakar
> > <prabhakar.mahadev-lad.rj@bp.renesas.com>; tomm.merciai@gmail.com
> > Subject: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
> >
> > Dear All,
> >
> > This series adds support for the RZ/G3E ICU driver into linux 6.12.y-cip.
> >
> > 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 supported 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
> >
> > This series applies on top of [1]
> >
> > [1]
> > https://patchwork.kernel.org/project/cip-dev/list/?series=978150&state=%2
> > A&archive=both
> >
> > Thanks & Regards,
> > Tommaso
> >
> > Biju Das (14):
> > dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E
> > SoC
> > irqchip/renesas-rzv2h: Fix wrong variable usage in
> > rzv2h_tint_set_type()
> > irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv
> > irqchip/renesas-rzv2h: Simplify rzv2h_icu_init()
> > irqchip/renesas-rzv2h: Use
> > devm_reset_control_get_exclusive_deasserted()
> > irqchip/renesas-rzv2h: Use devm_pm_runtime_enable()
> > irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
> > irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info
> > irqchip/renesas-rzv2h: Add field_width to struct rzv2h_hw_info
> > irqchip/renesas-rzv2h: Update TSSR_TIEN macro
> > irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP}
> > irqchip/renesas-rzv2h: Add RZ/G3E support
> > irqchip/renesas-rzv2h: Prevent TINT spurious interrupt
> > arm64: dts: renesas: r9a09g047: Add ICU node
> >
> > Fabrizio Castro (2):
> > dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt
> > Controller
> > irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver
> >
> > Philipp Zabel (2):
> > reset: replace boolean parameters with flags parameter
> > reset: Add devres helpers to request pre-deasserted reset controls
> >
> > .../renesas,rzv2h-icu.yaml | 280 ++++++++
> > arch/arm64/boot/dts/renesas/r9a09g047.dtsi | 90 +++
> > drivers/irqchip/Kconfig | 7 +
> > drivers/irqchip/Makefile | 1 +
> > drivers/irqchip/irq-renesas-rzv2h.c | 601
> > ++++++++++++++++++
> > drivers/reset/core.c | 119 +++-
> > drivers/soc/renesas/Kconfig | 1 +
> > include/linux/reset.h | 274 ++++++--
> > 8 files changed, 1278 insertions(+), 95 deletions(-) create mode 100644
> > Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.y
> > aml
> > create mode 100644 drivers/irqchip/irq-renesas-rzv2h.c
> >
>
> I reviewed this series, looks good to me. I can apply, if there are no other comments and test was OK.
> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Thanks for your work!
Regards,
Tommaso
>
> Best regards,
> Nobuhiro
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
2025-07-07 8:49 ` Tommaso Merciai
@ 2025-07-07 9:33 ` Pavel Machek
0 siblings, 0 replies; 27+ messages in thread
From: Pavel Machek @ 2025-07-07 9:33 UTC (permalink / raw)
To: Tommaso Merciai
Cc: cip-dev, Nobuhiro Iwamatsu, Biju Das, Lad Prabhakar, tomm.merciai
[-- Attachment #1: Type: text/plain, Size: 1713 bytes --]
On Mon 2025-07-07 10:49:15, Tommaso Merciai wrote:
> Hi Pavel,
> Thanks for your work!
>
> On Fri, Jul 04, 2025 at 08:12:56PM +0200, Pavel Machek wrote:
> > Hi!
> >
> > > This series adds support for the RZ/G3E ICU driver into linux 6.12.y-cip.
> > >
> > > 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 supported 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
> > >
> > > This series applies on top of [1]
> > >
> > > [1] https://patchwork.kernel.org/project/cip-dev/list/?series=978150&state=%2A&archive=both
> >
> > Series looks ok to me.
> >
> > I'll have some minor comments but nothing that should prevent
> > merge... so I can merge this if it passes testing and there are no
> > other comments.
> >
> > One thing: "Signed-off-by:" section should not have empty lines in
> > that. I guess we can fix that up doing merge.
>
> Sorry for that and thanks for taking care of this.
> Tbh I'm just using "git commit -s" to apply upstream patches.
> Any suggestion? Thanks in advance.
>
> Maybe I have somenthing wrong in my configuration :'(
I guess git rebase -i to manually edit the changelogs is easiest
option there.
Best regards,
Pavel
--
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich,
Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 03/18] dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt Controller
2025-07-04 9:07 ` [PATCH 6.12.y-cip 03/18] dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt Controller Tommaso Merciai
@ 2025-07-07 9:35 ` Pavel Machek
0 siblings, 0 replies; 27+ messages in thread
From: Pavel Machek @ 2025-07-07 9:35 UTC (permalink / raw)
To: Tommaso Merciai
Cc: cip-dev, Nobuhiro Iwamatsu, Biju Das, Lad Prabhakar, tomm.merciai
[-- Attachment #1: Type: text/plain, Size: 1017 bytes --]
Hi!
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,rzv2h-icu.yaml
> @@ -0,0 +1,278 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interrupt-controller/renesas,rzv2h-icu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Renesas RZ/V2H(P) Interrupt Control Unit
> +
> +maintainers:
> + - Fabrizio Castro <fabrizio.castro.jz@renesas.com>
> + - Geert Uytterhoeven <geert+renesas@glider.be>
> +
> +allOf:
> + - $ref: /schemas/interrupt-controller.yaml#
> +
> +description:
> + The Interrupt Control Unit (ICU) handles external interrupts (NMI, IRQ, and
> + TINT), error interrupts, DMAC requests, GPT interrupts, and internal
> + interrupts.
I believe "," is not needed before and.
Best regards,
Pavel
--
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich,
Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 05/18] irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver
2025-07-04 9:07 ` [PATCH 6.12.y-cip 05/18] irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver Tommaso Merciai
@ 2025-07-07 9:37 ` Pavel Machek
0 siblings, 0 replies; 27+ messages in thread
From: Pavel Machek @ 2025-07-07 9:37 UTC (permalink / raw)
To: Tommaso Merciai
Cc: cip-dev, Nobuhiro Iwamatsu, Biju Das, Lad Prabhakar, tomm.merciai
[-- Attachment #1: Type: text/plain, Size: 1769 bytes --]
Hi!
> From: Fabrizio Castro <fabrizio.castro.jz@renesas.com>
>
> commit 0d7605e75ac2d8620929148f932cde54746c485f upstream.
>
> Add driver for the Renesas RZ/V2H(P) Interrupt Control Unit (ICU).
>
> This driver supports the external interrupts NMI, IRQn, and TINTn.
>
> +++ b/drivers/irqchip/irq-renesas-rzv2h.c
> +static void rzv2h_clear_irq_int(struct rzv2h_icu_priv *priv, unsigned int hwirq)
> +{
> + unsigned int irq_nr = hwirq - ICU_IRQ_START;
> + u32 isctr, iitsr, iitsel;
> + u32 bit = BIT(irq_nr);
> +
> + isctr = readl_relaxed(priv->base + ICU_ISCTR);
> + iitsr = readl_relaxed(priv->base + ICU_IITSR);
> + iitsel = ICU_IITSR_IITSEL_GET(iitsr, irq_nr);
> +
> + /*
> + * When level sensing is used, the interrupt flag gets automatically cleared when the
> + * interrupt signal is de-asserted by the source of the interrupt request, therefore clear
> + * the interrupt only for edge triggered interrupts.
> + */
I'd wrap this at 80 columns.
> + titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n);
> +
> + /*
> + * Writing 1 to the corresponding flag from register ICU_TSCTR only has effect if
> + * TSTATn = 1b and if it's a rising edge or a falling edge interrupt.
> + */
And this.
> + /*
> + * 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.
> + */
> + return 0;
cocci -> Cocci... but more seriously people are submitting stable
patches to silence checkers, so this may be worth finding some
workaround.
Best regards,
Pavel
--
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich,
Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU
2025-07-07 5:00 ` nobuhiro1.iwamatsu
2025-07-07 9:00 ` Tommaso Merciai
@ 2025-07-07 10:44 ` Pavel Machek
1 sibling, 0 replies; 27+ messages in thread
From: Pavel Machek @ 2025-07-07 10:44 UTC (permalink / raw)
To: nobuhiro1.iwamatsu
Cc: tommaso.merciai.xr, cip-dev, biju.das.jz,
prabhakar.mahadev-lad.rj, tomm.merciai
[-- Attachment #1: Type: text/plain, Size: 654 bytes --]
Hi!
>
> I reviewed this series, looks good to me. I can apply, if there are no other comments and test was OK.
> Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu@toshiba.co.jp>
Thanks for the review.
I ran the tests at
https://gitlab.com/cip-project/cip-kernel/linux-cip/-/pipelines/1910922707
. vx2 is not yet finished, but I don't believe that will finish, as
reported in the other mail. This was arm patch, so....
I've added your reviewed-by tag and pushed the series.
Best regards,
Pavel
--
In cooperation with DENX Software Engineering GmbH, HRB 165235 Munich,
Office: Kirchenstr.5, D-82194 Groebenzell, Germany
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2025-07-07 10:44 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-04 9:07 [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 01/18] reset: replace boolean parameters with flags parameter Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 02/18] reset: Add devres helpers to request pre-deasserted reset controls Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 03/18] dt-bindings: interrupt-controller: Add Renesas RZ/V2H(P) Interrupt Controller Tommaso Merciai
2025-07-07 9:35 ` Pavel Machek
2025-07-04 9:07 ` [PATCH 6.12.y-cip 04/18] dt-bindings: interrupt-controller: renesas,rzv2h-icu: Document RZ/G3E SoC Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 05/18] irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver Tommaso Merciai
2025-07-07 9:37 ` Pavel Machek
2025-07-04 9:07 ` [PATCH 6.12.y-cip 06/18] irqchip/renesas-rzv2h: Fix wrong variable usage in rzv2h_tint_set_type() Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 07/18] irqchip/renesas-rzv2h: Drop irqchip from struct rzv2h_icu_priv Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 08/18] irqchip/renesas-rzv2h: Simplify rzv2h_icu_init() Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 09/18] irqchip/renesas-rzv2h: Use devm_reset_control_get_exclusive_deasserted() Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 10/18] irqchip/renesas-rzv2h: Use devm_pm_runtime_enable() Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 11/18] irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 12/18] irqchip/renesas-rzv2h: Add max_tssel to struct rzv2h_hw_info Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 13/18] irqchip/renesas-rzv2h: Add field_width " Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 14/18] irqchip/renesas-rzv2h: Update TSSR_TIEN macro Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 15/18] irqchip/renesas-rzv2h: Update macros ICU_TSSR_TSSEL_{MASK,PREP} Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 16/18] irqchip/renesas-rzv2h: Add RZ/G3E support Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 17/18] irqchip/renesas-rzv2h: Prevent TINT spurious interrupt Tommaso Merciai
2025-07-04 9:07 ` [PATCH 6.12.y-cip 18/18] arm64: dts: renesas: r9a09g047: Add ICU node Tommaso Merciai
2025-07-04 18:12 ` [PATCH 6.12.y-cip 00/18] Add Support for RZ/G3E ICU Pavel Machek
2025-07-07 8:49 ` Tommaso Merciai
2025-07-07 9:33 ` Pavel Machek
2025-07-07 5:00 ` nobuhiro1.iwamatsu
2025-07-07 9:00 ` Tommaso Merciai
2025-07-07 10:44 ` Pavel Machek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox