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