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
);
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
;
94 viodrv
->driver
.probe
= vio_bus_probe
;
95 viodrv
->driver
.remove
= vio_bus_remove
;
96 viodrv
->driver
.shutdown
= vio_bus_shutdown
;
98 return driver_register(&viodrv
->driver
);
100 EXPORT_SYMBOL(vio_register_driver
);
103 * vio_unregister_driver - Remove registration of vio driver.
104 * @driver: The vio_driver struct to be removed form registration
106 void vio_unregister_driver(struct vio_driver
*viodrv
)
108 driver_unregister(&viodrv
->driver
);
110 EXPORT_SYMBOL(vio_unregister_driver
);
113 * vio_match_device: - Tell if a VIO device has a matching
114 * VIO device id structure.
115 * @ids: array of VIO device id structures to search in
116 * @dev: the VIO device structure to match against
118 * Used by a driver to check whether a VIO device present in the
119 * system is in its list of supported devices. Returns the matching
120 * vio_device_id structure or NULL if there is no match.
122 static const struct vio_device_id
*vio_match_device(
123 const struct vio_device_id
*ids
, const struct vio_dev
*dev
)
125 while (ids
->type
[0] != '\0') {
126 if (vio_bus_ops
.match(ids
, dev
))
134 * vio_bus_init: - Initialize the virtual IO bus
136 int __init
vio_bus_init(struct vio_bus_ops
*ops
)
142 err
= bus_register(&vio_bus_type
);
144 printk(KERN_ERR
"failed to register VIO bus\n");
149 * The fake parent of all vio devices, just to give us
152 err
= device_register(&vio_bus_device
.dev
);
154 printk(KERN_WARNING
"%s: device_register returned %i\n",
162 /* vio_dev refcount hit 0 */
163 static void __devinit
vio_dev_release(struct device
*dev
)
165 if (vio_bus_ops
.release_device
)
166 vio_bus_ops
.release_device(dev
);
167 kfree(to_vio_dev(dev
));
170 static ssize_t
viodev_show_name(struct device
*dev
,
171 struct device_attribute
*attr
, char *buf
)
173 return sprintf(buf
, "%s\n", to_vio_dev(dev
)->name
);
175 DEVICE_ATTR(name
, S_IRUSR
| S_IRGRP
| S_IROTH
, viodev_show_name
, NULL
);
177 struct vio_dev
* __devinit
vio_register_device(struct vio_dev
*viodev
)
179 /* init generic 'struct device' fields: */
180 viodev
->dev
.parent
= &vio_bus_device
.dev
;
181 viodev
->dev
.bus
= &vio_bus_type
;
182 viodev
->dev
.release
= vio_dev_release
;
184 /* register with generic device framework */
185 if (device_register(&viodev
->dev
)) {
186 printk(KERN_ERR
"%s: failed to register device %s\n",
187 __FUNCTION__
, viodev
->dev
.bus_id
);
190 device_create_file(&viodev
->dev
, &dev_attr_name
);
195 void __devinit
vio_unregister_device(struct vio_dev
*viodev
)
197 if (vio_bus_ops
.unregister_device
)
198 vio_bus_ops
.unregister_device(viodev
);
199 device_remove_file(&viodev
->dev
, &dev_attr_name
);
200 device_unregister(&viodev
->dev
);
202 EXPORT_SYMBOL(vio_unregister_device
);
204 static dma_addr_t
vio_map_single(struct device
*dev
, void *vaddr
,
205 size_t size
, enum dma_data_direction direction
)
207 return iommu_map_single(to_vio_dev(dev
)->iommu_table
, vaddr
, size
,
211 static void vio_unmap_single(struct device
*dev
, dma_addr_t dma_handle
,
212 size_t size
, enum dma_data_direction direction
)
214 iommu_unmap_single(to_vio_dev(dev
)->iommu_table
, dma_handle
, size
,
218 static int vio_map_sg(struct device
*dev
, struct scatterlist
*sglist
,
219 int nelems
, enum dma_data_direction direction
)
221 return iommu_map_sg(dev
, to_vio_dev(dev
)->iommu_table
, sglist
,
225 static void vio_unmap_sg(struct device
*dev
, struct scatterlist
*sglist
,
226 int nelems
, enum dma_data_direction direction
)
228 iommu_unmap_sg(to_vio_dev(dev
)->iommu_table
, sglist
, nelems
, direction
);
231 static void *vio_alloc_coherent(struct device
*dev
, size_t size
,
232 dma_addr_t
*dma_handle
, gfp_t flag
)
234 return iommu_alloc_coherent(to_vio_dev(dev
)->iommu_table
, size
,
238 static void vio_free_coherent(struct device
*dev
, size_t size
,
239 void *vaddr
, dma_addr_t dma_handle
)
241 iommu_free_coherent(to_vio_dev(dev
)->iommu_table
, size
, vaddr
,
245 static int vio_dma_supported(struct device
*dev
, u64 mask
)
250 struct dma_mapping_ops vio_dma_ops
= {
251 .alloc_coherent
= vio_alloc_coherent
,
252 .free_coherent
= vio_free_coherent
,
253 .map_single
= vio_map_single
,
254 .unmap_single
= vio_unmap_single
,
255 .map_sg
= vio_map_sg
,
256 .unmap_sg
= vio_unmap_sg
,
257 .dma_supported
= vio_dma_supported
,
260 static int vio_bus_match(struct device
*dev
, struct device_driver
*drv
)
262 const struct vio_dev
*vio_dev
= to_vio_dev(dev
);
263 struct vio_driver
*vio_drv
= to_vio_driver(drv
);
264 const struct vio_device_id
*ids
= vio_drv
->id_table
;
266 return (ids
!= NULL
) && (vio_match_device(ids
, vio_dev
) != NULL
);
269 static int vio_hotplug(struct device
*dev
, char **envp
, int num_envp
,
270 char *buffer
, int buffer_size
)
272 const struct vio_dev
*vio_dev
= to_vio_dev(dev
);
279 if (!vio_dev
->dev
.platform_data
)
281 cp
= (char *)get_property(vio_dev
->dev
.platform_data
, "compatible", &length
);
286 length
= scnprintf(buffer
, buffer_size
, "MODALIAS=vio:T%sS%s",
288 if (buffer_size
- length
<= 0)
294 struct bus_type vio_bus_type
= {
296 .hotplug
= vio_hotplug
,
297 .match
= vio_bus_match
,