[POWERPC] 4xx: PCIe indirect DCR spinlock fix.

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 <vbarshak@ru.mvista.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
This commit is contained in:
Valentine Barshak 2008-02-06 05:36:49 +11:00 committed by Josh Boyer
parent 853265e588
commit e8318d98e9
1 changed files with 29 additions and 18 deletions

View File

@ -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; \
})
static inline unsigned __mfdcri(int base_addr, int base_data, int reg)
{
unsigned long flags;
unsigned int 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)
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__ */