irqchip/irq-csky-mpintc: Add triger type and priority
Subsystems (3)
[email protected]
maintainerPATCH v2 1/2 irqchip/irq-csky-mpintc: Add triger type and priority
From: Guo Ren <[email protected]>
Support 4 triger types:
- IRQ_TYPE_LEVEL_HIGH
- IRQ_TYPE_LEVEL_LOW
- IRQ_TYPE_EDGE_RISING
- IRQ_TYPE_EDGE_FALLING
Support 0-255 priority setting for each irq.
Changelog:
- Fixup this_cpu_read() preempted problem.
- Optimize the coding style.
--- drivers/irqchip/irq-csky-mpintc.c | 105 +++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-)
drivers/irqchip/irq-csky-mpintc.c +104 -1
@@ -17,6 +17,7 @@#include <asm/reg_ops.h> static struct irq_domain *root_domain; +static void __iomem *INTCG_base;static void __iomem *INTCL_base;
@@ -29,9 +30,12 @@ static void __iomem *INTCL_base;#define INTCG_ICTLR 0x0#define INTCG_CICFGR 0x100 +#define INTCG_CIPRTR 0x200#define INTCG_CIDSTR 0x1000#define INTCL_PICTLR 0x0 +#define INTCL_CFGR 0x14 +#define INTCL_PRTR 0x20#define INTCL_SIGR 0x60#define INTCL_RDYIR 0x6c#define INTCL_SENR 0xa0
@@ -40,6 +44,51 @@ static void __iomem *INTCL_base; static DEFINE_PER_CPU(void __iomem *, intcl_reg); +static unsigned long *__trigger; +static unsigned long *__priority; + +#define IRQ_OFFSET (irq) ((irq < COMM_IRQ_BASE) ? irq : (irq - COMM_IRQ_BASE)) + +#define TRIG_BYTE_OFFSET (i) ((((i) * 2) / 32) * 4) +#define TRIG_BIT_OFFSET (i) (((i) * 2) % 32) + +#define PRI_BYTE_OFFSET (i) ((((i) * 8) / 32) * 4) +#define PRI_BIT_OFFSET (i) (((i) * 8) % 32) + +#define TRIG_VAL (trigger, irq) (trigger << TRIG_BIT_OFFSET(IRQ_OFFSET(irq))) +#define TRIG_VAL_MSK (irq) (~(3 << TRIG_BIT_OFFSET(IRQ_OFFSET(irq)))) +#define PRI_VAL (priority, irq) (priority << PRI_BIT_OFFSET(IRQ_OFFSET(irq))) +#define PRI_VAL_MSK (irq) (~(0xff << PRI_BIT_OFFSET(IRQ_OFFSET(irq)))) + +#define TRIG_BASE (irq) \ + (TRIG_BYTE_OFFSET(IRQ_OFFSET(irq)) + ((irq < COMM_IRQ_BASE) ? \ + (this_cpu_read(intcl_reg) + INTCL_CFGR) : (INTCG_base + INTCG_CICFGR))) + +#define PRI_BASE (irq) \ + (PRI_BYTE_OFFSET(IRQ_OFFSET(irq)) + ((irq < COMM_IRQ_BASE) ? \ + (this_cpu_read(intcl_reg) + INTCL_PRTR) : (INTCG_base + INTCG_CIPRTR))) + +static DEFINE_SPINLOCK (setup_lock); +static void setup_trigger_priority (unsigned long irq,unsigned long trigger, +unsigned long priority) +{ +unsigned int tmp; + +spin_lock (&setup_lock); + +/* setup trigger */ + tmp =readl_relaxed (TRIG_BASE (irq)) &TRIG_VAL_MSK (irq); + +writel_relaxed (tmp |TRIG_VAL (trigger, irq),TRIG_BASE (irq)); + +/* setup priority */ + tmp =readl_relaxed (PRI_BASE (irq)) &PRI_VAL_MSK (irq); + +writel_relaxed (tmp |PRI_VAL (priority, irq),PRI_BASE (irq)); + +spin_unlock (&setup_lock); +} +static void csky_mpintc_handler (struct pt_regs *regs) {void __iomem *reg_base =this_cpu_read (intcl_reg);
@@ -52,6 +101,9 @@ static void csky_mpintc_enable(struct irq_data *d) {void __iomem *reg_base =this_cpu_read (intcl_reg); +setup_trigger_priority (d->hwirq, __trigger[d->hwirq], + __priority[d->hwirq]); +writel_relaxed (d->hwirq, reg_base +INTCL_SENR ); }
@@ -69,6 +121,28 @@ static void csky_mpintc_eoi(struct irq_data *d)writel_relaxed (d->hwirq, reg_base +INTCL_CACR ); } +static int csky_mpintc_set_type (struct irq_data *d,unsigned int type) +{ +switch (type &IRQ_TYPE_SENSE_MASK ) { +case IRQ_TYPE_LEVEL_HIGH : + __trigger[d->hwirq] =0 ; +break ; +case IRQ_TYPE_LEVEL_LOW : + __trigger[d->hwirq] =1 ; +break ; +case IRQ_TYPE_EDGE_RISING : + __trigger[d->hwirq] =2 ; +break ; +case IRQ_TYPE_EDGE_FALLING : + __trigger[d->hwirq] =3 ; +break ; +default : +return -EINVAL ; + } + +return 0 ; +} +#ifdef CONFIG_SMP static int csky_irq_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
@@ -101,6 +175,7 @@ static struct irq_chip csky_irq_chip = { .irq_eoi = csky_mpintc_eoi, .irq_enable = csky_mpintc_enable, .irq_disable = csky_mpintc_disable, + .irq_set_type = csky_mpintc_set_type,#ifdef CONFIG_SMP .irq_set_affinity = csky_irq_set_affinity,#endif
@@ -121,9 +196,29 @@ static int csky_irqdomain_map(struct irq_domain *d, unsigned int irq,return 0 ; } +static int csky_irq_domain_xlate_cells (struct irq_domain *d, +struct device_node *ctrlr,const u32 *intspec, +unsigned int intsize,unsigned long *out_hwirq, +unsigned int *out_type) +{ +if (WARN_ON (intsize <1 )) +return -EINVAL ; + + *out_hwirq = intspec[0 ]; +if (intsize >1 ) + *out_type = intspec[1 ] &IRQ_TYPE_SENSE_MASK ; +else + *out_type =IRQ_TYPE_NONE ; + +if (intsize >2 ) + __priority[*out_hwirq] = intspec[2 ]; + +return 0 ; +} +static const struct irq_domain_ops csky_irqdomain_ops = { .map = csky_irqdomain_map, - .xlate = irq_domain_xlate_onecell, + .xlate = csky_irq_domain_xlate_cells, };#ifdef CONFIG_SMP
@@ -157,6 +252,14 @@ csky_mpintc_init(struct device_node *node, struct device_node *parent)if (ret <0 ) nr_irq =INTC_IRQS ; + __priority =kcalloc (nr_irq,sizeof (unsigned long ),GFP_KERNEL ); +if (__priority ==NULL ) +return -ENXIO ; + + __trigger =kcalloc (nr_irq,sizeof (unsigned long ),GFP_KERNEL ); +if (__trigger ==NULL ) +return -ENXIO ; +if (INTCG_base ==NULL ) { INTCG_base =ioremap (mfcr ("cr<31, 14>" ),INTCL_SIZE *nr_cpu_ids +INTCG_SIZE );
Signature · 1 line
2.7.4
[email protected]
maintainerPATCH v2 2/2 dt-bindings: interrupt-controller: Update csky mpintc
From: Guo Ren <[email protected]>
Add trigger type and priority setting for csky,mpintc.
--- .../bindings/interrupt-controller/csky,mpintc.txt | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt +29 -4
@@ -6,11 +6,18 @@ C-SKY Multi-processors Interrupt Controller is designed for ck807/ck810/ck860 SMP soc, and it also could be used in non-SMP system. Interrupt number definition: - 0-15 : software irq, and we use 15 as our IPI_IRQ. 16-31 : private irq, and we use 16 as the co-processor timer. 31-1024: common irq for soc ip. +Interrupt triger mode: + IRQ_TYPE_LEVEL_HIGH (default) + IRQ_TYPE_LEVEL_LOW + IRQ_TYPE_EDGE_RISING + IRQ_TYPE_EDGE_FALLING + +Interrupt priority range: 0-255 + ============================= intc node bindings definition =============================
@@ -26,15 +33,33 @@ intc node bindings definition - #interrupt-cells Usage: required Value type: <u32> - Definition: must be <1> + Definition: could be <1> or <2> or <3> - interrupt-controller: Usage: required -Examples: +Examples: ("interrupts = <irq IRQ_TYPE_XXX priority>") --------- intc: interrupt-controller { compatible = "csky,mpintc"; - #interrupt-cells = <1>; + #interrupt-cells = <3>; interrupt-controller; }; + + 0: device-example0 { + ... + interrupts = <33>; + interrupt-parent = <&intc>; + }; + + 1: device-example1 { + ... + interrupts = <33 IRQ_TYPE_EDGE_RISING>; + interrupt-parent = <&intc>; + }; + + 2: device-example2 { + ... + interrupts = <34 IRQ_TYPE_EDGE_RISING 254>; + interrupt-parent = <&intc>; + };
Signature · 1 line
2.7.4
Re: [PATCH V2 2/2] dt-bindings: interrupt-controller: Update csky mpintc
Quoted 35 lines · On Fri, Jan 18, 2019 at 10:53 AM <[email protected]> wrote:
From: Guo Ren <[email protected]>
Add trigger type and priority setting for csky,mpintc.
Signed-off-by Guo Ren <[email protected]>--- .../bindings/interrupt-controller/csky,mpintc.txt | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-)Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt +8
-1@@ -6,11 +6,18 @@ C-SKY Multi-processors Interrupt Controller is designed for ck807/ck810/ck860 SMP soc, and it also could be used in non-SMP system. Interrupt number definition: - 0-15 : software irq, and we use 15 as our IPI_IRQ. 16-31 : private irq, and we use 16 as the co-processor timer. 31-1024: common irq for soc ip. +Interrupt triger mode: + IRQ_TYPE_LEVEL_HIGH (default) + IRQ_TYPE_LEVEL_LOW + IRQ_TYPE_EDGE_RISING + IRQ_TYPE_EDGE_FALLING + +Interrupt priority range: 0-255 + ============================= intc node bindings definition =============================
Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt intc node bindings definition · line 36
Quoted 5 lines
Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt +1
-1@@ -26,15 +33,33 @@ intc node bindings definition - #interrupt-cells Usage: required Value type: <u32> - Definition: must be <1> + Definition: could be <1> or <2> or <3>
For a given controller, '#interrupt-cells' shouldn't really be variable. If there are different capabilities, then you should have different compatible strings.
Rob
Guo Ren
maintainerRe: [PATCH V2 2/2] dt-bindings: interrupt-controller: Update csky mpintc
Quoted 37 lines · Rob Herring
Quoted 36 lines · On Fri, Jan 18, 2019 at 10:53 AM <[email protected]> wrote:
From: Guo Ren <[email protected]>
Add trigger type and priority setting for csky,mpintc.
Signed-off-by Guo Ren <[email protected]>--- .../bindings/interrupt-controller/csky,mpintc.txt | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-)Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt +8
-1@@ -6,11 +6,18 @@ C-SKY Multi-processors Interrupt Controller is designed for ck807/ck810/ck860 SMP soc, and it also could be used in non-SMP system. Interrupt number definition: - 0-15 : software irq, and we use 15 as our IPI_IRQ. 16-31 : private irq, and we use 16 as the co-processor timer. 31-1024: common irq for soc ip. +Interrupt triger mode: + IRQ_TYPE_LEVEL_HIGH (default) + IRQ_TYPE_LEVEL_LOW + IRQ_TYPE_EDGE_RISING + IRQ_TYPE_EDGE_FALLING + +Interrupt priority range: 0-255 + ============================= intc node bindings definition =============================@@ -26,15 +33,33 @@ intc node bindings definition - #interrupt-cells
Quoted 8 lines
Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt intc node bindings definition · line 36
Quoted 4 lines
Documentation/devicetree/bindings/interrupt-controller/csky,mpintc.txt +1
-1Usage: required Value type: <u32> - Definition: must be <1> + Definition: could be <1> or <2> or <3>For a given controller, '#interrupt-cells' shouldn't really be variable. If there are different capabilities, then you should have different compatible strings.
Ok, I'll Define it to <3>, see my next version of patch.
<irqnum trigger_type priority>
Best Regards
Guo Ren