aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/vio.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/vio.c')
-rw-r--r--arch/ppc64/kernel/vio.c73
1 files changed, 27 insertions, 46 deletions
diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c
index 3b790bafcaad..c90e1dd875ce 100644
--- a/arch/ppc64/kernel/vio.c
+++ b/arch/ppc64/kernel/vio.c
@@ -32,14 +32,13 @@ struct vio_dev vio_bus_device = { /* fake "parent" device */
32 .dev.bus = &vio_bus_type, 32 .dev.bus = &vio_bus_type,
33}; 33};
34 34
35static int (*is_match)(const struct vio_device_id *id, 35static struct vio_bus_ops vio_bus_ops;
36 const struct vio_dev *dev);
37static void (*unregister_device_callback)(struct vio_dev *dev);
38static void (*release_device_callback)(struct device *dev);
39 36
40/* convert from struct device to struct vio_dev and pass to driver. 37/*
38 * Convert from struct device to struct vio_dev and pass to driver.
41 * dev->driver has already been set by generic code because vio_bus_match 39 * dev->driver has already been set by generic code because vio_bus_match
42 * succeeded. */ 40 * succeeded.
41 */
43static int vio_bus_probe(struct device *dev) 42static int vio_bus_probe(struct device *dev)
44{ 43{
45 struct vio_dev *viodev = to_vio_dev(dev); 44 struct vio_dev *viodev = to_vio_dev(dev);
@@ -51,9 +50,8 @@ static int vio_bus_probe(struct device *dev)
51 return error; 50 return error;
52 51
53 id = vio_match_device(viodrv->id_table, viodev); 52 id = vio_match_device(viodrv->id_table, viodev);
54 if (id) { 53 if (id)
55 error = viodrv->probe(viodev, id); 54 error = viodrv->probe(viodev, id);
56 }
57 55
58 return error; 56 return error;
59} 57}
@@ -64,9 +62,8 @@ static int vio_bus_remove(struct device *dev)
64 struct vio_dev *viodev = to_vio_dev(dev); 62 struct vio_dev *viodev = to_vio_dev(dev);
65 struct vio_driver *viodrv = to_vio_driver(dev->driver); 63 struct vio_driver *viodrv = to_vio_driver(dev->driver);
66 64
67 if (viodrv->remove) { 65 if (viodrv->remove)
68 return viodrv->remove(viodev); 66 return viodrv->remove(viodev);
69 }
70 67
71 /* driver can't remove */ 68 /* driver can't remove */
72 return 1; 69 return 1;
@@ -102,19 +99,20 @@ void vio_unregister_driver(struct vio_driver *viodrv)
102EXPORT_SYMBOL(vio_unregister_driver); 99EXPORT_SYMBOL(vio_unregister_driver);
103 100
104/** 101/**
105 * vio_match_device: - Tell if a VIO device has a matching VIO device id structure. 102 * vio_match_device: - Tell if a VIO device has a matching
106 * @ids: array of VIO device id structures to search in 103 * VIO device id structure.
107 * @dev: the VIO device structure to match against 104 * @ids: array of VIO device id structures to search in
105 * @dev: the VIO device structure to match against
108 * 106 *
109 * Used by a driver to check whether a VIO device present in the 107 * Used by a driver to check whether a VIO device present in the
110 * system is in its list of supported devices. Returns the matching 108 * system is in its list of supported devices. Returns the matching
111 * vio_device_id structure or NULL if there is no match. 109 * vio_device_id structure or NULL if there is no match.
112 */ 110 */
113static const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, 111static const struct vio_device_id *vio_match_device(
114 const struct vio_dev *dev) 112 const struct vio_device_id *ids, const struct vio_dev *dev)
115{ 113{
116 while (ids->type) { 114 while (ids->type[0] != '\0') {
117 if (is_match(ids, dev)) 115 if (vio_bus_ops.match(ids, dev))
118 return ids; 116 return ids;
119 ids++; 117 ids++;
120 } 118 }
@@ -124,16 +122,11 @@ static const struct vio_device_id * vio_match_device(const struct vio_device_id
124/** 122/**
125 * vio_bus_init: - Initialize the virtual IO bus 123 * vio_bus_init: - Initialize the virtual IO bus
126 */ 124 */
127int __init vio_bus_init(int (*match_func)(const struct vio_device_id *id, 125int __init vio_bus_init(struct vio_bus_ops *ops)
128 const struct vio_dev *dev),
129 void (*unregister_dev)(struct vio_dev *),
130 void (*release_dev)(struct device *))
131{ 126{
132 int err; 127 int err;
133 128
134 is_match = match_func; 129 vio_bus_ops = *ops;
135 unregister_device_callback = unregister_dev;
136 release_device_callback = release_dev;
137 130
138 err = bus_register(&vio_bus_type); 131 err = bus_register(&vio_bus_type);
139 if (err) { 132 if (err) {
@@ -141,7 +134,8 @@ int __init vio_bus_init(int (*match_func)(const struct vio_device_id *id,
141 return err; 134 return err;
142 } 135 }
143 136
144 /* the fake parent of all vio devices, just to give us 137 /*
138 * The fake parent of all vio devices, just to give us
145 * a nice directory 139 * a nice directory
146 */ 140 */
147 err = device_register(&vio_bus_device.dev); 141 err = device_register(&vio_bus_device.dev);
@@ -157,25 +151,20 @@ int __init vio_bus_init(int (*match_func)(const struct vio_device_id *id,
157/* vio_dev refcount hit 0 */ 151/* vio_dev refcount hit 0 */
158static void __devinit vio_dev_release(struct device *dev) 152static void __devinit vio_dev_release(struct device *dev)
159{ 153{
160 if (release_device_callback) 154 if (vio_bus_ops.release_device)
161 release_device_callback(dev); 155 vio_bus_ops.release_device(dev);
162 kfree(to_vio_dev(dev)); 156 kfree(to_vio_dev(dev));
163} 157}
164 158
165static ssize_t viodev_show_name(struct device *dev, struct device_attribute *attr, char *buf) 159static ssize_t viodev_show_name(struct device *dev,
160 struct device_attribute *attr, char *buf)
166{ 161{
167 return sprintf(buf, "%s\n", to_vio_dev(dev)->name); 162 return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
168} 163}
169DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL); 164DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
170 165
171struct vio_dev * __devinit vio_register_device_common( 166struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
172 struct vio_dev *viodev, char *name, char *type,
173 uint32_t unit_address, struct iommu_table *iommu_table)
174{ 167{
175 viodev->name = name;
176 viodev->type = type;
177 viodev->unit_address = unit_address;
178 viodev->iommu_table = iommu_table;
179 /* init generic 'struct device' fields: */ 168 /* init generic 'struct device' fields: */
180 viodev->dev.parent = &vio_bus_device.dev; 169 viodev->dev.parent = &vio_bus_device.dev;
181 viodev->dev.bus = &vio_bus_type; 170 viodev->dev.bus = &vio_bus_type;
@@ -194,8 +183,8 @@ struct vio_dev * __devinit vio_register_device_common(
194 183
195void __devinit vio_unregister_device(struct vio_dev *viodev) 184void __devinit vio_unregister_device(struct vio_dev *viodev)
196{ 185{
197 if (unregister_device_callback) 186 if (vio_bus_ops.unregister_device)
198 unregister_device_callback(viodev); 187 vio_bus_ops.unregister_device(viodev);
199 device_remove_file(&viodev->dev, &dev_attr_name); 188 device_remove_file(&viodev->dev, &dev_attr_name);
200 device_unregister(&viodev->dev); 189 device_unregister(&viodev->dev);
201} 190}
@@ -262,16 +251,8 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
262 const struct vio_dev *vio_dev = to_vio_dev(dev); 251 const struct vio_dev *vio_dev = to_vio_dev(dev);
263 struct vio_driver *vio_drv = to_vio_driver(drv); 252 struct vio_driver *vio_drv = to_vio_driver(drv);
264 const struct vio_device_id *ids = vio_drv->id_table; 253 const struct vio_device_id *ids = vio_drv->id_table;
265 const struct vio_device_id *found_id;
266
267 if (!ids)
268 return 0;
269 254
270 found_id = vio_match_device(ids, vio_dev); 255 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
271 if (found_id)
272 return 1;
273
274 return 0;
275} 256}
276 257
277struct bus_type vio_bus_type = { 258struct bus_type vio_bus_type = {