On Mon, 2008-02-04 at 21:27 +0300, Valentine Barshak wrote:
> Since we have mfdcri() and mtdcri() as macros, we can't use constructions, 
> such
> as "mtdcri(base, reg, mfdcri(base, reg) | val)". In this case the mfdcri() 
> stuff
> is not evaluated first. It's evaluated inside the mtdcr() macro and we have
> the dcr_ind_lock spinlock acquired twice. To avoid this error, I've added
> set_dcri() and clr_dcri() macros which set/clear the specified bits.
> 
> Signed-off-by: Valentine Barshak <[EMAIL PROTECTED]>

No, better is to fix the macros to use functions.

Make mfdcri/mtdcri call into __mfdcri/__mtdcri functions after fixing
up the macro register names, and have those be inlines that take the
lock.

Ben.

>  arch/powerpc/sysdev/ppc4xx_pci.c |   13 +++++--------
>  include/asm-powerpc/dcr-native.h |   22 ++++++++++++++++++++++
>  2 files changed, 27 insertions(+), 8 deletions(-)
> 
> diff -pruN linux-2.6.orig/arch/powerpc/sysdev/ppc4xx_pci.c 
> linux-2.6/arch/powerpc/sysdev/ppc4xx_pci.c
> --- linux-2.6.orig/arch/powerpc/sysdev/ppc4xx_pci.c   2008-02-04 
> 20:05:37.000000000 +0300
> +++ linux-2.6/arch/powerpc/sysdev/ppc4xx_pci.c        2008-02-04 
> 20:16:33.000000000 +0300
> @@ -645,7 +645,7 @@ static int __init ppc440spe_pciex_core_i
>       int time_out = 20;
>  
>       /* Set PLL clock receiver to LVPECL */
> -     mtdcri(SDR0, PESDR0_PLLLCT1, mfdcri(SDR0, PESDR0_PLLLCT1) | 1 << 28);
> +     set_dcri(SDR0, PESDR0_PLLLCT1, 1 << 28);
>  
>       /* Shouldn't we do all the calibration stuff etc... here ? */
>       if (ppc440spe_pciex_check_reset(np))
> @@ -659,8 +659,7 @@ static int __init ppc440spe_pciex_core_i
>       }
>  
>       /* De-assert reset of PCIe PLL, wait for lock */
> -     mtdcri(SDR0, PESDR0_PLLLCT1,
> -            mfdcri(SDR0, PESDR0_PLLLCT1) & ~(1 << 24));
> +     clr_dcri(SDR0, PESDR0_PLLLCT1, 1 << 24);
>       udelay(3);
>  
>       while (time_out) {
> @@ -712,9 +711,8 @@ static int ppc440spe_pciex_init_port_hw(
>               mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1,
>                      0x35000000);
>       }
> -     val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET);
> -     mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
> -            (val & ~(1 << 24 | 1 << 16)) | 1 << 12);
> +     clr_dcri(SDR0, port->sdr_base + PESDRn_RCSSET, 1 << 24 | 1 << 16)
> +     set_dcri(SDR0, port->sdr_base + PESDRn_RCSSET, 1 << 12);
>  
>       return 0;
>  }
> @@ -1042,8 +1040,7 @@ static int __init ppc4xx_pciex_port_init
>               port->link = 0;
>       }
>  
> -     mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
> -            mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20);
> +     set_dcri(SDR0, port->sdr_base + PESDRn_RCSSET, 1 << 20);
>       msleep(100);
>  
>       return 0;
> diff -pruN linux-2.6.orig/include/asm-powerpc/dcr-native.h 
> linux-2.6/include/asm-powerpc/dcr-native.h
> --- linux-2.6.orig/include/asm-powerpc/dcr-native.h   2008-02-04 
> 20:06:34.000000000 +0300
> +++ linux-2.6/include/asm-powerpc/dcr-native.h        2008-02-04 
> 20:16:33.000000000 +0300
> @@ -79,6 +79,28 @@ do {                                                       
> \
>       spin_unlock_irqrestore(&dcr_ind_lock, flags);   \
>  } while (0)
>  
> +#define set_dcri(base, reg, data)                            \
> +do {                                                         \
> +     unsigned long flags;                                    \
> +     unsigned int val;                                       \
> +     spin_lock_irqsave(&dcr_ind_lock, flags);                \
> +     mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg);              \
> +     val = mfdcr(DCRN_ ## base ## _CONFIG_DATA);             \
> +     mtdcr(DCRN_ ## base ## _CONFIG_DATA, val | (data));     \
> +     spin_unlock_irqrestore(&dcr_ind_lock, flags);           \
> +} while (0)
> +
> +#define clr_dcri(base, reg, data)                            \
> +do {                                                         \
> +     unsigned long flags;                                    \
> +     unsigned int val;                                       \
> +     spin_lock_irqsave(&dcr_ind_lock, flags);                \
> +     mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg);              \
> +     val = mfdcr(DCRN_ ## base ## _CONFIG_DATA);             \
> +     mtdcr(DCRN_ ## base ## _CONFIG_DATA, val & ~(data));    \
> +     spin_unlock_irqrestore(&dcr_ind_lock, flags);           \
> +} while (0)
> +
>  #endif /* __ASSEMBLY__ */
>  #endif /* __KERNEL__ */
>  #endif /* _ASM_POWERPC_DCR_NATIVE_H */

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

Reply via email to