* [PATCH v3 0/2] irqchip/qcom-pdc: support v3.2 HW @ 2023-08-29 9:21 Dmitry Baryshkov 2023-08-29 9:21 ` [PATCH v3 1/2] irqchip/qcom-pdc: Add support for " Dmitry Baryshkov 2023-08-29 9:21 ` [PATCH v3 2/2] arm64: dts: qcom: sm8150: extend the size of the PDC resource Dmitry Baryshkov 0 siblings, 2 replies; 6+ messages in thread From: Dmitry Baryshkov @ 2023-08-29 9:21 UTC (permalink / raw) To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Thomas Gleixner, Marc Zyngier Cc: linux-arm-msm, linux-kernel As Neil's patch has been dropped, because of the regression, squash the fix for sm8150 into the original patch (so that we don't have broken kernel commit). Changes since v2: - Fix PDC resource size if it is too short instead of setting version to dummy 0 value (Marc). - Squashed the fix into the original patch. Changes since v1: - Changed IRQ_ENABLE handling based on Maulik's comments Dmitry Baryshkov (1): arm64: dts: qcom: sm8150: extend the size of the PDC resource Neil Armstrong (1): irqchip/qcom-pdc: Add support for v3.2 HW arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +- drivers/irqchip/qcom-pdc.c | 73 ++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 15 deletions(-) -- 2.39.2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 1/2] irqchip/qcom-pdc: Add support for v3.2 HW 2023-08-29 9:21 [PATCH v3 0/2] irqchip/qcom-pdc: support v3.2 HW Dmitry Baryshkov @ 2023-08-29 9:21 ` Dmitry Baryshkov 2023-08-29 9:50 ` Maulik Shah (mkshah) 2023-08-29 12:30 ` Marc Zyngier 2023-08-29 9:21 ` [PATCH v3 2/2] arm64: dts: qcom: sm8150: extend the size of the PDC resource Dmitry Baryshkov 1 sibling, 2 replies; 6+ messages in thread From: Dmitry Baryshkov @ 2023-08-29 9:21 UTC (permalink / raw) To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Thomas Gleixner, Marc Zyngier Cc: linux-arm-msm, linux-kernel, Neil Armstrong From: Neil Armstrong <neil.armstrong@linaro.org> Starting from HW version 3.2 the IRQ_ENABLE bit has moved to the IRQ_i_CFG register and requires a change of the driver to avoid writing into an undefined register address. Get the HW version from registers and set the IRQ_ENABLE bit to the correct register depending on the HW version. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> [DB: fix crash on sm8150 DTs which listed short PDC region] Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- drivers/irqchip/qcom-pdc.c | 73 ++++++++++++++++++++++++++++++-------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index a32c0d28d038..f9f44b494b1d 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -22,9 +22,22 @@ #define PDC_MAX_GPIO_IRQS 256 +/* Valid only on HW version < 3.2 */ #define IRQ_ENABLE_BANK 0x10 #define IRQ_i_CFG 0x110 +/* Valid only on HW version >= 3.2 */ +#define IRQ_i_CFG_IRQ_ENABLE 3 + +#define IRQ_i_CFG_TYPE_MASK GENMASK(2, 0) + +#define PDC_VERSION 0x1000 + +/* Notable PDC versions */ +enum { + PDC_VERSION_3_2 = 0x30200, +}; + struct pdc_pin_region { u32 pin_base; u32 parent_base; @@ -37,6 +50,7 @@ static DEFINE_RAW_SPINLOCK(pdc_lock); static void __iomem *pdc_base; static struct pdc_pin_region *pdc_region; static int pdc_region_cnt; +static unsigned int pdc_version; static void pdc_reg_write(int reg, u32 i, u32 val) { @@ -53,15 +67,22 @@ static void pdc_enable_intr(struct irq_data *d, bool on) int pin_out = d->hwirq; unsigned long enable; unsigned long flags; - u32 index, mask; - - index = pin_out / 32; - mask = pin_out % 32; raw_spin_lock_irqsave(&pdc_lock, flags); - enable = pdc_reg_read(IRQ_ENABLE_BANK, index); - __assign_bit(mask, &enable, on); - pdc_reg_write(IRQ_ENABLE_BANK, index, enable); + if (pdc_version < PDC_VERSION_3_2) { + u32 index, mask; + + index = pin_out / 32; + mask = pin_out % 32; + + enable = pdc_reg_read(IRQ_ENABLE_BANK, index); + __assign_bit(mask, &enable, on); + pdc_reg_write(IRQ_ENABLE_BANK, index, enable); + } else { + enable = pdc_reg_read(IRQ_i_CFG, pin_out); + __assign_bit(IRQ_i_CFG_IRQ_ENABLE, &enable, on); + pdc_reg_write(IRQ_i_CFG, pin_out, enable); + } raw_spin_unlock_irqrestore(&pdc_lock, flags); } @@ -142,6 +163,7 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) } old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq); + pdc_type |= (old_pdc_type & ~IRQ_i_CFG_TYPE_MASK); pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type); ret = irq_chip_set_type_parent(d, type); @@ -246,7 +268,7 @@ static const struct irq_domain_ops qcom_pdc_ops = { static int pdc_setup_pin_mapping(struct device_node *np) { int ret, n, i; - u32 irq_index, reg_index, val; + unsigned long val; n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32)); if (n <= 0 || n % 3) @@ -277,28 +299,51 @@ static int pdc_setup_pin_mapping(struct device_node *np) return ret; for (i = 0; i < pdc_region[n].cnt; i++) { - reg_index = (i + pdc_region[n].pin_base) >> 5; - irq_index = (i + pdc_region[n].pin_base) & 0x1f; - val = pdc_reg_read(IRQ_ENABLE_BANK, reg_index); - val &= ~BIT(irq_index); - pdc_reg_write(IRQ_ENABLE_BANK, reg_index, val); + if (pdc_version < PDC_VERSION_3_2) { + u32 irq_index, reg_index; + + reg_index = (i + pdc_region[n].pin_base) >> 5; + irq_index = (i + pdc_region[n].pin_base) & 0x1f; + val = pdc_reg_read(IRQ_ENABLE_BANK, reg_index); + __assign_bit(irq_index, &val, 0); + pdc_reg_write(IRQ_ENABLE_BANK, reg_index, val); + } else { + u32 irq; + + irq = i + pdc_region[n].pin_base; + val = pdc_reg_read(IRQ_i_CFG, irq); + __assign_bit(IRQ_i_CFG_IRQ_ENABLE, &val, 0); + pdc_reg_write(IRQ_i_CFG, irq, val); + } } } return 0; } +#define QCOM_PDC_SIZE 0x30000 + static int qcom_pdc_init(struct device_node *node, struct device_node *parent) { struct irq_domain *parent_domain, *pdc_domain; + struct resource res; + resource_size_t res_size; int ret; - pdc_base = of_iomap(node, 0); + /* compat with old sm8150 DT which had very small region for PDC */ + if (of_address_to_resource(node, 0, &res)) + return -EINVAL; + + res_size = max_t(resource_size_t, resource_size(&res), QCOM_PDC_SIZE); + + pdc_base = ioremap(res.start, res_size); if (!pdc_base) { pr_err("%pOF: unable to map PDC registers\n", node); return -ENXIO; } + pdc_version = pdc_reg_read(PDC_VERSION, 0); + parent_domain = irq_find_host(parent); if (!parent_domain) { pr_err("%pOF: unable to find PDC's parent domain\n", node); -- 2.39.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] irqchip/qcom-pdc: Add support for v3.2 HW 2023-08-29 9:21 ` [PATCH v3 1/2] irqchip/qcom-pdc: Add support for " Dmitry Baryshkov @ 2023-08-29 9:50 ` Maulik Shah (mkshah) 2023-08-29 12:30 ` Marc Zyngier 1 sibling, 0 replies; 6+ messages in thread From: Maulik Shah (mkshah) @ 2023-08-29 9:50 UTC (permalink / raw) To: Dmitry Baryshkov, Andy Gross, Bjorn Andersson, Konrad Dybcio, Thomas Gleixner, Marc Zyngier Cc: linux-arm-msm, linux-kernel, Neil Armstrong Hi, On 8/29/2023 2:51 PM, Dmitry Baryshkov wrote: > From: Neil Armstrong <neil.armstrong@linaro.org> > > Starting from HW version 3.2 the IRQ_ENABLE bit has moved to the > IRQ_i_CFG register and requires a change of the driver to avoid > writing into an undefined register address. > > Get the HW version from registers and set the IRQ_ENABLE bit to the > correct register depending on the HW version. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > [DB: fix crash on sm8150 DTs which listed short PDC region] > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > --- > drivers/irqchip/qcom-pdc.c | 73 ++++++++++++++++++++++++++++++-------- > 1 file changed, 59 insertions(+), 14 deletions(-) Reviewed-by: Maulik Shah <quic_mkshah@quicinc.com> Thanks, Maulik ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 1/2] irqchip/qcom-pdc: Add support for v3.2 HW 2023-08-29 9:21 ` [PATCH v3 1/2] irqchip/qcom-pdc: Add support for " Dmitry Baryshkov 2023-08-29 9:50 ` Maulik Shah (mkshah) @ 2023-08-29 12:30 ` Marc Zyngier 1 sibling, 0 replies; 6+ messages in thread From: Marc Zyngier @ 2023-08-29 12:30 UTC (permalink / raw) To: Dmitry Baryshkov Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Thomas Gleixner, linux-arm-msm, linux-kernel, Neil Armstrong On Tue, 29 Aug 2023 10:21:18 +0100, Dmitry Baryshkov <dmitry.baryshkov@linaro.org> wrote: > > From: Neil Armstrong <neil.armstrong@linaro.org> > > Starting from HW version 3.2 the IRQ_ENABLE bit has moved to the > IRQ_i_CFG register and requires a change of the driver to avoid > writing into an undefined register address. > > Get the HW version from registers and set the IRQ_ENABLE bit to the > correct register depending on the HW version. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > [DB: fix crash on sm8150 DTs which listed short PDC region] > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > --- > drivers/irqchip/qcom-pdc.c | 73 ++++++++++++++++++++++++++++++-------- > 1 file changed, 59 insertions(+), 14 deletions(-) > > diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c > index a32c0d28d038..f9f44b494b1d 100644 > --- a/drivers/irqchip/qcom-pdc.c > +++ b/drivers/irqchip/qcom-pdc.c > @@ -22,9 +22,22 @@ > > #define PDC_MAX_GPIO_IRQS 256 > > +/* Valid only on HW version < 3.2 */ > #define IRQ_ENABLE_BANK 0x10 > #define IRQ_i_CFG 0x110 > > +/* Valid only on HW version >= 3.2 */ > +#define IRQ_i_CFG_IRQ_ENABLE 3 > + > +#define IRQ_i_CFG_TYPE_MASK GENMASK(2, 0) > + > +#define PDC_VERSION 0x1000 That's an offset, right? Maybe spelling it as such would make this more readable... > + > +/* Notable PDC versions */ > +enum { > + PDC_VERSION_3_2 = 0x30200, ... specially when reading this (why is it all of a sudden an enum?). > +}; > + > struct pdc_pin_region { > u32 pin_base; > u32 parent_base; > @@ -37,6 +50,7 @@ static DEFINE_RAW_SPINLOCK(pdc_lock); > static void __iomem *pdc_base; > static struct pdc_pin_region *pdc_region; > static int pdc_region_cnt; > +static unsigned int pdc_version; > > static void pdc_reg_write(int reg, u32 i, u32 val) > { > @@ -53,15 +67,22 @@ static void pdc_enable_intr(struct irq_data *d, bool on) > int pin_out = d->hwirq; > unsigned long enable; > unsigned long flags; > - u32 index, mask; > - > - index = pin_out / 32; > - mask = pin_out % 32; > > raw_spin_lock_irqsave(&pdc_lock, flags); > - enable = pdc_reg_read(IRQ_ENABLE_BANK, index); > - __assign_bit(mask, &enable, on); > - pdc_reg_write(IRQ_ENABLE_BANK, index, enable); > + if (pdc_version < PDC_VERSION_3_2) { > + u32 index, mask; > + > + index = pin_out / 32; > + mask = pin_out % 32; > + > + enable = pdc_reg_read(IRQ_ENABLE_BANK, index); > + __assign_bit(mask, &enable, on); > + pdc_reg_write(IRQ_ENABLE_BANK, index, enable); > + } else { > + enable = pdc_reg_read(IRQ_i_CFG, pin_out); > + __assign_bit(IRQ_i_CFG_IRQ_ENABLE, &enable, on); > + pdc_reg_write(IRQ_i_CFG, pin_out, enable); > + } > raw_spin_unlock_irqrestore(&pdc_lock, flags); > } > > @@ -142,6 +163,7 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) > } > > old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq); > + pdc_type |= (old_pdc_type & ~IRQ_i_CFG_TYPE_MASK); > pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type); > > ret = irq_chip_set_type_parent(d, type); > @@ -246,7 +268,7 @@ static const struct irq_domain_ops qcom_pdc_ops = { > static int pdc_setup_pin_mapping(struct device_node *np) > { > int ret, n, i; > - u32 irq_index, reg_index, val; > + unsigned long val; > > n = of_property_count_elems_of_size(np, "qcom,pdc-ranges", sizeof(u32)); > if (n <= 0 || n % 3) > @@ -277,28 +299,51 @@ static int pdc_setup_pin_mapping(struct device_node *np) > return ret; > > for (i = 0; i < pdc_region[n].cnt; i++) { > - reg_index = (i + pdc_region[n].pin_base) >> 5; > - irq_index = (i + pdc_region[n].pin_base) & 0x1f; > - val = pdc_reg_read(IRQ_ENABLE_BANK, reg_index); > - val &= ~BIT(irq_index); > - pdc_reg_write(IRQ_ENABLE_BANK, reg_index, val); > + if (pdc_version < PDC_VERSION_3_2) { > + u32 irq_index, reg_index; > + > + reg_index = (i + pdc_region[n].pin_base) >> 5; > + irq_index = (i + pdc_region[n].pin_base) & 0x1f; > + val = pdc_reg_read(IRQ_ENABLE_BANK, reg_index); > + __assign_bit(irq_index, &val, 0); > + pdc_reg_write(IRQ_ENABLE_BANK, reg_index, val); > + } else { > + u32 irq; > + > + irq = i + pdc_region[n].pin_base; > + val = pdc_reg_read(IRQ_i_CFG, irq); > + __assign_bit(IRQ_i_CFG_IRQ_ENABLE, &val, 0); > + pdc_reg_write(IRQ_i_CFG, irq, val); > + } This is a bit backwards. The PDC version doesn't change within the loop. But more importantly, this is a rewrite of the pdc_enable_intr() helper, only taking raw indices instead of an irq_data pointer. Surely this can be written in a better way. > } > } > > return 0; > } > > +#define QCOM_PDC_SIZE 0x30000 > + > static int qcom_pdc_init(struct device_node *node, struct device_node *parent) > { > struct irq_domain *parent_domain, *pdc_domain; > + struct resource res; > + resource_size_t res_size; nit: swapping these two lines will make things vaguely more readable. > int ret; > > - pdc_base = of_iomap(node, 0); > + /* compat with old sm8150 DT which had very small region for PDC */ > + if (of_address_to_resource(node, 0, &res)) > + return -EINVAL; > + > + res_size = max_t(resource_size_t, resource_size(&res), QCOM_PDC_SIZE); This probably deserves a warning so that DTs that do not have the correct size get fixed. Thanks, M. -- Without deviation from the norm, progress is not possible. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 2/2] arm64: dts: qcom: sm8150: extend the size of the PDC resource 2023-08-29 9:21 [PATCH v3 0/2] irqchip/qcom-pdc: support v3.2 HW Dmitry Baryshkov 2023-08-29 9:21 ` [PATCH v3 1/2] irqchip/qcom-pdc: Add support for " Dmitry Baryshkov @ 2023-08-29 9:21 ` Dmitry Baryshkov 2023-08-29 9:33 ` Neil Armstrong 1 sibling, 1 reply; 6+ messages in thread From: Dmitry Baryshkov @ 2023-08-29 9:21 UTC (permalink / raw) To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Thomas Gleixner, Marc Zyngier Cc: linux-arm-msm, linux-kernel Follow the example of other platforms and extend the PDC resource region to 0x30000, so that the PDC driver can read the PDC_VERSION register. Fixes: 397ad94668c1 ("arm64: dts: qcom: sm8150: Add pdc interrupt controller node") Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> --- arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index 380712aee977..38c5d6dbd0d7 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -3923,7 +3923,7 @@ dispcc: clock-controller@af00000 { pdc: interrupt-controller@b220000 { compatible = "qcom,sm8150-pdc", "qcom,pdc"; - reg = <0 0x0b220000 0 0x400>; + reg = <0 0x0b220000 0 0x30000>; qcom,pdc-ranges = <0 480 94>, <94 609 31>, <125 63 1>; #interrupt-cells = <2>; -- 2.39.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 2/2] arm64: dts: qcom: sm8150: extend the size of the PDC resource 2023-08-29 9:21 ` [PATCH v3 2/2] arm64: dts: qcom: sm8150: extend the size of the PDC resource Dmitry Baryshkov @ 2023-08-29 9:33 ` Neil Armstrong 0 siblings, 0 replies; 6+ messages in thread From: Neil Armstrong @ 2023-08-29 9:33 UTC (permalink / raw) To: Dmitry Baryshkov, Andy Gross, Bjorn Andersson, Konrad Dybcio, Thomas Gleixner, Marc Zyngier Cc: linux-arm-msm, linux-kernel On 29/08/2023 11:21, Dmitry Baryshkov wrote: > Follow the example of other platforms and extend the PDC resource region > to 0x30000, so that the PDC driver can read the PDC_VERSION register. > > Fixes: 397ad94668c1 ("arm64: dts: qcom: sm8150: Add pdc interrupt controller node") > Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> > --- > arch/arm64/boot/dts/qcom/sm8150.dtsi | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi > index 380712aee977..38c5d6dbd0d7 100644 > --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi > +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi > @@ -3923,7 +3923,7 @@ dispcc: clock-controller@af00000 { > > pdc: interrupt-controller@b220000 { > compatible = "qcom,sm8150-pdc", "qcom,pdc"; > - reg = <0 0x0b220000 0 0x400>; > + reg = <0 0x0b220000 0 0x30000>; > qcom,pdc-ranges = <0 480 94>, <94 609 31>, > <125 63 1>; > #interrupt-cells = <2>; Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org> ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-08-29 12:31 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-08-29 9:21 [PATCH v3 0/2] irqchip/qcom-pdc: support v3.2 HW Dmitry Baryshkov 2023-08-29 9:21 ` [PATCH v3 1/2] irqchip/qcom-pdc: Add support for " Dmitry Baryshkov 2023-08-29 9:50 ` Maulik Shah (mkshah) 2023-08-29 12:30 ` Marc Zyngier 2023-08-29 9:21 ` [PATCH v3 2/2] arm64: dts: qcom: sm8150: extend the size of the PDC resource Dmitry Baryshkov 2023-08-29 9:33 ` Neil Armstrong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox