On Jul 9, 2012, at 3:45 AM, Varun Sethi wrote:

> Previously, these interrupts would be mapped, but the offset
> calculation was broken, and only the first group was initialized.
> 
> Signed-off-by: Scott Wood <scottw...@freescale.com>
> ---
> arch/powerpc/include/asm/mpic.h |    5 +++
> arch/powerpc/sysdev/mpic.c      |   58 ++++++++++++++++++++++++++++-----------
> 2 files changed, 47 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
> index c9f698a..e14d35d 100644
> --- a/arch/powerpc/include/asm/mpic.h
> +++ b/arch/powerpc/include/asm/mpic.h
> @@ -63,6 +63,7 @@
>  */
> #define MPIC_TIMER_BASE                       0x01100
> #define MPIC_TIMER_STRIDE             0x40
> +#define MPIC_TIMER_GROUP_STRIDE              0x1000
> 
> #define MPIC_TIMER_CURRENT_CNT                0x00000
> #define MPIC_TIMER_BASE_CNT           0x00010
> @@ -110,6 +111,9 @@
> #define       MPIC_VECPRI_SENSE_MASK                  0x00400000
> #define MPIC_IRQ_DESTINATION          0x00010
> 
> +#define MPIC_FSL_BRR1                        0x00000
> +#define      MPIC_FSL_BRR1_VER                       0x0000ffff
> +
> #define MPIC_MAX_IRQ_SOURCES  2048
> #define MPIC_MAX_CPUS         32
> #define MPIC_MAX_ISU          32
> @@ -296,6 +300,7 @@ struct mpic
>       phys_addr_t paddr;
> 
>       /* The various ioremap'ed bases */
> +     struct mpic_reg_bank    thiscpuregs;
>       struct mpic_reg_bank    gregs;
>       struct mpic_reg_bank    tmregs;
>       struct mpic_reg_bank    cpuregs[MPIC_MAX_CPUS];
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index 395af13..a98eb77 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -6,7 +6,7 @@
>  *  with various broken implementations of this HW.
>  *
>  *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
> - *  Copyright 2010-2011 Freescale Semiconductor, Inc.
> + *  Copyright 2010-2012 Freescale Semiconductor, Inc.
>  *
>  *  This file is subject to the terms and conditions of the GNU General Public
>  *  License.  See the file COPYING in the main directory of this archive
> @@ -221,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, 
> unsigned int ipi, u32 valu
>       _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
> }
> 
> -static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
> +static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
> {
> -     unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
> -                           ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
> +     return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
> +            (tm & 3) * MPIC_INFO(TIMER_STRIDE);
> +}
> 
> -     if (tm >= 4)
> -             offset += 0x1000 / 4;
> +static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
> +{
> +     unsigned int offset = mpic_tm_offset(mpic, tm) +
> +                           MPIC_INFO(TIMER_VECTOR_PRI);
> 
>       return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
> }
> 
> static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 
> value)
> {
> -     unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
> -                           ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
> -
> -     if (tm >= 4)
> -             offset += 0x1000 / 4;
> +     unsigned int offset = mpic_tm_offset(mpic, tm) +
> +                           MPIC_INFO(TIMER_VECTOR_PRI);
> 
>       _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
> }
> @@ -1301,6 +1301,16 @@ struct mpic * __init mpic_alloc(struct device_node 
> *node,
>       mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
>       mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 
> 0x1000);
> 
> +     if (mpic->flags & MPIC_FSL) {
> +             /*
> +              * Yes, Freescale really did put global registers in the
> +              * magic per-cpu area -- and they don't even show up in the
> +              * non-magic per-cpu copies that this driver normally uses.
> +              */
> +             mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
> +                      MPIC_CPU_THISBASE, 0x1000);
> +     }
> +
>       /* Reset */
> 
>       /* When using a device-node, reset requests are only honored if the MPIC
> @@ -1440,6 +1450,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned 
> int isu_num,
> void __init mpic_init(struct mpic *mpic)
> {
>       int i, cpu;
> +     int num_timers = 4;
> 
>       BUG_ON(mpic->num_sources == 0);
> 
> @@ -1448,15 +1459,30 @@ void __init mpic_init(struct mpic *mpic)
>       /* Set current processor priority to max */
>       mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
> 
> +     if (mpic->flags & MPIC_FSL) {
> +             u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
> +                                   MPIC_FSL_BRR1);
> +             u32 version = brr1 & MPIC_FSL_BRR1_VER;
> +
> +             /*
> +              * Timer group B is present at the latest in MPIC 3.1 (e.g.
> +              * mpc8536).  It is not present in MPIC 2.0 (e.g. mpc8544).
> +              * I don't know about the status of intermediate versions (or
> +              * whether they even exist).
> +              */
> +             if (version >= 0x0301)
> +                     num_timers = 8;
> +     }
> +

Why don't we do this just via the device tree?

>       /* Initialize timers to our reserved vectors and mask them for now */
> -     for (i = 0; i < 4; i++) {
> +     for (i = 0; i < num_timers; i++) {
> +             unsigned int offset = mpic_tm_offset(mpic, i);
> +
>               mpic_write(mpic->tmregs,
> -                        i * MPIC_INFO(TIMER_STRIDE) +
> -                        MPIC_INFO(TIMER_DESTINATION),
> +                        offset + MPIC_INFO(TIMER_DESTINATION),
>                          1 << hard_smp_processor_id());
>               mpic_write(mpic->tmregs,
> -                        i * MPIC_INFO(TIMER_STRIDE) +
> -                        MPIC_INFO(TIMER_VECTOR_PRI),
> +                        offset + MPIC_INFO(TIMER_VECTOR_PRI),
>                          MPIC_VECPRI_MASK |
>                          (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
>                          (mpic->timer_vecs[0] + i));
> -- 
> 1.7.2.2
> 

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to