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