diff options
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/Kconfig | 2 | ||||
-rw-r--r-- | drivers/pcmcia/at91_cf.c | 51 | ||||
-rw-r--r-- | drivers/pcmcia/ds.c | 22 | ||||
-rw-r--r-- | drivers/pcmcia/i82365.c | 7 | ||||
-rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 23 | ||||
-rw-r--r-- | drivers/pcmcia/pcmcia_resource.c | 18 | ||||
-rw-r--r-- | drivers/pcmcia/pd6729.c | 2 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_sharpsl.c | 8 |
8 files changed, 77 insertions, 56 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index cba6c9eef28..61cb4b29f55 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -250,7 +250,7 @@ config M32R_CFC_NUM config PCMCIA_VRC4171 tristate "NEC VRC4171 Card Controllers support" - depends on VRC4171 && PCMCIA + depends on CPU_VR41XX && ISA && PCMCIA config PCMCIA_VRC4173 tristate "NEC VRC4173 CARDU support" diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 67cc5f7d0c9..a4d50940ebe 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -28,8 +28,6 @@ #include <asm/arch/gpio.h> -#define CF_SIZE 0x30000000 /* CS5+CS6: unavailable */ - /* * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; * some other bit in {A24,A22..A11} is nREG to flag memory access @@ -76,7 +74,8 @@ static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r) /* kick pccard as needed */ if (present != cf->present) { cf->present = present; - pr_debug("%s: card %s\n", driver_name, present ? "present" : "gone"); + pr_debug("%s: card %s\n", driver_name, + present ? "present" : "gone"); pcmcia_parse_events(&cf->socket, SS_DETECT); } } @@ -93,7 +92,7 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) cf = container_of(s, struct at91_cf_socket, socket); - /* NOTE: we assume 3VCARD, not XVCARD... */ + /* NOTE: CF is always 3VCARD */ if (at91_cf_present(cf)) { int rdy = cf->board->irq_pin; /* RDY/nIRQ */ int vcc = cf->board->vcc_pin; @@ -109,7 +108,8 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) return 0; } -static int at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) +static int +at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s) { struct at91_cf_socket *cf; @@ -184,7 +184,8 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) } /* pcmcia layer maps/unmaps mem regions */ -static int at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) +static int +at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) { struct at91_cf_socket *cf; @@ -218,12 +219,17 @@ static int __init at91_cf_probe(struct device *dev) struct at91_cf_socket *cf; struct at91_cf_data *board = dev->platform_data; struct platform_device *pdev = to_platform_device(dev); + struct resource *io; unsigned int csa; int status; if (!board || !board->det_pin || !board->rst_pin) return -ENODEV; + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!io) + return -ENODEV; + cf = kcalloc(1, sizeof *cf, GFP_KERNEL); if (!cf) return -ENOMEM; @@ -250,10 +256,14 @@ static int __init at91_cf_probe(struct device *dev) * REVISIT: these timings are in terms of MCK cycles, so * when MCK changes (cpufreq etc) so must these values... */ - at91_sys_write(AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT | AT91_SMC_WSEN - | AT91_SMC_NWS_(32) /* wait states */ - | AT91_SMC_RWSETUP_(6) /* setup time */ - | AT91_SMC_RWHOLD_(4) /* hold time */ + at91_sys_write(AT91_SMC_CSR(4), + AT91_SMC_ACSS_STD + | AT91_SMC_DBW_16 + | AT91_SMC_BAT + | AT91_SMC_WSEN + | AT91_SMC_NWS_(32) /* wait states */ + | AT91_SMC_RWSETUP_(6) /* setup time */ + | AT91_SMC_RWHOLD_(4) /* hold time */ ); /* must be a GPIO; ergo must trigger on both edges */ @@ -274,8 +284,7 @@ static int __init at91_cf_probe(struct device *dev) if (status < 0) goto fail0a; cf->socket.pci_irq = board->irq_pin; - } - else + } else cf->socket.pci_irq = NR_IRQS + 1; /* pcmcia layer only remaps "real" memory not iospace */ @@ -284,7 +293,8 @@ static int __init at91_cf_probe(struct device *dev) goto fail1; /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ - if (!request_mem_region(AT91_CF_BASE, CF_SIZE, driver_name)) + if (!request_mem_region(io->start, io->end + 1 - io->start, + driver_name)) goto fail1; pr_info("%s: irqs det #%d, io #%d\n", driver_name, @@ -297,7 +307,7 @@ static int __init at91_cf_probe(struct device *dev) cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | SS_CAP_MEM_ALIGN; cf->socket.map_size = SZ_2K; - cf->socket.io[0].NumPorts = SZ_2K; + cf->socket.io[0].res = io; status = pcmcia_register_socket(&cf->socket); if (status < 0) @@ -307,7 +317,7 @@ static int __init at91_cf_probe(struct device *dev) fail2: iounmap((void __iomem *) cf->socket.io_offset); - release_mem_region(AT91_CF_BASE, CF_SIZE); + release_mem_region(io->start, io->end + 1 - io->start); fail1: if (board->irq_pin) free_irq(board->irq_pin, cf); @@ -321,14 +331,15 @@ fail0: static int __exit at91_cf_remove(struct device *dev) { - struct at91_cf_socket *cf = dev_get_drvdata(dev); - unsigned int csa; + struct at91_cf_socket *cf = dev_get_drvdata(dev); + struct resource *io = cf->socket.io[0].res; + unsigned int csa; pcmcia_unregister_socket(&cf->socket); free_irq(cf->board->irq_pin, cf); free_irq(cf->board->det_pin, cf); iounmap((void __iomem *) cf->socket.io_offset); - release_mem_region(AT91_CF_BASE, CF_SIZE); + release_mem_region(io->start, io->end + 1 - io->start); csa = at91_sys_read(AT91_EBI_CSA); at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); @@ -342,8 +353,8 @@ static struct device_driver at91_cf_driver = { .bus = &platform_bus_type, .probe = at91_cf_probe, .remove = __exit_p(at91_cf_remove), - .suspend = pcmcia_socket_dev_suspend, - .resume = pcmcia_socket_dev_resume, + .suspend = pcmcia_socket_dev_suspend, + .resume = pcmcia_socket_dev_resume, }; /*--------------------------------------------------------------------------*/ diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index ae10d1eed65..74b3124e824 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -236,11 +236,11 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) /** * pcmcia_load_firmware - load CIS from userspace if device-provided is broken * @dev - the pcmcia device which needs a CIS override - * @filename - requested filename in /lib/firmware/cis/ + * @filename - requested filename in /lib/firmware/ * * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if * the one provided by the card is broken. The firmware files reside in - * /lib/firmware/cis/ in userspace. + * /lib/firmware/ in userspace. */ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) { @@ -298,9 +298,6 @@ static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filenam * * Registers a PCMCIA driver with the PCMCIA bus core. */ -static int pcmcia_device_probe(struct device *dev); -static int pcmcia_device_remove(struct device * dev); - int pcmcia_register_driver(struct pcmcia_driver *driver) { if (!driver) @@ -400,7 +397,7 @@ static int pcmcia_device_probe(struct device * dev) * call which will then check whether there are two * pseudo devices, and if not, add the second one. */ - did = (struct pcmcia_device_id *) p_dev->dev.driver_data; + did = p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) pcmcia_add_pseudo_device(p_dev->socket); @@ -448,7 +445,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le return; } - static int pcmcia_device_remove(struct device * dev) { struct pcmcia_device *p_dev; @@ -463,7 +459,7 @@ static int pcmcia_device_remove(struct device * dev) * pseudo multi-function card, we need to unbind * all devices */ - did = (struct pcmcia_device_id *) p_dev->dev.driver_data; + did = p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count != 0) && (p_dev->device_no == 0)) @@ -476,6 +472,8 @@ static int pcmcia_device_remove(struct device * dev) if (p_drv->remove) p_drv->remove(p_dev); + p_dev->dev_node = NULL; + /* check for proper unloading */ if (p_dev->_irq || p_dev->_io || p_dev->_locked) printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", @@ -628,7 +626,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f } /* Add to the list in pcmcia_bus_socket */ - list_add_tail(&p_dev->socket_device_list, &s->devices_list); + list_add(&p_dev->socket_device_list, &s->devices_list); spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); @@ -1145,6 +1143,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) { struct pcmcia_socket *s = pcmcia_get_socket(skt); + if (!s) { + printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \ + "failed, event 0x%x lost!\n", skt, event); + return -ENODEV; + } + ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", event, priority, skt); diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index bd0308e8981..a2f05f48515 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -509,7 +509,8 @@ static irqreturn_t i365_count_irq(int irq, void *dev, struct pt_regs *regs) static u_int __init test_irq(u_short sock, int irq) { debug(2, " testing ISA irq %d\n", irq); - if (request_irq(irq, i365_count_irq, 0, "scan", i365_count_irq) != 0) + if (request_irq(irq, i365_count_irq, SA_PROBEIRQ, "scan", + i365_count_irq) != 0) return 1; irq_hits = 0; irq_sock = sock; msleep(10); @@ -561,7 +562,7 @@ static u_int __init isa_scan(u_short sock, u_int mask0) } else { /* Fallback: just find interrupts that aren't in use */ for (i = 0; i < 16; i++) - if ((mask0 & (1 << i)) && (_check_irq(i, 0) == 0)) + if ((mask0 & (1 << i)) && (_check_irq(i, SA_PROBEIRQ) == 0)) mask1 |= (1 << i); printk("default"); /* If scan failed, default to polled status */ @@ -725,7 +726,7 @@ static void __init add_pcic(int ns, int type) u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12)); for (cs_irq = 15; cs_irq > 0; cs_irq--) if ((cs_mask & (1 << cs_irq)) && - (_check_irq(cs_irq, 0) == 0)) + (_check_irq(cs_irq, SA_PROBEIRQ) == 0)) break; if (cs_irq) { grab_irq = 1; diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index c53db7ceda5..738b1ef595a 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -426,7 +426,7 @@ static int ds_open(struct inode *inode, struct file *file) if (!warning_printed) { printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl " - "usage.\n"); + "usage from process: %s.\n", current->comm); printk(KERN_INFO "pcmcia: This interface will soon be removed from " "the kernel; please expect breakage unless you upgrade " "to new tools.\n"); @@ -601,8 +601,12 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); - ret = pccard_get_configuration_info(s, p_dev, &buf->config); - pcmcia_put_dev(p_dev); + if (p_dev == NULL) + ret = CS_BAD_ARGS; + else { + ret = pccard_get_configuration_info(s, p_dev, &buf->config); + pcmcia_put_dev(p_dev); + } } break; case DS_GET_FIRST_TUPLE: @@ -632,8 +636,12 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); - ret = pccard_get_status(s, p_dev, &buf->status); - pcmcia_put_dev(p_dev); + if (p_dev == NULL) + ret = CS_BAD_ARGS; + else { + ret = pccard_get_status(s, p_dev, &buf->status); + pcmcia_put_dev(p_dev); + } } break; case DS_VALIDATE_CIS: @@ -665,9 +673,10 @@ static int ds_ioctl(struct inode * inode, struct file * file, if (!(buf->conf_reg.Function && (buf->conf_reg.Function >= s->functions))) { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function); - if (p_dev) + if (p_dev) { ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg); - pcmcia_put_dev(p_dev); + pcmcia_put_dev(p_dev); + } } break; case DS_GET_FIRST_REGION: diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 45063b4e5b7..3131bb0a009 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -88,7 +88,6 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, } if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { *base = s->io_offset | (*base & 0x0fff); - s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); return 0; } /* Check for an already-allocated window that must conflict with @@ -209,7 +208,6 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, if (!(s->state & SOCKET_PRESENT)) return CS_NO_CARD; - config->Function = p_dev->func; #ifdef CONFIG_CARDBUS if (s->state & SOCKET_CARDBUS) { @@ -223,14 +221,22 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, config->AssignedIRQ = s->irq.AssignedIRQ; if (config->AssignedIRQ) config->Attributes |= CONF_ENABLE_IRQ; - config->BasePort1 = s->io[0].res->start; - config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; + if (s->io[0].res) { + config->BasePort1 = s->io[0].res->start; + config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; + } } return CS_SUCCESS; } #endif - c = (p_dev) ? p_dev->function_config : NULL; + if (p_dev) { + c = p_dev->function_config; + config->Function = p_dev->func; + } else { + c = NULL; + config->Function = 0; + } if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { config->Attributes = 0; @@ -947,7 +953,5 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { pcmcia_release_irq(p_dev, &p_dev->irq); if (&p_dev->win) pcmcia_release_window(p_dev->win); - - p_dev->dev_node = NULL; } EXPORT_SYMBOL(pcmcia_disable_device); diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 16d1ea7b0a1..247ab837f84 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -589,7 +589,7 @@ static int pd6729_check_irq(int irq, int flags) return 0; } -static u_int __init pd6729_isa_scan(void) +static u_int __devinit pd6729_isa_scan(void) { u_int mask0, mask = 0; int i; diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index fd364736895..b7b9e149c5b 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -26,14 +26,6 @@ #include "soc_common.h" #define NO_KEEP_VS 0x0001 - -/* PCMCIA to Scoop linkage - - There is no easy way to link multiple scoop devices into one - single entity for the pxa2xx_pcmcia device so this structure - is used which is setup by the platform code -*/ -struct scoop_pcmcia_config *platform_scoop_config; #define SCOOP_DEV platform_scoop_config->devs static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) |