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>
25 static const struct vio_device_id
*vio_match_device(
26 const struct vio_device_id
*, const struct vio_dev
*);
28 struct vio_dev vio_bus_device
= { /* fake "parent" device */
29 .name
= vio_bus_device
.dev
.bus_id
,
32 .dev
.bus
= &vio_bus_type
,
35 static struct vio_bus_ops vio_bus_ops
;
38 * Convert from struct device to struct vio_dev and pass to driver.
39 * dev->driver has already been set by generic code because vio_bus_match
42 static int vio_bus_probe(struct device
*dev
)
44 struct vio_dev
*viodev
= to_vio_dev(dev
);
45 struct vio_driver
*viodrv
= to_vio_driver(dev
->driver
);
46 const struct vio_device_id
*id
;
52 id
= vio_match_device(viodrv
->id_table
, viodev
);
54 error
= viodrv
->probe(viodev
, id
);
59 /* convert from struct device to struct vio_dev and pass to driver. */
60 static int vio_bus_remove(struct device
*dev
)
62 struct vio_dev
*viodev
= to_vio_dev(dev
);
63 struct vio_driver
*viodrv
= to_vio_driver(dev
->driver
);
66 return viodrv
->remove(viodev
);
68 /* driver can't remove */
73 * vio_register_driver: - Register a new vio driver
74 * @drv: The vio_driver structure to be registered.
76 int vio_register_driver(struct vio_driver
*viodrv
)
78 printk(KERN_DEBUG
"%s: driver %s registering\n", __FUNCTION__
,
81 /* fill in 'struct driver' fields */
82 viodrv
->driver
.name
= viodrv
->name
;
83 viodrv
->driver
.bus
= &vio_bus_type
;
84 viodrv
->driver
.probe
= vio_bus_probe
;
85 viodrv
->driver
.remove
= vio_bus_remove
;
87 return driver_register(&viodrv
->driver
);
89 EXPORT_SYMBOL(vio_register_driver
);
92 * vio_unregister_driver - Remove registration of vio driver.
93 * @driver: The vio_driver struct to be removed form registration
95 void vio_unregister_driver(struct vio_driver
*viodrv
)
97 driver_unregister(&viodrv
->driver
);
99 EXPORT_SYMBOL(vio_unregister_driver
);
102 * vio_match_device: - Tell if a VIO device has a matching
103 * VIO device id structure.
104 * @ids: array of VIO device id structures to search in
105 * @dev: the VIO device structure to match against
107 * Used by a driver to check whether a VIO device present in the
108 * system is in its list of supported devices. Returns the matching
109 * vio_device_id structure or NULL if there is no match.
111 static const struct vio_device_id
*vio_match_device(
112 const struct vio_device_id
*ids
, const struct vio_dev
*dev
)
114 while (ids
->type
[0] != '\0') {
115 if (vio_bus_ops
.match(ids
, dev
))
123 * vio_bus_init: - Initialize the virtual IO bus
125 int __init
vio_bus_init(struct vio_bus_ops
*ops
)
131 err
= bus_register(&vio_bus_type
);
133 printk(KERN_ERR
"failed to register VIO bus\n");
138 * The fake parent of all vio devices, just to give us
141 err
= device_register(&vio_bus_device
.dev
);
143 printk(KERN_WARNING
"%s: device_register returned %i\n",
151 /* vio_dev refcount hit 0 */
152 static void __devinit
vio_dev_release(struct device
*dev
)
154 if (vio_bus_ops
.release_device
)
155 vio_bus_ops
.release_device(dev
);
156 kfree(to_vio_dev(dev
));
159 static ssize_t
viodev_show_name(struct device
*dev
,
160 struct device_attribute
*attr
, char *buf
)
162 return sprintf(buf
, "%s\n", to_vio_dev(dev
)->name
);
164 DEVICE_ATTR(name
, S_IRUSR
| S_IRGRP
| S_IROTH
, viodev_show_name
, NULL
);
166 struct vio_dev
* __devinit
vio_register_device(struct vio_dev
*viodev
)
168 /* init generic 'struct device' fields: */
169 viodev
->dev
.parent
= &vio_bus_device
.dev
;
170 viodev
->dev
.bus
= &vio_bus_type
;
171 viodev
->dev
.release
= vio_dev_release
;
173 /* register with generic device framework */
174 if (device_register(&viodev
->dev
)) {
175 printk(KERN_ERR
"%s: failed to register device %s\n",
176 __FUNCTION__
, viodev
->dev
.bus_id
);
179 device_create_file(&viodev
->dev
, &dev_attr_name
);
184 void __devinit
vio_unregister_device(struct vio_dev
*viodev
)
186 if (vio_bus_ops
.unregister_device
)
187 vio_bus_ops
.unregister_device(viodev
);
188 device_remove_file(&viodev
->dev
, &dev_attr_name
);
189 device_unregister(&viodev
->dev
);
191 EXPORT_SYMBOL(vio_unregister_device
);
193 static dma_addr_t
vio_map_single(struct device
*dev
, void *vaddr
,
194 size_t size
, enum dma_data_direction direction
)
196 return iommu_map_single(to_vio_dev(dev
)->iommu_table
, vaddr
, size
,
200 static void vio_unmap_single(struct device
*dev
, dma_addr_t dma_handle
,
201 size_t size
, enum dma_data_direction direction
)
203 iommu_unmap_single(to_vio_dev(dev
)->iommu_table
, dma_handle
, size
,
207 static int vio_map_sg(struct device
*dev
, struct scatterlist
*sglist
,
208 int nelems
, enum dma_data_direction direction
)
210 return iommu_map_sg(dev
, to_vio_dev(dev
)->iommu_table
, sglist
,
214 static void vio_unmap_sg(struct device
*dev
, struct scatterlist
*sglist
,
215 int nelems
, enum dma_data_direction direction
)
217 iommu_unmap_sg(to_vio_dev(dev
)->iommu_table
, sglist
, nelems
, direction
);
220 static void *vio_alloc_coherent(struct device
*dev
, size_t size
,
221 dma_addr_t
*dma_handle
, gfp_t flag
)
223 return iommu_alloc_coherent(to_vio_dev(dev
)->iommu_table
, size
,
227 static void vio_free_coherent(struct device
*dev
, size_t size
,
228 void *vaddr
, dma_addr_t dma_handle
)
230 iommu_free_coherent(to_vio_dev(dev
)->iommu_table
, size
, vaddr
,
234 static int vio_dma_supported(struct device
*dev
, u64 mask
)
239 struct dma_mapping_ops vio_dma_ops
= {
240 .alloc_coherent
= vio_alloc_coherent
,
241 .free_coherent
= vio_free_coherent
,
242 .map_single
= vio_map_single
,
243 .unmap_single
= vio_unmap_single
,
244 .map_sg
= vio_map_sg
,
245 .unmap_sg
= vio_unmap_sg
,
246 .dma_supported
= vio_dma_supported
,
249 static int vio_bus_match(struct device
*dev
, struct device_driver
*drv
)
251 const struct vio_dev
*vio_dev
= to_vio_dev(dev
);
252 struct vio_driver
*vio_drv
= to_vio_driver(drv
);
253 const struct vio_device_id
*ids
= vio_drv
->id_table
;
255 return (ids
!= NULL
) && (vio_match_device(ids
, vio_dev
) != NULL
);
258 struct bus_type vio_bus_type
= {
260 .match
= vio_bus_match
,