[PATCH 1/4] [POWERPC] cpm2: Updates for CPM2 pic
Kumar Gala
galak at kernel.crashing.org
Wed Dec 13 06:58:44 EST 2006
On Dec 12, 2006, at 12:55 PM, Vitaly Bordug wrote:
> On Mon, 11 Dec 2006 20:21:52 -0600
> Kumar Gala <galak at kernel.crashing.org> wrote:
>
>>
>> On Dec 11, 2006, at 4:36 PM, Vitaly Bordug wrote:
>>
>>>
>>> This contains important fixes for the CPM2 PIC code. Eliminated
>>> CPM_IRQ_OFFSET, pulling the respective interrupt numbers from the
>>> interrupt
>>> mapping. Updated devicetree files to reflect that. Changed direct
>>> IC-related IO accesses to the IO accessors.
>>
>> Since your changing the interrupt numbers, do you mind changing the
>> interrupt sense to match ipic? I was hoping to introduce a generic
>> host_xlate function to cover the various embedded pic's.
> Umm, can you pls elaborate what do you want to achieve?
Its a minor thing, but the values we picked for ipic to encode sense/
polarity match the linux definitions. The idea is that if we use
the same encoding on multiple pic's we can sure the host_xlate code.
> I'm inlining updated patch with cpm2_set_irq_type () func which
> sets up
> senses for EXT irq's and PortC irq's. ipic seems to have only EXT
> irq's hence
> this approach differs from ipic one...
>
>
>
>
> This contains important fixes for the CPM2 PIC code. Eliminated
> CPM_IRQ_OFFSET, pulling the respective interrupt numbers from the
> interrupt
> mapping. Updated devicetree files to reflect that. Changed direct
> IC-related IO accesses to the IO accessors.
>
> Signed-off-by: Vitaly Bordug <vbordug at ru.mvista.com>
> ---
>
> arch/powerpc/boot/dts/mpc8560ads.dts | 8 +-
> arch/powerpc/sysdev/cpm2_pic.c | 127 +++++++++++++++++++
> +--------------
> arch/powerpc/sysdev/cpm2_pic.h | 9 ++
> include/asm-powerpc/mpc8260.h | 32 +++++++++
> 4 files changed, 120 insertions(+), 56 deletions(-)
>
> diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/
> boot/dts/mpc8560ads.dts
> index 2b16848..3c1e44a 100644
> --- a/arch/powerpc/boot/dts/mpc8560ads.dts
> +++ b/arch/powerpc/boot/dts/mpc8560ads.dts
> @@ -250,7 +250,7 @@
> rx-clock = <1>;
> tx-clock = <1>;
> current-speed = <1c200>;
> - interrupts = <64 1>;
> + interrupts = <28 1>;
> interrupt-parent = <90c00>;
> };
>
> @@ -264,7 +264,7 @@
> rx-clock = <2>;
> tx-clock = <2>;
> current-speed = <1c200>;
> - interrupts = <65 1>;
> + interrupts = <29 1>;
> interrupt-parent = <90c00>;
> };
>
> @@ -278,7 +278,7 @@
> clock-setup = <ff00ffff 250000>;
> rx-clock = <15>;
> tx-clock = <16>;
> - interrupts = <5d 1>;
> + interrupts = <21 1>;
> interrupt-parent = <90c00>;
> phy-handle = <2452002>;
> };
> @@ -293,7 +293,7 @@
> clock-setup = <ffff00ff 3700>;
> rx-clock = <17>;
> tx-clock = <18>;
> - interrupts = <5e 1>;
> + interrupts = <22 1>;
> interrupt-parent = <90c00>;
> phy-handle = <2452003>;
> };
> diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/
> cpm2_pic.c
> index 767ee66..bf5c952 100644
> --- a/arch/powerpc/sysdev/cpm2_pic.c
> +++ b/arch/powerpc/sysdev/cpm2_pic.c
> @@ -36,6 +36,7 @@ #include <asm/immap_cpm2.h>
> #include <asm/mpc8260.h>
> #include <asm/io.h>
> #include <asm/prom.h>
> +#include <asm/fs_pd.h>
>
> #include "cpm2_pic.h"
>
> @@ -68,68 +69,55 @@ static const u_char irq_to_siubit[] = {
> 24, 25, 26, 27, 28, 29, 30, 31,
> };
>
> -static void cpm2_mask_irq(unsigned int irq_nr)
> +static void cpm2_mask_irq(unsigned int irq)
> {
> int bit, word;
> - volatile uint *simr;
> -
> - irq_nr -= CPM_IRQ_OFFSET;
> + unsigned int irq_nr = (unsigned int)irq_map[irq].hwirq;
>
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
>
> - simr = &(cpm2_intctl->ic_simrh);
> ppc_cached_irq_mask[word] &= ~(1 << bit);
> - simr[word] = ppc_cached_irq_mask[word];
> + out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
> }
>
> -static void cpm2_unmask_irq(unsigned int irq_nr)
> +static void cpm2_unmask_irq(unsigned int irq)
> {
> int bit, word;
> - volatile uint *simr;
> -
> - irq_nr -= CPM_IRQ_OFFSET;
> + unsigned int irq_nr = (unsigned int)irq_map[irq].hwirq;
>
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
>
> - simr = &(cpm2_intctl->ic_simrh);
> ppc_cached_irq_mask[word] |= 1 << bit;
> - simr[word] = ppc_cached_irq_mask[word];
> + out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
> }
>
> -static void cpm2_mask_and_ack(unsigned int irq_nr)
> +static void cpm2_ack(unsigned int irq)
> {
> int bit, word;
> - volatile uint *simr, *sipnr;
> -
> - irq_nr -= CPM_IRQ_OFFSET;
> + unsigned int irq_nr = (unsigned int)irq_map[irq].hwirq;
>
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
>
> - simr = &(cpm2_intctl->ic_simrh);
> - sipnr = &(cpm2_intctl->ic_sipnrh);
> - ppc_cached_irq_mask[word] &= ~(1 << bit);
> - simr[word] = ppc_cached_irq_mask[word];
> - sipnr[word] = 1 << bit;
> + out_be32(&cpm2_intctl->ic_sipnrh + word, 1 << bit);
> }
>
> -static void cpm2_end_irq(unsigned int irq_nr)
> +static void cpm2_end_irq(unsigned int irq)
> {
> int bit, word;
> - volatile uint *simr;
> + unsigned int irq_nr = (unsigned int)irq_map[irq].hwirq;
>
> if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
> && irq_desc[irq_nr].action) {
>
> - irq_nr -= CPM_IRQ_OFFSET;
> bit = irq_to_siubit[irq_nr];
> word = irq_to_siureg[irq_nr];
>
> - simr = &(cpm2_intctl->ic_simrh);
> ppc_cached_irq_mask[word] |= 1 << bit;
> - simr[word] = ppc_cached_irq_mask[word];
> + out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
> +
> /*
> * Work around large numbers of spurious IRQs on PowerPC 82xx
> * systems.
> @@ -138,13 +126,59 @@ static void cpm2_end_irq(unsigned int ir
> }
> }
>
> +static int cpm2_set_irq_type(unsigned int virq, unsigned int
> flow_type)
> +{
> + unsigned int src = (unsigned int)irq_map[virq].hwirq;
> + struct irq_desc *desc = get_irq_desc(virq);
> + unsigned int vold, vnew, edibit;
> +
> + if (flow_type == IRQ_TYPE_NONE)
> + flow_type = IRQ_TYPE_LEVEL_LOW;
> +
> + if (flow_type & IRQ_TYPE_EDGE_RISING) {
> + printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n",
> + flow_type);
> + return -EINVAL;
> + }
> +
> + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
> + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
> + if (flow_type & IRQ_TYPE_LEVEL_LOW) {
> + desc->status |= IRQ_LEVEL;
> + desc->handle_irq = handle_level_irq;
> + } else
> + desc->handle_irq = handle_edge_irq;
> +
> + /* internal IRQ senses are LEVEL_LOW
> + * EXT IRQ and Port C IRQ senses are programmable
> + */
> + if (src >= CPM2_IRQ_EXT1 && src <= CPM2_IRQ_EXT7)
> + edibit = (14 - (src - CPM2_IRQ_EXT1));
> + else
> + if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0)
> + edibit = (31 - (src - CPM2_IRQ_PORTC15));
> + else
> + return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
> +
> + vold = in_be32(&cpm2_intctl->ic_siexr);
> +
> + if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING)
> + vnew = vold | (1 << edibit);
> + else
> + vnew = vold & ~(1 << edibit);
> +
> + if (vold != vnew)
> + out_be32(&cpm2_intctl->ic_siexr, vnew);
> + return 0;
> +}
> +
> static struct irq_chip cpm2_pic = {
> .typename = " CPM2 SIU ",
> - .enable = cpm2_unmask_irq,
> - .disable = cpm2_mask_irq,
> + .mask = cpm2_mask_irq,
> .unmask = cpm2_unmask_irq,
> - .mask_ack = cpm2_mask_and_ack,
> - .end = cpm2_end_irq,
> + .ack = cpm2_ack,
> + .eoi = cpm2_end_irq,
> + .set_type = cpm2_set_irq_type,
> };
>
> unsigned int cpm2_get_irq(void)
> @@ -154,17 +188,17 @@ unsigned int cpm2_get_irq(void)
>
> /* For CPM2, read the SIVEC register and shift the bits down
> * to get the irq number. */
> - bits = cpm2_intctl->ic_sivec;
> + bits = in_be32(&cpm2_intctl->ic_sivec);
> irq = bits >> 26;
>
> if (irq == 0)
> return(-1);
> - return irq+CPM_IRQ_OFFSET;
> + return irq_linear_revmap(cpm2_pic_host, irq);
> }
>
> static int cpm2_pic_host_match(struct irq_host *h, struct
> device_node *node)
> {
> - return cpm2_pic_node == NULL || cpm2_pic_node == node;
> + return cpm2_pic_node == node;
> }
>
> static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
> @@ -177,15 +211,6 @@ static int cpm2_pic_host_map(struct irq_
> return 0;
> }
>
> -static void cpm2_host_unmap(struct irq_host *h, unsigned int virq)
> -{
> - /* Make sure irq is masked in hardware */
> - cpm2_mask_irq(virq);
> -
> - /* remove chip and handler */
> - set_irq_chip_and_handler(virq, NULL, NULL);
> -}
> -
> static int cpm2_pic_host_xlate(struct irq_host *h, struct
> device_node *ct,
> u32 *intspec, unsigned int intsize,
> irq_hw_number_t *out_hwirq, unsigned int *out_flags)
> @@ -202,14 +227,12 @@ static int cpm2_pic_host_xlate(struct ir
> *out_flags = map_cpm2_senses[intspec[1]];
> else
> *out_flags = IRQ_TYPE_NONE;
> -
> return 0;
> }
>
> static struct irq_host_ops cpm2_pic_host_ops = {
> .match = cpm2_pic_host_match,
> .map = cpm2_pic_host_map,
> - .unmap = cpm2_host_unmap,
> .xlate = cpm2_pic_host_xlate,
> };
>
> @@ -223,26 +246,26 @@ void cpm2_pic_init(struct device_node *n
>
> /* Mask out everything */
>
> - cpm2_intctl->ic_simrh = 0x00000000;
> - cpm2_intctl->ic_simrl = 0x00000000;
> + out_be32(&cpm2_intctl->ic_simrh, 0x00000000);
> + out_be32(&cpm2_intctl->ic_simrl, 0x00000000);
>
> wmb();
>
> /* Ack everything */
> - cpm2_intctl->ic_sipnrh = 0xffffffff;
> - cpm2_intctl->ic_sipnrl = 0xffffffff;
> + out_be32(&cpm2_intctl->ic_sipnrh, 0xffffffff);
> + out_be32(&cpm2_intctl->ic_sipnrl, 0xffffffff);
> wmb();
>
> /* Dummy read of the vector */
> - i = cpm2_intctl->ic_sivec;
> + i = in_be32(&cpm2_intctl->ic_sivec);
> rmb();
>
> /* Initialize the default interrupt mapping priorities,
> * in case the boot rom changed something on us.
> */
> - cpm2_intctl->ic_sicr = 0;
> - cpm2_intctl->ic_scprrh = 0x05309770;
> - cpm2_intctl->ic_scprrl = 0x05309770;
> + out_be16(&cpm2_intctl->ic_sicr, 0);
> + out_be32(&cpm2_intctl->ic_scprrh, 0x05309770);
> + out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
>
> /* create a legacy host */
> if (node)
> diff --git a/arch/powerpc/sysdev/cpm2_pic.h b/arch/powerpc/sysdev/
> cpm2_pic.h
> index 2840616..643a857 100644
> --- a/arch/powerpc/sysdev/cpm2_pic.h
> +++ b/arch/powerpc/sysdev/cpm2_pic.h
> @@ -1,6 +1,15 @@
> #ifndef _PPC_KERNEL_CPM2_H
> #define _PPC_KERNEL_CPM2_H
>
> +
> +/* External IRQS */
> +#define CPM2_IRQ_EXT1 19
> +#define CPM2_IRQ_EXT7 25
> +
> +/* Port C IRQS */
> +#define CPM2_IRQ_PORTC15 48
> +#define CPM2_IRQ_PORTC0 63
> +
> extern intctl_cpm2_t *cpm2_intctl;
>
> extern unsigned int cpm2_get_irq(void);
> diff --git a/include/asm-powerpc/mpc8260.h b/include/asm-powerpc/
> mpc8260.h
> new file mode 100644
> index 0000000..c2adcb0
> --- /dev/null
> +++ b/include/asm-powerpc/mpc8260.h
> @@ -0,0 +1,32 @@
> +/*
> + * Since there are many different boards and no standard
> configuration,
> + * we have a unique include file for each. Rather than change every
> + * file that has to include MPC8260 configuration, they all include
> + * this one and the configuration switching is done here.
> + */
> +#ifdef __KERNEL__
> +#ifndef __ASM_PPC_MPC8260_H__
> +#define __ASM_PPC_MPC8260_H__
> +
> +
> +#ifdef CONFIG_8260
> +
> +#if defined(CONFIG_PQ2ADS) || defined (CONFIG_PQ2FADS)
> +#include <platforms/82xx/pq2ads.h>
> +#endif
> +
> +#ifdef CONFIG_PCI_8260
> +#include <platforms/82xx/m82xx_pci.h>
> +#endif
> +
> +#ifndef _ISA_MEM_BASE
> +#define _ISA_MEM_BASE 0
> +#endif
> +
> +#ifndef PCI_DRAM_OFFSET
> +#define PCI_DRAM_OFFSET 0
> +#endif
> +
> +#endif /* CONFIG_8260 */
> +#endif /* !__ASM_PPC_MPC8260_H__ */
> +#endif /* __KERNEL__ */
>
>
> --
> Sincerely,
> Vitaly
More information about the Linuxppc-dev
mailing list