can: cc770: Fix indirect access deadlock on ISA cards
This fix avoids a deadlock if an interrupt occurs during consecutive port operations on ISA cards utilising indirect access via address and data port. Tested on a B&R ISA card. Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org Signed-off-by: Wolfgang Zarre <lkdev@essax.com> Acked-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
parent
7bb4db93ae
commit
2d5091e08c
|
@ -110,6 +110,11 @@ MODULE_PARM_DESC(bcr, "Bus configuration register (default=0x40 [CBY])");
|
|||
#define CC770_IOSIZE 0x20
|
||||
#define CC770_IOSIZE_INDIRECT 0x02
|
||||
|
||||
/* Spinlock for cc770_isa_port_write_reg_indirect
|
||||
* and cc770_isa_port_read_reg_indirect
|
||||
*/
|
||||
static DEFINE_SPINLOCK(cc770_isa_port_lock);
|
||||
|
||||
static struct platform_device *cc770_isa_devs[MAXDEV];
|
||||
|
||||
static u8 cc770_isa_mem_read_reg(const struct cc770_priv *priv, int reg)
|
||||
|
@ -138,18 +143,27 @@ static u8 cc770_isa_port_read_reg_indirect(const struct cc770_priv *priv,
|
|||
int reg)
|
||||
{
|
||||
unsigned long base = (unsigned long)priv->reg_base;
|
||||
unsigned long flags;
|
||||
u8 val;
|
||||
|
||||
spin_lock_irqsave(&cc770_isa_port_lock, flags);
|
||||
outb(reg, base);
|
||||
return inb(base + 1);
|
||||
val = inb(base + 1);
|
||||
spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
|
||||
int reg, u8 val)
|
||||
{
|
||||
unsigned long base = (unsigned long)priv->reg_base;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cc770_isa_port_lock, flags);
|
||||
outb(reg, base);
|
||||
outb(val, base + 1);
|
||||
spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
|
||||
}
|
||||
|
||||
static int __devinit cc770_isa_probe(struct platform_device *pdev)
|
||||
|
|
Loading…
Reference in New Issue