diff options
| author | Jens Künzer <Jens.Kuenzer@fpga.homeip.net> | 2010-03-06 01:46:16 -0500 |
|---|---|---|
| committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-03-15 09:50:15 -0400 |
| commit | 28ca8dd71fc170090edca62cb8129625d01b7760 (patch) | |
| tree | afd386c42c2319f877883db6fd55c77958ff75ed | |
| parent | b416cd8efb6ce2661f8f98f603972f0b8f796ee4 (diff) | |
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>
| -rw-r--r-- | drivers/pcmcia/i82365.h | 1 | ||||
| -rw-r--r-- | drivers/pcmcia/yenta_socket.c | 15 |
2 files changed, 12 insertions, 4 deletions
diff --git a/drivers/pcmcia/i82365.h b/drivers/pcmcia/i82365.h index 849ef1b5d687..3f84d7a2dc84 100644 --- a/drivers/pcmcia/i82365.h +++ b/drivers/pcmcia/i82365.h | |||
| @@ -95,6 +95,7 @@ | |||
| 95 | #define I365_CSC_DETECT 0x08 | 95 | #define I365_CSC_DETECT 0x08 |
| 96 | #define I365_CSC_ANY 0x0F | 96 | #define I365_CSC_ANY 0x0F |
| 97 | #define I365_CSC_GPI 0x10 | 97 | #define I365_CSC_GPI 0x10 |
| 98 | #define I365_CSC_IRQ_MASK 0xF0 | ||
| 98 | 99 | ||
| 99 | /* Flags for I365_ADDRWIN */ | 100 | /* Flags for I365_ADDRWIN */ |
| 100 | #define I365_ENA_IO(map) (0x40 << (map)) | 101 | #define I365_ENA_IO(map) (0x40 << (map)) |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 967c766f53ba..42f6763db400 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
| @@ -356,7 +356,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | |||
| 356 | exca_writeb(socket, I365_POWER, reg); | 356 | exca_writeb(socket, I365_POWER, reg); |
| 357 | 357 | ||
| 358 | /* CSC interrupt: no ISA irq for CSC */ | 358 | /* CSC interrupt: no ISA irq for CSC */ |
| 359 | reg = I365_CSC_DETECT; | 359 | reg = exca_readb(socket, I365_CSCINT); |
| 360 | reg &= I365_CSC_IRQ_MASK; | ||
| 361 | reg |= I365_CSC_DETECT; | ||
| 360 | if (state->flags & SS_IOCARD) { | 362 | if (state->flags & SS_IOCARD) { |
| 361 | if (state->csc_mask & SS_STSCHG) | 363 | if (state->csc_mask & SS_STSCHG) |
| 362 | reg |= I365_CSC_STSCHG; | 364 | reg |= I365_CSC_STSCHG; |
| @@ -912,6 +914,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
| 912 | int i; | 914 | int i; |
| 913 | unsigned long val; | 915 | unsigned long val; |
| 914 | u32 mask; | 916 | u32 mask; |
| 917 | u8 reg; | ||
| 915 | 918 | ||
| 916 | /* | 919 | /* |
| 917 | * Probe for usable interrupts using the force | 920 | * 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 | |||
| 919 | */ | 922 | */ |
| 920 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 923 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
| 921 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); | 924 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); |
| 925 | reg = exca_readb(socket, I365_CSCINT); | ||
| 922 | exca_writeb(socket, I365_CSCINT, 0); | 926 | exca_writeb(socket, I365_CSCINT, 0); |
| 923 | val = probe_irq_on() & isa_irq_mask; | 927 | val = probe_irq_on() & isa_irq_mask; |
| 924 | for (i = 1; i < 16; i++) { | 928 | for (i = 1; i < 16; i++) { |
| @@ -930,7 +934,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas | |||
| 930 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 934 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
| 931 | } | 935 | } |
| 932 | cb_writel(socket, CB_SOCKET_MASK, 0); | 936 | cb_writel(socket, CB_SOCKET_MASK, 0); |
| 933 | exca_writeb(socket, I365_CSCINT, 0); | 937 | exca_writeb(socket, I365_CSCINT, reg); |
| 934 | 938 | ||
| 935 | mask = probe_irq_mask(val) & 0xffff; | 939 | mask = probe_irq_mask(val) & 0xffff; |
| 936 | 940 | ||
| @@ -967,6 +971,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id) | |||
| 967 | /* probes the PCI interrupt, use only on override functions */ | 971 | /* probes the PCI interrupt, use only on override functions */ |
| 968 | static int yenta_probe_cb_irq(struct yenta_socket *socket) | 972 | static int yenta_probe_cb_irq(struct yenta_socket *socket) |
| 969 | { | 973 | { |
| 974 | u8 reg; | ||
| 975 | |||
| 970 | if (!socket->cb_irq) | 976 | if (!socket->cb_irq) |
| 971 | return -1; | 977 | return -1; |
| 972 | 978 | ||
| @@ -979,7 +985,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
| 979 | } | 985 | } |
| 980 | 986 | ||
| 981 | /* generate interrupt, wait */ | 987 | /* generate interrupt, wait */ |
| 982 | exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG); | 988 | reg = exca_readb(socket, I365_CSCINT); |
| 989 | exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG); | ||
| 983 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 990 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
| 984 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); | 991 | cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); |
| 985 | cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); | 992 | cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS); |
| @@ -988,7 +995,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) | |||
| 988 | 995 | ||
| 989 | /* disable interrupts */ | 996 | /* disable interrupts */ |
| 990 | cb_writel(socket, CB_SOCKET_MASK, 0); | 997 | cb_writel(socket, CB_SOCKET_MASK, 0); |
| 991 | exca_writeb(socket, I365_CSCINT, 0); | 998 | exca_writeb(socket, I365_CSCINT, reg); |
| 992 | cb_writel(socket, CB_SOCKET_EVENT, -1); | 999 | cb_writel(socket, CB_SOCKET_EVENT, -1); |
| 993 | exca_readb(socket, I365_CSC); | 1000 | exca_readb(socket, I365_CSC); |
| 994 | 1001 | ||
