1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * DIO Driver Services 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * Copyright (C) 2004 Jochen Friedrich 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * Loosely based on drivers/pci/pci-driver.c and drivers/zorro/zorro-driver.c 7*1da177e4SLinus Torvalds * 8*1da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 9*1da177e4SLinus Torvalds * License. See the file COPYING in the main directory of this archive 10*1da177e4SLinus Torvalds * for more details. 11*1da177e4SLinus Torvalds */ 12*1da177e4SLinus Torvalds 13*1da177e4SLinus Torvalds #include <linux/init.h> 14*1da177e4SLinus Torvalds #include <linux/module.h> 15*1da177e4SLinus Torvalds #include <linux/dio.h> 16*1da177e4SLinus Torvalds 17*1da177e4SLinus Torvalds 18*1da177e4SLinus Torvalds /** 19*1da177e4SLinus Torvalds * dio_match_device - Tell if a DIO device structure has a matching 20*1da177e4SLinus Torvalds * DIO device id structure 21*1da177e4SLinus Torvalds * @ids: array of DIO device id structures to search in 22*1da177e4SLinus Torvalds * @dev: the DIO device structure to match against 23*1da177e4SLinus Torvalds * 24*1da177e4SLinus Torvalds * Used by a driver to check whether a DIO device present in the 25*1da177e4SLinus Torvalds * system is in its list of supported devices. Returns the matching 26*1da177e4SLinus Torvalds * dio_device_id structure or %NULL if there is no match. 27*1da177e4SLinus Torvalds */ 28*1da177e4SLinus Torvalds 29*1da177e4SLinus Torvalds const struct dio_device_id * 30*1da177e4SLinus Torvalds dio_match_device(const struct dio_device_id *ids, 31*1da177e4SLinus Torvalds const struct dio_dev *d) 32*1da177e4SLinus Torvalds { 33*1da177e4SLinus Torvalds while (ids->id) { 34*1da177e4SLinus Torvalds if (ids->id == DIO_WILDCARD) 35*1da177e4SLinus Torvalds return ids; 36*1da177e4SLinus Torvalds if (DIO_NEEDSSECID(ids->id & 0xff)) { 37*1da177e4SLinus Torvalds if (ids->id == d->id) 38*1da177e4SLinus Torvalds return ids; 39*1da177e4SLinus Torvalds } else { 40*1da177e4SLinus Torvalds if ((ids->id & 0xff) == (d->id & 0xff)) 41*1da177e4SLinus Torvalds return ids; 42*1da177e4SLinus Torvalds } 43*1da177e4SLinus Torvalds ids++; 44*1da177e4SLinus Torvalds } 45*1da177e4SLinus Torvalds return NULL; 46*1da177e4SLinus Torvalds } 47*1da177e4SLinus Torvalds 48*1da177e4SLinus Torvalds static int dio_device_probe(struct device *dev) 49*1da177e4SLinus Torvalds { 50*1da177e4SLinus Torvalds int error = 0; 51*1da177e4SLinus Torvalds struct dio_driver *drv = to_dio_driver(dev->driver); 52*1da177e4SLinus Torvalds struct dio_dev *d = to_dio_dev(dev); 53*1da177e4SLinus Torvalds 54*1da177e4SLinus Torvalds if (!d->driver && drv->probe) { 55*1da177e4SLinus Torvalds const struct dio_device_id *id; 56*1da177e4SLinus Torvalds 57*1da177e4SLinus Torvalds id = dio_match_device(drv->id_table, d); 58*1da177e4SLinus Torvalds if (id) 59*1da177e4SLinus Torvalds error = drv->probe(d, id); 60*1da177e4SLinus Torvalds if (error >= 0) { 61*1da177e4SLinus Torvalds d->driver = drv; 62*1da177e4SLinus Torvalds error = 0; 63*1da177e4SLinus Torvalds } 64*1da177e4SLinus Torvalds } 65*1da177e4SLinus Torvalds return error; 66*1da177e4SLinus Torvalds } 67*1da177e4SLinus Torvalds 68*1da177e4SLinus Torvalds 69*1da177e4SLinus Torvalds /** 70*1da177e4SLinus Torvalds * dio_register_driver - register a new DIO driver 71*1da177e4SLinus Torvalds * @drv: the driver structure to register 72*1da177e4SLinus Torvalds * 73*1da177e4SLinus Torvalds * Adds the driver structure to the list of registered drivers 74*1da177e4SLinus Torvalds * Returns the number of DIO devices which were claimed by the driver 75*1da177e4SLinus Torvalds * during registration. The driver remains registered even if the 76*1da177e4SLinus Torvalds * return value is zero. 77*1da177e4SLinus Torvalds */ 78*1da177e4SLinus Torvalds 79*1da177e4SLinus Torvalds int dio_register_driver(struct dio_driver *drv) 80*1da177e4SLinus Torvalds { 81*1da177e4SLinus Torvalds int count = 0; 82*1da177e4SLinus Torvalds 83*1da177e4SLinus Torvalds /* initialize common driver fields */ 84*1da177e4SLinus Torvalds drv->driver.name = drv->name; 85*1da177e4SLinus Torvalds drv->driver.bus = &dio_bus_type; 86*1da177e4SLinus Torvalds drv->driver.probe = dio_device_probe; 87*1da177e4SLinus Torvalds 88*1da177e4SLinus Torvalds /* register with core */ 89*1da177e4SLinus Torvalds count = driver_register(&drv->driver); 90*1da177e4SLinus Torvalds return count ? count : 1; 91*1da177e4SLinus Torvalds } 92*1da177e4SLinus Torvalds 93*1da177e4SLinus Torvalds 94*1da177e4SLinus Torvalds /** 95*1da177e4SLinus Torvalds * dio_unregister_driver - unregister a DIO driver 96*1da177e4SLinus Torvalds * @drv: the driver structure to unregister 97*1da177e4SLinus Torvalds * 98*1da177e4SLinus Torvalds * Deletes the driver structure from the list of registered DIO drivers, 99*1da177e4SLinus Torvalds * gives it a chance to clean up by calling its remove() function for 100*1da177e4SLinus Torvalds * each device it was responsible for, and marks those devices as 101*1da177e4SLinus Torvalds * driverless. 102*1da177e4SLinus Torvalds */ 103*1da177e4SLinus Torvalds 104*1da177e4SLinus Torvalds void dio_unregister_driver(struct dio_driver *drv) 105*1da177e4SLinus Torvalds { 106*1da177e4SLinus Torvalds driver_unregister(&drv->driver); 107*1da177e4SLinus Torvalds } 108*1da177e4SLinus Torvalds 109*1da177e4SLinus Torvalds 110*1da177e4SLinus Torvalds /** 111*1da177e4SLinus Torvalds * dio_bus_match - Tell if a DIO device structure has a matching DIO 112*1da177e4SLinus Torvalds * device id structure 113*1da177e4SLinus Torvalds * @ids: array of DIO device id structures to search in 114*1da177e4SLinus Torvalds * @dev: the DIO device structure to match against 115*1da177e4SLinus Torvalds * 116*1da177e4SLinus Torvalds * Used by a driver to check whether a DIO device present in the 117*1da177e4SLinus Torvalds * system is in its list of supported devices. Returns the matching 118*1da177e4SLinus Torvalds * dio_device_id structure or %NULL if there is no match. 119*1da177e4SLinus Torvalds */ 120*1da177e4SLinus Torvalds 121*1da177e4SLinus Torvalds static int dio_bus_match(struct device *dev, struct device_driver *drv) 122*1da177e4SLinus Torvalds { 123*1da177e4SLinus Torvalds struct dio_dev *d = to_dio_dev(dev); 124*1da177e4SLinus Torvalds struct dio_driver *dio_drv = to_dio_driver(drv); 125*1da177e4SLinus Torvalds const struct dio_device_id *ids = dio_drv->id_table; 126*1da177e4SLinus Torvalds 127*1da177e4SLinus Torvalds if (!ids) 128*1da177e4SLinus Torvalds return 0; 129*1da177e4SLinus Torvalds 130*1da177e4SLinus Torvalds while (ids->id) { 131*1da177e4SLinus Torvalds if (ids->id == DIO_WILDCARD) 132*1da177e4SLinus Torvalds return 1; 133*1da177e4SLinus Torvalds if (DIO_NEEDSSECID(ids->id & 0xff)) { 134*1da177e4SLinus Torvalds if (ids->id == d->id) 135*1da177e4SLinus Torvalds return 1; 136*1da177e4SLinus Torvalds } else { 137*1da177e4SLinus Torvalds if ((ids->id & 0xff) == (d->id & 0xff)) 138*1da177e4SLinus Torvalds return 1; 139*1da177e4SLinus Torvalds } 140*1da177e4SLinus Torvalds ids++; 141*1da177e4SLinus Torvalds } 142*1da177e4SLinus Torvalds return 0; 143*1da177e4SLinus Torvalds } 144*1da177e4SLinus Torvalds 145*1da177e4SLinus Torvalds 146*1da177e4SLinus Torvalds struct bus_type dio_bus_type = { 147*1da177e4SLinus Torvalds .name = "dio", 148*1da177e4SLinus Torvalds .match = dio_bus_match 149*1da177e4SLinus Torvalds }; 150*1da177e4SLinus Torvalds 151*1da177e4SLinus Torvalds 152*1da177e4SLinus Torvalds static int __init dio_driver_init(void) 153*1da177e4SLinus Torvalds { 154*1da177e4SLinus Torvalds return bus_register(&dio_bus_type); 155*1da177e4SLinus Torvalds } 156*1da177e4SLinus Torvalds 157*1da177e4SLinus Torvalds postcore_initcall(dio_driver_init); 158*1da177e4SLinus Torvalds 159*1da177e4SLinus Torvalds EXPORT_SYMBOL(dio_match_device); 160*1da177e4SLinus Torvalds EXPORT_SYMBOL(dio_register_driver); 161*1da177e4SLinus Torvalds EXPORT_SYMBOL(dio_unregister_driver); 162*1da177e4SLinus Torvalds EXPORT_SYMBOL(dio_dev_driver); 163*1da177e4SLinus Torvalds EXPORT_SYMBOL(dio_bus_type); 164