Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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