Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
[linux-2.6] / arch / powerpc / kernel / vio.c
1 /*
2  * IBM PowerPC Virtual I/O Infrastructure Support.
3  *
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>
8  *     Stephen Rothwell
9  *
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.
14  */
15
16 #include <linux/types.h>
17 #include <linux/device.h>
18 #include <linux/init.h>
19 #include <linux/console.h>
20 #include <linux/module.h>
21 #include <linux/mm.h>
22 #include <linux/dma-mapping.h>
23 #include <linux/kobject.h>
24
25 #include <asm/iommu.h>
26 #include <asm/dma.h>
27 #include <asm/vio.h>
28 #include <asm/prom.h>
29 #include <asm/firmware.h>
30 #include <asm/tce.h>
31 #include <asm/abs_addr.h>
32 #include <asm/page.h>
33 #include <asm/hvcall.h>
34 #include <asm/iseries/vio.h>
35 #include <asm/iseries/hv_types.h>
36 #include <asm/iseries/hv_lp_config.h>
37 #include <asm/iseries/hv_call_xm.h>
38 #include <asm/iseries/iommu.h>
39
40 static struct bus_type vio_bus_type;
41
42 static struct vio_dev vio_bus_device  = { /* fake "parent" device */
43         .name = vio_bus_device.dev.bus_id,
44         .type = "",
45         .dev.bus_id = "vio",
46         .dev.bus = &vio_bus_type,
47 };
48
49 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
50 {
51         const unsigned char *dma_window;
52         struct iommu_table *tbl;
53         unsigned long offset, size;
54
55         if (firmware_has_feature(FW_FEATURE_ISERIES))
56                 return vio_build_iommu_table_iseries(dev);
57
58         dma_window = of_get_property(dev->dev.archdata.of_node,
59                                   "ibm,my-dma-window", NULL);
60         if (!dma_window)
61                 return NULL;
62
63         tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
64
65         of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
66                             &tbl->it_index, &offset, &size);
67
68         /* TCE table size - measured in tce entries */
69         tbl->it_size = size >> IOMMU_PAGE_SHIFT;
70         /* offset for VIO should always be 0 */
71         tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
72         tbl->it_busno = 0;
73         tbl->it_type = TCE_VB;
74
75         return iommu_init_table(tbl, -1);
76 }
77
78 /**
79  * vio_match_device: - Tell if a VIO device has a matching
80  *                      VIO device id structure.
81  * @ids:        array of VIO device id structures to search in
82  * @dev:        the VIO device structure to match against
83  *
84  * Used by a driver to check whether a VIO device present in the
85  * system is in its list of supported devices. Returns the matching
86  * vio_device_id structure or NULL if there is no match.
87  */
88 static const struct vio_device_id *vio_match_device(
89                 const struct vio_device_id *ids, const struct vio_dev *dev)
90 {
91         while (ids->type[0] != '\0') {
92                 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
93                     of_device_is_compatible(dev->dev.archdata.of_node,
94                                          ids->compat))
95                         return ids;
96                 ids++;
97         }
98         return NULL;
99 }
100
101 /*
102  * Convert from struct device to struct vio_dev and pass to driver.
103  * dev->driver has already been set by generic code because vio_bus_match
104  * succeeded.
105  */
106 static int vio_bus_probe(struct device *dev)
107 {
108         struct vio_dev *viodev = to_vio_dev(dev);
109         struct vio_driver *viodrv = to_vio_driver(dev->driver);
110         const struct vio_device_id *id;
111         int error = -ENODEV;
112
113         if (!viodrv->probe)
114                 return error;
115
116         id = vio_match_device(viodrv->id_table, viodev);
117         if (id)
118                 error = viodrv->probe(viodev, id);
119
120         return error;
121 }
122
123 /* convert from struct device to struct vio_dev and pass to driver. */
124 static int vio_bus_remove(struct device *dev)
125 {
126         struct vio_dev *viodev = to_vio_dev(dev);
127         struct vio_driver *viodrv = to_vio_driver(dev->driver);
128
129         if (viodrv->remove)
130                 return viodrv->remove(viodev);
131
132         /* driver can't remove */
133         return 1;
134 }
135
136 /**
137  * vio_register_driver: - Register a new vio driver
138  * @drv:        The vio_driver structure to be registered.
139  */
140 int vio_register_driver(struct vio_driver *viodrv)
141 {
142         printk(KERN_DEBUG "%s: driver %s registering\n", __func__,
143                 viodrv->driver.name);
144
145         /* fill in 'struct driver' fields */
146         viodrv->driver.bus = &vio_bus_type;
147
148         return driver_register(&viodrv->driver);
149 }
150 EXPORT_SYMBOL(vio_register_driver);
151
152 /**
153  * vio_unregister_driver - Remove registration of vio driver.
154  * @driver:     The vio_driver struct to be removed form registration
155  */
156 void vio_unregister_driver(struct vio_driver *viodrv)
157 {
158         driver_unregister(&viodrv->driver);
159 }
160 EXPORT_SYMBOL(vio_unregister_driver);
161
162 /* vio_dev refcount hit 0 */
163 static void __devinit vio_dev_release(struct device *dev)
164 {
165         /* XXX should free TCE table */
166         of_node_put(dev->archdata.of_node);
167         kfree(to_vio_dev(dev));
168 }
169
170 /**
171  * vio_register_device_node: - Register a new vio device.
172  * @of_node:    The OF node for this device.
173  *
174  * Creates and initializes a vio_dev structure from the data in
175  * of_node and adds it to the list of virtual devices.
176  * Returns a pointer to the created vio_dev or NULL if node has
177  * NULL device_type or compatible fields.
178  */
179 struct vio_dev *vio_register_device_node(struct device_node *of_node)
180 {
181         struct vio_dev *viodev;
182         const unsigned int *unit_address;
183
184         /* we need the 'device_type' property, in order to match with drivers */
185         if (of_node->type == NULL) {
186                 printk(KERN_WARNING "%s: node %s missing 'device_type'\n",
187                                 __func__,
188                                 of_node->name ? of_node->name : "<unknown>");
189                 return NULL;
190         }
191
192         unit_address = of_get_property(of_node, "reg", NULL);
193         if (unit_address == NULL) {
194                 printk(KERN_WARNING "%s: node %s missing 'reg'\n",
195                                 __func__,
196                                 of_node->name ? of_node->name : "<unknown>");
197                 return NULL;
198         }
199
200         /* allocate a vio_dev for this node */
201         viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL);
202         if (viodev == NULL)
203                 return NULL;
204
205         viodev->irq = irq_of_parse_and_map(of_node, 0);
206
207         snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
208         viodev->name = of_node->name;
209         viodev->type = of_node->type;
210         viodev->unit_address = *unit_address;
211         if (firmware_has_feature(FW_FEATURE_ISERIES)) {
212                 unit_address = of_get_property(of_node,
213                                 "linux,unit_address", NULL);
214                 if (unit_address != NULL)
215                         viodev->unit_address = *unit_address;
216         }
217         viodev->dev.archdata.of_node = of_node_get(of_node);
218         viodev->dev.archdata.dma_ops = &dma_iommu_ops;
219         viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev);
220         viodev->dev.archdata.numa_node = of_node_to_nid(of_node);
221
222         /* init generic 'struct device' fields: */
223         viodev->dev.parent = &vio_bus_device.dev;
224         viodev->dev.bus = &vio_bus_type;
225         viodev->dev.release = vio_dev_release;
226
227         /* register with generic device framework */
228         if (device_register(&viodev->dev)) {
229                 printk(KERN_ERR "%s: failed to register device %s\n",
230                                 __func__, viodev->dev.bus_id);
231                 /* XXX free TCE table */
232                 kfree(viodev);
233                 return NULL;
234         }
235
236         return viodev;
237 }
238 EXPORT_SYMBOL(vio_register_device_node);
239
240 /**
241  * vio_bus_init: - Initialize the virtual IO bus
242  */
243 static int __init vio_bus_init(void)
244 {
245         int err;
246         struct device_node *node_vroot;
247
248         err = bus_register(&vio_bus_type);
249         if (err) {
250                 printk(KERN_ERR "failed to register VIO bus\n");
251                 return err;
252         }
253
254         /*
255          * The fake parent of all vio devices, just to give us
256          * a nice directory
257          */
258         err = device_register(&vio_bus_device.dev);
259         if (err) {
260                 printk(KERN_WARNING "%s: device_register returned %i\n",
261                                 __func__, err);
262                 return err;
263         }
264
265         node_vroot = of_find_node_by_name(NULL, "vdevice");
266         if (node_vroot) {
267                 struct device_node *of_node;
268
269                 /*
270                  * Create struct vio_devices for each virtual device in
271                  * the device tree. Drivers will associate with them later.
272                  */
273                 for (of_node = node_vroot->child; of_node != NULL;
274                                 of_node = of_node->sibling)
275                         vio_register_device_node(of_node);
276                 of_node_put(node_vroot);
277         }
278
279         return 0;
280 }
281 __initcall(vio_bus_init);
282
283 static ssize_t name_show(struct device *dev,
284                 struct device_attribute *attr, char *buf)
285 {
286         return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
287 }
288
289 static ssize_t devspec_show(struct device *dev,
290                 struct device_attribute *attr, char *buf)
291 {
292         struct device_node *of_node = dev->archdata.of_node;
293
294         return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
295 }
296
297 static struct device_attribute vio_dev_attrs[] = {
298         __ATTR_RO(name),
299         __ATTR_RO(devspec),
300         __ATTR_NULL
301 };
302
303 void __devinit vio_unregister_device(struct vio_dev *viodev)
304 {
305         device_unregister(&viodev->dev);
306 }
307 EXPORT_SYMBOL(vio_unregister_device);
308
309 static int vio_bus_match(struct device *dev, struct device_driver *drv)
310 {
311         const struct vio_dev *vio_dev = to_vio_dev(dev);
312         struct vio_driver *vio_drv = to_vio_driver(drv);
313         const struct vio_device_id *ids = vio_drv->id_table;
314
315         return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
316 }
317
318 static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env)
319 {
320         const struct vio_dev *vio_dev = to_vio_dev(dev);
321         struct device_node *dn;
322         const char *cp;
323
324         dn = dev->archdata.of_node;
325         if (!dn)
326                 return -ENODEV;
327         cp = of_get_property(dn, "compatible", NULL);
328         if (!cp)
329                 return -ENODEV;
330
331         add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
332         return 0;
333 }
334
335 static struct bus_type vio_bus_type = {
336         .name = "vio",
337         .dev_attrs = vio_dev_attrs,
338         .uevent = vio_hotplug,
339         .match = vio_bus_match,
340         .probe = vio_bus_probe,
341         .remove = vio_bus_remove,
342 };
343
344 /**
345  * vio_get_attribute: - get attribute for virtual device
346  * @vdev:       The vio device to get property.
347  * @which:      The property/attribute to be extracted.
348  * @length:     Pointer to length of returned data size (unused if NULL).
349  *
350  * Calls prom.c's of_get_property() to return the value of the
351  * attribute specified by @which
352 */
353 const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
354 {
355         return of_get_property(vdev->dev.archdata.of_node, which, length);
356 }
357 EXPORT_SYMBOL(vio_get_attribute);
358
359 #ifdef CONFIG_PPC_PSERIES
360 /* vio_find_name() - internal because only vio.c knows how we formatted the
361  * kobject name
362  */
363 static struct vio_dev *vio_find_name(const char *name)
364 {
365         struct device *found;
366
367         found = bus_find_device_by_name(&vio_bus_type, NULL, name);
368         if (!found)
369                 return NULL;
370
371         return to_vio_dev(found);
372 }
373
374 /**
375  * vio_find_node - find an already-registered vio_dev
376  * @vnode: device_node of the virtual device we're looking for
377  */
378 struct vio_dev *vio_find_node(struct device_node *vnode)
379 {
380         const uint32_t *unit_address;
381         char kobj_name[BUS_ID_SIZE];
382
383         /* construct the kobject name from the device node */
384         unit_address = of_get_property(vnode, "reg", NULL);
385         if (!unit_address)
386                 return NULL;
387         snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
388
389         return vio_find_name(kobj_name);
390 }
391 EXPORT_SYMBOL(vio_find_node);
392
393 int vio_enable_interrupts(struct vio_dev *dev)
394 {
395         int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
396         if (rc != H_SUCCESS)
397                 printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
398         return rc;
399 }
400 EXPORT_SYMBOL(vio_enable_interrupts);
401
402 int vio_disable_interrupts(struct vio_dev *dev)
403 {
404         int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
405         if (rc != H_SUCCESS)
406                 printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
407         return rc;
408 }
409 EXPORT_SYMBOL(vio_disable_interrupts);
410 #endif /* CONFIG_PPC_PSERIES */