diff options
Diffstat (limited to 'drivers/pcmcia/ds.c')
| -rw-r--r-- | drivers/pcmcia/ds.c | 136 |
1 files changed, 73 insertions, 63 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 55570d9e1e4..757119b8714 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -26,7 +26,6 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <pcmcia/cs.h> #include <pcmcia/cistpl.h> #include <pcmcia/ds.h> #include <pcmcia/ss.h> @@ -46,13 +45,13 @@ MODULE_LICENSE("GPL"); static void pcmcia_check_driver(struct pcmcia_driver *p_drv) { - struct pcmcia_device_id *did = p_drv->id_table; + const struct pcmcia_device_id *did = p_drv->id_table; unsigned int i; u32 hash; if (!p_drv->probe || !p_drv->remove) printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " - "function\n", p_drv->drv.name); + "function\n", p_drv->name); while (did && did->match_flags) { for (i = 0; i < 4; i++) { @@ -65,7 +64,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) printk(KERN_DEBUG "pcmcia: %s: invalid hash for " "product string \"%s\": is 0x%x, should " - "be 0x%x\n", p_drv->drv.name, did->prod_id[i], + "be 0x%x\n", p_drv->name, did->prod_id[i], did->prod_id_hash[i], hash); printk(KERN_DEBUG "pcmcia: see " "Documentation/pcmcia/devicetable.txt for " @@ -128,10 +127,7 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) list_add_tail(&dynid->node, &pdrv->dynids.list); mutex_unlock(&pdrv->dynids.lock); - if (get_driver(&pdrv->drv)) { - retval = driver_attach(&pdrv->drv); - put_driver(&pdrv->drv); - } + retval = driver_attach(&pdrv->drv); if (retval) return retval; @@ -161,6 +157,11 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) return error; } +static void +pcmcia_remove_newid_file(struct pcmcia_driver *drv) +{ + driver_remove_file(&drv->drv, &driver_attr_new_id); +} /** * pcmcia_register_driver - register a PCMCIA driver with the bus core @@ -180,10 +181,11 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) /* initialize common fields */ driver->drv.bus = &pcmcia_bus_type; driver->drv.owner = driver->owner; + driver->drv.name = driver->name; mutex_init(&driver->dynids.lock); INIT_LIST_HEAD(&driver->dynids.list); - pr_debug("registering driver %s\n", driver->drv.name); + pr_debug("registering driver %s\n", driver->name); error = driver_register(&driver->drv); if (error < 0) @@ -203,7 +205,8 @@ EXPORT_SYMBOL(pcmcia_register_driver); */ void pcmcia_unregister_driver(struct pcmcia_driver *driver) { - pr_debug("unregistering driver %s\n", driver->drv.name); + pr_debug("unregistering driver %s\n", driver->name); + pcmcia_remove_newid_file(driver); driver_unregister(&driver->drv); pcmcia_free_dynids(driver); } @@ -264,7 +267,7 @@ static int pcmcia_device_probe(struct device *dev) p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; - dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name); + dev_dbg(dev, "trying to bind to %s\n", p_drv->name); if ((!p_drv->probe) || (!p_dev->function_config) || (!try_module_get(p_drv->owner))) { @@ -276,21 +279,28 @@ static int pcmcia_device_probe(struct device *dev) ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG, &cis_config); if (!ret) { - p_dev->conf.ConfigBase = cis_config.base; - p_dev->conf.Present = cis_config.rmask[0]; + p_dev->config_base = cis_config.base; + p_dev->config_regs = cis_config.rmask[0]; + dev_dbg(dev, "base %x, regs %x", p_dev->config_base, + p_dev->config_regs); } else { dev_printk(KERN_INFO, dev, "pcmcia: could not parse base and rmask0 of CIS\n"); - p_dev->conf.ConfigBase = 0; - p_dev->conf.Present = 0; + p_dev->config_base = 0; + p_dev->config_regs = 0; } ret = p_drv->probe(p_dev); if (ret) { dev_dbg(dev, "binding to %s failed with %d\n", - p_drv->drv.name, ret); + p_drv->name, ret); goto put_module; } + dev_dbg(dev, "%s bound: Vpp %d.%d, idx %x, IRQ %d", p_drv->name, + p_dev->vpp/10, p_dev->vpp%10, p_dev->config_index, p_dev->irq); + dev_dbg(dev, "resources: ioport %pR %pR iomem %pR %pR %pR", + p_dev->resource[0], p_dev->resource[1], p_dev->resource[2], + p_dev->resource[3], p_dev->resource[4]); mutex_lock(&s->ops_mutex); if ((s->pcmcia_pfc) && @@ -374,13 +384,13 @@ static int pcmcia_device_remove(struct device *dev) if (p_dev->_irq || p_dev->_io || p_dev->_locked) dev_printk(KERN_INFO, dev, "pcmcia: driver %s did not release config properly\n", - p_drv->drv.name); + p_drv->name); for (i = 0; i < MAX_WIN; i++) if (p_dev->_win & CLIENT_WIN_REQ(i)) dev_printk(KERN_INFO, dev, "pcmcia: driver %s did not release window properly\n", - p_drv->drv.name); + p_drv->name); /* references from pcmcia_probe_device */ pcmcia_put_dev(p_dev); @@ -777,7 +787,7 @@ static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filenam static inline int pcmcia_devmatch(struct pcmcia_device *dev, - struct pcmcia_device_id *did) + const struct pcmcia_device_id *did) { if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) { if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id)) @@ -883,7 +893,7 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = to_pcmcia_drv(drv); - struct pcmcia_device_id *did = p_drv->id_table; + const struct pcmcia_device_id *did = p_drv->id_table; struct pcmcia_dynid *dynid; /* match dynamic devices first */ @@ -910,8 +920,6 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) return 0; } -#ifdef CONFIG_HOTPLUG - static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) { struct pcmcia_device *p_dev; @@ -952,15 +960,6 @@ static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#else - -static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return -ENODEV; -} - -#endif - /************************ runtime PM support ***************************/ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state); @@ -993,16 +992,17 @@ static ssize_t field##_show (struct device *dev, struct device_attribute *attr, { \ struct pcmcia_device *p_dev = to_pcmcia_dev(dev); \ return p_dev->test ? sprintf(buf, format, p_dev->field) : -ENODEV; \ -} +} \ +static DEVICE_ATTR_RO(field); #define pcmcia_device_stringattr(name, field) \ static ssize_t name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct pcmcia_device *p_dev = to_pcmcia_dev(dev); \ return p_dev->field ? sprintf(buf, "%s\n", p_dev->field) : -ENODEV; \ -} +} \ +static DEVICE_ATTR_RO(name); -pcmcia_device_attr(func, socket, "0x%02x\n"); pcmcia_device_attr(func_id, has_func_id, "0x%02x\n"); pcmcia_device_attr(manf_id, has_manf_id, "0x%04x\n"); pcmcia_device_attr(card_id, has_card_id, "0x%04x\n"); @@ -1011,8 +1011,16 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); pcmcia_device_stringattr(prod_id3, prod_id[2]); pcmcia_device_stringattr(prod_id4, prod_id[3]); -static ssize_t pcmcia_show_resources(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t function_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + return p_dev->socket ? sprintf(buf, "0x%02x\n", p_dev->func) : -ENODEV; +} +static DEVICE_ATTR_RO(function); + +static ssize_t resources_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); char *str = buf; @@ -1023,8 +1031,9 @@ static ssize_t pcmcia_show_resources(struct device *dev, return str - buf; } +static DEVICE_ATTR_RO(resources); -static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t pm_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); @@ -1034,8 +1043,8 @@ static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute return sprintf(buf, "on\n"); } -static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t pm_state_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); int ret = 0; @@ -1050,7 +1059,7 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute return ret ? ret : count; } - +static DEVICE_ATTR_RW(pm_state); static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1073,8 +1082,9 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, p_dev->func, p_dev->device_no, hash[0], hash[1], hash[2], hash[3]); } +static DEVICE_ATTR_RO(modalias); -static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, +static ssize_t allow_func_id_match_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); @@ -1089,22 +1099,24 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, return count; } - -static struct device_attribute pcmcia_dev_attrs[] = { - __ATTR(function, 0444, func_show, NULL), - __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state), - __ATTR(resources, 0444, pcmcia_show_resources, NULL), - __ATTR_RO(func_id), - __ATTR_RO(manf_id), - __ATTR_RO(card_id), - __ATTR_RO(prod_id1), - __ATTR_RO(prod_id2), - __ATTR_RO(prod_id3), - __ATTR_RO(prod_id4), - __ATTR_RO(modalias), - __ATTR(allow_func_id_match, 0200, NULL, pcmcia_store_allow_func_id_match), - __ATTR_NULL, +static DEVICE_ATTR_WO(allow_func_id_match); + +static struct attribute *pcmcia_dev_attrs[] = { + &dev_attr_resources.attr, + &dev_attr_pm_state.attr, + &dev_attr_function.attr, + &dev_attr_func_id.attr, + &dev_attr_manf_id.attr, + &dev_attr_card_id.attr, + &dev_attr_prod_id1.attr, + &dev_attr_prod_id2.attr, + &dev_attr_prod_id3.attr, + &dev_attr_prod_id4.attr, + &dev_attr_modalias.attr, + &dev_attr_allow_func_id_match.attr, + NULL, }; +ATTRIBUTE_GROUPS(pcmcia_dev); /* PM support, also needed for reset */ @@ -1136,7 +1148,7 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) dev_printk(KERN_ERR, dev, "pcmcia: device %s (driver %s) did " "not want to go to sleep (%d)\n", - p_dev->devname, p_drv->drv.name, ret); + p_dev->devname, p_drv->name, ret); mutex_lock(&p_dev->socket->ops_mutex); p_dev->suspended = 0; mutex_unlock(&p_dev->socket->ops_mutex); @@ -1178,7 +1190,7 @@ static int pcmcia_dev_resume(struct device *dev) if (p_dev->device_no == p_dev->func) { dev_dbg(dev, "requesting configuration\n"); - ret = pcmcia_request_configuration(p_dev, &p_dev->conf); + ret = pcmcia_enable_device(p_dev); if (ret) goto out; } @@ -1262,10 +1274,8 @@ static int pcmcia_bus_add(struct pcmcia_socket *skt) static int pcmcia_bus_early_resume(struct pcmcia_socket *skt) { - if (!verify_cis_cache(skt)) { - pcmcia_put_socket(skt); + if (!verify_cis_cache(skt)) return 0; - } dev_dbg(&skt->dev, "cis mismatch - different card\n"); @@ -1321,7 +1331,7 @@ static struct pcmcia_callback pcmcia_bus_callback = { .resume = pcmcia_bus_resume, }; -static int __devinit pcmcia_bus_add_socket(struct device *dev, +static int pcmcia_bus_add_socket(struct device *dev, struct class_interface *class_intf) { struct pcmcia_socket *socket = dev_get_drvdata(dev); @@ -1392,7 +1402,7 @@ struct bus_type pcmcia_bus_type = { .name = "pcmcia", .uevent = pcmcia_bus_uevent, .match = pcmcia_bus_match, - .dev_attrs = pcmcia_dev_attrs, + .dev_groups = pcmcia_dev_groups, .probe = pcmcia_device_probe, .remove = pcmcia_device_remove, .suspend = pcmcia_dev_suspend, |
