On Tue, 2008-02-05 at 21:36 +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 mtdcri() macro and we have > the dcr_ind_lock spinlock acquired twice. To avoid this error, I've added > __mfdcri()/__mtdcri() inline functions that take the lock after register name > fix-up. > > Signed-off-by: Valentine Barshak <[EMAIL PROTECTED]>
Acked-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> > --- > include/asm-powerpc/dcr-native.h | 49 > +++++++++++++++++++++++---------------- > 1 files changed, 30 insertions(+), 19 deletions(-) > > diff -pruN linux-2.6.orig/include/asm-powerpc/dcr-native.h > linux-2.6.bld/include/asm-powerpc/dcr-native.h > --- linux-2.6.orig/include/asm-powerpc/dcr-native.h 2008-02-05 > 16:44:54.000000000 +0300 > +++ linux-2.6.bld/include/asm-powerpc/dcr-native.h 2008-02-05 > 19:11:55.000000000 +0300 > @@ -59,25 +59,36 @@ do { > \ > /* R/W of indirect DCRs make use of standard naming conventions for DCRs */ > extern spinlock_t dcr_ind_lock; > > -#define mfdcri(base, reg) \ > -({ \ > - 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); \ > - spin_unlock_irqrestore(&dcr_ind_lock, flags); \ > - val; \ > -}) > - > -#define mtdcri(base, reg, data) \ > -do { \ > - unsigned long flags; \ > - spin_lock_irqsave(&dcr_ind_lock, flags); \ > - mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \ > - mtdcr(DCRN_ ## base ## _CONFIG_DATA, data); \ > - spin_unlock_irqrestore(&dcr_ind_lock, flags); \ > -} while (0) > +static inline unsigned __mfdcri(int base_addr, int base_data, int reg) > +{ > + unsigned long flags; > + unsigned int val; > + > + spin_lock_irqsave(&dcr_ind_lock, flags); > + __mtdcr(base_addr, reg); > + val = __mfdcr(base_data); > + spin_unlock_irqrestore(&dcr_ind_lock, flags); > + return val; > +} > + > +static inline void __mtdcri(int base_addr, int base_data, int reg, > + unsigned val) > +{ > + unsigned long flags; > + > + spin_lock_irqsave(&dcr_ind_lock, flags); > + __mtdcr(base_addr, reg); > + __mtdcr(base_data, val); > + spin_unlock_irqrestore(&dcr_ind_lock, flags); > +} > + > +#define mfdcri(base, reg) __mfdcri(DCRN_ ## base ## _CONFIG_ADDR, \ > + DCRN_ ## base ## _CONFIG_DATA, \ > + reg) > + > +#define mtdcri(base, reg, data) __mtdcri(DCRN_ ## base ## _CONFIG_ADDR, > \ > + DCRN_ ## base ## _CONFIG_DATA, \ > + reg, data) > > #endif /* __ASSEMBLY__ */ > #endif /* __KERNEL__ */ _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev