Commit b877b90f227fb9698d99fb70492d432362584082

Authored by Stephen Rothwell
Committed by Paul Mackerras
1 parent 5c0b4b8759

[PATCH] Create vio_register_device

Take some assignments out of vio_register_device_common and
rename it to vio_register_device.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>

Showing 4 changed files with 19 additions and 17 deletions Inline Diff

arch/ppc64/kernel/iSeries_vio.c
1 /* 1 /*
2 * IBM PowerPC iSeries Virtual I/O Infrastructure Support. 2 * IBM PowerPC iSeries Virtual I/O Infrastructure Support.
3 * 3 *
4 * Copyright (c) 2005 Stephen Rothwell, IBM Corp. 4 * Copyright (c) 2005 Stephen Rothwell, IBM Corp.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 #include <linux/types.h> 11 #include <linux/types.h>
12 #include <linux/device.h> 12 #include <linux/device.h>
13 #include <linux/init.h> 13 #include <linux/init.h>
14 14
15 #include <asm/vio.h> 15 #include <asm/vio.h>
16 #include <asm/iommu.h> 16 #include <asm/iommu.h>
17 #include <asm/abs_addr.h> 17 #include <asm/abs_addr.h>
18 #include <asm/page.h> 18 #include <asm/page.h>
19 #include <asm/iSeries/vio.h> 19 #include <asm/iSeries/vio.h>
20 #include <asm/iSeries/HvTypes.h> 20 #include <asm/iSeries/HvTypes.h>
21 #include <asm/iSeries/HvLpConfig.h> 21 #include <asm/iSeries/HvLpConfig.h>
22 #include <asm/iSeries/HvCallXm.h> 22 #include <asm/iSeries/HvCallXm.h>
23 23
24 struct device *iSeries_vio_dev = &vio_bus_device.dev; 24 struct device *iSeries_vio_dev = &vio_bus_device.dev;
25 EXPORT_SYMBOL(iSeries_vio_dev); 25 EXPORT_SYMBOL(iSeries_vio_dev);
26 26
27 static struct iommu_table veth_iommu_table; 27 static struct iommu_table veth_iommu_table;
28 static struct iommu_table vio_iommu_table; 28 static struct iommu_table vio_iommu_table;
29 29
30 static void __init iommu_vio_init(void) 30 static void __init iommu_vio_init(void)
31 { 31 {
32 struct iommu_table *t; 32 struct iommu_table *t;
33 struct iommu_table_cb cb; 33 struct iommu_table_cb cb;
34 unsigned long cbp; 34 unsigned long cbp;
35 unsigned long itc_entries; 35 unsigned long itc_entries;
36 36
37 cb.itc_busno = 255; /* Bus 255 is the virtual bus */ 37 cb.itc_busno = 255; /* Bus 255 is the virtual bus */
38 cb.itc_virtbus = 0xff; /* Ask for virtual bus */ 38 cb.itc_virtbus = 0xff; /* Ask for virtual bus */
39 39
40 cbp = virt_to_abs(&cb); 40 cbp = virt_to_abs(&cb);
41 HvCallXm_getTceTableParms(cbp); 41 HvCallXm_getTceTableParms(cbp);
42 42
43 itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry); 43 itc_entries = cb.itc_size * PAGE_SIZE / sizeof(union tce_entry);
44 veth_iommu_table.it_size = itc_entries / 2; 44 veth_iommu_table.it_size = itc_entries / 2;
45 veth_iommu_table.it_busno = cb.itc_busno; 45 veth_iommu_table.it_busno = cb.itc_busno;
46 veth_iommu_table.it_offset = cb.itc_offset; 46 veth_iommu_table.it_offset = cb.itc_offset;
47 veth_iommu_table.it_index = cb.itc_index; 47 veth_iommu_table.it_index = cb.itc_index;
48 veth_iommu_table.it_type = TCE_VB; 48 veth_iommu_table.it_type = TCE_VB;
49 veth_iommu_table.it_blocksize = 1; 49 veth_iommu_table.it_blocksize = 1;
50 50
51 t = iommu_init_table(&veth_iommu_table); 51 t = iommu_init_table(&veth_iommu_table);
52 52
53 if (!t) 53 if (!t)
54 printk("Virtual Bus VETH TCE table failed.\n"); 54 printk("Virtual Bus VETH TCE table failed.\n");
55 55
56 vio_iommu_table.it_size = itc_entries - veth_iommu_table.it_size; 56 vio_iommu_table.it_size = itc_entries - veth_iommu_table.it_size;
57 vio_iommu_table.it_busno = cb.itc_busno; 57 vio_iommu_table.it_busno = cb.itc_busno;
58 vio_iommu_table.it_offset = cb.itc_offset + 58 vio_iommu_table.it_offset = cb.itc_offset +
59 veth_iommu_table.it_size; 59 veth_iommu_table.it_size;
60 vio_iommu_table.it_index = cb.itc_index; 60 vio_iommu_table.it_index = cb.itc_index;
61 vio_iommu_table.it_type = TCE_VB; 61 vio_iommu_table.it_type = TCE_VB;
62 vio_iommu_table.it_blocksize = 1; 62 vio_iommu_table.it_blocksize = 1;
63 63
64 t = iommu_init_table(&vio_iommu_table); 64 t = iommu_init_table(&vio_iommu_table);
65 65
66 if (!t) 66 if (!t)
67 printk("Virtual Bus VIO TCE table failed.\n"); 67 printk("Virtual Bus VIO TCE table failed.\n");
68 } 68 }
69 69
70 /** 70 /**
71 * vio_register_device: - Register a new vio device. 71 * vio_register_device_iseries: - Register a new iSeries vio device.
72 * @voidev: The device to register. 72 * @voidev: The device to register.
73 */ 73 */
74 static struct vio_dev *__init vio_register_device_iseries(char *type, 74 static struct vio_dev *__init vio_register_device_iseries(char *type,
75 uint32_t unit_num) 75 uint32_t unit_num)
76 { 76 {
77 struct vio_dev *viodev; 77 struct vio_dev *viodev;
78 78
79 /* allocate a vio_dev for this node */ 79 /* allocate a vio_dev for this device */
80 viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); 80 viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
81 if (!viodev) 81 if (!viodev)
82 return NULL; 82 return NULL;
83 memset(viodev, 0, sizeof(struct vio_dev)); 83 memset(viodev, 0, sizeof(struct vio_dev));
84 84
85 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num); 85 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
86 86
87 return vio_register_device_common(viodev, viodev->dev.bus_id, type, 87 viodev->name = viodev->dev.bus_id;
88 unit_num, &vio_iommu_table); 88 viodev->type = type;
89 viodev->unit_address = unit_num;
90 viodev->iommu_table = &vio_iommu_table;
91 if (vio_register_device(viodev) == NULL) {
92 kfree(viodev);
93 return NULL;
94 }
95 return viodev;
89 } 96 }
90 97
91 void __init probe_bus_iseries(void) 98 void __init probe_bus_iseries(void)
92 { 99 {
93 HvLpIndexMap vlan_map; 100 HvLpIndexMap vlan_map;
94 struct vio_dev *viodev; 101 struct vio_dev *viodev;
95 int i; 102 int i;
96 103
97 /* there is only one of each of these */ 104 /* there is only one of each of these */
98 vio_register_device_iseries("viocons", 0); 105 vio_register_device_iseries("viocons", 0);
99 vio_register_device_iseries("vscsi", 0); 106 vio_register_device_iseries("vscsi", 0);
100 107
101 vlan_map = HvLpConfig_getVirtualLanIndexMap(); 108 vlan_map = HvLpConfig_getVirtualLanIndexMap();
102 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { 109 for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
103 if ((vlan_map & (0x8000 >> i)) == 0) 110 if ((vlan_map & (0x8000 >> i)) == 0)
104 continue; 111 continue;
105 viodev = vio_register_device_iseries("vlan", i); 112 viodev = vio_register_device_iseries("vlan", i);
106 /* veth is special and has it own iommu_table */ 113 /* veth is special and has it own iommu_table */
107 viodev->iommu_table = &veth_iommu_table; 114 viodev->iommu_table = &veth_iommu_table;
108 } 115 }
109 for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) 116 for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
110 vio_register_device_iseries("viodasd", i); 117 vio_register_device_iseries("viodasd", i);
111 for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) 118 for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
112 vio_register_device_iseries("viocd", i); 119 vio_register_device_iseries("viocd", i);
113 for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) 120 for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
114 vio_register_device_iseries("viotape", i); 121 vio_register_device_iseries("viotape", i);
115 } 122 }
116 123
117 /** 124 /**
118 * vio_match_device_iseries: - Tell if a iSeries VIO device matches a 125 * vio_match_device_iseries: - Tell if a iSeries VIO device matches a
119 * vio_device_id 126 * vio_device_id
120 */ 127 */
121 static int vio_match_device_iseries(const struct vio_device_id *id, 128 static int vio_match_device_iseries(const struct vio_device_id *id,
122 const struct vio_dev *dev) 129 const struct vio_dev *dev)
123 { 130 {
124 return strncmp(dev->type, id->type, strlen(id->type)) == 0; 131 return strncmp(dev->type, id->type, strlen(id->type)) == 0;
125 } 132 }
126 133
127 /** 134 /**
128 * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus 135 * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus
129 */ 136 */
130 static int __init vio_bus_init_iseries(void) 137 static int __init vio_bus_init_iseries(void)
131 { 138 {
132 int err; 139 int err;
133 140
134 err = vio_bus_init(vio_match_device_iseries, NULL, NULL); 141 err = vio_bus_init(vio_match_device_iseries, NULL, NULL);
135 if (err == 0) { 142 if (err == 0) {
136 iommu_vio_init(); 143 iommu_vio_init();
137 vio_bus_device.iommu_table = &vio_iommu_table; 144 vio_bus_device.iommu_table = &vio_iommu_table;
138 iSeries_vio_dev = &vio_bus_device.dev; 145 iSeries_vio_dev = &vio_bus_device.dev;
139 probe_bus_iseries(); 146 probe_bus_iseries();
140 } 147 }
141 return err; 148 return err;
142 } 149 }
143 150
144 __initcall(vio_bus_init_iseries); 151 __initcall(vio_bus_init_iseries);
145 152
arch/ppc64/kernel/pSeries_vio.c
1 /* 1 /*
2 * IBM PowerPC pSeries Virtual I/O Infrastructure Support. 2 * IBM PowerPC pSeries Virtual I/O Infrastructure Support.
3 * 3 *
4 * Copyright (c) 2003-2005 IBM Corp. 4 * Copyright (c) 2003-2005 IBM Corp.
5 * Dave Engebretsen engebret@us.ibm.com 5 * Dave Engebretsen engebret@us.ibm.com
6 * Santiago Leon santil@us.ibm.com 6 * Santiago Leon santil@us.ibm.com
7 * Hollis Blanchard <hollisb@us.ibm.com> 7 * Hollis Blanchard <hollisb@us.ibm.com>
8 * Stephen Rothwell 8 * Stephen Rothwell
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version. 13 * 2 of the License, or (at your option) any later version.
14 */ 14 */
15 15
16 #include <linux/init.h> 16 #include <linux/init.h>
17 #include <linux/module.h> 17 #include <linux/module.h>
18 #include <linux/mm.h> 18 #include <linux/mm.h>
19 #include <linux/kobject.h> 19 #include <linux/kobject.h>
20 #include <asm/iommu.h> 20 #include <asm/iommu.h>
21 #include <asm/dma.h> 21 #include <asm/dma.h>
22 #include <asm/prom.h>
22 #include <asm/vio.h> 23 #include <asm/vio.h>
23 #include <asm/hvcall.h> 24 #include <asm/hvcall.h>
24 25
25 extern struct subsystem devices_subsys; /* needed for vio_find_name() */ 26 extern struct subsystem devices_subsys; /* needed for vio_find_name() */
26 27
27 static void probe_bus_pseries(void) 28 static void probe_bus_pseries(void)
28 { 29 {
29 struct device_node *node_vroot, *of_node; 30 struct device_node *node_vroot, *of_node;
30 31
31 node_vroot = find_devices("vdevice"); 32 node_vroot = find_devices("vdevice");
32 if ((node_vroot == NULL) || (node_vroot->child == NULL)) 33 if ((node_vroot == NULL) || (node_vroot->child == NULL))
33 /* this machine doesn't do virtual IO, and that's ok */ 34 /* this machine doesn't do virtual IO, and that's ok */
34 return; 35 return;
35 36
36 /* 37 /*
37 * Create struct vio_devices for each virtual device in the device tree. 38 * Create struct vio_devices for each virtual device in the device tree.
38 * Drivers will associate with them later. 39 * Drivers will associate with them later.
39 */ 40 */
40 for (of_node = node_vroot->child; of_node != NULL; 41 for (of_node = node_vroot->child; of_node != NULL;
41 of_node = of_node->sibling) { 42 of_node = of_node->sibling) {
42 printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node); 43 printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
43 vio_register_device_node(of_node); 44 vio_register_device_node(of_node);
44 } 45 }
45 } 46 }
46 47
47 /** 48 /**
48 * vio_match_device_pseries: - Tell if a pSeries VIO device matches a 49 * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
49 * vio_device_id 50 * vio_device_id
50 */ 51 */
51 static int vio_match_device_pseries(const struct vio_device_id *id, 52 static int vio_match_device_pseries(const struct vio_device_id *id,
52 const struct vio_dev *dev) 53 const struct vio_dev *dev)
53 { 54 {
54 return (strncmp(dev->type, id->type, strlen(id->type)) == 0) && 55 return (strncmp(dev->type, id->type, strlen(id->type)) == 0) &&
55 device_is_compatible(dev->dev.platform_data, id->compat); 56 device_is_compatible(dev->dev.platform_data, id->compat);
56 } 57 }
57 58
58 static void vio_release_device_pseries(struct device *dev) 59 static void vio_release_device_pseries(struct device *dev)
59 { 60 {
60 /* XXX free TCE table */ 61 /* XXX free TCE table */
61 of_node_put(dev->platform_data); 62 of_node_put(dev->platform_data);
62 } 63 }
63 64
64 static ssize_t viodev_show_devspec(struct device *dev, 65 static ssize_t viodev_show_devspec(struct device *dev,
65 struct device_attribute *attr, char *buf) 66 struct device_attribute *attr, char *buf)
66 { 67 {
67 struct device_node *of_node = dev->platform_data; 68 struct device_node *of_node = dev->platform_data;
68 69
69 return sprintf(buf, "%s\n", of_node->full_name); 70 return sprintf(buf, "%s\n", of_node->full_name);
70 } 71 }
71 DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL); 72 DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
72 73
73 static void vio_unregister_device_pseries(struct vio_dev *viodev) 74 static void vio_unregister_device_pseries(struct vio_dev *viodev)
74 { 75 {
75 device_remove_file(&viodev->dev, &dev_attr_devspec); 76 device_remove_file(&viodev->dev, &dev_attr_devspec);
76 } 77 }
77 78
78 /** 79 /**
79 * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus 80 * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
80 */ 81 */
81 static int __init vio_bus_init_pseries(void) 82 static int __init vio_bus_init_pseries(void)
82 { 83 {
83 int err; 84 int err;
84 85
85 err = vio_bus_init(vio_match_device_pseries, 86 err = vio_bus_init(vio_match_device_pseries,
86 vio_unregister_device_pseries, 87 vio_unregister_device_pseries,
87 vio_release_device_pseries); 88 vio_release_device_pseries);
88 if (err == 0) 89 if (err == 0)
89 probe_bus_pseries(); 90 probe_bus_pseries();
90 return err; 91 return err;
91 } 92 }
92 93
93 __initcall(vio_bus_init_pseries); 94 __initcall(vio_bus_init_pseries);
94 95
95 /** 96 /**
96 * vio_build_iommu_table: - gets the dma information from OF and 97 * vio_build_iommu_table: - gets the dma information from OF and
97 * builds the TCE tree. 98 * builds the TCE tree.
98 * @dev: the virtual device. 99 * @dev: the virtual device.
99 * 100 *
100 * Returns a pointer to the built tce tree, or NULL if it can't 101 * Returns a pointer to the built tce tree, or NULL if it can't
101 * find property. 102 * find property.
102 */ 103 */
103 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) 104 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
104 { 105 {
105 unsigned int *dma_window; 106 unsigned int *dma_window;
106 struct iommu_table *newTceTable; 107 struct iommu_table *newTceTable;
107 unsigned long offset; 108 unsigned long offset;
108 int dma_window_property_size; 109 int dma_window_property_size;
109 110
110 dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size); 111 dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
111 if(!dma_window) { 112 if(!dma_window) {
112 return NULL; 113 return NULL;
113 } 114 }
114 115
115 newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL); 116 newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
116 117
117 /* There should be some code to extract the phys-encoded offset 118 /* There should be some code to extract the phys-encoded offset
118 using prom_n_addr_cells(). However, according to a comment 119 using prom_n_addr_cells(). However, according to a comment
119 on earlier versions, it's always zero, so we don't bother */ 120 on earlier versions, it's always zero, so we don't bother */
120 offset = dma_window[1] >> PAGE_SHIFT; 121 offset = dma_window[1] >> PAGE_SHIFT;
121 122
122 /* TCE table size - measured in tce entries */ 123 /* TCE table size - measured in tce entries */
123 newTceTable->it_size = dma_window[4] >> PAGE_SHIFT; 124 newTceTable->it_size = dma_window[4] >> PAGE_SHIFT;
124 /* offset for VIO should always be 0 */ 125 /* offset for VIO should always be 0 */
125 newTceTable->it_offset = offset; 126 newTceTable->it_offset = offset;
126 newTceTable->it_busno = 0; 127 newTceTable->it_busno = 0;
127 newTceTable->it_index = (unsigned long)dma_window[0]; 128 newTceTable->it_index = (unsigned long)dma_window[0];
128 newTceTable->it_type = TCE_VB; 129 newTceTable->it_type = TCE_VB;
129 130
130 return iommu_init_table(newTceTable); 131 return iommu_init_table(newTceTable);
131 } 132 }
132 133
133 /** 134 /**
134 * vio_register_device_node: - Register a new vio device. 135 * vio_register_device_node: - Register a new vio device.
135 * @of_node: The OF node for this device. 136 * @of_node: The OF node for this device.
136 * 137 *
137 * Creates and initializes a vio_dev structure from the data in 138 * Creates and initializes a vio_dev structure from the data in
138 * of_node (dev.platform_data) and adds it to the list of virtual devices. 139 * of_node (dev.platform_data) and adds it to the list of virtual devices.
139 * Returns a pointer to the created vio_dev or NULL if node has 140 * Returns a pointer to the created vio_dev or NULL if node has
140 * NULL device_type or compatible fields. 141 * NULL device_type or compatible fields.
141 */ 142 */
142 struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) 143 struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
143 { 144 {
144 struct vio_dev *viodev; 145 struct vio_dev *viodev;
145 unsigned int *unit_address; 146 unsigned int *unit_address;
146 unsigned int *irq_p; 147 unsigned int *irq_p;
147 148
148 /* we need the 'device_type' property, in order to match with drivers */ 149 /* we need the 'device_type' property, in order to match with drivers */
149 if ((NULL == of_node->type)) { 150 if ((NULL == of_node->type)) {
150 printk(KERN_WARNING 151 printk(KERN_WARNING
151 "%s: node %s missing 'device_type'\n", __FUNCTION__, 152 "%s: node %s missing 'device_type'\n", __FUNCTION__,
152 of_node->name ? of_node->name : "<unknown>"); 153 of_node->name ? of_node->name : "<unknown>");
153 return NULL; 154 return NULL;
154 } 155 }
155 156
156 unit_address = (unsigned int *)get_property(of_node, "reg", NULL); 157 unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
157 if (!unit_address) { 158 if (!unit_address) {
158 printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__, 159 printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
159 of_node->name ? of_node->name : "<unknown>"); 160 of_node->name ? of_node->name : "<unknown>");
160 return NULL; 161 return NULL;
161 } 162 }
162 163
163 /* allocate a vio_dev for this node */ 164 /* allocate a vio_dev for this node */
164 viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); 165 viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
165 if (!viodev) { 166 if (!viodev) {
166 return NULL; 167 return NULL;
167 } 168 }
168 memset(viodev, 0, sizeof(struct vio_dev)); 169 memset(viodev, 0, sizeof(struct vio_dev));
169 170
170 viodev->dev.platform_data = of_node_get(of_node); 171 viodev->dev.platform_data = of_node_get(of_node);
171 172
172 viodev->irq = NO_IRQ; 173 viodev->irq = NO_IRQ;
173 irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL); 174 irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
174 if (irq_p) { 175 if (irq_p) {
175 int virq = virt_irq_create_mapping(*irq_p); 176 int virq = virt_irq_create_mapping(*irq_p);
176 if (virq == NO_IRQ) { 177 if (virq == NO_IRQ) {
177 printk(KERN_ERR "Unable to allocate interrupt " 178 printk(KERN_ERR "Unable to allocate interrupt "
178 "number for %s\n", of_node->full_name); 179 "number for %s\n", of_node->full_name);
179 } else 180 } else
180 viodev->irq = irq_offset_up(virq); 181 viodev->irq = irq_offset_up(virq);
181 } 182 }
182 183
183 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); 184 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
185 viodev->name = of_node->name;
186 viodev->type = of_node->type;
187 viodev->unit_address = *unit_address;
188 viodev->iommu_table = vio_build_iommu_table(viodev);
184 189
185 /* register with generic device framework */ 190 /* register with generic device framework */
186 if (vio_register_device_common(viodev, of_node->name, of_node->type, 191 if (vio_register_device(viodev) == NULL) {
187 *unit_address, vio_build_iommu_table(viodev))
188 == NULL) {
189 /* XXX free TCE table */ 192 /* XXX free TCE table */
190 kfree(viodev); 193 kfree(viodev);
191 return NULL; 194 return NULL;
192 } 195 }
193 device_create_file(&viodev->dev, &dev_attr_devspec); 196 device_create_file(&viodev->dev, &dev_attr_devspec);
194 197
195 return viodev; 198 return viodev;
196 } 199 }
197 EXPORT_SYMBOL(vio_register_device_node); 200 EXPORT_SYMBOL(vio_register_device_node);
198 201
199 /** 202 /**
200 * vio_get_attribute: - get attribute for virtual device 203 * vio_get_attribute: - get attribute for virtual device
201 * @vdev: The vio device to get property. 204 * @vdev: The vio device to get property.
202 * @which: The property/attribute to be extracted. 205 * @which: The property/attribute to be extracted.
203 * @length: Pointer to length of returned data size (unused if NULL). 206 * @length: Pointer to length of returned data size (unused if NULL).
204 * 207 *
205 * Calls prom.c's get_property() to return the value of the 208 * Calls prom.c's get_property() to return the value of the
206 * attribute specified by the preprocessor constant @which 209 * attribute specified by the preprocessor constant @which
207 */ 210 */
208 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length) 211 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
209 { 212 {
210 return get_property(vdev->dev.platform_data, (char*)which, length); 213 return get_property(vdev->dev.platform_data, (char*)which, length);
211 } 214 }
212 EXPORT_SYMBOL(vio_get_attribute); 215 EXPORT_SYMBOL(vio_get_attribute);
213 216
214 /* vio_find_name() - internal because only vio.c knows how we formatted the 217 /* vio_find_name() - internal because only vio.c knows how we formatted the
215 * kobject name 218 * kobject name
216 * XXX once vio_bus_type.devices is actually used as a kset in 219 * XXX once vio_bus_type.devices is actually used as a kset in
217 * drivers/base/bus.c, this function should be removed in favor of 220 * drivers/base/bus.c, this function should be removed in favor of
218 * "device_find(kobj_name, &vio_bus_type)" 221 * "device_find(kobj_name, &vio_bus_type)"
219 */ 222 */
220 static struct vio_dev *vio_find_name(const char *kobj_name) 223 static struct vio_dev *vio_find_name(const char *kobj_name)
221 { 224 {
222 struct kobject *found; 225 struct kobject *found;
223 226
224 found = kset_find_obj(&devices_subsys.kset, kobj_name); 227 found = kset_find_obj(&devices_subsys.kset, kobj_name);
225 if (!found) 228 if (!found)
226 return NULL; 229 return NULL;
227 230
228 return to_vio_dev(container_of(found, struct device, kobj)); 231 return to_vio_dev(container_of(found, struct device, kobj));
229 } 232 }
230 233
231 /** 234 /**
232 * vio_find_node - find an already-registered vio_dev 235 * vio_find_node - find an already-registered vio_dev
233 * @vnode: device_node of the virtual device we're looking for 236 * @vnode: device_node of the virtual device we're looking for
234 */ 237 */
235 struct vio_dev *vio_find_node(struct device_node *vnode) 238 struct vio_dev *vio_find_node(struct device_node *vnode)
236 { 239 {
237 uint32_t *unit_address; 240 uint32_t *unit_address;
238 char kobj_name[BUS_ID_SIZE]; 241 char kobj_name[BUS_ID_SIZE];
239 242
240 /* construct the kobject name from the device node */ 243 /* construct the kobject name from the device node */
241 unit_address = (uint32_t *)get_property(vnode, "reg", NULL); 244 unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
242 if (!unit_address) 245 if (!unit_address)
243 return NULL; 246 return NULL;
244 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); 247 snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
245 248
246 return vio_find_name(kobj_name); 249 return vio_find_name(kobj_name);
247 } 250 }
248 EXPORT_SYMBOL(vio_find_node); 251 EXPORT_SYMBOL(vio_find_node);
249 252
250 int vio_enable_interrupts(struct vio_dev *dev) 253 int vio_enable_interrupts(struct vio_dev *dev)
251 { 254 {
252 int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE); 255 int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
253 if (rc != H_Success) 256 if (rc != H_Success)
254 printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc); 257 printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
255 return rc; 258 return rc;
256 } 259 }
257 EXPORT_SYMBOL(vio_enable_interrupts); 260 EXPORT_SYMBOL(vio_enable_interrupts);
258 261
259 int vio_disable_interrupts(struct vio_dev *dev) 262 int vio_disable_interrupts(struct vio_dev *dev)
260 { 263 {
261 int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE); 264 int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
262 if (rc != H_Success) 265 if (rc != H_Success)
263 printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc); 266 printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
264 return rc; 267 return rc;
265 } 268 }
arch/ppc64/kernel/vio.c
1 /* 1 /*
2 * IBM PowerPC Virtual I/O Infrastructure Support. 2 * IBM PowerPC Virtual I/O Infrastructure Support.
3 * 3 *
4 * Copyright (c) 2003-2005 IBM Corp. 4 * Copyright (c) 2003-2005 IBM Corp.
5 * Dave Engebretsen engebret@us.ibm.com 5 * Dave Engebretsen engebret@us.ibm.com
6 * Santiago Leon santil@us.ibm.com 6 * Santiago Leon santil@us.ibm.com
7 * Hollis Blanchard <hollisb@us.ibm.com> 7 * Hollis Blanchard <hollisb@us.ibm.com>
8 * Stephen Rothwell 8 * Stephen Rothwell
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version. 13 * 2 of the License, or (at your option) any later version.
14 */ 14 */
15 15
16 #include <linux/init.h> 16 #include <linux/init.h>
17 #include <linux/console.h> 17 #include <linux/console.h>
18 #include <linux/module.h> 18 #include <linux/module.h>
19 #include <linux/mm.h> 19 #include <linux/mm.h>
20 #include <linux/dma-mapping.h> 20 #include <linux/dma-mapping.h>
21 #include <asm/iommu.h> 21 #include <asm/iommu.h>
22 #include <asm/dma.h> 22 #include <asm/dma.h>
23 #include <asm/vio.h> 23 #include <asm/vio.h>
24 24
25 static const struct vio_device_id *vio_match_device( 25 static const struct vio_device_id *vio_match_device(
26 const struct vio_device_id *, const struct vio_dev *); 26 const struct vio_device_id *, const struct vio_dev *);
27 27
28 struct vio_dev vio_bus_device = { /* fake "parent" device */ 28 struct vio_dev vio_bus_device = { /* fake "parent" device */
29 .name = vio_bus_device.dev.bus_id, 29 .name = vio_bus_device.dev.bus_id,
30 .type = "", 30 .type = "",
31 .dev.bus_id = "vio", 31 .dev.bus_id = "vio",
32 .dev.bus = &vio_bus_type, 32 .dev.bus = &vio_bus_type,
33 }; 33 };
34 34
35 static int (*is_match)(const struct vio_device_id *id, 35 static int (*is_match)(const struct vio_device_id *id,
36 const struct vio_dev *dev); 36 const struct vio_dev *dev);
37 static void (*unregister_device_callback)(struct vio_dev *dev); 37 static void (*unregister_device_callback)(struct vio_dev *dev);
38 static void (*release_device_callback)(struct device *dev); 38 static void (*release_device_callback)(struct device *dev);
39 39
40 /* 40 /*
41 * Convert from struct device to struct vio_dev and pass to driver. 41 * Convert from struct device to struct vio_dev and pass to driver.
42 * dev->driver has already been set by generic code because vio_bus_match 42 * dev->driver has already been set by generic code because vio_bus_match
43 * succeeded. 43 * succeeded.
44 */ 44 */
45 static int vio_bus_probe(struct device *dev) 45 static int vio_bus_probe(struct device *dev)
46 { 46 {
47 struct vio_dev *viodev = to_vio_dev(dev); 47 struct vio_dev *viodev = to_vio_dev(dev);
48 struct vio_driver *viodrv = to_vio_driver(dev->driver); 48 struct vio_driver *viodrv = to_vio_driver(dev->driver);
49 const struct vio_device_id *id; 49 const struct vio_device_id *id;
50 int error = -ENODEV; 50 int error = -ENODEV;
51 51
52 if (!viodrv->probe) 52 if (!viodrv->probe)
53 return error; 53 return error;
54 54
55 id = vio_match_device(viodrv->id_table, viodev); 55 id = vio_match_device(viodrv->id_table, viodev);
56 if (id) 56 if (id)
57 error = viodrv->probe(viodev, id); 57 error = viodrv->probe(viodev, id);
58 58
59 return error; 59 return error;
60 } 60 }
61 61
62 /* convert from struct device to struct vio_dev and pass to driver. */ 62 /* convert from struct device to struct vio_dev and pass to driver. */
63 static int vio_bus_remove(struct device *dev) 63 static int vio_bus_remove(struct device *dev)
64 { 64 {
65 struct vio_dev *viodev = to_vio_dev(dev); 65 struct vio_dev *viodev = to_vio_dev(dev);
66 struct vio_driver *viodrv = to_vio_driver(dev->driver); 66 struct vio_driver *viodrv = to_vio_driver(dev->driver);
67 67
68 if (viodrv->remove) 68 if (viodrv->remove)
69 return viodrv->remove(viodev); 69 return viodrv->remove(viodev);
70 70
71 /* driver can't remove */ 71 /* driver can't remove */
72 return 1; 72 return 1;
73 } 73 }
74 74
75 /** 75 /**
76 * vio_register_driver: - Register a new vio driver 76 * vio_register_driver: - Register a new vio driver
77 * @drv: The vio_driver structure to be registered. 77 * @drv: The vio_driver structure to be registered.
78 */ 78 */
79 int vio_register_driver(struct vio_driver *viodrv) 79 int vio_register_driver(struct vio_driver *viodrv)
80 { 80 {
81 printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__, 81 printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__,
82 viodrv->name); 82 viodrv->name);
83 83
84 /* fill in 'struct driver' fields */ 84 /* fill in 'struct driver' fields */
85 viodrv->driver.name = viodrv->name; 85 viodrv->driver.name = viodrv->name;
86 viodrv->driver.bus = &vio_bus_type; 86 viodrv->driver.bus = &vio_bus_type;
87 viodrv->driver.probe = vio_bus_probe; 87 viodrv->driver.probe = vio_bus_probe;
88 viodrv->driver.remove = vio_bus_remove; 88 viodrv->driver.remove = vio_bus_remove;
89 89
90 return driver_register(&viodrv->driver); 90 return driver_register(&viodrv->driver);
91 } 91 }
92 EXPORT_SYMBOL(vio_register_driver); 92 EXPORT_SYMBOL(vio_register_driver);
93 93
94 /** 94 /**
95 * vio_unregister_driver - Remove registration of vio driver. 95 * vio_unregister_driver - Remove registration of vio driver.
96 * @driver: The vio_driver struct to be removed form registration 96 * @driver: The vio_driver struct to be removed form registration
97 */ 97 */
98 void vio_unregister_driver(struct vio_driver *viodrv) 98 void vio_unregister_driver(struct vio_driver *viodrv)
99 { 99 {
100 driver_unregister(&viodrv->driver); 100 driver_unregister(&viodrv->driver);
101 } 101 }
102 EXPORT_SYMBOL(vio_unregister_driver); 102 EXPORT_SYMBOL(vio_unregister_driver);
103 103
104 /** 104 /**
105 * vio_match_device: - Tell if a VIO device has a matching 105 * vio_match_device: - Tell if a VIO device has a matching
106 * VIO device id structure. 106 * VIO device id structure.
107 * @ids: array of VIO device id structures to search in 107 * @ids: array of VIO device id structures to search in
108 * @dev: the VIO device structure to match against 108 * @dev: the VIO device structure to match against
109 * 109 *
110 * Used by a driver to check whether a VIO device present in the 110 * Used by a driver to check whether a VIO device present in the
111 * system is in its list of supported devices. Returns the matching 111 * system is in its list of supported devices. Returns the matching
112 * vio_device_id structure or NULL if there is no match. 112 * vio_device_id structure or NULL if there is no match.
113 */ 113 */
114 static const struct vio_device_id *vio_match_device( 114 static const struct vio_device_id *vio_match_device(
115 const struct vio_device_id *ids, const struct vio_dev *dev) 115 const struct vio_device_id *ids, const struct vio_dev *dev)
116 { 116 {
117 while (ids->type) { 117 while (ids->type) {
118 if (is_match(ids, dev)) 118 if (is_match(ids, dev))
119 return ids; 119 return ids;
120 ids++; 120 ids++;
121 } 121 }
122 return NULL; 122 return NULL;
123 } 123 }
124 124
125 /** 125 /**
126 * vio_bus_init: - Initialize the virtual IO bus 126 * vio_bus_init: - Initialize the virtual IO bus
127 */ 127 */
128 int __init vio_bus_init(int (*match_func)(const struct vio_device_id *id, 128 int __init vio_bus_init(int (*match_func)(const struct vio_device_id *id,
129 const struct vio_dev *dev), 129 const struct vio_dev *dev),
130 void (*unregister_dev)(struct vio_dev *), 130 void (*unregister_dev)(struct vio_dev *),
131 void (*release_dev)(struct device *)) 131 void (*release_dev)(struct device *))
132 { 132 {
133 int err; 133 int err;
134 134
135 is_match = match_func; 135 is_match = match_func;
136 unregister_device_callback = unregister_dev; 136 unregister_device_callback = unregister_dev;
137 release_device_callback = release_dev; 137 release_device_callback = release_dev;
138 138
139 err = bus_register(&vio_bus_type); 139 err = bus_register(&vio_bus_type);
140 if (err) { 140 if (err) {
141 printk(KERN_ERR "failed to register VIO bus\n"); 141 printk(KERN_ERR "failed to register VIO bus\n");
142 return err; 142 return err;
143 } 143 }
144 144
145 /* 145 /*
146 * The fake parent of all vio devices, just to give us 146 * The fake parent of all vio devices, just to give us
147 * a nice directory 147 * a nice directory
148 */ 148 */
149 err = device_register(&vio_bus_device.dev); 149 err = device_register(&vio_bus_device.dev);
150 if (err) { 150 if (err) {
151 printk(KERN_WARNING "%s: device_register returned %i\n", 151 printk(KERN_WARNING "%s: device_register returned %i\n",
152 __FUNCTION__, err); 152 __FUNCTION__, err);
153 return err; 153 return err;
154 } 154 }
155 155
156 return 0; 156 return 0;
157 } 157 }
158 158
159 /* vio_dev refcount hit 0 */ 159 /* vio_dev refcount hit 0 */
160 static void __devinit vio_dev_release(struct device *dev) 160 static void __devinit vio_dev_release(struct device *dev)
161 { 161 {
162 if (release_device_callback) 162 if (release_device_callback)
163 release_device_callback(dev); 163 release_device_callback(dev);
164 kfree(to_vio_dev(dev)); 164 kfree(to_vio_dev(dev));
165 } 165 }
166 166
167 static ssize_t viodev_show_name(struct device *dev, 167 static ssize_t viodev_show_name(struct device *dev,
168 struct device_attribute *attr, char *buf) 168 struct device_attribute *attr, char *buf)
169 { 169 {
170 return sprintf(buf, "%s\n", to_vio_dev(dev)->name); 170 return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
171 } 171 }
172 DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL); 172 DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
173 173
174 struct vio_dev * __devinit vio_register_device_common( 174 struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
175 struct vio_dev *viodev, char *name, char *type,
176 uint32_t unit_address, struct iommu_table *iommu_table)
177 { 175 {
178 viodev->name = name;
179 viodev->type = type;
180 viodev->unit_address = unit_address;
181 viodev->iommu_table = iommu_table;
182 /* init generic 'struct device' fields: */ 176 /* init generic 'struct device' fields: */
183 viodev->dev.parent = &vio_bus_device.dev; 177 viodev->dev.parent = &vio_bus_device.dev;
184 viodev->dev.bus = &vio_bus_type; 178 viodev->dev.bus = &vio_bus_type;
185 viodev->dev.release = vio_dev_release; 179 viodev->dev.release = vio_dev_release;
186 180
187 /* register with generic device framework */ 181 /* register with generic device framework */
188 if (device_register(&viodev->dev)) { 182 if (device_register(&viodev->dev)) {
189 printk(KERN_ERR "%s: failed to register device %s\n", 183 printk(KERN_ERR "%s: failed to register device %s\n",
190 __FUNCTION__, viodev->dev.bus_id); 184 __FUNCTION__, viodev->dev.bus_id);
191 return NULL; 185 return NULL;
192 } 186 }
193 device_create_file(&viodev->dev, &dev_attr_name); 187 device_create_file(&viodev->dev, &dev_attr_name);
194 188
195 return viodev; 189 return viodev;
196 } 190 }
197 191
198 void __devinit vio_unregister_device(struct vio_dev *viodev) 192 void __devinit vio_unregister_device(struct vio_dev *viodev)
199 { 193 {
200 if (unregister_device_callback) 194 if (unregister_device_callback)
201 unregister_device_callback(viodev); 195 unregister_device_callback(viodev);
202 device_remove_file(&viodev->dev, &dev_attr_name); 196 device_remove_file(&viodev->dev, &dev_attr_name);
203 device_unregister(&viodev->dev); 197 device_unregister(&viodev->dev);
204 } 198 }
205 EXPORT_SYMBOL(vio_unregister_device); 199 EXPORT_SYMBOL(vio_unregister_device);
206 200
207 static dma_addr_t vio_map_single(struct device *dev, void *vaddr, 201 static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
208 size_t size, enum dma_data_direction direction) 202 size_t size, enum dma_data_direction direction)
209 { 203 {
210 return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size, 204 return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
211 direction); 205 direction);
212 } 206 }
213 207
214 static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle, 208 static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
215 size_t size, enum dma_data_direction direction) 209 size_t size, enum dma_data_direction direction)
216 { 210 {
217 iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size, 211 iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
218 direction); 212 direction);
219 } 213 }
220 214
221 static int vio_map_sg(struct device *dev, struct scatterlist *sglist, 215 static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
222 int nelems, enum dma_data_direction direction) 216 int nelems, enum dma_data_direction direction)
223 { 217 {
224 return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist, 218 return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
225 nelems, direction); 219 nelems, direction);
226 } 220 }
227 221
228 static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist, 222 static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
229 int nelems, enum dma_data_direction direction) 223 int nelems, enum dma_data_direction direction)
230 { 224 {
231 iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction); 225 iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
232 } 226 }
233 227
234 static void *vio_alloc_coherent(struct device *dev, size_t size, 228 static void *vio_alloc_coherent(struct device *dev, size_t size,
235 dma_addr_t *dma_handle, unsigned int __nocast flag) 229 dma_addr_t *dma_handle, unsigned int __nocast flag)
236 { 230 {
237 return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size, 231 return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
238 dma_handle, flag); 232 dma_handle, flag);
239 } 233 }
240 234
241 static void vio_free_coherent(struct device *dev, size_t size, 235 static void vio_free_coherent(struct device *dev, size_t size,
242 void *vaddr, dma_addr_t dma_handle) 236 void *vaddr, dma_addr_t dma_handle)
243 { 237 {
244 iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr, 238 iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
245 dma_handle); 239 dma_handle);
246 } 240 }
247 241
248 static int vio_dma_supported(struct device *dev, u64 mask) 242 static int vio_dma_supported(struct device *dev, u64 mask)
249 { 243 {
250 return 1; 244 return 1;
251 } 245 }
252 246
253 struct dma_mapping_ops vio_dma_ops = { 247 struct dma_mapping_ops vio_dma_ops = {
254 .alloc_coherent = vio_alloc_coherent, 248 .alloc_coherent = vio_alloc_coherent,
255 .free_coherent = vio_free_coherent, 249 .free_coherent = vio_free_coherent,
256 .map_single = vio_map_single, 250 .map_single = vio_map_single,
257 .unmap_single = vio_unmap_single, 251 .unmap_single = vio_unmap_single,
258 .map_sg = vio_map_sg, 252 .map_sg = vio_map_sg,
259 .unmap_sg = vio_unmap_sg, 253 .unmap_sg = vio_unmap_sg,
260 .dma_supported = vio_dma_supported, 254 .dma_supported = vio_dma_supported,
261 }; 255 };
262 256
263 static int vio_bus_match(struct device *dev, struct device_driver *drv) 257 static int vio_bus_match(struct device *dev, struct device_driver *drv)
264 { 258 {
265 const struct vio_dev *vio_dev = to_vio_dev(dev); 259 const struct vio_dev *vio_dev = to_vio_dev(dev);
266 struct vio_driver *vio_drv = to_vio_driver(drv); 260 struct vio_driver *vio_drv = to_vio_driver(drv);
267 const struct vio_device_id *ids = vio_drv->id_table; 261 const struct vio_device_id *ids = vio_drv->id_table;
268 262
269 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); 263 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
270 } 264 }
271 265
272 struct bus_type vio_bus_type = { 266 struct bus_type vio_bus_type = {
273 .name = "vio", 267 .name = "vio",
274 .match = vio_bus_match, 268 .match = vio_bus_match,
275 }; 269 };
276 270
include/asm-ppc64/vio.h
1 /* 1 /*
2 * IBM PowerPC Virtual I/O Infrastructure Support. 2 * IBM PowerPC Virtual I/O Infrastructure Support.
3 * 3 *
4 * Copyright (c) 2003 IBM Corp. 4 * Copyright (c) 2003 IBM Corp.
5 * Dave Engebretsen engebret@us.ibm.com 5 * Dave Engebretsen engebret@us.ibm.com
6 * Santiago Leon santil@us.ibm.com 6 * Santiago Leon santil@us.ibm.com
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version. 11 * 2 of the License, or (at your option) any later version.
12 */ 12 */
13 13
14 #ifndef _ASM_VIO_H 14 #ifndef _ASM_VIO_H
15 #define _ASM_VIO_H 15 #define _ASM_VIO_H
16 16
17 #include <linux/config.h> 17 #include <linux/config.h>
18 #include <linux/init.h> 18 #include <linux/init.h>
19 #include <linux/errno.h> 19 #include <linux/errno.h>
20 #include <linux/device.h> 20 #include <linux/device.h>
21 #include <linux/dma-mapping.h> 21 #include <linux/dma-mapping.h>
22 #include <asm/hvcall.h> 22 #include <asm/hvcall.h>
23 #include <asm/prom.h> 23 #include <asm/prom.h>
24 #include <asm/scatterlist.h> 24 #include <asm/scatterlist.h>
25 /* 25 /*
26 * Architecture-specific constants for drivers to 26 * Architecture-specific constants for drivers to
27 * extract attributes of the device using vio_get_attribute() 27 * extract attributes of the device using vio_get_attribute()
28 */ 28 */
29 #define VETH_MAC_ADDR "local-mac-address" 29 #define VETH_MAC_ADDR "local-mac-address"
30 #define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters" 30 #define VETH_MCAST_FILTER_SIZE "ibm,mac-address-filters"
31 31
32 /* End architecture-specific constants */ 32 /* End architecture-specific constants */
33 33
34 #define h_vio_signal(ua, mode) \ 34 #define h_vio_signal(ua, mode) \
35 plpar_hcall_norets(H_VIO_SIGNAL, ua, mode) 35 plpar_hcall_norets(H_VIO_SIGNAL, ua, mode)
36 36
37 #define VIO_IRQ_DISABLE 0UL 37 #define VIO_IRQ_DISABLE 0UL
38 #define VIO_IRQ_ENABLE 1UL 38 #define VIO_IRQ_ENABLE 1UL
39 39
40 struct vio_dev; 40 struct vio_dev;
41 struct vio_driver; 41 struct vio_driver;
42 struct vio_device_id; 42 struct vio_device_id;
43 struct iommu_table; 43 struct iommu_table;
44 44
45 int vio_register_driver(struct vio_driver *drv); 45 int vio_register_driver(struct vio_driver *drv);
46 void vio_unregister_driver(struct vio_driver *drv); 46 void vio_unregister_driver(struct vio_driver *drv);
47 47
48 #ifdef CONFIG_PPC_PSERIES 48 #ifdef CONFIG_PPC_PSERIES
49 struct vio_dev * __devinit vio_register_device_node( 49 struct vio_dev * __devinit vio_register_device_node(
50 struct device_node *node_vdev); 50 struct device_node *node_vdev);
51 #endif 51 #endif
52 void __devinit vio_unregister_device(struct vio_dev *dev); 52 void __devinit vio_unregister_device(struct vio_dev *dev);
53 struct vio_dev *vio_find_node(struct device_node *vnode); 53 struct vio_dev *vio_find_node(struct device_node *vnode);
54 54
55 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length); 55 const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length);
56 int vio_get_irq(struct vio_dev *dev); 56 int vio_get_irq(struct vio_dev *dev);
57 int vio_enable_interrupts(struct vio_dev *dev); 57 int vio_enable_interrupts(struct vio_dev *dev);
58 int vio_disable_interrupts(struct vio_dev *dev); 58 int vio_disable_interrupts(struct vio_dev *dev);
59 extern struct vio_dev * __devinit vio_register_device_common( 59 extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev);
60 struct vio_dev *viodev, char *name, char *type,
61 uint32_t unit_address, struct iommu_table *iommu_table);
62 60
63 extern struct dma_mapping_ops vio_dma_ops; 61 extern struct dma_mapping_ops vio_dma_ops;
64 62
65 extern struct bus_type vio_bus_type; 63 extern struct bus_type vio_bus_type;
66 64
67 struct vio_device_id { 65 struct vio_device_id {
68 char *type; 66 char *type;
69 char *compat; 67 char *compat;
70 }; 68 };
71 69
72 struct vio_driver { 70 struct vio_driver {
73 struct list_head node; 71 struct list_head node;
74 char *name; 72 char *name;
75 const struct vio_device_id *id_table; /* NULL if wants all devices */ 73 const struct vio_device_id *id_table; /* NULL if wants all devices */
76 int (*probe) (struct vio_dev *dev, const struct vio_device_id *id); /* New device inserted */ 74 int (*probe) (struct vio_dev *dev, const struct vio_device_id *id); /* New device inserted */
77 int (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ 75 int (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
78 unsigned long driver_data; 76 unsigned long driver_data;
79 77
80 struct device_driver driver; 78 struct device_driver driver;
81 }; 79 };
82 80
83 static inline struct vio_driver *to_vio_driver(struct device_driver *drv) 81 static inline struct vio_driver *to_vio_driver(struct device_driver *drv)
84 { 82 {
85 return container_of(drv, struct vio_driver, driver); 83 return container_of(drv, struct vio_driver, driver);
86 } 84 }
87 85
88 /* 86 /*
89 * The vio_dev structure is used to describe virtual I/O devices. 87 * The vio_dev structure is used to describe virtual I/O devices.
90 */ 88 */
91 struct vio_dev { 89 struct vio_dev {
92 struct iommu_table *iommu_table; /* vio_map_* uses this */ 90 struct iommu_table *iommu_table; /* vio_map_* uses this */
93 char *name; 91 char *name;
94 char *type; 92 char *type;
95 uint32_t unit_address; 93 uint32_t unit_address;
96 unsigned int irq; 94 unsigned int irq;
97 95
98 struct device dev; 96 struct device dev;
99 }; 97 };
100 98
101 extern struct vio_dev vio_bus_device; 99 extern struct vio_dev vio_bus_device;
102 100
103 static inline struct vio_dev *to_vio_dev(struct device *dev) 101 static inline struct vio_dev *to_vio_dev(struct device *dev)
104 { 102 {
105 return container_of(dev, struct vio_dev, dev); 103 return container_of(dev, struct vio_dev, dev);
106 } 104 }
107 105
108 extern int vio_bus_init(int (*is_match)(const struct vio_device_id *id, 106 extern int vio_bus_init(int (*is_match)(const struct vio_device_id *id,
109 const struct vio_dev *dev), 107 const struct vio_dev *dev),
110 void (*)(struct vio_dev *), 108 void (*)(struct vio_dev *),
111 void (*)(struct device *)); 109 void (*)(struct device *));
112 110
113 #endif /* _ASM_VIO_H */ 111 #endif /* _ASM_VIO_H */
114 112