1 /* 2 * ISA bus. 3 */ 4 5 #include <linux/device.h> 6 #include <linux/kernel.h> 7 #include <linux/slab.h> 8 #include <linux/module.h> 9 #include <linux/init.h> 10 #include <linux/dma-mapping.h> 11 #include <linux/isa.h> 12 13 static struct device isa_bus = { 14 .init_name = "isa" 15 }; 16 17 struct isa_dev { 18 struct device dev; 19 struct device *next; 20 unsigned int id; 21 }; 22 23 #define to_isa_dev(x) container_of((x), struct isa_dev, dev) 24 25 static int isa_bus_match(struct device *dev, struct device_driver *driver) 26 { 27 struct isa_driver *isa_driver = to_isa_driver(driver); 28 29 if (dev->platform_data == isa_driver) { 30 if (!isa_driver->match || 31 isa_driver->match(dev, to_isa_dev(dev)->id)) 32 return 1; 33 dev->platform_data = NULL; 34 } 35 return 0; 36 } 37 38 static int isa_bus_probe(struct device *dev) 39 { 40 struct isa_driver *isa_driver = dev->platform_data; 41 42 if (isa_driver->probe) 43 return isa_driver->probe(dev, to_isa_dev(dev)->id); 44 45 return 0; 46 } 47 48 static int isa_bus_remove(struct device *dev) 49 { 50 struct isa_driver *isa_driver = dev->platform_data; 51 52 if (isa_driver->remove) 53 return isa_driver->remove(dev, to_isa_dev(dev)->id); 54 55 return 0; 56 } 57 58 static void isa_bus_shutdown(struct device *dev) 59 { 60 struct isa_driver *isa_driver = dev->platform_data; 61 62 if (isa_driver->shutdown) 63 isa_driver->shutdown(dev, to_isa_dev(dev)->id); 64 } 65 66 static int isa_bus_suspend(struct device *dev, pm_message_t state) 67 { 68 struct isa_driver *isa_driver = dev->platform_data; 69 70 if (isa_driver->suspend) 71 return isa_driver->suspend(dev, to_isa_dev(dev)->id, state); 72 73 return 0; 74 } 75 76 static int isa_bus_resume(struct device *dev) 77 { 78 struct isa_driver *isa_driver = dev->platform_data; 79 80 if (isa_driver->resume) 81 return isa_driver->resume(dev, to_isa_dev(dev)->id); 82 83 return 0; 84 } 85 86 static struct bus_type isa_bus_type = { 87 .name = "isa", 88 .match = isa_bus_match, 89 .probe = isa_bus_probe, 90 .remove = isa_bus_remove, 91 .shutdown = isa_bus_shutdown, 92 .suspend = isa_bus_suspend, 93 .resume = isa_bus_resume 94 }; 95 96 static void isa_dev_release(struct device *dev) 97 { 98 kfree(to_isa_dev(dev)); 99 } 100 101 void isa_unregister_driver(struct isa_driver *isa_driver) 102 { 103 struct device *dev = isa_driver->devices; 104 105 while (dev) { 106 struct device *tmp = to_isa_dev(dev)->next; 107 device_unregister(dev); 108 dev = tmp; 109 } 110 driver_unregister(&isa_driver->driver); 111 } 112 EXPORT_SYMBOL_GPL(isa_unregister_driver); 113 114 int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev) 115 { 116 int error; 117 unsigned int id; 118 119 isa_driver->driver.bus = &isa_bus_type; 120 isa_driver->devices = NULL; 121 122 error = driver_register(&isa_driver->driver); 123 if (error) 124 return error; 125 126 for (id = 0; id < ndev; id++) { 127 struct isa_dev *isa_dev; 128 129 isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); 130 if (!isa_dev) { 131 error = -ENOMEM; 132 break; 133 } 134 135 isa_dev->dev.parent = &isa_bus; 136 isa_dev->dev.bus = &isa_bus_type; 137 138 dev_set_name(&isa_dev->dev, "%s.%u", 139 isa_driver->driver.name, id); 140 isa_dev->dev.platform_data = isa_driver; 141 isa_dev->dev.release = isa_dev_release; 142 isa_dev->id = id; 143 144 isa_dev->dev.coherent_dma_mask = DMA_BIT_MASK(24); 145 isa_dev->dev.dma_mask = &isa_dev->dev.coherent_dma_mask; 146 147 error = device_register(&isa_dev->dev); 148 if (error) { 149 put_device(&isa_dev->dev); 150 break; 151 } 152 153 if (isa_dev->dev.platform_data) { 154 isa_dev->next = isa_driver->devices; 155 isa_driver->devices = &isa_dev->dev; 156 } else 157 device_unregister(&isa_dev->dev); 158 } 159 160 if (!error && !isa_driver->devices) 161 error = -ENODEV; 162 163 if (error) 164 isa_unregister_driver(isa_driver); 165 166 return error; 167 } 168 EXPORT_SYMBOL_GPL(isa_register_driver); 169 170 static int __init isa_bus_init(void) 171 { 172 int error; 173 174 error = bus_register(&isa_bus_type); 175 if (!error) { 176 error = device_register(&isa_bus); 177 if (error) 178 bus_unregister(&isa_bus_type); 179 } 180 return error; 181 } 182 183 device_initcall(isa_bus_init); 184