From 312c004d36ce6c739512bac83b452f4c20ab1f62 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 09:00:00 +0100 Subject: [PATCH] driver core: replace "hotplug" by "uevent" Leave the overloaded "hotplug" word to susbsystems which are handling real devices. The driver core does not "plug" anything, it just exports the state to userspace and generates events. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/cs.c | 10 +++++----- drivers/pcmcia/ds.c | 50 +++++++++++++++++++++++++------------------------- 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index a30aa74304a2..7cf09084ef61 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -901,14 +901,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt) EXPORT_SYMBOL(pcmcia_insert_card); -static int pcmcia_socket_hotplug(struct class_device *dev, char **envp, - int num_envp, char *buffer, int buffer_size) +static int pcmcia_socket_uevent(struct class_device *dev, char **envp, + int num_envp, char *buffer, int buffer_size) { struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); int i = 0, length = 0; - if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, - &length, "SOCKET_NO=%u", s->sock)) + if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, + &length, "SOCKET_NO=%u", s->sock)) return -ENOMEM; envp[i] = NULL; @@ -927,7 +927,7 @@ static void pcmcia_release_socket_class(struct class *data) struct class pcmcia_socket_class = { .name = "pcmcia_socket", - .hotplug = pcmcia_socket_hotplug, + .uevent = pcmcia_socket_uevent, .release = pcmcia_release_socket, .class_release = pcmcia_release_socket_class, }; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 7f8219f3fd9e..6fb76399547e 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -779,8 +779,8 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { #ifdef CONFIG_HOTPLUG -static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) +static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) { struct pcmcia_device *p_dev; int i, length = 0; @@ -800,31 +800,31 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, i = 0; - if (add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "SOCKET_NO=%u", - p_dev->socket->sock)) + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "SOCKET_NO=%u", + p_dev->socket->sock)) return -ENOMEM; - if (add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "DEVICE_NO=%02X", - p_dev->device_no)) + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "DEVICE_NO=%02X", + p_dev->device_no)) return -ENOMEM; - if (add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" - "pa%08Xpb%08Xpc%08Xpd%08X", - p_dev->has_manf_id ? p_dev->manf_id : 0, - p_dev->has_card_id ? p_dev->card_id : 0, - p_dev->has_func_id ? p_dev->func_id : 0, - p_dev->func, - p_dev->device_no, - hash[0], - hash[1], - hash[2], - hash[3])) + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X" + "pa%08Xpb%08Xpc%08Xpd%08X", + p_dev->has_manf_id ? p_dev->manf_id : 0, + p_dev->has_card_id ? p_dev->card_id : 0, + p_dev->has_func_id ? p_dev->func_id : 0, + p_dev->func, + p_dev->device_no, + hash[0], + hash[1], + hash[2], + hash[3])) return -ENOMEM; envp[i] = NULL; @@ -834,7 +834,7 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, #else -static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp, +static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { return -ENODEV; @@ -1223,7 +1223,7 @@ static struct class_interface pcmcia_bus_interface = { struct bus_type pcmcia_bus_type = { .name = "pcmcia", - .hotplug = pcmcia_bus_hotplug, + .uevent = pcmcia_bus_uevent, .match = pcmcia_bus_match, .dev_attrs = pcmcia_dev_attrs, }; -- cgit v1.2.3 From 37f779554404ddca981ac4b4cc6692fc09b71e96 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 7 Sep 2005 16:00:26 -0700 Subject: [PATCH] pcmcia: avoid macro usage in cistpl Fix macro abuse in pcmcia. Signed-off-by: Pavel Machek Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cistpl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 2dc3e611a9a3..55d7247b58e7 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -60,9 +60,9 @@ static const u_int exponent[] = { /* Parameters that can be set with 'insmod' */ -#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) - -INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ +/* 16-bit CIS? */ +static int cis_width; +module_param(cis_width, int, 0444); void release_cis_mem(struct pcmcia_socket *s) { -- cgit v1.2.3 From e4115805cf2020da94e8bd1296243605cda487ff Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Tue, 20 Sep 2005 14:17:37 -0700 Subject: [PATCH] yenta: optimize interrupt handler Don't waste cpu time in yenta interrupt handler when the interrupt was for another device. Signed-off-by: Daniel Ritz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/yenta_socket.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index ec6ab65f0872..8bfe72b71302 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -531,6 +531,9 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) csc = exca_readb(socket, I365_CSC); + if (!(cb_event || csc)) + return IRQ_NONE; + events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ; events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0; if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { @@ -544,10 +547,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (events) pcmcia_parse_events(&socket->socket, events); - if (cb_event || csc) - return IRQ_HANDLED; - - return IRQ_NONE; + return IRQ_HANDLED; } static void yenta_interrupt_wrapper(unsigned long data) -- cgit v1.2.3 From 9da4bc6d6a38c1c3d850c046d0aee324c1a2e52a Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sat, 12 Nov 2005 23:56:33 +0100 Subject: [PATCH] pcmcia: remove get_socket callback The .get_socket callback is never used by the PCMCIA core, therefore remove it. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/au1000_generic.c | 18 --------- drivers/pcmcia/hd64465_ss.c | 13 ------ drivers/pcmcia/i82092.c | 73 --------------------------------- drivers/pcmcia/i82092aa.h | 1 - drivers/pcmcia/i82365.c | 83 ------------------------------------- drivers/pcmcia/m32r_cfc.c | 32 --------------- drivers/pcmcia/m32r_pcc.c | 20 --------- drivers/pcmcia/m8xx_pcmcia.c | 12 ------ drivers/pcmcia/pd6729.c | 70 -------------------------------- drivers/pcmcia/soc_common.c | 20 --------- drivers/pcmcia/tcic.c | 61 ---------------------------- drivers/pcmcia/vrc4171_card.c | 70 -------------------------------- drivers/pcmcia/vrc4173_cardu.c | 43 -------------------- drivers/pcmcia/yenta_socket.c | 90 ----------------------------------------- 14 files changed, 606 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 87302c548c24..0868b72c3996 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -241,23 +241,6 @@ au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) return 0; } -/* au1x00_pcmcia_get_socket() - * Implements the get_socket() operation for the in-kernel PCMCIA - * service (formerly SS_GetSocket in Card Services). Not a very - * exciting routine. - * - * Returns: 0 - */ -static int -au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); - - debug("for sock %u\n", skt->nr); - *state = skt->cs_state; - return 0; -} - /* au1x00_pcmcia_set_socket() * Implements the set_socket() operation for the in-kernel PCMCIA * service (formerly SS_SetSocket in Card Services). We more or @@ -352,7 +335,6 @@ static struct pccard_operations au1x00_pcmcia_operations = { .init = au1x00_pcmcia_sock_init, .suspend = au1x00_pcmcia_suspend, .get_status = au1x00_pcmcia_get_status, - .get_socket = au1x00_pcmcia_get_socket, .set_socket = au1x00_pcmcia_set_socket, .set_io_map = au1x00_pcmcia_set_io_map, .set_mem_map = au1x00_pcmcia_set_mem_map, diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 561706ba4499..b39435bbfaeb 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -417,18 +417,6 @@ static int hs_get_status(struct pcmcia_socket *s, u_int *value) /*============================================================*/ -static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ - hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); - - DPRINTK("hs_get_socket(%d)\n", sock); - - *state = sp->state; - return 0; -} - -/*============================================================*/ - static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state) { hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); @@ -749,7 +737,6 @@ static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs) static struct pccard_operations hs_operations = { .init = hs_init, .get_status = hs_get_status, - .get_socket = hs_get_socket, .set_socket = hs_set_socket, .set_io_map = hs_set_io_map, .set_mem_map = hs_set_mem_map, diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index f3fdc748659d..7979c85df3dc 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -66,7 +66,6 @@ static struct pci_driver i82092aa_pci_drv = { static struct pccard_operations i82092aa_operations = { .init = i82092aa_init, .get_status = i82092aa_get_status, - .get_socket = i82092aa_get_socket, .set_socket = i82092aa_set_socket, .set_io_map = i82092aa_set_io_map, .set_mem_map = i82092aa_set_mem_map, @@ -482,78 +481,6 @@ static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value) } -static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state) -{ - unsigned int sock = container_of(socket, struct socket_info, socket)->number; - unsigned char reg,vcc,vpp; - - enter("i82092aa_get_socket"); - state->flags = 0; - state->Vcc = 0; - state->Vpp = 0; - state->io_irq = 0; - state->csc_mask = 0; - - /* First the power status of the socket */ - reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */ - - if (reg & I365_PWR_AUTO) - state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */ - - if (reg & I365_PWR_OUT) - state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ - - vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; - - if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */ - state->Vcc = 50; - - if (vpp == I365_VPP1_5V) - state->Vpp = 50; - if (vpp == I365_VPP1_12V) - state->Vpp = 120; - - } - - if ((reg & I365_VCC_3V)==I365_VCC_3V) - state->Vcc = 33; - - - /* Now the IO card, RESET flags and IO interrupt */ - - reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */ - - if ((reg & I365_PC_RESET)==0) - state->flags |= SS_RESET; - if (reg & I365_PC_IOCARD) - state->flags |= SS_IOCARD; /* This is an IO card */ - - /* Set the IRQ number */ - if (sockets[sock].dev!=NULL) - state->io_irq = sockets[sock].dev->irq; - - /* Card status change */ - reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */ - - if (reg & I365_CSC_DETECT) - state->csc_mask |= SS_DETECT; /* Card detect is enabled */ - - if (state->flags & SS_IOCARD) {/* IO Cards behave different */ - if (reg & I365_CSC_STSCHG) - state->csc_mask |= SS_STSCHG; - } else { - if (reg & I365_CSC_BVD1) - state->csc_mask |= SS_BATDEAD; - if (reg & I365_CSC_BVD2) - state->csc_mask |= SS_BATWARN; - if (reg & I365_CSC_READY) - state->csc_mask |= SS_READY; - } - - leave("i82092aa_get_socket"); - return 0; -} - static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) { unsigned int sock = container_of(socket, struct socket_info, socket)->number; diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h index b98cac7bda9f..9c14599d0673 100644 --- a/drivers/pcmcia/i82092aa.h +++ b/drivers/pcmcia/i82092aa.h @@ -29,7 +29,6 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs); static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value); -static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state); static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state); static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io); static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem); diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 4d56bc9926d6..35a92d1e4945 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -940,78 +940,6 @@ static int i365_get_status(u_short sock, u_int *value) /*====================================================================*/ -static int i365_get_socket(u_short sock, socket_state_t *state) -{ - struct i82365_socket *t = &socket[sock]; - u_char reg, vcc, vpp; - - reg = i365_get(sock, I365_POWER); - state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; - state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; - vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; - state->Vcc = state->Vpp = 0; - if (t->flags & IS_CIRRUS) { - if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) { - if (reg & I365_VCC_5V) state->Vcc = 33; - if (vpp == I365_VPP1_5V) state->Vpp = 33; - } else { - if (reg & I365_VCC_5V) state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - } - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } else if (t->flags & IS_VG_PWR) { - if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) { - if (reg & I365_VCC_5V) state->Vcc = 33; - if (vpp == I365_VPP1_5V) state->Vpp = 33; - } else { - if (reg & I365_VCC_5V) state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - } - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } else if (t->flags & IS_DF_PWR) { - if (vcc == I365_VCC_3V) state->Vcc = 33; - if (vcc == I365_VCC_5V) state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } else { - if (reg & I365_VCC_5V) { - state->Vcc = 50; - if (vpp == I365_VPP1_5V) state->Vpp = 50; - if (vpp == I365_VPP1_12V) state->Vpp = 120; - } - } - - /* IO card, RESET flags, IO interrupt */ - reg = i365_get(sock, I365_INTCTL); - state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; - if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD; - state->io_irq = reg & I365_IRQ_MASK; - - /* speaker control */ - if (t->flags & IS_CIRRUS) { - if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA) - state->flags |= SS_SPKR_ENA; - } - - /* Card status change mask */ - reg = i365_get(sock, I365_CSCINT); - state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; - if (state->flags & SS_IOCARD) - state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; - else { - state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; - state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; - state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; - } - - debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - return 0; -} /* i365_get_socket */ - -/*====================================================================*/ - static int i365_set_socket(u_short sock, socket_state_t *state) { struct i82365_socket *t = &socket[sock]; @@ -1265,16 +1193,6 @@ static int pcic_get_status(struct pcmcia_socket *s, u_int *value) LOCKED(i365_get_status(sock, value)); } -static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ - unsigned int sock = container_of(s, struct i82365_socket, socket)->number; - - if (socket[sock].flags & IS_ALIVE) - return -EINVAL; - - LOCKED(i365_get_socket(sock, state)); -} - static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state) { unsigned int sock = container_of(s, struct i82365_socket, socket)->number; @@ -1324,7 +1242,6 @@ static int pcic_init(struct pcmcia_socket *s) static struct pccard_operations pcic_operations = { .init = pcic_init, .get_status = pcic_get_status, - .get_socket = pcic_get_socket, .set_socket = pcic_set_socket, .set_io_map = pcic_set_io_map, .set_mem_map = pcic_set_mem_map, diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 078579ae6359..071cf485e1a3 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -480,25 +480,6 @@ static int _pcc_get_status(u_short sock, u_int *value) /*====================================================================*/ -static int _pcc_get_socket(u_short sock, socket_state_t *state) -{ -// pcc_socket_t *t = &socket[sock]; - - state->flags = 0; - state->csc_mask = SS_DETECT; - state->csc_mask |= SS_READY; - state->io_irq = 0; - state->Vcc = 33; /* 3.3V fixed */ - state->Vpp = 33; - - debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - return 0; -} /* _get_socket */ - -/*====================================================================*/ - static int _pcc_set_socket(u_short sock, socket_state_t *state) { debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " @@ -667,18 +648,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value) LOCKED(_pcc_get_status(sock, value)); } -static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ - unsigned int sock = container_of(s, struct pcc_socket, socket)->number; - - if (socket[sock].flags & IS_ALIVE) { - debug(3, "m32r_cfc: pcc_get_socket: sock(%d) -EINVAL\n", sock); - return -EINVAL; - } - debug(3, "m32r_cfc: pcc_get_socket: sock(%d)\n", sock); - LOCKED(_pcc_get_socket(sock, state)); -} - static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) { unsigned int sock = container_of(s, struct pcc_socket, socket)->number; @@ -724,7 +693,6 @@ static int pcc_init(struct pcmcia_socket *s) static struct pccard_operations pcc_operations = { .init = pcc_init, .get_status = pcc_get_status, - .get_socket = pcc_get_socket, .set_socket = pcc_set_socket, .set_io_map = pcc_set_io_map, .set_mem_map = pcc_set_mem_map, diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 356a6fb416a1..70d5f0748d55 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -429,16 +429,6 @@ static int _pcc_get_status(u_short sock, u_int *value) /*====================================================================*/ -static int _pcc_get_socket(u_short sock, socket_state_t *state) -{ - debug(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - return 0; -} /* _get_socket */ - -/*====================================================================*/ - static int _pcc_set_socket(u_short sock, socket_state_t *state) { u_long reg = 0; @@ -641,15 +631,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value) LOCKED(_pcc_get_status(sock, value)); } -static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ - unsigned int sock = container_of(s, struct pcc_socket, socket)->number; - - if (socket[sock].flags & IS_ALIVE) - return -EINVAL; - LOCKED(_pcc_get_socket(sock, state)); -} - static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state) { unsigned int sock = container_of(s, struct pcc_socket, socket)->number; @@ -687,7 +668,6 @@ static int pcc_init(struct pcmcia_socket *s) static struct pccard_operations pcc_operations = { .init = pcc_init, .get_status = pcc_get_status, - .get_socket = pcc_get_socket, .set_socket = pcc_set_socket, .set_io_map = pcc_set_io_map, .set_mem_map = pcc_set_mem_map, diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 6d9f71cfcb34..a7f27c3dfc24 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -823,17 +823,6 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value) return 0; } -static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - int lsock = container_of(sock, struct socket_info, socket)->slot; - *state = socket[lsock].state; /* copy the whole structure */ - - dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - return 0; -} - static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state) { int lsock = container_of(sock, struct socket_info, socket)->slot; @@ -1169,7 +1158,6 @@ static struct pccard_operations m8xx_services = { .init = m8xx_sock_init, .suspend = m8xx_suspend, .get_status = m8xx_get_status, - .get_socket = m8xx_get_socket, .set_socket = m8xx_set_socket, .set_io_map = m8xx_set_io_map, .set_mem_map = m8xx_set_mem_map, diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 20642f0e7bfe..e7a6d9ac5ed8 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -304,75 +304,6 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value) } -static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - struct pd6729_socket *socket - = container_of(sock, struct pd6729_socket, socket); - unsigned char reg, vcc, vpp; - - state->flags = 0; - state->Vcc = 0; - state->Vpp = 0; - state->io_irq = 0; - state->csc_mask = 0; - - /* First the power status of the socket */ - reg = indirect_read(socket, I365_POWER); - - if (reg & I365_PWR_AUTO) - state->flags |= SS_PWR_AUTO; /* Automatic Power Switch */ - - if (reg & I365_PWR_OUT) - state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ - - vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; - - if (reg & I365_VCC_5V) { - state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) & - PD67_MC1_VCC_3V) ? 33 : 50; - - if (vpp == I365_VPP1_5V) { - if (state->Vcc == 50) - state->Vpp = 50; - else - state->Vpp = 33; - } - if (vpp == I365_VPP1_12V) - state->Vpp = 120; - } - - /* Now the IO card, RESET flags and IO interrupt */ - reg = indirect_read(socket, I365_INTCTL); - - if ((reg & I365_PC_RESET) == 0) - state->flags |= SS_RESET; - if (reg & I365_PC_IOCARD) - state->flags |= SS_IOCARD; /* This is an IO card */ - - /* Set the IRQ number */ - state->io_irq = socket->card_irq; - - /* Card status change */ - reg = indirect_read(socket, I365_CSCINT); - - if (reg & I365_CSC_DETECT) - state->csc_mask |= SS_DETECT; /* Card detect is enabled */ - - if (state->flags & SS_IOCARD) {/* IO Cards behave different */ - if (reg & I365_CSC_STSCHG) - state->csc_mask |= SS_STSCHG; - } else { - if (reg & I365_CSC_BVD1) - state->csc_mask |= SS_BATDEAD; - if (reg & I365_CSC_BVD2) - state->csc_mask |= SS_BATWARN; - if (reg & I365_CSC_READY) - state->csc_mask |= SS_READY; - } - - return 0; -} - static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state) { struct pd6729_socket *socket @@ -640,7 +571,6 @@ static int pd6729_init(struct pcmcia_socket *sock) static struct pccard_operations pd6729_operations = { .init = pd6729_init, .get_status = pd6729_get_status, - .get_socket = pd6729_get_socket, .set_socket = pd6729_set_socket, .set_io_map = pd6729_set_io_map, .set_mem_map = pd6729_set_mem_map, diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 9e7ccd8a4321..a563bd9a8898 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -296,25 +296,6 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) } -/* - * Implements the get_socket() operation for the in-kernel PCMCIA - * service (formerly SS_GetSocket in Card Services). Not a very - * exciting routine. - * - * Returns: 0 - */ -static int -soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); - - debug(skt, 2, "\n"); - - *state = skt->cs_state; - - return 0; -} - /* * Implements the set_socket() operation for the in-kernel PCMCIA * service (formerly SS_SetSocket in Card Services). We more or @@ -528,7 +509,6 @@ static struct pccard_operations soc_common_pcmcia_operations = { .init = soc_common_pcmcia_sock_init, .suspend = soc_common_pcmcia_suspend, .get_status = soc_common_pcmcia_get_status, - .get_socket = soc_common_pcmcia_get_socket, .set_socket = soc_common_pcmcia_set_socket, .set_io_map = soc_common_pcmcia_set_io_map, .set_mem_map = soc_common_pcmcia_set_mem_map, diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index e31263864377..73bad1d5cb23 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -181,13 +181,6 @@ static void tcic_setl(u_char reg, u_int data) outw(data >> 16, tcic_base+reg+2); } -static u_char tcic_aux_getb(u_short reg) -{ - u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; - tcic_setb(TCIC_MODE, mode); - return tcic_getb(TCIC_AUX); -} - static void tcic_aux_setb(u_short reg, u_char data) { u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; @@ -641,59 +634,6 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value) debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value); return 0; } /* tcic_get_status */ - -/*====================================================================*/ - -static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - u_short psock = container_of(sock, struct tcic_socket, socket)->psock; - u_char reg; - u_short scf1, scf2; - - tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT) - | TCIC_ADDR_INDREG | TCIC_SCF1(psock)); - scf1 = tcic_getw(TCIC_DATA); - state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0; - state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0; - state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0; - if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA) - state->flags |= SS_OUTPUT_ENA; - state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK; - if (state->io_irq == 1) state->io_irq = 11; - - reg = tcic_getb(TCIC_PWR); - state->Vcc = state->Vpp = 0; - if (reg & TCIC_PWR_VCC(psock)) { - if (reg & TCIC_PWR_VPP(psock)) - state->Vcc = 50; - else - state->Vcc = state->Vpp = 50; - } else { - if (reg & TCIC_PWR_VPP(psock)) { - state->Vcc = 50; - state->Vpp = 120; - } - } - reg = tcic_aux_getb(TCIC_AUX_ILOCK); - state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0; - - /* Card status change interrupt mask */ - tcic_setw(TCIC_ADDR, TCIC_SCF2(psock)); - scf2 = tcic_getw(TCIC_DATA); - state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT; - if (state->flags & SS_IOCARD) { - state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG; - } else { - state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD; - state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN; - state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY; - } - - debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " - "io_irq %d, csc_mask %#2.2x\n", psock, state->flags, - state->Vcc, state->Vpp, state->io_irq, state->csc_mask); - return 0; -} /* tcic_get_socket */ /*====================================================================*/ @@ -874,7 +814,6 @@ static int tcic_init(struct pcmcia_socket *s) static struct pccard_operations tcic_operations = { .init = tcic_init, .get_status = tcic_get_status, - .get_socket = tcic_get_socket, .set_socket = tcic_set_socket, .set_io_map = tcic_set_io_map, .set_mem_map = tcic_set_mem_map, diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 38a028c725d4..24c547ef512b 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -301,75 +301,6 @@ static int pccard_get_status(struct pcmcia_socket *sock, u_int *value) return 0; } -static inline u_char get_Vcc_value(uint8_t voltage) -{ - switch (voltage) { - case VCC_STATUS_3V: - return 33; - case VCC_STATUS_5V: - return 50; - default: - break; - } - - return 0; -} - -static inline u_char get_Vpp_value(uint8_t power, u_char Vcc) -{ - if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02) - return Vcc; - - return 0; -} - -static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - unsigned int slot; - uint8_t power, voltage, control, cscint; - - if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL) - return -EINVAL; - - slot = sock->sock; - - power = exca_read_byte(slot, I365_POWER); - voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT); - - state->Vcc = get_Vcc_value(voltage); - state->Vpp = get_Vpp_value(power, state->Vcc); - - state->flags = 0; - if (power & POWER_ENABLE) - state->flags |= SS_PWR_AUTO; - if (power & I365_PWR_OUT) - state->flags |= SS_OUTPUT_ENA; - - control = exca_read_byte(slot, I365_INTCTL); - if (control & I365_PC_IOCARD) - state->flags |= SS_IOCARD; - if (!(control & I365_PC_RESET)) - state->flags |= SS_RESET; - - cscint = exca_read_byte(slot, I365_CSCINT); - state->csc_mask = 0; - if (state->flags & SS_IOCARD) { - if (cscint & I365_CSC_STSCHG) - state->flags |= SS_STSCHG; - } else { - if (cscint & I365_CSC_BVD1) - state->csc_mask |= SS_BATDEAD; - if (cscint & I365_CSC_BVD2) - state->csc_mask |= SS_BATWARN; - } - if (cscint & I365_CSC_READY) - state->csc_mask |= SS_READY; - if (cscint & I365_CSC_DETECT) - state->csc_mask |= SS_DETECT; - - return 0; -} - static inline uint8_t set_Vcc_value(u_char Vcc) { switch (Vcc) { @@ -551,7 +482,6 @@ static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map static struct pccard_operations vrc4171_pccard_operations = { .init = pccard_init, .get_status = pccard_get_status, - .get_socket = pccard_get_socket, .set_socket = pccard_set_socket, .set_io_map = pccard_set_io_map, .set_mem_map = pccard_set_mem_map, diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index db91259dc50e..1b277d2c1c96 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c @@ -198,48 +198,6 @@ static int cardu_get_status(unsigned int sock, u_int *value) return 0; } -static inline u_char get_Vcc_value(uint8_t val) -{ - switch (val & VCC_MASK) { - case VCC_3V: - return 33; - case VCC_5V: - return 50; - } - - return 0; -} - -static inline u_char get_Vpp_value(uint8_t val) -{ - switch (val & VPP_MASK) { - case VPP_12V: - return 120; - case VPP_VCC: - return get_Vcc_value(val); - } - - return 0; -} - -static int cardu_get_socket(unsigned int sock, socket_state_t *state) -{ - vrc4173_socket_t *socket = &cardu_sockets[sock]; - uint8_t val; - - val = exca_readb(socket, PWR_CNT); - state->Vcc = get_Vcc_value(val); - state->Vpp = get_Vpp_value(val); - state->flags = 0; - if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA; - - val = exca_readb(socket, INT_GEN_CNT); - if (!(val & CARD_REST0)) state->flags |= SS_RESET; - if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD; - - return 0; -} - static inline uint8_t set_Vcc_value(u_char Vcc) { switch (Vcc) { @@ -431,7 +389,6 @@ static struct pccard_operations cardu_operations = { .register_callback = cardu_register_callback, .inquire_socket = cardu_inquire_socket, .get_status = cardu_get_status, - .get_socket = cardu_get_socket, .set_socket = cardu_set_socket, .get_io_map = cardu_get_io_map, .set_io_map = cardu_set_io_map, diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 8bfe72b71302..fa0625c438dc 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -224,95 +224,6 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value) return 0; } -static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state) -{ - if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && - (socket->flags & YENTA_16BIT_POWER_EXCA)) { - u8 reg, vcc, vpp; - - reg = exca_readb(socket, I365_POWER); - vcc = reg & I365_VCC_MASK; - vpp = reg & I365_VPP1_MASK; - state->Vcc = state->Vpp = 0; - - if (socket->flags & YENTA_16BIT_POWER_DF) { - if (vcc == I365_VCC_3V) - state->Vcc = 33; - if (vcc == I365_VCC_5V) - state->Vcc = 50; - if (vpp == I365_VPP1_5V) - state->Vpp = state->Vcc; - if (vpp == I365_VPP1_12V) - state->Vpp = 120; - } else { - if (reg & I365_VCC_5V) { - state->Vcc = 50; - if (vpp == I365_VPP1_5V) - state->Vpp = 50; - if (vpp == I365_VPP1_12V) - state->Vpp = 120; - } - } - } else { - u32 control; - - control = cb_readl(socket, CB_SOCKET_CONTROL); - - switch (control & CB_SC_VCC_MASK) { - case CB_SC_VCC_5V: state->Vcc = 50; break; - case CB_SC_VCC_3V: state->Vcc = 33; break; - default: state->Vcc = 0; - } - - switch (control & CB_SC_VPP_MASK) { - case CB_SC_VPP_12V: state->Vpp = 120; break; - case CB_SC_VPP_5V: state->Vpp = 50; break; - case CB_SC_VPP_3V: state->Vpp = 33; break; - default: state->Vpp = 0; - } - } -} - -static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ - struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); - u8 reg; - u32 control; - - control = cb_readl(socket, CB_SOCKET_CONTROL); - - yenta_get_power(socket, state); - state->io_irq = socket->io_irq; - - if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { - u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL); - if (bridge & CB_BRIDGE_CRST) - state->flags |= SS_RESET; - return 0; - } - - /* 16-bit card state.. */ - reg = exca_readb(socket, I365_POWER); - state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; - state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; - - reg = exca_readb(socket, I365_INTCTL); - state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; - state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0; - - reg = exca_readb(socket, I365_CSCINT); - state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; - if (state->flags & SS_IOCARD) { - state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; - } else { - state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; - state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; - state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; - } - - return 0; -} - static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state) { /* some birdges require to use the ExCA registers to power 16bit cards */ @@ -828,7 +739,6 @@ static struct pccard_operations yenta_socket_operations = { .init = yenta_sock_init, .suspend = yenta_sock_suspend, .get_status = yenta_get_status, - .get_socket = yenta_get_socket, .set_socket = yenta_set_socket, .set_io_map = yenta_set_io_map, .set_mem_map = yenta_set_mem_map, -- cgit v1.2.3 From de75914ee103a30d82ad21b39b7e04f70e4fa1f0 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 28 Sep 2005 19:41:56 +0200 Subject: [PATCH] pcmcia: validate_mem shouldn't be void Add a return value to pcmcia_validate_mem. Only if we have enough memory available to map the CIS, we should proceed in trying to determine information about the device. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cs_internal.h | 2 +- drivers/pcmcia/ds.c | 4 +- drivers/pcmcia/rsrc_mgr.c | 6 +- drivers/pcmcia/rsrc_nonstatic.c | 123 +++++++++++++++++++++------------------- 4 files changed, 74 insertions(+), 61 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 55867bc7f199..634426b78f2c 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -117,7 +117,7 @@ int verify_cis_cache(struct pcmcia_socket *s); int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse); /* In rsrc_mgr */ -void pcmcia_validate_mem(struct pcmcia_socket *s); +int pcmcia_validate_mem(struct pcmcia_socket *s); struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align, struct pcmcia_socket *s); int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 6fb76399547e..b120794c03a9 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -583,7 +583,9 @@ static int pcmcia_card_add(struct pcmcia_socket *s) if (!(s->resource_setup_done)) return -EAGAIN; /* try again, but later... */ - pcmcia_validate_mem(s); + if (pcmcia_validate_mem(s)) + return -EAGAIN; /* try again, but later... */ + ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); if (ret || !cisinfo.Chains) { ds_dbg(0, "invalid CIS or invalid resources\n"); diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 0668384ebc8b..b02598a5a912 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -98,10 +98,12 @@ int pcmcia_adjust_resource_info(adjust_t *adj) } EXPORT_SYMBOL(pcmcia_adjust_resource_info); -void pcmcia_validate_mem(struct pcmcia_socket *s) +int pcmcia_validate_mem(struct pcmcia_socket *s) { if (s->resource_ops->validate_mem) - s->resource_ops->validate_mem(s); + return s->resource_ops->validate_mem(s); + /* if there is no callback, we can assume that everything is OK */ + return 0; } EXPORT_SYMBOL(pcmcia_validate_mem); diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 00960a379b9c..ebfcab5df9ea 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -407,56 +407,62 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s) static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s) { - struct socket_data *s_data = s->resource_data; - u_long ok; - if (m == &s_data->mem_db) - return 0; - ok = inv_probe(m->next, s); - if (ok) { - if (m->base >= 0x100000) - sub_interval(&s_data->mem_db, m->base, m->num); - return ok; - } - if (m->base < 0x100000) - return 0; - return do_mem_probe(m->base, m->num, s); + struct socket_data *s_data = s->resource_data; + u_long ok; + if (m == &s_data->mem_db) + return 0; + ok = inv_probe(m->next, s); + if (ok) { + if (m->base >= 0x100000) + sub_interval(&s_data->mem_db, m->base, m->num); + return ok; + } + if (m->base < 0x100000) + return 0; + return do_mem_probe(m->base, m->num, s); } -static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) +static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) { - struct resource_map *m, mm; - static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; - u_long b, i, ok = 0; - struct socket_data *s_data = s->resource_data; + struct resource_map *m, mm; + static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; + unsigned long b, i, ok = 0; + struct socket_data *s_data = s->resource_data; - /* We do up to four passes through the list */ - if (probe_mask & MEM_PROBE_HIGH) { - if (inv_probe(s_data->mem_db.next, s) > 0) - return; - printk(KERN_NOTICE "cs: warning: no high memory space " - "available!\n"); - } - if ((probe_mask & MEM_PROBE_LOW) == 0) - return; - for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { - mm = *m; - /* Only probe < 1 MB */ - if (mm.base >= 0x100000) continue; - if ((mm.base | mm.num) & 0xffff) { - ok += do_mem_probe(mm.base, mm.num, s); - continue; + /* We do up to four passes through the list */ + if (probe_mask & MEM_PROBE_HIGH) { + if (inv_probe(s_data->mem_db.next, s) > 0) + return 0; + printk(KERN_NOTICE "cs: warning: no high memory space " + "available!\n"); + return -ENODEV; } - /* Special probe for 64K-aligned block */ - for (i = 0; i < 4; i++) { - b = order[i] << 12; - if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { - if (ok >= mem_limit) - sub_interval(&s_data->mem_db, b, 0x10000); - else - ok += do_mem_probe(b, 0x10000, s); - } + + for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { + mm = *m; + /* Only probe < 1 MB */ + if (mm.base >= 0x100000) + continue; + if ((mm.base | mm.num) & 0xffff) { + ok += do_mem_probe(mm.base, mm.num, s); + continue; + } + /* Special probe for 64K-aligned block */ + for (i = 0; i < 4; i++) { + b = order[i] << 12; + if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { + if (ok >= mem_limit) + sub_interval(&s_data->mem_db, b, 0x10000); + else + ok += do_mem_probe(b, 0x10000, s); + } + } } - } + + if (ok > 0) + return 0; + + return -ENODEV; } #else /* CONFIG_PCMCIA_PROBE */ @@ -478,27 +484,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) /* * Locking note: Must be called with skt_sem held! */ -static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) +static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) { struct socket_data *s_data = s->resource_data; - if (probe_mem) { - unsigned int probe_mask; + unsigned int probe_mask = MEM_PROBE_LOW; + int ret = 0; - down(&rsrc_sem); + if (!probe_mem) + return 0; - probe_mask = MEM_PROBE_LOW; - if (s->features & SS_CAP_PAGE_REGS) - probe_mask = MEM_PROBE_HIGH; + down(&rsrc_sem); - if (probe_mask & ~s_data->rsrc_mem_probe) { + if (s->features & SS_CAP_PAGE_REGS) + probe_mask = MEM_PROBE_HIGH; + + if (probe_mask & ~s_data->rsrc_mem_probe) { + if (s->state & SOCKET_PRESENT) + ret = validate_mem(s, probe_mask); + if (!ret) s_data->rsrc_mem_probe |= probe_mask; + } - if (s->state & SOCKET_PRESENT) - validate_mem(s, probe_mask); - } + up(&rsrc_sem); - up(&rsrc_sem); - } + return ret; } struct pcmcia_align_data { -- cgit v1.2.3 From 2cff944720332535a24b7eae16cff32055a43048 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 16 Nov 2005 21:29:26 -0800 Subject: [PATCH] pcmcia: validate_mem fix Also return a value if CONFIG_PCMCIA_PROBE is not set. Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/rsrc_nonstatic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index ebfcab5df9ea..6b18092205b1 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -467,15 +467,19 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) #else /* CONFIG_PCMCIA_PROBE */ -static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) +static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) { struct resource_map *m, mm; struct socket_data *s_data = s->resource_data; + unsigned long ok = 0; for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { mm = *m; - do_mem_probe(mm.base, mm.num, s); + ok += do_mem_probe(mm.base, mm.num, s); } + if (ok > 0) + return 0; + return -ENODEV; } #endif /* CONFIG_PCMCIA_PROBE */ -- cgit v1.2.3 From 63e7ebd06402951bc8863ba5b7bc9b9f42044849 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Thu, 3 Nov 2005 21:12:14 +0100 Subject: [PATCH] yenta: make bridge specific init code configurable Make the bridge specific initialization code config options depending on CONFIG_EMBEDDED. Config options for TI/EnE, Toshiba, Ricoh and O2Micro are available. Disabling all of the specific tweaks cuts off more than half of yenta_socket.ko. Signed-off-by: Daniel Ritz Signed-off-by: Dominik Brodowski --- drivers/pcmcia/Kconfig | 25 +++++++++++++++++++++++++ drivers/pcmcia/ti113x.h | 4 ++-- drivers/pcmcia/yenta_socket.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 309eb557f9a3..ea00b1f3cb44 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -116,6 +116,31 @@ config YENTA If unsure, say Y. +config YENTA_O2 + default y + bool "Special initialization for O2Micro bridges" if EMBEDDED + depends on YENTA + +config YENTA_RICOH + default y + bool "Special initialization for Ricoh bridges" if EMBEDDED + depends on YENTA + +config YENTA_TI + default y + bool "Special initialization for TI and EnE bridges" if EMBEDDED + depends on YENTA + +config YENTA_ENE_TUNE + default y + bool "Auto-tune EnE bridges for CB cards" if EMBEDDED + depends on YENTA_TI && CARDBUS + +config YENTA_TOSHIBA + default y + bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED + depends on YENTA + config PD6729 tristate "Cirrus PD6729 compatible bridge support" depends on PCMCIA && PCI diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 539b5cd1a598..d5b4ff74462e 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -873,7 +873,7 @@ static int ti1250_override(struct yenta_socket *socket) * Some fixup code to make everybody happy (TM). */ -#ifdef CONFIG_CARDBUS +#ifdef CONFIG_YENTA_ENE_TUNE /** * set/clear various test bits: * Defaults to clear the bit. @@ -937,7 +937,7 @@ static int ene_override(struct yenta_socket *socket) } #else # define ene_override ti1250_override -#endif +#endif /* !CONFIG_YENTA_ENE_TUNE */ #endif /* _LINUX_TI113X_H */ diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index fa0625c438dc..826e7e133269 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -49,7 +49,13 @@ MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only #define to_cycles(ns) ((ns)/120) #define to_ns(cycles) ((cycles)*120) +/** + * yenta PCI irq probing. + * currently only used in the TI/EnE initialization code + */ +#ifdef CONFIG_YENTA_TI static int yenta_probe_cb_irq(struct yenta_socket *socket); +#endif static unsigned int override_bios; @@ -745,10 +751,18 @@ static struct pccard_operations yenta_socket_operations = { }; +#ifdef CONFIG_YENTA_TI #include "ti113x.h" +#endif +#ifdef CONFIG_YENTA_RICOH #include "ricoh.h" +#endif +#ifdef CONFIG_YENTA_TOSHIBA #include "topic.h" +#endif +#ifdef CONFIG_YENTA_O2 #include "o2micro.h" +#endif enum { CARDBUS_TYPE_DEFAULT = -1, @@ -768,6 +782,7 @@ enum { * initialization sequences etc details. List them here.. */ static struct cardbus_type cardbus_type[] = { +#ifdef CONFIG_YENTA_TI [CARDBUS_TYPE_TI] = { .override = ti_override, .save_state = ti_save_state, @@ -792,27 +807,36 @@ static struct cardbus_type cardbus_type[] = { .restore_state = ti_restore_state, .sock_init = ti_init, }, +#endif +#ifdef CONFIG_YENTA_RICOH [CARDBUS_TYPE_RICOH] = { .override = ricoh_override, .save_state = ricoh_save_state, .restore_state = ricoh_restore_state, }, +#endif +#ifdef CONFIG_YENTA_TOSHIBA [CARDBUS_TYPE_TOPIC95] = { .override = topic95_override, }, [CARDBUS_TYPE_TOPIC97] = { .override = topic97_override, }, +#endif +#ifdef CONFIG_YENTA_O2 [CARDBUS_TYPE_O2MICRO] = { .override = o2micro_override, .restore_state = o2micro_restore_state, }, +#endif +#ifdef CONFIG_YENTA_TI [CARDBUS_TYPE_ENE] = { .override = ene_override, .save_state = ti_save_state, .restore_state = ti_restore_state, .sock_init = ti_init, }, +#endif }; @@ -858,6 +882,12 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas } +/** + * yenta PCI irq probing. + * currently only used in the TI/EnE initialization code + */ +#ifdef CONFIG_YENTA_TI + /* interrupt handler, only used during probing */ static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs) { @@ -910,6 +940,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket) return (int) socket->probe_status; } +#endif /* CONFIG_YENTA_TI */ /* @@ -1173,6 +1204,7 @@ static struct pci_device_id yenta_table [] = { * advanced overrides instead. (I can't get the * data sheets for these devices. --rmk) */ +#ifdef CONFIG_YENTA_TI CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI), CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), @@ -1215,18 +1247,25 @@ static struct pci_device_id yenta_table [] = { CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE), CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE), CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), +#endif /* CONFIG_YENTA_TI */ +#ifdef CONFIG_YENTA_RICOH CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH), CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH), CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), +#endif +#ifdef CONFIG_YENTA_TOSHIBA CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95), CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97), CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), +#endif +#ifdef CONFIG_YENTA_O2 CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), +#endif /* match any cardbus bridge */ CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), -- cgit v1.2.3 From 98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:21:18 +0100 Subject: [PATCH] pcmcia: new suspend core Move the suspend and resume methods out of the event handler, and into special functions. Also use these functions for pre- and post-reset, as almost all drivers already do, and the remaining ones can easily be converted. Bugfix to include/pcmcia/ds.c Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index b120794c03a9..a802c65c3534 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -951,6 +951,16 @@ static int send_event_callback(struct device *dev, void * _data) if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) return 0; + if ((data->event == CS_EVENT_PM_SUSPEND) || + (data->event == CS_EVENT_RESET_PHYSICAL)) { + if (p_drv->suspend) + return p_drv->suspend(p_dev); + } else if ((data->event == CS_EVENT_PM_RESUME) || + (data->event == CS_EVENT_CARD_RESET)) { + if (p_drv->resume) + return p_drv->resume(p_dev); + } + if (p_drv->event) return p_drv->event(data->event, data->priority, &p_dev->event_callback_args); -- cgit v1.2.3 From 8e9e793d68fcda6cc84c18cedf85ca0f91d801a8 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 6 Jan 2006 00:02:03 +0100 Subject: [PATCH] pcmcia: merge suspend into device model Merge the suspend and resume methods for 16-bit PCMCIA cards into the device model -- for both runtime power management and suspend to ram/disk. Bugfix in ds.c by Richard Purdie Signed-Off-By: Richard Purdie Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cs.c | 14 ++++++- drivers/pcmcia/cs_internal.h | 2 + drivers/pcmcia/ds.c | 94 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 99 insertions(+), 11 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 7cf09084ef61..83d2753814c2 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -780,8 +780,13 @@ int pccard_reset_card(struct pcmcia_socket *skt) ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); if (ret == 0) { send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); - if (socket_reset(skt) == CS_SUCCESS) + if (skt->callback) + skt->callback->suspend(skt); + if (socket_reset(skt) == CS_SUCCESS) { send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); + if (skt->callback) + skt->callback->resume(skt); + } } ret = CS_SUCCESS; @@ -812,6 +817,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt) ret = CS_UNSUPPORTED_FUNCTION; break; } + if (skt->callback) { + ret = skt->callback->suspend(skt); + if (ret) + break; + } ret = socket_suspend(skt); } while (0); up(&skt->skt_sem); @@ -838,6 +848,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt) break; } ret = socket_resume(skt); + if (!ret && skt->callback) + skt->callback->resume(skt); } while (0); up(&skt->skt_sem); diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 634426b78f2c..7b37eba35bf1 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -143,6 +143,8 @@ struct pcmcia_callback{ struct module *owner; int (*event) (struct pcmcia_socket *s, event_t event, int priority); void (*requery) (struct pcmcia_socket *s); + int (*suspend) (struct pcmcia_socket *s); + int (*resume) (struct pcmcia_socket *s); }; int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index a802c65c3534..5223395b246a 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -920,6 +920,78 @@ static struct device_attribute pcmcia_dev_attrs[] = { __ATTR_NULL, }; +/* PM support, also needed for reset */ + +static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) +{ + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + struct pcmcia_driver *p_drv = NULL; + + if (dev->driver) + p_drv = to_pcmcia_drv(dev->driver); + + if (p_drv && p_drv->suspend) + return p_drv->suspend(p_dev); + + return 0; +} + + +static int pcmcia_dev_resume(struct device * dev) +{ + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + struct pcmcia_driver *p_drv = NULL; + + if (dev->driver) + p_drv = to_pcmcia_drv(dev->driver); + + if (p_drv && p_drv->resume) + return p_drv->resume(p_dev); + + return 0; +} + + +static int pcmcia_bus_suspend_callback(struct device *dev, void * _data) +{ + struct pcmcia_socket *skt = _data; + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + + if (p_dev->socket != skt) + return 0; + + return dpm_runtime_suspend(dev, PMSG_SUSPEND); +} + +static int pcmcia_bus_resume_callback(struct device *dev, void * _data) +{ + struct pcmcia_socket *skt = _data; + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + + if (p_dev->socket != skt) + return 0; + + dpm_runtime_resume(dev); + + return 0; +} + +static int pcmcia_bus_resume(struct pcmcia_socket *skt) +{ + bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); + return 0; +} + +static int pcmcia_bus_suspend(struct pcmcia_socket *skt) +{ + if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, + pcmcia_bus_suspend_callback)) { + pcmcia_bus_resume(skt); + return -EIO; + } + return 0; +} + /*====================================================================== @@ -951,16 +1023,6 @@ static int send_event_callback(struct device *dev, void * _data) if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) return 0; - if ((data->event == CS_EVENT_PM_SUSPEND) || - (data->event == CS_EVENT_RESET_PHYSICAL)) { - if (p_drv->suspend) - return p_drv->suspend(p_dev); - } else if ((data->event == CS_EVENT_PM_RESUME) || - (data->event == CS_EVENT_CARD_RESET)) { - if (p_drv->resume) - return p_drv->resume(p_dev); - } - if (p_drv->event) return p_drv->event(data->event, data->priority, &p_dev->event_callback_args); @@ -1012,6 +1074,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) ret = send_event(skt, event, priority); break; + case CS_EVENT_PM_SUSPEND: + case CS_EVENT_PM_RESUME: + case CS_EVENT_RESET_PHYSICAL: + case CS_EVENT_CARD_RESET: + handle_event(skt, event); + break; + default: handle_event(skt, event); send_event(skt, event, priority); @@ -1166,10 +1235,13 @@ int pcmcia_deregister_client(struct pcmcia_device *p_dev) } /* deregister_client */ EXPORT_SYMBOL(pcmcia_deregister_client); + static struct pcmcia_callback pcmcia_bus_callback = { .owner = THIS_MODULE, .event = ds_event, .requery = pcmcia_bus_rescan, + .suspend = pcmcia_bus_suspend, + .resume = pcmcia_bus_resume, }; static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, @@ -1238,6 +1310,8 @@ struct bus_type pcmcia_bus_type = { .uevent = pcmcia_bus_uevent, .match = pcmcia_bus_match, .dev_attrs = pcmcia_dev_attrs, + .suspend = pcmcia_dev_suspend, + .resume = pcmcia_dev_resume, }; -- cgit v1.2.3 From cc3b4866bee996c922e875b8c8efe9f0d8803aae Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:23:14 +0100 Subject: [PATCH] pcmcia: unify detach, REMOVAL_EVENT handlers into one remove callback Unify the "detach" and REMOVAL_EVENT handlers to one "remove" function. Old functionality is preserved, for the moment. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 97 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 35 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 5223395b246a..32b4d6baa917 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -57,8 +57,6 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644); spinlock_t pcmcia_dev_list_lock; -static int unbind_request(struct pcmcia_socket *s); - /*====================================================================*/ /* code which was in cs.c before */ @@ -205,7 +203,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) unsigned int i; u32 hash; - if (!p_drv->attach || !p_drv->event || !p_drv->detach) + if (!p_drv->attach || !p_drv->event || !p_drv->remove) printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " "function\n", p_drv->drv.name); @@ -399,13 +397,42 @@ static int pcmcia_device_remove(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; + int i; /* detach the "instance" */ p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); + /* the likely, new path */ + if (p_drv && p_drv->remove) { + p_drv->remove(p_dev); + + /* check for proper unloading */ + if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) + printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", + p_drv->drv.name); + + for (i = 0; i < MAX_WIN; i++) + if (p_dev->state & CLIENT_WIN_REQ(i)) + printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", + p_drv->drv.name); + + /* undo pcmcia_register_client */ + p_dev->state = CLIENT_UNBOUND; + pcmcia_put_dev(p_dev); + + /* references from pcmcia_probe_device */ + pcmcia_put_dev(p_dev); + module_put(p_drv->owner); + + return 0; + } + + /* old path */ if (p_drv) { if ((p_drv->detach) && (p_dev->instance)) { + printk(KERN_INFO "pcmcia: using deprecated detach mechanism. Fix the driver!\n"); + p_drv->detach(p_dev->instance); /* from pcmcia_probe_device */ put_device(&p_dev->dev); @@ -417,6 +444,36 @@ static int pcmcia_device_remove(struct device * dev) } +/* + * Removes a PCMCIA card from the device tree and socket list. + */ +static void pcmcia_card_remove(struct pcmcia_socket *s) +{ + struct pcmcia_device *p_dev; + unsigned long flags; + + ds_dbg(2, "unbind_request(%d)\n", s->sock); + + s->device_count = 0; + + for (;;) { + /* unregister all pcmcia_devices registered with this socket*/ + spin_lock_irqsave(&pcmcia_dev_list_lock, flags); + if (list_empty(&s->devices_list)) { + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + return; + } + p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); + list_del(&p_dev->socket_device_list); + p_dev->state |= CLIENT_STALE; + spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + + device_unregister(&p_dev->dev); + } + + return; +} /* unbind_request */ + /* * pcmcia_device_query -- determine information about a pcmcia device @@ -1059,8 +1116,8 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) case CS_EVENT_CARD_REMOVAL: s->pcmcia_state.present = 0; - send_event(skt, event, priority); - unbind_request(skt); + send_event(skt, event, priority); + pcmcia_card_remove(skt); handle_event(skt, event); break; @@ -1177,36 +1234,6 @@ int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req) EXPORT_SYMBOL(pcmcia_register_client); -/* unbind _all_ devices attached to a given pcmcia_bus_socket. The - * drivers have been called with EVENT_CARD_REMOVAL before. - */ -static int unbind_request(struct pcmcia_socket *s) -{ - struct pcmcia_device *p_dev; - unsigned long flags; - - ds_dbg(2, "unbind_request(%d)\n", s->sock); - - s->device_count = 0; - - for (;;) { - /* unregister all pcmcia_devices registered with this socket*/ - spin_lock_irqsave(&pcmcia_dev_list_lock, flags); - if (list_empty(&s->devices_list)) { - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - return 0; - } - p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); - list_del(&p_dev->socket_device_list); - p_dev->state |= CLIENT_STALE; - spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - - device_unregister(&p_dev->dev); - } - - return 0; -} /* unbind_request */ - int pcmcia_deregister_client(struct pcmcia_device *p_dev) { struct pcmcia_socket *s; -- cgit v1.2.3 From f3990715589d378a2d3aa9b8accd78bb4a2378b7 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:25:23 +0100 Subject: [PATCH] pcmcia: remove old detach mechanism Remove the old "detach" mechanism as it is unused now. Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 77 ++++++++++++----------------------------------------- 1 file changed, 17 insertions(+), 60 deletions(-) (limited to 'drivers/pcmcia') diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 32b4d6baa917..8eff55b6c9e9 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -402,43 +402,29 @@ static int pcmcia_device_remove(struct device * dev) /* detach the "instance" */ p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); + if (!p_drv) + return 0; - /* the likely, new path */ - if (p_drv && p_drv->remove) { + if (p_drv->remove) p_drv->remove(p_dev); - /* check for proper unloading */ - if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) - printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", - p_drv->drv.name); - - for (i = 0; i < MAX_WIN; i++) - if (p_dev->state & CLIENT_WIN_REQ(i)) - printk(KERN_INFO "pcmcia