Introduce an interrupt controller driver for Realtek DHC
(Digital Home Center) SoCs.
Change log:
v3 -> v4:
- Adjusted the allOf block to add constraints on the interrupts per variant
- Adjusted the error path and label
- Added the 'irq_domain_remove' to the error path
- Removed the 'devm_kfree' from the error path
- Replaced the 'irq_of_parse_and_map' with 'of_irq_get'
- Replaced the 'raw_spin_lock' with 'raw_spin_lock_irqsave'
- Adjusted the return value of the 'realtek_intc_subset'
- Replaced the '~1' with macro 'CLEAN_INTC_STATUS'
- Improved code comments and description
- Fixed coding style issues
- Fixed the incorrect control register in mask and unmask functions
- Changed the 'EXPORT_SYMBOL' to the 'EXPORT_SYMBOL_GPL'
- Renamed the 'realtek_intc_subset_cfg' to 'realtek_intc_mask'
- Removed unused and unnecessary code
- Removed 'irq_enable' and 'irq_disable' callback
- Replaced the 'core_initcall' with 'module_init'
- Removed redundant header files
- Moved the function of suspend and resume to common code
- Improved the description of config
v2 -> v3:
- Retested the bindings using the new version of the dtschema
- Fixed the order of property items
- Removed redundant files and replaced them with 'realtek,intc.yaml'
- Replaced 'interrupts-extended' with 'interrupts'
- Added a description for 'interrupts'
- Reduced the example code
- Resolved kernel test robot build warnings
v1 -> v2:
- Tested the bindings using 'make dt_binding_check'
- Fixed code style issues
- Resolved kernel test robot build warnings
- Replaced spin_lock_irqsave with raw_spin_lock
- Replaced magic number with macro
- Removed the realtek_intc_set_affinity function
James Tai (6):
dt-bindings: interrupt-controller: Add support for Realtek DHC SoCs
irqchip: Add interrupt controller support for Realtek DHC SoCs
irqchip: Introduce RTD1319 support using the Realtek common interrupt
controller driver
irqchip: Introduce RTD1319D support using the Realtek common interrupt
controller driver
irqchip: Introduce RTD1325 support using the Realtek common interrupt
controller driver
irqchip: Introduce RTD1619B support using the Realtek common interrupt
controller driver
.../interrupt-controller/realtek,intc.yaml | 131 +++++++++++
drivers/irqchip/Kconfig | 44 ++++
drivers/irqchip/Makefile | 5 +
drivers/irqchip/irq-realtek-intc-common.c | 211 ++++++++++++++++++
drivers/irqchip/irq-realtek-intc-common.h | 76 +++++++
drivers/irqchip/irq-realtek-rtd1319.c | 187 ++++++++++++++++
drivers/irqchip/irq-realtek-rtd1319d.c | 196 ++++++++++++++++
drivers/irqchip/irq-realtek-rtd1325.c | 196 ++++++++++++++++
drivers/irqchip/irq-realtek-rtd1619b.c | 186 +++++++++++++++
9 files changed, 1232 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/realtek,intc.yaml
create mode 100644 drivers/irqchip/irq-realtek-intc-common.c
create mode 100644 drivers/irqchip/irq-realtek-intc-common.h
create mode 100644 drivers/irqchip/irq-realtek-rtd1319.c
create mode 100644 drivers/irqchip/irq-realtek-rtd1319d.c
create mode 100644 drivers/irqchip/irq-realtek-rtd1325.c
create mode 100644 drivers/irqchip/irq-realtek-rtd1619b.c
--
2.25.1
Add the YAML documentation for Realtek DHC (Digital Home Center) SoCs.
Signed-off-by: James Tai <[email protected]>
---
CC: Thomas Gleixner <[email protected]>
CC: Marc Zyngier <[email protected]>
CC: Rob Herring <[email protected]>
CC: Krzysztof Kozlowski <[email protected]>
CC: Conor Dooley <[email protected]>
CC: [email protected]
CC: [email protected]
v3 to v4 change:
- Adjusted the allOf block to add constraints on the interrupts per variant
v2 to v3 change:
- Retested the bindings using the new version of the dtschema
- Fixed the order of property items
- Removed redundant files and replaced them with 'realtek,intc.yaml'
- Replaced 'interrupts-extended' with 'interrupts'
- Added a description for 'interrupts'
- Reduced the example code
v1 to v2 change:
- Tested the bindings using 'make dt_binding_check'
- Fixed code style issues
.../interrupt-controller/realtek,intc.yaml | 131 ++++++++++++++++++
1 file changed, 131 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/realtek,intc.yaml
diff --git a/Documentation/devicetree/bindings/interrupt-controller/realtek,intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/realtek,intc.yaml
new file mode 100644
index 000000000000..d3e4919850cc
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/realtek,intc.yaml
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/realtek,intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek DHC SoCs Interrupt Controller
+
+maintainers:
+ - James Tai <[email protected]>
+
+description:
+ This interrupt controller is a component of Realtek DHC (Digital Home Center)
+ SoCs and is designed to receive interrupts from peripheral devices.
+
+ Each DHC SoC has two sets of interrupt controllers, each capable of
+ handling up to 32 interrupts.
+
+properties:
+ compatible:
+ enum:
+ - realtek,rtd1319-intc-iso
+ - realtek,rtd1319-intc-misc
+ - realtek,rtd1319d-intc-iso
+ - realtek,rtd1319d-intc-misc
+ - realtek,rtd1325-intc-iso
+ - realtek,rtd1325-intc-misc
+ - realtek,rtd1619b-intc-iso
+ - realtek,rtd1619b-intc-misc
+
+ reg:
+ maxItems: 1
+
+ interrupt-controller: true
+
+ '#interrupt-cells':
+ const: 1
+
+ '#address-cells':
+ const: 0
+
+ interrupts:
+ minItems: 1
+ maxItems: 3
+ description:
+ Contains the GIC SPI IRQs mapped to the external interrupt lines.
+
+required:
+ - compatible
+ - reg
+ - interrupt-controller
+ - '#interrupt-cells'
+ - '#address-cells'
+ - interrupts
+
+additionalProperties: false
+
+allOf:
+ - $ref: /schemas/interrupt-controller.yaml#
+ - if:
+ properties:
+ compatible:
+ enum:
+ - realtek,rtd1319-intc-iso
+ then:
+ properties:
+ interrupts:
+ minItems: 1
+ items:
+ - description: isolation irqs
+ - description: rtc irq
+ - if:
+ properties:
+ compatible:
+ enum:
+ - realtek,rtd1319d-intc-iso
+ - realtek,rtd1325-intc-iso
+ - realtek,rtd1619b-intc-iso
+ then:
+ properties:
+ interrupts:
+ minItems: 1
+ items:
+ - description: isolation irqs
+ - description: watchdog irq
+ - if:
+ properties:
+ compatible:
+ enum:
+ - realtek,rtd1319-intc-misc
+ then:
+ properties:
+ interrupts:
+ minItems: 3
+ items:
+ - description: miscellaneous irqs
+ - description: watchdog irq
+ - description: uart1 irq
+ - description: uart2 irq
+ - if:
+ properties:
+ compatible:
+ enum:
+ - realtek,rtd1319d-intc-misc
+ - realtek,rtd1325-intc-misc
+ - realtek,rtd1619b-intc-misc
+ then:
+ properties:
+ interrupts:
+ minItems: 2
+ items:
+ - description: miscellaneous irqs
+ - description: uart1 irq
+ - description: uart2 irq
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ realtek_iso_intc: interrupt-controller@40 {
+ compatible = "realtek,rtd1319-intc-iso";
+ reg = <0x00 0x40>;
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ };
+...
--
2.25.1
Realtek DHC (Digital Home Center) SoCs share a common interrupt controller
design. This universal interrupt controller driver provides support for
various variants within the Realtek DHC SoC family.
Each DHC SoC features two sets of extended interrupt controllers, each
capable of handling up to 32 interrupts. These expansion controllers are
connected to the GIC (Generic Interrupt Controller).
Signed-off-by: James Tai <[email protected]>
---
CC: Thomas Gleixner <[email protected]>
CC: Marc Zyngier <[email protected]>
CC: [email protected]
v3 to v4 change:
- Adjusted the error path and label
- Added the 'irq_domain_remove' to the error path
- Removed the 'devm_kfree' from the error path
- Replaced the 'irq_of_parse_and_map' with 'of_irq_get'
- Replaced the 'raw_spin_lock' with 'raw_spin_lock_irqsave'
- Adjusted the return value of the 'realtek_intc_subset'
- Replaced the '~1' with macro 'CLEAN_INTC_STATUS'
- Improved code comments and description
- Fixed coding style issues
- Fixed the incorrect control register in mask and unmask functions
- Changed the 'EXPORT_SYMBOL' to the 'EXPORT_SYMBOL_GPL'
- Renamed the 'realtek_intc_subset_cfg' to 'realtek_intc_mask'
- Removed unused and unnecessary code
- Removed 'irq_enable' and 'irq_disable' callback
v2 to v3 change:
- Resolved kernel test robot build warnings
https://lore.kernel.org/r/[email protected]/
v1 to v2 change:
- Fixed code style issues
- Removed the realtek_intc_set_affinity funcation
- Replaced spin_lock_irqsave with raw_spin_lock
drivers/irqchip/Kconfig | 4 +
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-realtek-intc-common.c | 211 ++++++++++++++++++++++
drivers/irqchip/irq-realtek-intc-common.h | 76 ++++++++
4 files changed, 292 insertions(+)
create mode 100644 drivers/irqchip/irq-realtek-intc-common.c
create mode 100644 drivers/irqchip/irq-realtek-intc-common.h
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index f7149d0f3d45..267c3429b48d 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -218,6 +218,10 @@ config RDA_INTC
bool
select IRQ_DOMAIN
+config REALTEK_DHC_INTC
+ tristate
+ select IRQ_DOMAIN
+
config RENESAS_INTC_IRQPIN
bool "Renesas INTC External IRQ Pin Support" if COMPILE_TEST
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index ffd945fe71aa..f6774af7fde2 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_IRQ_MIPS_CPU) += irq-mips-cpu.o
obj-$(CONFIG_IXP4XX_IRQ) += irq-ixp4xx.o
obj-$(CONFIG_JCORE_AIC) += irq-jcore-aic.o
obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
+obj-$(CONFIG_REALTEK_DHC_INTC) += irq-realtek-intc-common.o
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
diff --git a/drivers/irqchip/irq-realtek-intc-common.c b/drivers/irqchip/irq-realtek-intc-common.c
new file mode 100644
index 000000000000..caff61730ff8
--- /dev/null
+++ b/drivers/irqchip/irq-realtek-intc-common.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek DHC SoCs interrupt controller driver
+ *
+ * Copyright (c) 2023 Realtek Semiconductor Corporation
+ */
+
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#include "irq-realtek-intc-common.h"
+
+static inline unsigned int realtek_intc_get_ints(struct realtek_intc_data *data)
+{
+ return readl(data->base + data->info->isr_offset);
+}
+
+static inline void realtek_intc_clear_ints_bit(struct realtek_intc_data *data, int bit)
+{
+ writel(BIT(bit) & CLEAN_INTC_STATUS, data->base + data->info->isr_offset);
+}
+
+static inline unsigned int realtek_intc_get_inte(struct realtek_intc_data *data)
+{
+ unsigned int val;
+
+ val = readl(data->base + data->info->scpu_int_en_offset);
+
+ return val;
+}
+
+static void realtek_intc_handler(struct irq_desc *desc)
+{
+ struct realtek_intc_subset_data *subset_data = irq_desc_get_handler_data(desc);
+ struct realtek_intc_data *data = subset_data->common;
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ u32 ints, inte, mask;
+ int irq;
+
+ chained_irq_enter(chip, desc);
+
+ ints = realtek_intc_get_ints(data) & subset_data->subset_mask->ints_mask;
+ inte = realtek_intc_get_inte(data);
+
+ while (ints) {
+ irq = __ffs(ints);
+ ints &= ~BIT(irq);
+
+ mask = data->info->isr_to_scpu_int_en_mask[irq];
+ if (mask != IRQ_ALWAYS_ENABLED && !(inte & mask))
+ continue;
+
+ generic_handle_irq(irq_find_mapping(data->domain, irq));
+ realtek_intc_clear_ints_bit(data, irq);
+ }
+
+ chained_irq_exit(chip, desc);
+}
+
+static void realtek_intc_mask_irq(struct irq_data *data)
+{
+ struct realtek_intc_data *intc_data = irq_data_get_irq_chip_data(data);
+ unsigned long lock_flags;
+ u32 scpu_int_en, mask;
+
+ mask = intc_data->info->isr_to_scpu_int_en_mask[data->hwirq];
+ if (!mask)
+ return;
+
+ raw_spin_lock_irqsave(&intc_data->lock, lock_flags);
+ scpu_int_en = readl(intc_data->base + intc_data->info->scpu_int_en_offset);
+ scpu_int_en &= ~mask;
+ writel(scpu_int_en, intc_data->base + intc_data->info->scpu_int_en_offset);
+ raw_spin_unlock_irqrestore(&intc_data->lock, lock_flags);
+}
+
+static void realtek_intc_unmask_irq(struct irq_data *data)
+{
+ struct realtek_intc_data *intc_data = irq_data_get_irq_chip_data(data);
+ unsigned long lock_flags;
+ u32 scpu_int_en, mask;
+
+ mask = intc_data->info->isr_to_scpu_int_en_mask[data->hwirq];
+ if (!mask)
+ return;
+
+ raw_spin_lock_irqsave(&intc_data->lock, lock_flags);
+ scpu_int_en = readl(intc_data->base + intc_data->info->scpu_int_en_offset);
+ scpu_int_en |= mask;
+ writel(scpu_int_en, intc_data->base + intc_data->info->scpu_int_en_offset);
+ raw_spin_unlock_irqrestore(&intc_data->lock, lock_flags);
+}
+
+static struct irq_chip realtek_intc_chip = {
+ .name = "realtek-intc",
+ .irq_mask = realtek_intc_mask_irq,
+ .irq_unmask = realtek_intc_unmask_irq,
+};
+
+static int realtek_intc_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+ struct realtek_intc_data *data = d->host_data;
+
+ irq_set_chip_and_handler(irq, &realtek_intc_chip, handle_level_irq);
+ irq_set_chip_data(irq, data);
+ irq_set_probe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops realtek_intc_domain_ops = {
+ .xlate = irq_domain_xlate_onecell,
+ .map = realtek_intc_domain_map,
+};
+
+static int realtek_intc_subset(struct device_node *node, struct realtek_intc_data *data, int index)
+{
+ struct realtek_intc_subset_data *subset_data = &data->subset_data[index];
+ const struct realtek_intc_mask *mask = &data->info->subset_mask[index];
+ int irq;
+
+ irq = of_irq_get(node, index);
+ if (irq <= 0)
+ return -EINVAL;
+
+ subset_data->common = data;
+ subset_data->subset_mask = mask;
+ subset_data->parent_irq = irq;
+ irq_set_chained_handler_and_data(irq, realtek_intc_handler, subset_data);
+
+ return irq;
+}
+
+int realtek_intc_suspend(struct device *dev)
+{
+ struct realtek_intc_data *data = dev_get_drvdata(dev);
+ const struct realtek_intc_info *info = data->info;
+
+ data->saved_en = readl(data->base + info->scpu_int_en_offset);
+
+ writel(DISABLE_INTC, data->base + info->scpu_int_en_offset);
+ writel(CLEAN_INTC_STATUS, data->base + info->isr_offset);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(realtek_intc_suspend);
+
+int realtek_intc_resume(struct device *dev)
+{
+ struct realtek_intc_data *data = dev_get_drvdata(dev);
+ const struct realtek_intc_info *info = data->info;
+
+ writel(CLEAN_INTC_STATUS, data->base + info->isr_offset);
+ writel(data->saved_en, data->base + info->scpu_int_en_offset);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(realtek_intc_resume);
+
+int realtek_intc_probe(struct platform_device *pdev, const struct realtek_intc_info *info)
+{
+ struct realtek_intc_data *data;
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ int ret, i;
+
+ data = devm_kzalloc(dev, struct_size(data, subset_data, info->subset_num), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->base = of_iomap(node, 0);
+ if (!data->base)
+ goto iomap_cleanup;
+
+ data->info = info;
+
+ raw_spin_lock_init(&data->lock);
+
+ data->domain = irq_domain_add_linear(node, 32, &realtek_intc_domain_ops, data);
+ if (!data->domain)
+ goto iomap_cleanup;
+
+ data->subset_data_num = info->subset_num;
+ for (i = 0; i < info->subset_num; i++) {
+ ret = realtek_intc_subset(node, data, i);
+ if (ret <= 0) {
+ dev_err(dev, "failed to init subset %d: %d", i, ret);
+ goto irq_domain_cleanup;
+ }
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+
+irq_domain_cleanup:
+ if (data->domain)
+ irq_domain_remove(data->domain);
+
+iomap_cleanup:
+ if (data->base)
+ iounmap(data->base);
+
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(realtek_intc_probe);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek DHC SoC Interrupt Controller Driver");
diff --git a/drivers/irqchip/irq-realtek-intc-common.h b/drivers/irqchip/irq-realtek-intc-common.h
new file mode 100644
index 000000000000..0af989c09693
--- /dev/null
+++ b/drivers/irqchip/irq-realtek-intc-common.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2023 Realtek Semiconductor Corporation
+ */
+
+#ifndef _IRQ_REALTEK_COMMON_H
+#define _IRQ_REALTEK_COMMON_H
+
+#include <linux/bits.h>
+#include <linux/limits.h>
+#include <linux/hwspinlock.h>
+
+/**
+ * realtek_intc_mask - The mask of an interrupt subset.
+ * @ints_mask: The interrupt mask.
+ */
+struct realtek_intc_mask {
+ u32 ints_mask;
+};
+
+/**
+ * realtek_intc_info - Information about the interrupt controller.
+ * @subset_mask: The masks of the interrupt subsets.
+ * @subset_num: The number of interrupt subsets.
+ * @isr_offset: The offset of the interrupt status register.
+ * @scpu_int_en_offset: The offset of the interrupt enable register.
+ */
+struct realtek_intc_info {
+ const struct realtek_intc_mask *subset_mask;
+ int subset_num;
+ unsigned int isr_offset;
+ unsigned int scpu_int_en_offset;
+ const u32 *isr_to_scpu_int_en_mask;
+};
+
+/**
+ * realtek_intc_subset_data - The data of interrupt subset.
+ * @subset_mask: The subset interrupt masks.
+ * @common: The configuration data of interrupt controller.
+ * @parent_irq: The subset interrupt source.
+ */
+struct realtek_intc_subset_data {
+ const struct realtek_intc_mask *subset_mask;
+ struct realtek_intc_data *common;
+ int parent_irq;
+};
+
+/**
+ * realtek_intc_data - The configuration data for interrupt controller driver.
+ * @base: The base address of interrupt register.
+ * @info: The Information of the interrupt controller.
+ * @domain: Interrupt domain of the interrupt controller.
+ * @lock: The lock of the interrupt controller.
+ * @saved_en: Stores the state of the interrupt enable.
+ * @subset_data_num: The number of entries in the interrupt subset data.
+ * @subset_data: The data for the interrupt subset.
+ */
+struct realtek_intc_data {
+ void __iomem *base;
+ const struct realtek_intc_info *info;
+ struct irq_domain *domain;
+ struct raw_spinlock lock;
+ unsigned int saved_en;
+ int subset_data_num;
+ struct realtek_intc_subset_data subset_data[];
+};
+
+#define IRQ_ALWAYS_ENABLED U32_MAX
+#define DISABLE_INTC (0)
+#define CLEAN_INTC_STATUS GENMASK(31, 1)
+
+int realtek_intc_probe(struct platform_device *pdev, const struct realtek_intc_info *info);
+int realtek_intc_suspend(struct device *dev);
+int realtek_intc_resume(struct device *dev);
+
+#endif /* _IRQ_REALTEK_COMMON_H */
--
2.25.1
Add support for the RTD1319 platform.
Signed-off-by: James Tai <[email protected]>
---
CC: Thomas Gleixner <[email protected]>
CC: Marc Zyngier <[email protected]>
CC: [email protected]
v3 to v4 change:
- Replaced the 'core_initcall' with 'module_init'
- Removed redundant header files
- Moved the function of suspend and resume to common code
- Improved the description of config
v2 to v3 change:
- Unchanged
v1 to v2 change:
- Resolved kernel test robot build warnings
- Replaced magic number with macro
- Fixed code style issues
drivers/irqchip/Kconfig | 10 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-realtek-rtd1319.c | 187 ++++++++++++++++++++++++++
3 files changed, 198 insertions(+)
create mode 100644 drivers/irqchip/irq-realtek-rtd1319.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 267c3429b48d..b17006ff38c4 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -222,6 +222,16 @@ config REALTEK_DHC_INTC
tristate
select IRQ_DOMAIN
+config REALTEK_RTD1319_INTC
+ tristate "Realtek RTD1319 interrupt controller"
+ select REALTEK_DHC_INTC
+ help
+ Enable support for the Realtek RTD1319 SoC Interrupt Controller.
+ Each Realtek DHC SoC has two sets of interrupt controllers, each
+ capable of handling up to 32 interrupts.
+
+ If unsure, say N.
+
config RENESAS_INTC_IRQPIN
bool "Renesas INTC External IRQ Pin Support" if COMPILE_TEST
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f6774af7fde2..6a2650b0a924 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_IXP4XX_IRQ) += irq-ixp4xx.o
obj-$(CONFIG_JCORE_AIC) += irq-jcore-aic.o
obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
obj-$(CONFIG_REALTEK_DHC_INTC) += irq-realtek-intc-common.o
+obj-$(CONFIG_REALTEK_RTD1319_INTC) += irq-realtek-rtd1319.o
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
diff --git a/drivers/irqchip/irq-realtek-rtd1319.c b/drivers/irqchip/irq-realtek-rtd1319.c
new file mode 100644
index 000000000000..2d1f949f6dba
--- /dev/null
+++ b/drivers/irqchip/irq-realtek-rtd1319.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1319 interrupt controller driver
+ *
+ * Copyright (c) 2023 Realtek Semiconductor Corporation
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "irq-realtek-intc-common.h"
+
+#define ISO_NORMAL_MASK 0xffffcffe
+#define ISO_RTC_MASK 0x00003001
+#define MISC_NMI_WDT_MASK 0x00000004
+#define MISC_NORMAL_MASK 0xffffc0d2
+#define MISC_UART1_MASK 0x00000028
+#define MISC_UART2_MASK 0x00002100
+
+#define ISO_ISR_EN_OFFSET 0x40
+#define ISO_ISR_OFFSET 0
+#define ISO_ISR_UMSK_OFFSET 0x4
+#define MISC_ISR_EN_OFFSET 0x80
+#define MISC_ISR_OFFSET 0xc
+#define MISC_ISR_UMSK_OFFSET 0x8
+
+enum rtd1319_iso_isr_bits {
+ RTD1319_ISO_ISR_TC3_SHIFT = 1,
+ RTD1319_ISO_ISR_UR0_SHIFT = 2,
+ RTD1319_ISO_ISR_LSADC0_SHIFT = 3,
+ RTD1319_ISO_ISR_IRDA_SHIFT = 5,
+ RTD1319_ISO_ISR_SPI1_SHIFT = 6,
+ RTD1319_ISO_ISR_WDOG_NMI_SHIFT = 7,
+ RTD1319_ISO_ISR_I2C0_SHIFT = 8,
+ RTD1319_ISO_ISR_TC4_SHIFT = 9,
+ RTD1319_ISO_ISR_TC7_SHIFT = 10,
+ RTD1319_ISO_ISR_I2C1_SHIFT = 11,
+ RTD1319_ISO_ISR_RTC_HSEC_SHIFT = 12,
+ RTD1319_ISO_ISR_RTC_ALARM_SHIFT = 13,
+ RTD1319_ISO_ISR_GPIOA_SHIFT = 19,
+ RTD1319_ISO_ISR_GPIODA_SHIFT = 20,
+ RTD1319_ISO_ISR_ISO_MISC_SHIFT = 21,
+ RTD1319_ISO_ISR_CBUS_SHIFT = 22,
+ RTD1319_ISO_ISR_ETN_SHIFT = 23,
+ RTD1319_ISO_ISR_USB_HOST_SHIFT = 24,
+ RTD1319_ISO_ISR_USB_U3_DRD_SHIFT = 25,
+ RTD1319_ISO_ISR_USB_U2_DRD_SHIFT = 26,
+ RTD1319_ISO_ISR_PORB_HV_SHIFT = 28,
+ RTD1319_ISO_ISR_PORB_DV_SHIFT = 29,
+ RTD1319_ISO_ISR_PORB_AV_SHIFT = 30,
+ RTD1319_ISO_ISR_I2C1_REQ_SHIFT = 31,
+};
+
+static const u32 rtd1319_iso_isr_to_scpu_int_en_mask[32] = {
+ [RTD1319_ISO_ISR_SPI1_SHIFT] = BIT(1),
+ [RTD1319_ISO_ISR_UR0_SHIFT] = BIT(2),
+ [RTD1319_ISO_ISR_LSADC0_SHIFT] = BIT(3),
+ [RTD1319_ISO_ISR_IRDA_SHIFT] = BIT(5),
+ [RTD1319_ISO_ISR_I2C0_SHIFT] = BIT(8),
+ [RTD1319_ISO_ISR_I2C1_SHIFT] = BIT(11),
+ [RTD1319_ISO_ISR_RTC_HSEC_SHIFT] = BIT(12),
+ [RTD1319_ISO_ISR_RTC_ALARM_SHIFT] = BIT(13),
+ [RTD1319_ISO_ISR_GPIOA_SHIFT] = BIT(19),
+ [RTD1319_ISO_ISR_GPIODA_SHIFT] = BIT(20),
+ [RTD1319_ISO_ISR_PORB_HV_SHIFT] = BIT(28),
+ [RTD1319_ISO_ISR_PORB_DV_SHIFT] = BIT(29),
+ [RTD1319_ISO_ISR_PORB_AV_SHIFT] = BIT(30),
+ [RTD1319_ISO_ISR_I2C1_REQ_SHIFT] = BIT(31),
+};
+
+enum rtd1319_misc_isr_bits {
+ RTD1319_ISR_WDOG_NMI_SHIFT = 2,
+ RTD1319_ISR_UR1_SHIFT = 3,
+ RTD1319_ISR_TC5_SHIFT = 4,
+ RTD1319_ISR_UR1_TO_SHIFT = 5,
+ RTD1319_ISR_TC0_SHIFT = 6,
+ RTD1319_ISR_TC1_SHIFT = 7,
+ RTD1319_ISR_UR2_SHIFT = 8,
+ RTD1319_ISR_RTC_HSEC_SHIFT = 9,
+ RTD1319_ISR_RTC_MIN_SHIFT = 10,
+ RTD1319_ISR_RTC_HOUR_SHIFT = 11,
+ RTD1319_ISR_RTC_DATE_SHIFT = 12,
+ RTD1319_ISR_UR2_TO_SHIFT = 13,
+ RTD1319_ISR_I2C5_SHIFT = 14,
+ RTD1319_ISR_I2C3_SHIFT = 23,
+ RTD1319_ISR_SC0_SHIFT = 24,
+ RTD1319_ISR_SC1_SHIFT = 25,
+ RTD1319_ISR_SPI_SHIFT = 27,
+ RTD1319_ISR_FAN_SHIFT = 29,
+};
+
+static const u32 rtd1319_misc_isr_to_scpu_int_en_mask[32] = {
+ [RTD1319_ISR_UR1_SHIFT] = BIT(3),
+ [RTD1319_ISR_UR1_TO_SHIFT] = BIT(5),
+ [RTD1319_ISR_UR2_TO_SHIFT] = BIT(6),
+ [RTD1319_ISR_UR2_SHIFT] = BIT(7),
+ [RTD1319_ISR_RTC_MIN_SHIFT] = BIT(10),
+ [RTD1319_ISR_RTC_HOUR_SHIFT] = BIT(11),
+ [RTD1319_ISR_RTC_DATE_SHIFT] = BIT(12),
+ [RTD1319_ISR_I2C5_SHIFT] = BIT(14),
+ [RTD1319_ISR_SC0_SHIFT] = BIT(24),
+ [RTD1319_ISR_SC1_SHIFT] = BIT(25),
+ [RTD1319_ISR_SPI_SHIFT] = BIT(27),
+ [RTD1319_ISR_I2C3_SHIFT] = BIT(28),
+ [RTD1319_ISR_FAN_SHIFT] = BIT(29),
+ [RTD1319_ISR_WDOG_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+};
+
+static struct realtek_intc_mask rtd1319_intc_iso_cfgs[] = {
+ { ISO_NORMAL_MASK, },
+ { ISO_RTC_MASK, },
+};
+
+static const struct realtek_intc_info rtd1319_intc_iso_info = {
+ .isr_offset = ISO_ISR_OFFSET,
+ .scpu_int_en_offset = ISO_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1319_iso_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1319_intc_iso_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1319_intc_iso_cfgs),
+};
+
+static struct realtek_intc_mask rtd1319_intc_misc_cfgs[] = {
+ { MISC_NORMAL_MASK, },
+ { MISC_NMI_WDT_MASK, },
+ { MISC_UART1_MASK, },
+ { MISC_UART2_MASK, },
+};
+
+static const struct realtek_intc_info rtd1319_intc_misc_info = {
+ .isr_offset = MISC_ISR_OFFSET,
+ .scpu_int_en_offset = MISC_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1319_misc_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1319_intc_misc_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1319_intc_misc_cfgs),
+};
+
+static const struct of_device_id realtek_intc_rtd1319_dt_matches[] = {
+ {
+ .compatible = "realtek,rtd1319-intc-iso",
+ .data = &rtd1319_intc_iso_info,
+ }, {
+ .compatible = "realtek,rtd1319-intc-misc",
+ .data = &rtd1319_intc_misc_info,
+ },
+ { /* sentinel */ }
+};
+
+static const struct dev_pm_ops realtek_intc_rtd1319_pm_ops = {
+ .suspend_noirq = realtek_intc_suspend,
+ .resume_noirq = realtek_intc_resume,
+};
+
+static int rtd1319_intc_probe(struct platform_device *pdev)
+{
+ const struct realtek_intc_info *info;
+
+ info = of_device_get_match_data(&pdev->dev);
+ if (!info)
+ return -EINVAL;
+
+ return realtek_intc_probe(pdev, info);
+}
+
+static struct platform_driver realtek_intc_rtd1319_driver = {
+ .probe = rtd1319_intc_probe,
+ .driver = {
+ .name = "realtek_intc_rtd1319",
+ .of_match_table = realtek_intc_rtd1319_dt_matches,
+ .suppress_bind_attrs = true,
+ .pm = &realtek_intc_rtd1319_pm_ops,
+ },
+};
+
+static int __init realtek_intc_rtd1319_init(void)
+{
+ return platform_driver_register(&realtek_intc_rtd1319_driver);
+}
+module_init(realtek_intc_rtd1319_init);
+
+static void __exit realtek_intc_rtd1319_exit(void)
+{
+ platform_driver_unregister(&realtek_intc_rtd1319_driver);
+}
+module_exit(realtek_intc_rtd1319_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek RTD1319 Interrupt Controller Driver");
--
2.25.1
Add support for the RTD1319D platform.
Signed-off-by: James Tai <[email protected]>
---
CC: Thomas Gleixner <[email protected]>
CC: Marc Zyngier <[email protected]>
CC: [email protected]
v3 to v4 change:
- Replaced the 'core_initcall' with 'module_init'
- Removed redundant header files
- Moved the function of suspend and resume to common code
- Improved the description of config
v2 to v3 change:
- Unchanged
v1 to v2 change:
- Resolved kernel test robot build warnings
- Replaced magic number with macro
- Fixed code style issues
drivers/irqchip/Kconfig | 10 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-realtek-rtd1319d.c | 196 +++++++++++++++++++++++++
3 files changed, 207 insertions(+)
create mode 100644 drivers/irqchip/irq-realtek-rtd1319d.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index b17006ff38c4..e34312ef7cd4 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -232,6 +232,16 @@ config REALTEK_RTD1319_INTC
If unsure, say N.
+config REALTEK_RTD1319D_INTC
+ tristate "Realtek RTD1319D interrupt controller"
+ select REALTEK_DHC_INTC
+ help
+ Enable support for the Realtek RTD1319D SoC Interrupt Controller.
+ Each Realtek DHC SoC has two sets of interrupt controllers, each
+ capable of handling up to 32 interrupts.
+
+ If unsure, say N.
+
config RENESAS_INTC_IRQPIN
bool "Renesas INTC External IRQ Pin Support" if COMPILE_TEST
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 6a2650b0a924..c8adaed4c1b2 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_JCORE_AIC) += irq-jcore-aic.o
obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
obj-$(CONFIG_REALTEK_DHC_INTC) += irq-realtek-intc-common.o
obj-$(CONFIG_REALTEK_RTD1319_INTC) += irq-realtek-rtd1319.o
+obj-$(CONFIG_REALTEK_RTD1319D_INTC) += irq-realtek-rtd1319d.o
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
diff --git a/drivers/irqchip/irq-realtek-rtd1319d.c b/drivers/irqchip/irq-realtek-rtd1319d.c
new file mode 100644
index 000000000000..8a18adeedc67
--- /dev/null
+++ b/drivers/irqchip/irq-realtek-rtd1319d.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1319D interrupt controller driver
+ *
+ * Copyright (c) 2023 Realtek Semiconductor Corporation
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "irq-realtek-intc-common.h"
+
+#define ISO_NMI_WDT_MASK 0x08008090
+#define ISO_NORMAL_MASK 0xf7ff7f6e
+#define MISC_NORMAL_MASK 0xffe0ded6
+#define MISC_UART1_MASK 0x00000028
+#define MISC_UART2_MASK 0x00002100
+
+#define ISO_ISR_EN_OFFSET 0x40
+#define ISO_ISR_OFFSET 0
+#define ISO_ISR_UMSK_OFFSET 0x4
+#define MISC_ISR_EN_OFFSET 0x80
+#define MISC_ISR_OFFSET 0xc
+#define MISC_ISR_UMSK_OFFSET 0x8
+
+enum rtd1319d_iso_isr_bits {
+ RTD1319D_ISO_ISR_TC3_SHIFT = 1,
+ RTD1319D_ISO_ISR_UR0_SHIFT = 2,
+ RTD1319D_ISO_ISR_LSADC0_SHIFT = 3,
+ RTD1319D_ISO_ISR_WDOG1_NMI_SHIFT = 4,
+ RTD1319D_ISO_ISR_IRDA_SHIFT = 5,
+ RTD1319D_ISO_ISR_SPI1_SHIFT = 6,
+ RTD1319D_ISO_ISR_WDOG2_NMI_SHIFT = 7,
+ RTD1319D_ISO_ISR_I2C0_SHIFT = 8,
+ RTD1319D_ISO_ISR_TC4_SHIFT = 9,
+ RTD1319D_ISO_ISR_TC7_SHIFT = 10,
+ RTD1319D_ISO_ISR_I2C1_SHIFT = 11,
+ RTD1319D_ISO_ISR_HIFI_WAKEUP_SHIFT = 14,
+ RTD1319D_ISO_ISR_WDOG4_NMI_SHIFT = 15,
+ RTD1319D_ISO_ISR_TC8_SHIFT = 16,
+ RTD1319D_ISO_ISR_VFD_SHIFT = 17,
+ RTD1319D_ISO_ISR_VTC_SHIFT = 18,
+ RTD1319D_ISO_ISR_GPIOA_SHIFT = 19,
+ RTD1319D_ISO_ISR_GPIODA_SHIFT = 20,
+ RTD1319D_ISO_ISR_ISO_MISC_SHIFT = 21,
+ RTD1319D_ISO_ISR_CBUS_SHIFT = 22,
+ RTD1319D_ISO_ISR_ETN_SHIFT = 23,
+ RTD1319D_ISO_ISR_USB_HOST_SHIFT = 24,
+ RTD1319D_ISO_ISR_USB_U3_DRD_SHIFT = 25,
+ RTD1319D_ISO_ISR_USB_U2_DRD_SHIFT = 26,
+ RTD1319D_ISO_ISR_WDOG3_NMI_SHIFT = 27,
+ RTD1319D_ISO_ISR_PORB_HV_CEN_SHIFT = 28,
+ RTD1319D_ISO_ISR_PORB_DV_CEN_SHIFT = 29,
+ RTD1319D_ISO_ISR_PORB_AV_CEN_SHIFT = 30,
+ RTD1319D_ISO_ISR_I2C1_REQ_SHIFT = 31,
+};
+
+static const u32 rtd1319d_iso_isr_to_scpu_int_en_mask[32] = {
+ [RTD1319D_ISO_ISR_SPI1_SHIFT] = BIT(1),
+ [RTD1319D_ISO_ISR_UR0_SHIFT] = BIT(2),
+ [RTD1319D_ISO_ISR_LSADC0_SHIFT] = BIT(3),
+ [RTD1319D_ISO_ISR_IRDA_SHIFT] = BIT(5),
+ [RTD1319D_ISO_ISR_I2C0_SHIFT] = BIT(8),
+ [RTD1319D_ISO_ISR_I2C1_SHIFT] = BIT(11),
+ [RTD1319D_ISO_ISR_VFD_SHIFT] = BIT(17),
+ [RTD1319D_ISO_ISR_GPIOA_SHIFT] = BIT(19),
+ [RTD1319D_ISO_ISR_GPIODA_SHIFT] = BIT(20),
+ [RTD1319D_ISO_ISR_PORB_HV_CEN_SHIFT] = BIT(28),
+ [RTD1319D_ISO_ISR_PORB_DV_CEN_SHIFT] = BIT(29),
+ [RTD1319D_ISO_ISR_PORB_AV_CEN_SHIFT] = BIT(30),
+ [RTD1319D_ISO_ISR_I2C1_REQ_SHIFT] = BIT(31),
+ [RTD1319D_ISO_ISR_WDOG1_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1319D_ISO_ISR_WDOG2_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1319D_ISO_ISR_WDOG3_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1319D_ISO_ISR_WDOG4_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+};
+
+enum rtd1319d_misc_isr_bits {
+ RTD1319D_ISR_UR1_SHIFT = 3,
+ RTD1319D_ISR_TC5_SHIFT = 4,
+ RTD1319D_ISR_UR1_TO_SHIFT = 5,
+ RTD1319D_ISR_TC0_SHIFT = 6,
+ RTD1319D_ISR_TC1_SHIFT = 7,
+ RTD1319D_ISR_UR2_SHIFT = 8,
+ RTD1319D_ISR_UR2_TO_SHIFT = 13,
+ RTD1319D_ISR_I2C5_SHIFT = 14,
+ RTD1319D_ISR_I2C4_SHIFT = 15,
+ RTD1319D_ISR_DRTC_HSEC_SHIFT = 16,
+ RTD1319D_ISR_DRTC_MIN_SHIFT = 17,
+ RTD1319D_ISR_DRTC_HOUR_SHIFT = 18,
+ RTD1319D_ISR_DRTC_DATE_SHIFT = 19,
+ RTD1319D_ISR_DRTC_ALARM_SHIFT = 20,
+ RTD1319D_ISR_I2C3_SHIFT = 23,
+ RTD1319D_ISR_SC0_SHIFT = 24,
+ RTD1319D_ISR_SC1_SHIFT = 25,
+ RTD1319D_ISR_SPI_SHIFT = 27,
+ RTD1319D_ISR_FAN_SHIFT = 29,
+};
+
+static const u32 rtd1319d_misc_isr_to_scpu_int_en_mask[32] = {
+ [RTD1319D_ISR_UR1_SHIFT] = BIT(3),
+ [RTD1319D_ISR_UR1_TO_SHIFT] = BIT(5),
+ [RTD1319D_ISR_UR2_TO_SHIFT] = BIT(6),
+ [RTD1319D_ISR_UR2_SHIFT] = BIT(7),
+ [RTD1319D_ISR_I2C5_SHIFT] = BIT(14),
+ [RTD1319D_ISR_I2C4_SHIFT] = BIT(15),
+ [RTD1319D_ISR_DRTC_HSEC_SHIFT] = BIT(16),
+ [RTD1319D_ISR_DRTC_MIN_SHIFT] = BIT(17),
+ [RTD1319D_ISR_DRTC_HOUR_SHIFT] = BIT(18),
+ [RTD1319D_ISR_DRTC_DATE_SHIFT] = BIT(19),
+ [RTD1319D_ISR_DRTC_ALARM_SHIFT] = BIT(20),
+ [RTD1319D_ISR_SC0_SHIFT] = BIT(24),
+ [RTD1319D_ISR_SC1_SHIFT] = BIT(25),
+ [RTD1319D_ISR_SPI_SHIFT] = BIT(27),
+ [RTD1319D_ISR_I2C3_SHIFT] = BIT(28),
+ [RTD1319D_ISR_FAN_SHIFT] = BIT(29),
+};
+
+static struct realtek_intc_mask rtd1319d_intc_iso_cfgs[] = {
+ { ISO_NORMAL_MASK, },
+ { ISO_NMI_WDT_MASK, },
+};
+
+static const struct realtek_intc_info rtd1319d_intc_iso_info = {
+ .isr_offset = ISO_ISR_OFFSET,
+ .scpu_int_en_offset = ISO_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1319d_iso_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1319d_intc_iso_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1319d_intc_iso_cfgs),
+};
+
+static struct realtek_intc_mask rtd1319d_intc_misc_cfgs[] = {
+ { MISC_NORMAL_MASK, },
+ { MISC_UART1_MASK, },
+ { MISC_UART2_MASK, },
+};
+
+static const struct realtek_intc_info rtd1319d_intc_misc_info = {
+ .isr_offset = MISC_ISR_OFFSET,
+ .scpu_int_en_offset = MISC_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1319d_misc_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1319d_intc_misc_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1319d_intc_misc_cfgs),
+};
+
+static const struct of_device_id realtek_intc_rtd1319d_dt_matches[] = {
+ {
+ .compatible = "realtek,rtd1319d-intc-iso",
+ .data = &rtd1319d_intc_iso_info,
+ }, {
+ .compatible = "realtek,rtd1319d-intc-misc",
+ .data = &rtd1319d_intc_misc_info,
+ },
+ { /* sentinel */ }
+};
+
+static const struct dev_pm_ops realtek_intc_rtd1319d_pm_ops = {
+ .suspend_noirq = realtek_intc_suspend,
+ .resume_noirq = realtek_intc_resume,
+};
+
+static int rtd1319d_intc_probe(struct platform_device *pdev)
+{
+ const struct realtek_intc_info *info;
+
+ info = of_device_get_match_data(&pdev->dev);
+ if (!info)
+ return -EINVAL;
+
+ return realtek_intc_probe(pdev, info);
+}
+
+static struct platform_driver realtek_intc_rtd1319d_driver = {
+ .probe = rtd1319d_intc_probe,
+ .driver = {
+ .name = "realtek_intc_rtd1319d",
+ .of_match_table = realtek_intc_rtd1319d_dt_matches,
+ .suppress_bind_attrs = true,
+ .pm = &realtek_intc_rtd1319d_pm_ops,
+ },
+};
+
+static int __init realtek_intc_rtd1319d_init(void)
+{
+ return platform_driver_register(&realtek_intc_rtd1319d_driver);
+}
+module_init(realtek_intc_rtd1319d_init);
+
+static void __exit realtek_intc_rtd1319d_exit(void)
+{
+ platform_driver_unregister(&realtek_intc_rtd1319d_driver);
+}
+module_exit(realtek_intc_rtd1319d_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek RTD1319D Interrupt Controller Driver");
--
2.25.1
Add support for the RTD1325 platform.
Signed-off-by: James Tai <[email protected]>
---
CC: Thomas Gleixner <[email protected]>
CC: Marc Zyngier <[email protected]>
CC: [email protected]
v3 to v4 change:
- Replaced the 'core_initcall' with 'module_init'
- Removed redundant header files
- Moved the function of suspend and resume to common code
- Improved the description of config
v2 to v3 change:
- Unchanged
v1 to v2 change:
- Resolved kernel test robot build warnings
- Replaced magic number with macro
- Fixed code style issues
drivers/irqchip/Kconfig | 10 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-realtek-rtd1325.c | 196 ++++++++++++++++++++++++++
3 files changed, 207 insertions(+)
create mode 100644 drivers/irqchip/irq-realtek-rtd1325.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index e34312ef7cd4..9354445ea0bb 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -242,6 +242,16 @@ config REALTEK_RTD1319D_INTC
If unsure, say N.
+config REALTEK_RTD1325_INTC
+ tristate "Realtek RTD1325 interrupt controller"
+ select REALTEK_DHC_INTC
+ help
+ Enable support for the Realtek RTD1325 SoC Interrupt Controller.
+ Each Realtek DHC SoC has two sets of interrupt controllers, each
+ capable of handling up to 32 interrupts.
+
+ If unsure, say N.
+
config RENESAS_INTC_IRQPIN
bool "Renesas INTC External IRQ Pin Support" if COMPILE_TEST
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c8adaed4c1b2..eaa12928d60b 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_RDA_INTC) += irq-rda-intc.o
obj-$(CONFIG_REALTEK_DHC_INTC) += irq-realtek-intc-common.o
obj-$(CONFIG_REALTEK_RTD1319_INTC) += irq-realtek-rtd1319.o
obj-$(CONFIG_REALTEK_RTD1319D_INTC) += irq-realtek-rtd1319d.o
+obj-$(CONFIG_REALTEK_RTD1325_INTC) += irq-realtek-rtd1325.o
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
diff --git a/drivers/irqchip/irq-realtek-rtd1325.c b/drivers/irqchip/irq-realtek-rtd1325.c
new file mode 100644
index 000000000000..c488008c46c1
--- /dev/null
+++ b/drivers/irqchip/irq-realtek-rtd1325.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1325 interrupt controller driver
+ *
+ * Copyright (c) 2023 Realtek Semiconductor Corporation
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "irq-realtek-intc-common.h"
+
+#define ISO_NMI_WDT_MASK 0x08008090
+#define ISO_NORMAL_MASK 0xf7ff7f6e
+#define MISC_NORMAL_MASK 0xffe0ded6
+#define MISC_UART1_MASK 0x00000028
+#define MISC_UART2_MASK 0x00002100
+
+#define ISO_ISR_EN_OFFSET 0x40
+#define ISO_ISR_OFFSET 0
+#define ISO_ISR_UMSK_OFFSET 0x4
+#define MISC_ISR_EN_OFFSET 0x80
+#define MISC_ISR_OFFSET 0xc
+#define MISC_ISR_UMSK_OFFSET 0x8
+
+enum rtd1325_iso_isr_bits {
+ RTD1325_ISO_ISR_TC3_SHIFT = 1,
+ RTD1325_ISO_ISR_UR0_SHIFT = 2,
+ RTD1325_ISO_ISR_LSADC0_SHIFT = 3,
+ RTD1325_ISO_ISR_WDOG1_NMI_SHIFT = 4,
+ RTD1325_ISO_ISR_IRDA_SHIFT = 5,
+ RTD1325_ISO_ISR_SPI1_SHIFT = 6,
+ RTD1325_ISO_ISR_WDOG2_NMI_SHIFT = 7,
+ RTD1325_ISO_ISR_I2C0_SHIFT = 8,
+ RTD1325_ISO_ISR_TC4_SHIFT = 9,
+ RTD1325_ISO_ISR_TC7_SHIFT = 10,
+ RTD1325_ISO_ISR_I2C1_SHIFT = 11,
+ RTD1325_ISO_ISR_HIFI_WAKEUP_SHIFT = 14,
+ RTD1325_ISO_ISR_WDOG4_NMI_SHIFT = 15,
+ RTD1325_ISO_ISR_TC8_SHIFT = 16,
+ RTD1325_ISO_ISR_VFD_SHIFT = 17,
+ RTD1325_ISO_ISR_VTC_SHIFT = 18,
+ RTD1325_ISO_ISR_GPIOA_SHIFT = 19,
+ RTD1325_ISO_ISR_GPIODA_SHIFT = 20,
+ RTD1325_ISO_ISR_ISO_MISC_SHIFT = 21,
+ RTD1325_ISO_ISR_CBUS_SHIFT = 22,
+ RTD1325_ISO_ISR_ETN_SHIFT = 23,
+ RTD1325_ISO_ISR_USB_HOST_SHIFT = 24,
+ RTD1325_ISO_ISR_USB_U3_DRD_SHIFT = 25,
+ RTD1325_ISO_ISR_USB_U2_DRD_SHIFT = 26,
+ RTD1325_ISO_ISR_WDOG3_NMI_SHIFT = 27,
+ RTD1325_ISO_ISR_PORB_HV_CEN_SHIFT = 28,
+ RTD1325_ISO_ISR_PORB_DV_CEN_SHIFT = 29,
+ RTD1325_ISO_ISR_PORB_AV_CEN_SHIFT = 30,
+ RTD1325_ISO_ISR_I2C1_REQ_SHIFT = 31,
+};
+
+static const u32 rtd1325_iso_isr_to_scpu_int_en_mask[32] = {
+ [RTD1325_ISO_ISR_SPI1_SHIFT] = BIT(1),
+ [RTD1325_ISO_ISR_UR0_SHIFT] = BIT(2),
+ [RTD1325_ISO_ISR_LSADC0_SHIFT] = BIT(3),
+ [RTD1325_ISO_ISR_IRDA_SHIFT] = BIT(5),
+ [RTD1325_ISO_ISR_I2C0_SHIFT] = BIT(8),
+ [RTD1325_ISO_ISR_I2C1_SHIFT] = BIT(11),
+ [RTD1325_ISO_ISR_VFD_SHIFT] = BIT(17),
+ [RTD1325_ISO_ISR_GPIOA_SHIFT] = BIT(19),
+ [RTD1325_ISO_ISR_GPIODA_SHIFT] = BIT(20),
+ [RTD1325_ISO_ISR_PORB_HV_CEN_SHIFT] = BIT(28),
+ [RTD1325_ISO_ISR_PORB_DV_CEN_SHIFT] = BIT(29),
+ [RTD1325_ISO_ISR_PORB_AV_CEN_SHIFT] = BIT(30),
+ [RTD1325_ISO_ISR_I2C1_REQ_SHIFT] = BIT(31),
+ [RTD1325_ISO_ISR_WDOG1_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1325_ISO_ISR_WDOG2_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1325_ISO_ISR_WDOG3_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1325_ISO_ISR_WDOG4_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+};
+
+enum rtd1325_misc_isr_bits {
+ RTD1325_ISR_UR1_SHIFT = 3,
+ RTD1325_ISR_TC5_SHIFT = 4,
+ RTD1325_ISR_UR1_TO_SHIFT = 5,
+ RTD1325_ISR_TC0_SHIFT = 6,
+ RTD1325_ISR_TC1_SHIFT = 7,
+ RTD1325_ISR_UR2_SHIFT = 8,
+ RTD1325_ISR_UR2_TO_SHIFT = 13,
+ RTD1325_ISR_I2C5_SHIFT = 14,
+ RTD1325_ISR_I2C4_SHIFT = 15,
+ RTD1325_ISR_DRTC_HSEC_SHIFT = 16,
+ RTD1325_ISR_DRTC_MIN_SHIFT = 17,
+ RTD1325_ISR_DRTC_HOUR_SHIFT = 18,
+ RTD1325_ISR_DRTC_DATE_SHIFT = 19,
+ RTD1325_ISR_DRTC_ALARM_SHIFT = 20,
+ RTD1325_ISR_I2C3_SHIFT = 23,
+ RTD1325_ISR_SC0_SHIFT = 24,
+ RTD1325_ISR_SC1_SHIFT = 25,
+ RTD1325_ISR_SPI_SHIFT = 27,
+ RTD1325_ISR_FAN_SHIFT = 29,
+};
+
+static const u32 rtd1325_misc_isr_to_scpu_int_en_mask[32] = {
+ [RTD1325_ISR_UR1_SHIFT] = BIT(3),
+ [RTD1325_ISR_UR1_TO_SHIFT] = BIT(5),
+ [RTD1325_ISR_UR2_TO_SHIFT] = BIT(6),
+ [RTD1325_ISR_UR2_SHIFT] = BIT(7),
+ [RTD1325_ISR_I2C5_SHIFT] = BIT(14),
+ [RTD1325_ISR_I2C4_SHIFT] = BIT(15),
+ [RTD1325_ISR_DRTC_HSEC_SHIFT] = BIT(16),
+ [RTD1325_ISR_DRTC_MIN_SHIFT] = BIT(17),
+ [RTD1325_ISR_DRTC_HOUR_SHIFT] = BIT(18),
+ [RTD1325_ISR_DRTC_DATE_SHIFT] = BIT(19),
+ [RTD1325_ISR_DRTC_ALARM_SHIFT] = BIT(20),
+ [RTD1325_ISR_SC0_SHIFT] = BIT(24),
+ [RTD1325_ISR_SC1_SHIFT] = BIT(25),
+ [RTD1325_ISR_SPI_SHIFT] = BIT(27),
+ [RTD1325_ISR_I2C3_SHIFT] = BIT(28),
+ [RTD1325_ISR_FAN_SHIFT] = BIT(29),
+};
+
+static struct realtek_intc_mask rtd1325_intc_iso_cfgs[] = {
+ { ISO_NORMAL_MASK, },
+ { ISO_NMI_WDT_MASK, },
+};
+
+static const struct realtek_intc_info rtd1325_intc_iso_info = {
+ .isr_offset = ISO_ISR_OFFSET,
+ .scpu_int_en_offset = ISO_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1325_iso_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1325_intc_iso_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1325_intc_iso_cfgs),
+};
+
+static struct realtek_intc_mask rtd1325_intc_misc_cfgs[] = {
+ { MISC_NORMAL_MASK, },
+ { MISC_UART1_MASK, },
+ { MISC_UART2_MASK, },
+};
+
+static const struct realtek_intc_info rtd1325_intc_misc_info = {
+ .isr_offset = MISC_ISR_OFFSET,
+ .scpu_int_en_offset = MISC_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1325_misc_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1325_intc_misc_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1325_intc_misc_cfgs),
+};
+
+static const struct of_device_id realtek_intc_rtd1325_dt_matches[] = {
+ {
+ .compatible = "realtek,rtd1325-intc-iso",
+ .data = &rtd1325_intc_iso_info,
+ }, {
+ .compatible = "realtek,rtd1325-intc-misc",
+ .data = &rtd1325_intc_misc_info,
+ },
+ { /* sentinel */ }
+};
+
+static const struct dev_pm_ops realtek_intc_rtd1325_pm_ops = {
+ .suspend_noirq = realtek_intc_suspend,
+ .resume_noirq = realtek_intc_resume,
+};
+
+static int rtd1325_intc_probe(struct platform_device *pdev)
+{
+ const struct realtek_intc_info *info;
+
+ info = of_device_get_match_data(&pdev->dev);
+ if (!info)
+ return -EINVAL;
+
+ return realtek_intc_probe(pdev, info);
+}
+
+static struct platform_driver realtek_intc_rtd1325_driver = {
+ .probe = rtd1325_intc_probe,
+ .driver = {
+ .name = "realtek_intc_rtd1325",
+ .of_match_table = realtek_intc_rtd1325_dt_matches,
+ .suppress_bind_attrs = true,
+ .pm = &realtek_intc_rtd1325_pm_ops,
+ },
+};
+
+static int __init realtek_intc_rtd1325_init(void)
+{
+ return platform_driver_register(&realtek_intc_rtd1325_driver);
+}
+module_init(realtek_intc_rtd1325_init);
+
+static void __exit realtek_intc_rtd1325_exit(void)
+{
+ platform_driver_unregister(&realtek_intc_rtd1325_driver);
+}
+module_exit(realtek_intc_rtd1325_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek RTD1325 Interrupt Controller Driver");
--
2.25.1
Add support for the RTD1619B platform.
Signed-off-by: James Tai <[email protected]>
---
CC: Thomas Gleixner <[email protected]>
CC: Marc Zyngier <[email protected]>
CC: [email protected]
v3 to v4 change:
- Replaced the 'core_initcall' with 'module_init'
- Removed redundant header files
- Moved the function of suspend and resume to common code
- Improved the description of config
v2 to v3 change:
- Unchanged
v1 to v2 change:
- Resolved kernel test robot build warnings
- Replaced magic number with macro
- Fixed code style issues
drivers/irqchip/Kconfig | 10 ++
drivers/irqchip/Makefile | 1 +
drivers/irqchip/irq-realtek-rtd1619b.c | 186 +++++++++++++++++++++++++
3 files changed, 197 insertions(+)
create mode 100644 drivers/irqchip/irq-realtek-rtd1619b.c
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 9354445ea0bb..0dc2a16dce70 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -252,6 +252,16 @@ config REALTEK_RTD1325_INTC
If unsure, say N.
+config REALTEK_RTD1619B_INTC
+ tristate "Realtek RTD1619B interrupt controller"
+ select REALTEK_DHC_INTC
+ help
+ Enable support for the Realtek RTD1619B SoC Interrupt Controller.
+ Each Realtek DHC SoC has two sets of interrupt controllers, each
+ capable of handling up to 32 interrupts.
+
+ If unsure, say N.
+
config RENESAS_INTC_IRQPIN
bool "Renesas INTC External IRQ Pin Support" if COMPILE_TEST
select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index eaa12928d60b..da308aefcb87 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_REALTEK_DHC_INTC) += irq-realtek-intc-common.o
obj-$(CONFIG_REALTEK_RTD1319_INTC) += irq-realtek-rtd1319.o
obj-$(CONFIG_REALTEK_RTD1319D_INTC) += irq-realtek-rtd1319d.o
obj-$(CONFIG_REALTEK_RTD1325_INTC) += irq-realtek-rtd1325.o
+obj-$(CONFIG_REALTEK_RTD1619B_INTC) += irq-realtek-rtd1619b.o
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
diff --git a/drivers/irqchip/irq-realtek-rtd1619b.c b/drivers/irqchip/irq-realtek-rtd1619b.c
new file mode 100644
index 000000000000..51e6b61e73df
--- /dev/null
+++ b/drivers/irqchip/irq-realtek-rtd1619b.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
+/*
+ * Realtek RTD1619B interrupt controller driver
+ *
+ * Copyright (c) 2023 Realtek Semiconductor Corporation
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "irq-realtek-intc-common.h"
+
+#define ISO_NMI_WDT_MASK 0x08008090
+#define ISO_NORMAL_MASK 0xf7ff7f6e
+#define MISC_NORMAL_MASK 0xffffded6
+#define MISC_UART1_MASK 0x00000028
+#define MISC_UART2_MASK 0x00002100
+
+#define ISO_ISR_EN_OFFSET 0x40
+#define ISO_ISR_OFFSET 0
+#define ISO_ISR_UMSK_OFFSET 0x4
+#define MISC_ISR_EN_OFFSET 0x80
+#define MISC_ISR_OFFSET 0xc
+#define MISC_ISR_UMSK_OFFSET 0x8
+
+enum rtd1619b_iso_isr_bits {
+ RTD1619B_ISO_ISR_TC3_SHIFT = 1,
+ RTD1619B_ISO_ISR_UR0_SHIFT = 2,
+ RTD1619B_ISO_ISR_LSADC0_SHIFT = 3,
+ RTD1619B_ISO_ISR_WDOG1_NMI_SHIFT = 4,
+ RTD1619B_ISO_ISR_IRDA_SHIFT = 5,
+ RTD1619B_ISO_ISR_SPI1_SHIFT = 6,
+ RTD1619B_ISO_ISR_WDOG2_NMI_SHIFT = 7,
+ RTD1619B_ISO_ISR_I2C0_SHIFT = 8,
+ RTD1619B_ISO_ISR_TC4_SHIFT = 9,
+ RTD1619B_ISO_ISR_TC7_SHIFT = 10,
+ RTD1619B_ISO_ISR_I2C1_SHIFT = 11,
+ RTD1619B_ISO_ISR_HIFI_WAKEUP_SHIFT = 14,
+ RTD1619B_ISO_ISR_WDOG4_NMI_SHIFT = 15,
+ RTD1619B_ISO_ISR_TC8_SHIFT = 16,
+ RTD1619B_ISO_ISR_VFD_SHIFT = 17,
+ RTD1619B_ISO_ISR_VTC_SHIFT = 18,
+ RTD1619B_ISO_ISR_GPIOA_SHIFT = 19,
+ RTD1619B_ISO_ISR_GPIODA_SHIFT = 20,
+ RTD1619B_ISO_ISR_ISO_MISC_SHIFT = 21,
+ RTD1619B_ISO_ISR_CBUS_SHIFT = 22,
+ RTD1619B_ISO_ISR_ETN_SHIFT = 23,
+ RTD1619B_ISO_ISR_USB_HOST_SHIFT = 24,
+ RTD1619B_ISO_ISR_USB_U3_DRD_SHIFT = 25,
+ RTD1619B_ISO_ISR_USB_U2_DRD_SHIFT = 26,
+ RTD1619B_ISO_ISR_WDOG3_NMI_SHIFT = 27,
+ RTD1619B_ISO_ISR_PORB_HV_CEN_SHIFT = 28,
+ RTD1619B_ISO_ISR_PORB_DV_CEN_SHIFT = 29,
+ RTD1619B_ISO_ISR_PORB_AV_CEN_SHIFT = 30,
+ RTD1619B_ISO_ISR_I2C1_REQ_SHIFT = 31,
+};
+
+static const u32 rtd1619b_iso_isr_to_scpu_int_en_mask[32] = {
+ [RTD1619B_ISO_ISR_SPI1_SHIFT] = BIT(1),
+ [RTD1619B_ISO_ISR_UR0_SHIFT] = BIT(2),
+ [RTD1619B_ISO_ISR_LSADC0_SHIFT] = BIT(3),
+ [RTD1619B_ISO_ISR_IRDA_SHIFT] = BIT(5),
+ [RTD1619B_ISO_ISR_I2C0_SHIFT] = BIT(8),
+ [RTD1619B_ISO_ISR_I2C1_SHIFT] = BIT(11),
+ [RTD1619B_ISO_ISR_VFD_SHIFT] = BIT(17),
+ [RTD1619B_ISO_ISR_GPIOA_SHIFT] = BIT(19),
+ [RTD1619B_ISO_ISR_GPIODA_SHIFT] = BIT(20),
+ [RTD1619B_ISO_ISR_PORB_HV_CEN_SHIFT] = BIT(28),
+ [RTD1619B_ISO_ISR_PORB_DV_CEN_SHIFT] = BIT(29),
+ [RTD1619B_ISO_ISR_PORB_AV_CEN_SHIFT] = BIT(30),
+ [RTD1619B_ISO_ISR_I2C1_REQ_SHIFT] = BIT(31),
+ [RTD1619B_ISO_ISR_WDOG1_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1619B_ISO_ISR_WDOG2_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1619B_ISO_ISR_WDOG3_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+ [RTD1619B_ISO_ISR_WDOG4_NMI_SHIFT] = IRQ_ALWAYS_ENABLED,
+};
+
+enum rtd1619b_misc_isr_bits {
+ RTD1619B_ISR_UR1_SHIFT = 3,
+ RTD1619B_ISR_TC5_SHIFT = 4,
+ RTD1619B_ISR_UR1_TO_SHIFT = 5,
+ RTD1619B_ISR_TC0_SHIFT = 6,
+ RTD1619B_ISR_TC1_SHIFT = 7,
+ RTD1619B_ISR_UR2_SHIFT = 8,
+ RTD1619B_ISR_UR2_TO_SHIFT = 13,
+ RTD1619B_ISR_I2C5_SHIFT = 14,
+ RTD1619B_ISR_I2C4_SHIFT = 15,
+ RTD1619B_ISR_I2C3_SHIFT = 23,
+ RTD1619B_ISR_SC0_SHIFT = 24,
+ RTD1619B_ISR_SC1_SHIFT = 25,
+ RTD1619B_ISR_SPI_SHIFT = 27,
+ RTD1619B_ISR_FAN_SHIFT = 29,
+};
+
+static const u32 rtd1619b_misc_isr_to_scpu_int_en_mask[32] = {
+ [RTD1619B_ISR_UR1_SHIFT] = BIT(3),
+ [RTD1619B_ISR_UR1_TO_SHIFT] = BIT(5),
+ [RTD1619B_ISR_UR2_TO_SHIFT] = BIT(6),
+ [RTD1619B_ISR_UR2_SHIFT] = BIT(7),
+ [RTD1619B_ISR_I2C5_SHIFT] = BIT(14),
+ [RTD1619B_ISR_I2C4_SHIFT] = BIT(15),
+ [RTD1619B_ISR_SC0_SHIFT] = BIT(24),
+ [RTD1619B_ISR_SC1_SHIFT] = BIT(25),
+ [RTD1619B_ISR_SPI_SHIFT] = BIT(27),
+ [RTD1619B_ISR_I2C3_SHIFT] = BIT(28),
+ [RTD1619B_ISR_FAN_SHIFT] = BIT(29),
+};
+
+static struct realtek_intc_mask rtd1619b_intc_iso_cfgs[] = {
+ { ISO_NORMAL_MASK, },
+ { ISO_NMI_WDT_MASK, },
+};
+
+static const struct realtek_intc_info rtd1619b_intc_iso_info = {
+ .isr_offset = ISO_ISR_OFFSET,
+ .scpu_int_en_offset = ISO_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1619b_iso_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1619b_intc_iso_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1619b_intc_iso_cfgs),
+};
+
+static struct realtek_intc_mask rtd1619b_intc_misc_cfgs[] = {
+ { MISC_NORMAL_MASK, },
+ { MISC_UART1_MASK, },
+ { MISC_UART2_MASK, },
+};
+
+static const struct realtek_intc_info rtd1619b_intc_misc_info = {
+ .isr_offset = MISC_ISR_OFFSET,
+ .scpu_int_en_offset = MISC_ISR_EN_OFFSET,
+ .isr_to_scpu_int_en_mask = rtd1619b_misc_isr_to_scpu_int_en_mask,
+ .subset_mask = rtd1619b_intc_misc_cfgs,
+ .subset_num = ARRAY_SIZE(rtd1619b_intc_misc_cfgs),
+};
+
+static const struct of_device_id realtek_intc_rtd1619b_dt_matches[] = {
+ {
+ .compatible = "realtek,rtd1619b-intc-iso",
+ .data = &rtd1619b_intc_iso_info,
+ }, {
+ .compatible = "realtek,rtd1619b-intc-misc",
+ .data = &rtd1619b_intc_misc_info,
+ },
+ { /* sentinel */ }
+};
+
+static const struct dev_pm_ops realtek_intc_rtd1619b_pm_ops = {
+ .suspend_noirq = realtek_intc_suspend,
+ .resume_noirq = realtek_intc_resume,
+};
+
+static int rtd1619b_intc_probe(struct platform_device *pdev)
+{
+ const struct realtek_intc_info *info;
+
+ info = of_device_get_match_data(&pdev->dev);
+ if (!info)
+ return -EINVAL;
+
+ return realtek_intc_probe(pdev, info);
+}
+
+static struct platform_driver realtek_intc_rtd1619b_driver = {
+ .probe = rtd1619b_intc_probe,
+ .driver = {
+ .name = "realtek_intc_rtd1619b",
+ .of_match_table = realtek_intc_rtd1619b_dt_matches,
+ .suppress_bind_attrs = true,
+ .pm = &realtek_intc_rtd1619b_pm_ops,
+ },
+};
+
+static int __init realtek_intc_rtd1619b_init(void)
+{
+ return platform_driver_register(&realtek_intc_rtd1619b_driver);
+}
+module_init(realtek_intc_rtd1619b_init);
+
+static void __exit realtek_intc_rtd1619b_exit(void)
+{
+ platform_driver_unregister(&realtek_intc_rtd1619b_driver);
+}
+module_exit(realtek_intc_rtd1619b_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek RTD1619B Interrupt Controller Driver");
--
2.25.1
On 28/12/2023 07:08, James Tai wrote:
> Add the YAML documentation for Realtek DHC (Digital Home Center) SoCs.
>
> Signed-off-by: James Tai <[email protected]>
Thank you for your patch. There is something to discuss/improve.
> + interrupts:
> + minItems: 1
> + maxItems: 3
> + description:
> + Contains the GIC SPI IRQs mapped to the external interrupt lines.
> +
> +required:
> + - compatible
> + - reg
> + - interrupt-controller
> + - '#interrupt-cells'
> + - '#address-cells'
> + - interrupts
> +
> +additionalProperties: false
> +
> +allOf:
If there is going to be new version/resend, allOf: block goes before
additionalProperties:.
> + - $ref: /schemas/interrupt-controller.yaml#
> + - if:
> + properties:
> + compatible:
> + enum:
> + - realtek,rtd1319-intc-iso
> + then:
> + properties:
> + interrupts:
> + minItems: 1
Why the second interrupt is optional? It's a SoC, the pins are not
configurable usually. Same question for other cases.
> +...
Best regards,
Krzysztof
Hi Krzysztof,
>> Add the YAML documentation for Realtek DHC (Digital Home Center) SoCs.
>>
>> Signed-off-by: James Tai <[email protected]>
>
>Thank you for your patch. There is something to discuss/improve.
>
>> + interrupts:
>> + minItems: 1
>> + maxItems: 3
>> + description:
>> + Contains the GIC SPI IRQs mapped to the external interrupt lines.
>> +
>> +required:
>> + - compatible
>> + - reg
>> + - interrupt-controller
>> + - '#interrupt-cells'
>> + - '#address-cells'
>> + - interrupts
>> +
>> +additionalProperties: false
>> +
>> +allOf:
>
>If there is going to be new version/resend, allOf: block goes before
>additionalProperties:.
>
I will move the 'allOf: block' to go before 'additionalPropertie' in next patches.
>> + - $ref: /schemas/interrupt-controller.yaml#
>> + - if:
>> + properties:
>> + compatible:
>> + enum:
>> + - realtek,rtd1319-intc-iso
>> + then:
>> + properties:
>> + interrupts:
>> + minItems: 1
>
>Why the second interrupt is optional? It's a SoC, the pins are not configurable
>usually. Same question for other cases.
>
I thought it was defined this way to accommodate different SoCs.
I will remove the 'minItems'. Should the correct version look like the following?
allOf:
- $ref: /schemas/interrupt-controller.yaml#
- if:
properties:
compatible:
enum:
- realtek,rtd1319-intc-iso
then:
properties:
interrupts:
items:
- description: isolation irqs
- description: rtc irq
...
...
Thanks for your feedback.
Regards,
James
Hi James,
kernel test robot noticed the following build errors:
[auto build test ERROR on tip/irq/core]
[also build test ERROR on robh/for-next linus/master v6.7 next-20240108]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/James-Tai/dt-bindings-interrupt-controller-Add-support-for-Realtek-DHC-SoCs/20231228-141213
base: tip/irq/core
patch link: https://lore.kernel.org/r/20231228060825.1380439-5-james.tai%40realtek.com
patch subject: [PATCH v4 4/6] irqchip: Introduce RTD1319D support using the Realtek common interrupt controller driver
config: s390-randconfig-r113-20240109 (https://download.01.org/0day-ci/archive/20240109/[email protected]/config)
compiler: clang version 18.0.0git (https://github.com/llvm/llvm-project 7e186d366d6c7def0543acc255931f617e76dff0)
reproduce: (https://download.01.org/0day-ci/archive/20240109/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
In file included from drivers/irqchip/irq-realtek-intc-common.c:8:
In file included from include/linux/irqchip.h:17:
In file included from include/linux/of_irq.h:7:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/s390/include/asm/io.h:78:
include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
547 | val = __raw_readb(PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
560 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/big_endian.h:37:59: note: expanded from macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
| ^
include/uapi/linux/swab.h:102:54: note: expanded from macro '__swab16'
102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
| ^
In file included from drivers/irqchip/irq-realtek-intc-common.c:8:
In file included from include/linux/irqchip.h:17:
In file included from include/linux/of_irq.h:7:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/s390/include/asm/io.h:78:
include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
573 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/big_endian.h:35:59: note: expanded from macro '__le32_to_cpu'
35 | #define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
| ^
include/uapi/linux/swab.h:115:54: note: expanded from macro '__swab32'
115 | #define __swab32(x) (__u32)__builtin_bswap32((__u32)(x))
| ^
In file included from drivers/irqchip/irq-realtek-intc-common.c:8:
In file included from include/linux/irqchip.h:17:
In file included from include/linux/of_irq.h:7:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/s390/include/asm/io.h:78:
include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
584 | __raw_writeb(value, PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
594 | __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
604 | __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:692:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
692 | readsb(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:700:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
700 | readsw(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:708:20: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
708 | readsl(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:717:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
717 | writesb(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:726:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
726 | writesw(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:735:21: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
735 | writesl(PCI_IOBASE + addr, buffer, count);
| ~~~~~~~~~~ ^
>> drivers/irqchip/irq-realtek-intc-common.c:204:3: error: call to undeclared function 'iounmap'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
204 | iounmap(data->base);
| ^
arch/s390/include/asm/io.h:29:17: note: expanded from macro 'iounmap'
29 | #define iounmap iounmap
| ^
drivers/irqchip/irq-realtek-intc-common.c:204:3: note: did you mean 'vunmap'?
arch/s390/include/asm/io.h:29:17: note: expanded from macro 'iounmap'
29 | #define iounmap iounmap
| ^
include/linux/vmalloc.h:167:13: note: 'vunmap' declared here
167 | extern void vunmap(const void *addr);
| ^
12 warnings and 1 error generated.
vim +/iounmap +204 drivers/irqchip/irq-realtek-intc-common.c
59fe9dce1f284e James Tai 2023-12-28 161
59fe9dce1f284e James Tai 2023-12-28 162 int realtek_intc_probe(struct platform_device *pdev, const struct realtek_intc_info *info)
59fe9dce1f284e James Tai 2023-12-28 163 {
59fe9dce1f284e James Tai 2023-12-28 164 struct realtek_intc_data *data;
59fe9dce1f284e James Tai 2023-12-28 165 struct device *dev = &pdev->dev;
59fe9dce1f284e James Tai 2023-12-28 166 struct device_node *node = dev->of_node;
59fe9dce1f284e James Tai 2023-12-28 167 int ret, i;
59fe9dce1f284e James Tai 2023-12-28 168
59fe9dce1f284e James Tai 2023-12-28 169 data = devm_kzalloc(dev, struct_size(data, subset_data, info->subset_num), GFP_KERNEL);
59fe9dce1f284e James Tai 2023-12-28 170 if (!data)
59fe9dce1f284e James Tai 2023-12-28 171 return -ENOMEM;
59fe9dce1f284e James Tai 2023-12-28 172
59fe9dce1f284e James Tai 2023-12-28 173 data->base = of_iomap(node, 0);
59fe9dce1f284e James Tai 2023-12-28 174 if (!data->base)
59fe9dce1f284e James Tai 2023-12-28 175 goto iomap_cleanup;
59fe9dce1f284e James Tai 2023-12-28 176
59fe9dce1f284e James Tai 2023-12-28 177 data->info = info;
59fe9dce1f284e James Tai 2023-12-28 178
59fe9dce1f284e James Tai 2023-12-28 179 raw_spin_lock_init(&data->lock);
59fe9dce1f284e James Tai 2023-12-28 180
59fe9dce1f284e James Tai 2023-12-28 181 data->domain = irq_domain_add_linear(node, 32, &realtek_intc_domain_ops, data);
59fe9dce1f284e James Tai 2023-12-28 182 if (!data->domain)
59fe9dce1f284e James Tai 2023-12-28 183 goto iomap_cleanup;
59fe9dce1f284e James Tai 2023-12-28 184
59fe9dce1f284e James Tai 2023-12-28 185 data->subset_data_num = info->subset_num;
59fe9dce1f284e James Tai 2023-12-28 186 for (i = 0; i < info->subset_num; i++) {
59fe9dce1f284e James Tai 2023-12-28 187 ret = realtek_intc_subset(node, data, i);
59fe9dce1f284e James Tai 2023-12-28 188 if (ret <= 0) {
59fe9dce1f284e James Tai 2023-12-28 189 dev_err(dev, "failed to init subset %d: %d", i, ret);
59fe9dce1f284e James Tai 2023-12-28 190 goto irq_domain_cleanup;
59fe9dce1f284e James Tai 2023-12-28 191 }
59fe9dce1f284e James Tai 2023-12-28 192 }
59fe9dce1f284e James Tai 2023-12-28 193
59fe9dce1f284e James Tai 2023-12-28 194 platform_set_drvdata(pdev, data);
59fe9dce1f284e James Tai 2023-12-28 195
59fe9dce1f284e James Tai 2023-12-28 196 return 0;
59fe9dce1f284e James Tai 2023-12-28 197
59fe9dce1f284e James Tai 2023-12-28 198 irq_domain_cleanup:
59fe9dce1f284e James Tai 2023-12-28 199 if (data->domain)
59fe9dce1f284e James Tai 2023-12-28 200 irq_domain_remove(data->domain);
59fe9dce1f284e James Tai 2023-12-28 201
59fe9dce1f284e James Tai 2023-12-28 202 iomap_cleanup:
59fe9dce1f284e James Tai 2023-12-28 203 if (data->base)
59fe9dce1f284e James Tai 2023-12-28 @204 iounmap(data->base);
59fe9dce1f284e James Tai 2023-12-28 205
59fe9dce1f284e James Tai 2023-12-28 206 return -ENOMEM;
59fe9dce1f284e James Tai 2023-12-28 207 }
59fe9dce1f284e James Tai 2023-12-28 208 EXPORT_SYMBOL_GPL(realtek_intc_probe);
59fe9dce1f284e James Tai 2023-12-28 209
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki