Index: local/sound/isa/adlib.c =================================================================== --- local.orig/sound/isa/adlib.c 2006-04-30 23:10:10.000000000 +0200 +++ local/sound/isa/adlib.c 2006-04-30 23:11:33.000000000 +0200 @@ -5,13 +5,14 @@ #include #include #include -#include +#include #include #include #include #define CRD_NAME "AdLib FM" -#define DRV_NAME "snd_adlib" +#define DEV_NAME "adlib" +#define DRV_NAME "snd-" DEV_NAME MODULE_DESCRIPTION(CRD_NAME); MODULE_AUTHOR("Rene Herman"); @@ -31,36 +32,47 @@ MODULE_PARM_DESC(enable, "Enable " CRD_N module_param_array(port, long, NULL, 0444); MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver."); -static struct platform_device *devices[SNDRV_CARDS]; +static int __devinit snd_adlib_match(struct isa_dev *isa_dev) +{ + unsigned int i = isa_dev->id; + char *bus_id = isa_dev->dev.bus_id; + + if (!enable[i]) + return 0; + + if (port[i] == SNDRV_AUTO_PORT) { + snd_printk(KERN_ERR "%s: please specify port\n", bus_id); + return 0; + } + + return 1; +} static void snd_adlib_free(struct snd_card *card) { release_and_free_resource(card->private_data); } -static int __devinit snd_adlib_probe(struct platform_device *device) +static int __devinit snd_adlib_probe(struct isa_dev *isa_dev) { struct snd_card *card; struct snd_opl3 *opl3; - int error, i = device->id; + int error; - if (port[i] == SNDRV_AUTO_PORT) { - snd_printk(KERN_ERR DRV_NAME ": please specify port\n"); - error = -EINVAL; - goto out0; - } + unsigned int i = isa_dev->id; + char *bus_id = isa_dev->dev.bus_id; card = snd_card_new(index[i], id[i], THIS_MODULE, 0); if (!card) { - snd_printk(KERN_ERR DRV_NAME ": could not create card\n"); + snd_printk(KERN_ERR "%s: could not create card\n", bus_id); error = -EINVAL; goto out0; } card->private_data = request_region(port[i], 4, CRD_NAME); if (!card->private_data) { - snd_printk(KERN_ERR DRV_NAME ": could not grab ports\n"); + snd_printk(KERN_ERR "%s: could not grab ports\n", bus_id); error = -EBUSY; goto out1; } @@ -68,101 +80,62 @@ static int __devinit snd_adlib_probe(str error = snd_opl3_create(card, port[i], port[i] + 2, OPL3_HW_AUTO, 1, &opl3); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create OPL\n"); + snd_printk(KERN_ERR "%s: could not create OPL\n", bus_id); goto out1; } error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not create FM\n"); + snd_printk(KERN_ERR "%s: could not create FM\n", bus_id); goto out1; } strcpy(card->driver, DRV_NAME); - strcpy(card->shortname, CRD_NAME); + strcpy(card->shortname, DEV_NAME); sprintf(card->longname, CRD_NAME " at %#lx", port[i]); - snd_card_set_dev(card, &device->dev); + snd_card_set_dev(card, &isa_dev->dev); error = snd_card_register(card); if (error < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register card\n"); + snd_printk(KERN_ERR "%s: could not register card\n", bus_id); goto out1; } - platform_set_drvdata(device, card); + isa_set_drvdata(isa_dev, card); return 0; out1: snd_card_free(card); out0: return error; } -static int __devexit snd_adlib_remove(struct platform_device *device) +static int __devexit snd_adlib_remove(struct isa_dev *isa_dev) { - snd_card_free(platform_get_drvdata(device)); - platform_set_drvdata(device, NULL); + snd_card_free(isa_get_drvdata(isa_dev)); + isa_set_drvdata(isa_dev, NULL); return 0; } -static struct platform_driver snd_adlib_driver = { +static struct isa_driver snd_adlib_driver = { + .nr_devices = SNDRV_CARDS, + + .match = snd_adlib_match, .probe = snd_adlib_probe, .remove = __devexit_p(snd_adlib_remove), .driver = { - .name = DRV_NAME + .name = DEV_NAME } }; static int __init alsa_card_adlib_init(void) { - int i, cards; - - if (platform_driver_register(&snd_adlib_driver) < 0) { - snd_printk(KERN_ERR DRV_NAME ": could not register driver\n"); - return -ENODEV; - } - - for (cards = 0, i = 0; i < SNDRV_CARDS; i++) { - struct platform_device *device; - - if (!enable[i]) - continue; - - device = platform_device_alloc(DRV_NAME, i); - if (!device) - continue; - - if (platform_device_add(device) < 0) { - platform_device_put(device); - continue; - } - - if (!platform_get_drvdata(device)) { - platform_device_unregister(device); - continue; - } - - devices[i] = device; - cards++; - } - - if (!cards) { -#ifdef MODULE - printk(KERN_ERR CRD_NAME " soundcard not found or device busy\n"); -#endif - platform_driver_unregister(&snd_adlib_driver); - return -ENODEV; - } - return 0; + return isa_register_driver(&snd_adlib_driver); } static void __exit alsa_card_adlib_exit(void) { - int i; - - for (i = 0; i < SNDRV_CARDS; i++) - platform_device_unregister(devices[i]); - platform_driver_unregister(&snd_adlib_driver); + isa_unregister_driver(&snd_adlib_driver); } module_init(alsa_card_adlib_init); Index: local/drivers/base/isa.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ local/drivers/base/isa.c 2006-05-01 00:23:42.000000000 +0200 @@ -0,0 +1,169 @@ +/* + * ISA bus. + */ + +#include +#include +#include +#include + +static struct device isa_bus = { + .bus_id = "isa" +}; + +static int isa_bus_match(struct device *dev, struct device_driver *driver) +{ + struct isa_driver *isa_driver = to_isa_driver(driver); + + if (dev->platform_data == isa_driver) { + if (!isa_driver->match || isa_driver->match(to_isa_dev(dev))) + return 1; + dev->platform_data = NULL; + } + return 0; +} + +static int isa_bus_probe(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->probe) + return isa_driver->probe(to_isa_dev(dev)); + + return 0; +} + +static int isa_bus_remove(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->remove) + return isa_driver->remove(to_isa_dev(dev)); + + return 0; +} + +static void isa_bus_shutdown(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->shutdown) + isa_driver->shutdown(to_isa_dev(dev)); +} + +static int isa_bus_suspend(struct device *dev, pm_message_t state) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->suspend) + return isa_driver->suspend(to_isa_dev(dev), state); + + return 0; +} + +static int isa_bus_resume(struct device *dev) +{ + struct isa_driver *isa_driver = dev->platform_data; + + if (isa_driver->resume) + return isa_driver->resume(to_isa_dev(dev)); + + return 0; +} + +static struct bus_type isa_bus_type = { + .name = "isa", + .match = isa_bus_match, + .probe = isa_bus_probe, + .remove = isa_bus_remove, + .shutdown = isa_bus_shutdown, + .suspend = isa_bus_suspend, + .resume = isa_bus_resume +}; + +static void isa_dev_release(struct device *dev) +{ + kfree(to_isa_dev(dev)); +} + +void isa_unregister_driver(struct isa_driver *isa_driver) +{ + struct isa_dev *isa_dev = isa_driver->devices; + + while (isa_dev) { + struct device *dev = &isa_dev->dev; + isa_dev = isa_dev->next; + device_unregister(dev); + } + driver_unregister(&isa_driver->driver); +} +EXPORT_SYMBOL_GPL(isa_unregister_driver); + +int isa_register_driver(struct isa_driver *isa_driver) +{ + int error; + unsigned int id; + + isa_driver->driver.bus = &isa_bus_type; + isa_driver->devices = NULL; + + error = driver_register(&isa_driver->driver); + if (error) + return error; + + for (id = 0; id < isa_driver->nr_devices; id++) { + struct isa_dev *isa_dev; + + isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + if (!isa_dev) { + error = -ENOMEM; + break; + } + + isa_dev->dev.parent = &isa_bus; + isa_dev->dev.bus = &isa_bus_type; + + snprintf(isa_dev->dev.bus_id, BUS_ID_SIZE, "%s.%u", + isa_driver->driver.name, id); + + isa_dev->dev.platform_data = isa_driver; + isa_dev->dev.release = isa_dev_release; + isa_dev->id = id; + + error = device_register(&isa_dev->dev); + if (error) { + put_device(&isa_dev->dev); + break; + } + + if (isa_dev->dev.platform_data) { + isa_dev->next = isa_driver->devices; + isa_driver->devices = isa_dev; + } else + device_unregister(&isa_dev->dev); + } + + if (!error && !isa_driver->devices) + error = -ENODEV; + + if (error) + isa_unregister_driver(isa_driver); + + return error; +} +EXPORT_SYMBOL_GPL(isa_register_driver); + +static int __init isa_bus_init(void) +{ + int error; + + error = bus_register(&isa_bus_type); + if (!error) { + error = device_register(&isa_bus); + if (error) + bus_unregister(&isa_bus_type); + } + return error; +} + +device_initcall(isa_bus_init); Index: local/include/linux/isa.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ local/include/linux/isa.h 2006-04-30 23:11:33.000000000 +0200 @@ -0,0 +1,40 @@ +/* + * ISA bus. + */ + +#ifndef __LINUX_ISA_H +#define __LINUX_ISA_H + +#include + +struct isa_dev { + struct device dev; + unsigned int id; + struct isa_dev *next; +}; + +#define to_isa_dev(x) container_of((x), struct isa_dev, dev) + +struct isa_driver { + unsigned int nr_devices; + struct isa_dev *devices; + + int (*match)(struct isa_dev *); + int (*probe)(struct isa_dev *); + int (*remove)(struct isa_dev *); + void (*shutdown)(struct isa_dev *); + int (*suspend)(struct isa_dev *, pm_message_t); + int (*resume)(struct isa_dev *); + + struct device_driver driver; +}; + +#define to_isa_driver(x) container_of((x), struct isa_driver, driver) + +#define isa_get_drvdata(x) dev_get_drvdata(&(x)->dev) +#define isa_set_drvdata(x, data) dev_set_drvdata(&(x)->dev, (data)) + +int isa_register_driver(struct isa_driver *); +void isa_unregister_driver(struct isa_driver *); + +#endif /* __LINUX_ISA_H */ Index: local/drivers/base/Makefile =================================================================== --- local.orig/drivers/base/Makefile 2006-04-30 23:10:10.000000000 +0200 +++ local/drivers/base/Makefile 2006-04-30 23:11:33.000000000 +0200 @@ -4,6 +4,7 @@ obj-y := core.o sys.o bus.o dd.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o dmapool.o \ attribute_container.o transport_class.o +obj-$(CONFIG_ISA) += isa.o obj-y += power/ obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o