pcmcia: honor saved flags in yenta_socket's I365_CSCINT register

Instead of overwriting the I365_CSCINT register, save the old value and
merely change the bits we care about.

Part 1 of a series to allow the ISA irq to be used for Cardbus devices
if the socket's PCI irq is unusable.

[linux@dominikbrodowski.net: split up the original patch, commit message]

Signed-off-by: Jens Kuenzer <Jens.Kuenzer@fpga.homeip.net>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
Jens Künzer 2010-03-06 07:46:16 +01:00 коммит произвёл Dominik Brodowski
Родитель b416cd8efb
Коммит 28ca8dd71f
2 изменённых файлов: 12 добавлений и 4 удалений

Просмотреть файл

@ -95,6 +95,7 @@
#define I365_CSC_DETECT 0x08 #define I365_CSC_DETECT 0x08
#define I365_CSC_ANY 0x0F #define I365_CSC_ANY 0x0F
#define I365_CSC_GPI 0x10 #define I365_CSC_GPI 0x10
#define I365_CSC_IRQ_MASK 0xF0
/* Flags for I365_ADDRWIN */ /* Flags for I365_ADDRWIN */
#define I365_ENA_IO(map) (0x40 << (map)) #define I365_ENA_IO(map) (0x40 << (map))

Просмотреть файл

@ -356,7 +356,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
exca_writeb(socket, I365_POWER, reg); exca_writeb(socket, I365_POWER, reg);
/* CSC interrupt: no ISA irq for CSC */ /* CSC interrupt: no ISA irq for CSC */
reg = I365_CSC_DETECT; reg = exca_readb(socket, I365_CSCINT);
reg &= I365_CSC_IRQ_MASK;
reg |= I365_CSC_DETECT;
if (state->flags & SS_IOCARD) { if (state->flags & SS_IOCARD) {
if (state->csc_mask & SS_STSCHG) if (state->csc_mask & SS_STSCHG)
reg |= I365_CSC_STSCHG; reg |= I365_CSC_STSCHG;
@ -912,6 +914,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
int i; int i;
unsigned long val; unsigned long val;
u32 mask; u32 mask;
u8 reg;
/* /*
* Probe for usable interrupts using the force * Probe for usable interrupts using the force
@ -919,6 +922,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
*/ */
cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
reg = exca_readb(socket, I365_CSCINT);
exca_writeb(socket, I365_CSCINT, 0); exca_writeb(socket, I365_CSCINT, 0);
val = probe_irq_on() & isa_irq_mask; val = probe_irq_on() & isa_irq_mask;
for (i = 1; i < 16; i++) { for (i = 1; i < 16; i++) {
@ -930,7 +934,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_EVENT, -1);
} }
cb_writel(socket, CB_SOCKET_MASK, 0); cb_writel(socket, CB_SOCKET_MASK, 0);
exca_writeb(socket, I365_CSCINT, 0); exca_writeb(socket, I365_CSCINT, reg);
mask = probe_irq_mask(val) & 0xffff; mask = probe_irq_mask(val) & 0xffff;
@ -967,6 +971,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id)
/* probes the PCI interrupt, use only on override functions */ /* probes the PCI interrupt, use only on override functions */
static int yenta_probe_cb_irq(struct yenta_socket *socket) static int yenta_probe_cb_irq(struct yenta_socket *socket)
{ {
u8 reg;
if (!socket->cb_irq) if (!socket->cb_irq)
return -1; return -1;
@ -979,7 +985,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
} }
/* generate interrupt, wait */ /* generate interrupt, wait */
exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); reg = exca_readb(socket, I365_CSCINT);
exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);
cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_EVENT, -1);
cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
@ -988,7 +995,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
/* disable interrupts */ /* disable interrupts */
cb_writel(socket, CB_SOCKET_MASK, 0); cb_writel(socket, CB_SOCKET_MASK, 0);
exca_writeb(socket, I365_CSCINT, 0); exca_writeb(socket, I365_CSCINT, reg);
cb_writel(socket, CB_SOCKET_EVENT, -1); cb_writel(socket, CB_SOCKET_EVENT, -1);
exca_readb(socket, I365_CSC); exca_readb(socket, I365_CSC);