Work is based on the proposal and initial version done by Pierre.
The option names has been preserved from the previous Kconfig version.
This means, that compilation should work correctly with actual Kconfig
and with new one after upper level Kconfig changes.
IRQ manipulation changed to spin-locks for rest of boards
to support better RT-Linux.
/* cli and sti are not allowed in 2.5.5x SMP kernels */
#ifdef WINDOWED_ACCESS
-can_spinlock_t bfadcan_win_lock=SPIN_LOCK_UNLOCKED;
+static can_spinlock_t bfadcan_win_lock=SPIN_LOCK_UNLOCKED;
#endif
/*
int nsican_irq=-1;
unsigned long nsican_base=0x0;
+static can_spinlock_t nsican_port_lock=SPIN_LOCK_UNLOCKED;
+
/* IO_RANGE is the io-memory range that gets reserved, please adjust according
* your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
* #define IO_RANGE 0x20 for sja1000 chips.
We use the two register, we write the address where we
want to read in a first time. In a second time we read the
data */
- unsigned char ret;
+ unsigned char ret;
+ can_spin_irqflags_t flags;
- can_disable_irq(nsican_irq);
- outb(address-nsican_base, nsican_base);
- ret=inb(nsican_base+1);
- can_enable_irq(nsican_irq);
- return ret;
+ can_spin_lock_irqsave(&nsican_port_lock,flags);
+ outb(address-nsican_base, nsican_base);
+ ret=inb(nsican_base+1);
+ can_spin_unlock_irqrestore(&nsican_port_lock,flags);
+ return ret;
}
int pcccan_irq=-1;
unsigned long pcccan_base=0x0;
+static can_spinlock_t pcccan_port_lock=SPIN_LOCK_UNLOCKED;
+
/*
* IO_RANGE is the io-memory range that gets reserved, please adjust according
* your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
*/
void pcccan_write_register(unsigned char data, unsigned long address)
{
- can_disable_irq(pcccan_irq);
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&pcccan_port_lock,flags);
outb(address - pcccan_base, pcccan_base+1);
outb(data, pcccan_base+6);
- can_enable_irq(pcccan_irq);
+ can_spin_unlock_irqrestore(&pcccan_port_lock,flags);
}
/**
unsigned pcccan_read_register(unsigned long address)
{
unsigned ret;
- can_disable_irq(pcccan_irq);
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&pcccan_port_lock,flags);
outb(address - pcccan_base, pcccan_base+1);
ret=inb(pcccan_base+2);
- can_enable_irq(pcccan_irq);
+ can_spin_unlock_irqrestore(&pcccan_port_lock,flags);
return ret;
}
int smartcan_irq=-1;
unsigned long smartcan_base=0x0;
+static can_spinlock_t smartcan_port_lock=SPIN_LOCK_UNLOCKED;
+
int smartcan_request_io(struct candevice_t *candev)
{
if (!can_request_io_region(candev->io_addr,0x04,DEVICE_NAME)) {
void smartcan_write_register(unsigned char data, unsigned long address)
{
- can_disable_irq(smartcan_irq);
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&smartcan_port_lock,flags);
outb(address-smartcan_base,smartcan_base);
outb(data,smartcan_base+1);
- can_enable_irq(smartcan_irq);
+ can_spin_unlock_irqrestore(&smartcan_port_lock,flags);
}
unsigned smartcan_read_register(unsigned long address)
{
unsigned ret;
- can_disable_irq(smartcan_irq);
+ can_spin_irqflags_t flags;
+ can_spin_lock_irqsave(&smartcan_port_lock,flags);
outb(address-smartcan_base,smartcan_base);
ret=inb(smartcan_base+1);
- can_enable_irq(smartcan_irq);
+ can_spin_unlock_irqrestore(&smartcan_port_lock,flags);
return ret;
}
int ssvcan_irq[2]={-1,-1};
unsigned long ssvcan_base=0x0;
+static can_spinlock_t ssv_port_lock=SPIN_LOCK_UNLOCKED;
+
/* IO_RANGE is the io-memory range that gets reserved, please adjust according
* your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or
* #define IO_RANGE 0x20 for sja1000 chips.
want to read in a first time. In a second time we read the
data */
unsigned char ret;
+ can_spin_irqflags_t flags;
if((address-ssvcan_base)<0x100)
{
- can_disable_irq(ssvcan_irq[0]);
+ can_spin_lock_irqsave(&ssv_port_lock,flags);
outb(address-ssvcan_base, ssvcan_base);
ret=inb(ssvcan_base+1);
- can_enable_irq(ssvcan_irq[0]);
+ can_spin_unlock_irqrestore(&ssv_port_lock,flags);
}
else
{
- can_disable_irq(ssvcan_irq[1]);
+ can_spin_lock_irqsave(&ssv_port_lock,flags);
outb(address-ssvcan_base-0x100, ssvcan_base+0x02);
ret=inb(ssvcan_base+1+0x02);
- can_enable_irq(ssvcan_irq[1]);
+ can_spin_unlock_irqrestore(&ssv_port_lock,flags);
}
return ret;