2 * IBM PowerPC Virtual I/O Infrastructure Support.
4 * Copyright (c) 2003-2005 IBM Corp.
5 * Dave Engebretsen engebret@us.ibm.com
6 * Santiago Leon santil@us.ibm.com
7 * Hollis Blanchard <hollisb@us.ibm.com>
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
16 #include <linux/init.h>
17 #include <linux/console.h>
18 #include <linux/module.h>
20 #include <linux/dma-mapping.h>
21 #include <asm/iommu.h>
26 static const struct vio_device_id
*vio_match_device(
27 const struct vio_device_id
*, const struct vio_dev
*);
29 struct vio_dev vio_bus_device
= { /* fake "parent" device */
30 .name
= vio_bus_device
.dev
.bus_id
,
33 .dev
.bus
= &vio_bus_type
,
36 static struct vio_bus_ops vio_bus_ops
;
39 * Convert from struct device to struct vio_dev and pass to driver.
40 * dev->driver has already been set by generic code because vio_bus_match
43 static int vio_bus_probe(struct device
*dev
)
45 struct vio_dev
*viodev
= to_vio_dev(dev
);
46 struct vio_driver
*viodrv
= to_vio_driver(dev
->driver
);
47 const struct vio_device_id
*id
;
53 id
= vio_match_device(viodrv
->id_table
, viodev
);
55 error
= viodrv
->probe(viodev
, id
);
60 /* convert from struct device to struct vio_dev and pass to driver. */
61 static int vio_bus_remove(struct device
*dev
)
63 struct vio_dev
*viodev
= to_vio_dev(dev
);
64 struct vio_driver
*viodrv
= to_vio_driver(dev
->driver
);
67 return viodrv
->remove(viodev
);
69 /* driver can't remove */
73 /* convert from struct device to struct vio_dev and pass to driver. */
74 static void vio_bus_shutdown(struct device
*dev
)
76 struct vio_dev
*viodev
= to_vio_dev(dev
);
77 struct vio_driver
*viodrv
= to_vio_driver(dev
->driver
);
79 if (dev
->driver
&& viodrv
->shutdown
)
80 viodrv
->shutdown(viodev
);
84 * vio_register_driver: - Register a new vio driver
85 * @drv: The vio_driver structure to be registered.
87 int vio_register_driver(struct vio_driver
*viodrv
)
89 printk(KERN_DEBUG
"%s: driver %s registering\n", __FUNCTION__
,
92 /* fill in 'struct driver' fields */
93 viodrv
->driver
.bus
= &vio_bus_type
;
95 return driver_register(&viodrv
->driver
);
97 EXPORT_SYMBOL(vio_register_driver
);
100 * vio_unregister_driver - Remove registration of vio driver.
101 * @driver: The vio_driver struct to be removed form registration
103 void vio_unregister_driver(struct vio_driver
*viodrv
)
105 driver_unregister(&viodrv
->driver
);
107 EXPORT_SYMBOL(vio_unregister_driver
);
110 * vio_match_device: - Tell if a VIO device has a matching
111 * VIO device id structure.
112 * @ids: array of VIO device id structures to search in
113 * @dev: the VIO device structure to match against
115 * Used by a driver to check whether a VIO device present in the
116 * system is in its list of supported devices. Returns the matching
117 * vio_device_id structure or NULL if there is no match.
119 static const struct vio_device_id
*vio_match_device(
120 const struct vio_device_id
*ids
, const struct vio_dev
*dev
)
122 while (ids
->type
[0] != '\0') {
123 if (vio_bus_ops
.match(ids
, dev
))
131 * vio_bus_init: - Initialize the virtual IO bus
133 int __init
vio_bus_init(struct vio_bus_ops
*ops
)
139 err
= bus_register(&vio_bus_type
);
141 printk(KERN_ERR
"failed to register VIO bus\n");
146 * The fake parent of all vio devices, just to give us
149 err
= device_register(&vio_bus_device
.dev
);
151 printk(KERN_WARNING
"%s: device_register returned %i\n",
159 /* vio_dev refcount hit 0 */
160 static void __devinit
vio_dev_release(struct device
*dev
)
162 if (vio_bus_ops
.release_device
)
163 vio_bus_ops
.release_device(dev
);
164 kfree(to_vio_dev(dev
));
167 static ssize_t
viodev_show_name(struct device
*dev
,
168 struct device_attribute
*attr
, char *buf
)
170 return sprintf(buf
, "%s\n", to_vio_dev(dev
)->name
);
172 DEVICE_ATTR(name
, S_IRUSR
| S_IRGRP
| S_IROTH
, viodev_show_name
, NULL
);
174 struct vio_dev
* __devinit
vio_register_device(struct vio_dev
*viodev
)
176 /* init generic 'struct device' fields: */
177 viodev
->dev
.parent
= &vio_bus_device
.dev
;
178 viodev
->dev
.bus
= &vio_bus_type
;
179 viodev
->dev
.release
= vio_dev_release
;
181 /* register with generic device framework */
182 if (device_register(&viodev
->dev
)) {
183 printk(KERN_ERR
"%s: failed to register device %s\n",
184 __FUNCTION__
, viodev
->dev
.bus_id
);
187 device_create_file(&viodev
->dev
, &dev_attr_name
);
192 void __devinit
vio_unregister_device(struct vio_dev
*viodev
)
194 if (vio_bus_ops
.unregister_device
)
195 vio_bus_ops
.unregister_device(viodev
);
196 device_remove_file(&viodev
->dev
, &dev_attr_name
);
197 device_unregister(&viodev
->dev
);
199 EXPORT_SYMBOL(vio_unregister_device
);
201 static dma_addr_t
vio_map_single(struct device
*dev
, void *vaddr
,
202 size_t size
, enum dma_data_direction direction
)
204 return iommu_map_single(to_vio_dev(dev
)->iommu_table
, vaddr
, size
,
208 static void vio_unmap_single(struct device
*dev
, dma_addr_t dma_handle
,
209 size_t size
, enum dma_data_direction direction
)
211 iommu_unmap_single(to_vio_dev(dev
)->iommu_table
, dma_handle
, size
,
215 static int vio_map_sg(struct device
*dev
, struct scatterlist
*sglist
,
216 int nelems
, enum dma_data_direction direction
)
218 return iommu_map_sg(dev
, to_vio_dev(dev
)->iommu_table
, sglist
,
222 static void vio_unmap_sg(struct device
*dev
, struct scatterlist
*sglist
,
223 int nelems
, enum dma_data_direction direction
)
225 iommu_unmap_sg(to_vio_dev(dev
)->iommu_table
, sglist
, nelems
, direction
);
228 static void *vio_alloc_coherent(struct device
*dev
, size_t size
,
229 dma_addr_t
*dma_handle
, gfp_t flag
)
231 return iommu_alloc_coherent(to_vio_dev(dev
)->iommu_table
, size
,
235 static void vio_free_coherent(struct device
*dev
, size_t size
,
236 void *vaddr
, dma_addr_t dma_handle
)
238 iommu_free_coherent(to_vio_dev(dev
)->iommu_table
, size
, vaddr
,
242 static int vio_dma_supported(struct device
*dev
, u64 mask
)
247 struct dma_mapping_ops vio_dma_ops
= {
248 .alloc_coherent
= vio_alloc_coherent
,
249 .free_coherent
= vio_free_coherent
,
250 .map_single
= vio_map_single
,
251 .unmap_single
= vio_unmap_single
,
252 .map_sg
= vio_map_sg
,
253 .unmap_sg
= vio_unmap_sg
,
254 .dma_supported
= vio_dma_supported
,
257 static int vio_bus_match(struct device
*dev
, struct device_driver
*drv
)
259 const struct vio_dev
*vio_dev
= to_vio_dev(dev
);
260 struct vio_driver
*vio_drv
= to_vio_driver(drv
);
261 const struct vio_device_id
*ids
= vio_drv
->id_table
;
263 return (ids
!= NULL
) && (vio_match_device(ids
, vio_dev
) != NULL
);
266 static int vio_hotplug(struct device
*dev
, char **envp
, int num_envp
,
267 char *buffer
, int buffer_size
)
269 const struct vio_dev
*vio_dev
= to_vio_dev(dev
);
276 if (!vio_dev
->dev
.platform_data
)
278 cp
= (char *)get_property(vio_dev
->dev
.platform_data
, "compatible", &length
);
283 length
= scnprintf(buffer
, buffer_size
, "MODALIAS=vio:T%sS%s",
285 if (buffer_size
- length
<= 0)
291 struct bus_type vio_bus_type
= {
293 .uevent
= vio_hotplug
,
294 .match
= vio_bus_match
,
295 .probe
= vio_bus_probe
,
296 .remove
= vio_bus_remove
,
297 .shutdown
= vio_bus_shutdown
,