diff options
80 files changed, 1418 insertions, 607 deletions
diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt index 5eee3e0bfc4c..9f0bc3bfd776 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.txt | |||
@@ -1,99 +1,131 @@ | |||
1 | Platform Devices and Drivers | 1 | Platform Devices and Drivers |
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
3 | See <linux/platform_device.h> for the driver model interface to the | ||
4 | platform bus: platform_device, and platform_driver. This pseudo-bus | ||
5 | is used to connect devices on busses with minimal infrastructure, | ||
6 | like those used to integrate peripherals on many system-on-chip | ||
7 | processors, or some "legacy" PC interconnects; as opposed to large | ||
8 | formally specified ones like PCI or USB. | ||
9 | |||
3 | 10 | ||
4 | Platform devices | 11 | Platform devices |
5 | ~~~~~~~~~~~~~~~~ | 12 | ~~~~~~~~~~~~~~~~ |
6 | Platform devices are devices that typically appear as autonomous | 13 | Platform devices are devices that typically appear as autonomous |
7 | entities in the system. This includes legacy port-based devices and | 14 | entities in the system. This includes legacy port-based devices and |
8 | host bridges to peripheral buses. | 15 | host bridges to peripheral buses, and most controllers integrated |
9 | 16 | into system-on-chip platforms. What they usually have in common | |
10 | 17 | is direct addressing from a CPU bus. Rarely, a platform_device will | |
11 | Platform drivers | 18 | be connected through a segment of some other kind of bus; but its |
12 | ~~~~~~~~~~~~~~~~ | 19 | registers will still be directly addressible. |
13 | Drivers for platform devices are typically very simple and | ||
14 | unstructured. Either the device was present at a particular I/O port | ||
15 | and the driver was loaded, or it was not. There was no possibility | ||
16 | of hotplugging or alternative discovery besides probing at a specific | ||
17 | I/O address and expecting a specific response. | ||
18 | 20 | ||
21 | Platform devices are given a name, used in driver binding, and a | ||
22 | list of resources such as addresses and IRQs. | ||
19 | 23 | ||
20 | Other Architectures, Modern Firmware, and new Platforms | 24 | struct platform_device { |
21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 25 | const char *name; |
22 | These devices are not always at the legacy I/O ports. This is true on | 26 | u32 id; |
23 | other architectures and on some modern architectures. In most cases, | 27 | struct device dev; |
24 | the drivers are modified to discover the devices at other well-known | 28 | u32 num_resources; |
25 | ports for the given platform. However, the firmware in these systems | 29 | struct resource *resource; |
26 | does usually know where exactly these devices reside, and in some | 30 | }; |
27 | cases, it's the only way of discovering them. | ||
28 | 31 | ||
29 | 32 | ||
30 | The Platform Bus | 33 | Platform drivers |
31 | ~~~~~~~~~~~~~~~~ | ||
32 | A platform bus has been created to deal with these issues. First and | ||
33 | foremost, it groups all the legacy devices under a common bus, and | ||
34 | gives them a common parent if they don't already have one. | ||
35 | |||
36 | But, besides the organizational benefits, the platform bus can also | ||
37 | accommodate firmware-based enumeration. | ||
38 | |||
39 | |||
40 | Device Discovery | ||
41 | ~~~~~~~~~~~~~~~~ | 34 | ~~~~~~~~~~~~~~~~ |
42 | The platform bus has no concept of probing for devices. Devices | 35 | Platform drivers follow the standard driver model convention, where |
43 | discovery is left up to either the legacy drivers or the | 36 | discovery/enumeration is handled outside the drivers, and drivers |
44 | firmware. These entities are expected to notify the platform of | 37 | provide probe() and remove() methods. They support power management |
45 | devices that it discovers via the bus's add() callback: | 38 | and shutdown notifications using the standard conventions. |
46 | 39 | ||
47 | platform_bus.add(parent,bus_id). | 40 | struct platform_driver { |
48 | 41 | int (*probe)(struct platform_device *); | |
49 | 42 | int (*remove)(struct platform_device *); | |
50 | Bus IDs | 43 | void (*shutdown)(struct platform_device *); |
51 | ~~~~~~~ | 44 | int (*suspend)(struct platform_device *, pm_message_t state); |
52 | Bus IDs are the canonical names for the devices. There is no globally | 45 | int (*suspend_late)(struct platform_device *, pm_message_t state); |
53 | standard addressing mechanism for legacy devices. In the IA-32 world, | 46 | int (*resume_early)(struct platform_device *); |
54 | we have Pnp IDs to use, as well as the legacy I/O ports. However, | 47 | int (*resume)(struct platform_device *); |
55 | neither tell what the device really is or have any meaning on other | 48 | struct device_driver driver; |
56 | platforms. | 49 | }; |
57 | 50 | ||
58 | Since both PnP IDs and the legacy I/O ports (and other standard I/O | 51 | Note that probe() should general verify that the specified device hardware |
59 | ports for specific devices) have a 1:1 mapping, we map the | 52 | actually exists; sometimes platform setup code can't be sure. The probing |
60 | platform-specific name or identifier to a generic name (at least | 53 | can use device resources, including clocks, and device platform_data. |
61 | within the scope of the kernel). | 54 | |
62 | 55 | Platform drivers register themselves the normal way: | |
63 | For example, a serial driver might find a device at I/O 0x3f8. The | 56 | |
64 | ACPI firmware might also discover a device with PnP ID (_HID) | 57 | int platform_driver_register(struct platform_driver *drv); |
65 | PNP0501. Both correspond to the same device and should be mapped to the | 58 | |
66 | canonical name 'serial'. | 59 | Or, in common situations where the device is known not to be hot-pluggable, |
67 | 60 | the probe() routine can live in an init section to reduce the driver's | |
68 | The bus_id field should be a concatenation of the canonical name and | 61 | runtime memory footprint: |
69 | the instance of that type of device. For example, the device at I/O | 62 | |
70 | port 0x3f8 should have a bus_id of "serial0". This places the | 63 | int platform_driver_probe(struct platform_driver *drv, |
71 | responsibility of enumerating devices of a particular type up to the | 64 | int (*probe)(struct platform_device *)) |
72 | discovery mechanism. But, they are the entity that should know best | 65 | |
73 | (as opposed to the platform bus driver). | 66 | |
74 | 67 | Device Enumeration | |
75 | 68 | ~~~~~~~~~~~~~~~~~~ | |
76 | Drivers | 69 | As a rule, platform specific (and often board-specific) setup code wil |
77 | ~~~~~~~ | 70 | register platform devices: |
78 | Drivers for platform devices should have a name that is the same as | 71 | |
79 | the canonical name of the devices they support. This allows the | 72 | int platform_device_register(struct platform_device *pdev); |
80 | platform bus driver to do simple matching with the basic data | 73 | |
81 | structures to determine if a driver supports a certain device. | 74 | int platform_add_devices(struct platform_device **pdevs, int ndev); |
82 | 75 | ||
83 | For example, a legacy serial driver should have a name of 'serial' and | 76 | The general rule is to register only those devices that actually exist, |
84 | register itself with the platform bus. | 77 | but in some cases extra devices might be registered. For example, a kernel |
85 | 78 | might be configured to work with an external network adapter that might not | |
86 | 79 | be populated on all boards, or likewise to work with an integrated controller | |
87 | Driver Binding | 80 | that some boards might not hook up to any peripherals. |
88 | ~~~~~~~~~~~~~~ | 81 | |
89 | Legacy drivers assume they are bound to the device once they start up | 82 | In some cases, boot firmware will export tables describing the devices |
90 | and probe an I/O port. Divorcing them from this will be a difficult | 83 | that are populated on a given board. Without such tables, often the |
91 | process. However, that shouldn't prevent us from implementing | 84 | only way for system setup code to set up the correct devices is to build |
92 | firmware-based enumeration. | 85 | a kernel for a specific target board. Such board-specific kernels are |
93 | 86 | common with embedded and custom systems development. | |
94 | The firmware should notify the platform bus about devices before the | 87 | |
95 | legacy drivers have had a chance to load. Once the drivers are loaded, | 88 | In many cases, the memory and IRQ resources associated with the platform |
96 | they driver model core will attempt to bind the driver to any | 89 | device are not enough to let the device's driver work. Board setup code |
97 | previously-discovered devices. Once that has happened, it will be free | 90 | will often provide additional information using the device's platform_data |
98 | to discover any other devices it pleases. | 91 | field to hold additional information. |
92 | |||
93 | Embedded systems frequently need one or more clocks for platform devices, | ||
94 | which are normally kept off until they're actively needed (to save power). | ||
95 | System setup also associates those clocks with the device, so that that | ||
96 | calls to clk_get(&pdev->dev, clock_name) return them as needed. | ||
97 | |||
98 | |||
99 | Device Naming and Driver Binding | ||
100 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
101 | The platform_device.dev.bus_id is the canonical name for the devices. | ||
102 | It's built from two components: | ||
103 | |||
104 | * platform_device.name ... which is also used to for driver matching. | ||
105 | |||
106 | * platform_device.id ... the device instance number, or else "-1" | ||
107 | to indicate there's only one. | ||
108 | |||
109 | These are catenated, so name/id "serial"/0 indicates bus_id "serial.0", and | ||
110 | "serial/3" indicates bus_id "serial.3"; both would use the platform_driver | ||
111 | named "serial". While "my_rtc"/-1 would be bus_id "my_rtc" (no instance id) | ||
112 | and use the platform_driver called "my_rtc". | ||
113 | |||
114 | Driver binding is performed automatically by the driver core, invoking | ||
115 | driver probe() after finding a match between device and driver. If the | ||
116 | probe() succeeds, the driver and device are bound as usual. There are | ||
117 | three different ways to find such a match: | ||
118 | |||
119 | - Whenever a device is registered, the drivers for that bus are | ||
120 | checked for matches. Platform devices should be registered very | ||
121 | early during system boot. | ||
122 | |||
123 | - When a driver is registered using platform_driver_register(), all | ||
124 | unbound devices on that bus are checked for matches. Drivers | ||
125 | usually register later during booting, or by module loading. | ||
126 | |||
127 | - Registering a driver using platform_driver_probe() works just like | ||
128 | using platform_driver_register(), except that the the driver won't | ||
129 | be probed later if another device registers. (Which is OK, since | ||
130 | this interface is only for use with non-hotpluggable devices.) | ||
99 | 131 | ||
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index fde8bea85cee..ab0c327e79dc 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c | |||
@@ -156,14 +156,14 @@ static struct file_operations cpuid_fops = { | |||
156 | .open = cpuid_open, | 156 | .open = cpuid_open, |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static int cpuid_class_device_create(int i) | 159 | static int cpuid_device_create(int i) |
160 | { | 160 | { |
161 | int err = 0; | 161 | int err = 0; |
162 | struct class_device *class_err; | 162 | struct device *dev; |
163 | 163 | ||
164 | class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); | 164 | dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i); |
165 | if (IS_ERR(class_err)) | 165 | if (IS_ERR(dev)) |
166 | err = PTR_ERR(class_err); | 166 | err = PTR_ERR(dev); |
167 | return err; | 167 | return err; |
168 | } | 168 | } |
169 | 169 | ||
@@ -174,10 +174,10 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac | |||
174 | 174 | ||
175 | switch (action) { | 175 | switch (action) { |
176 | case CPU_ONLINE: | 176 | case CPU_ONLINE: |
177 | cpuid_class_device_create(cpu); | 177 | cpuid_device_create(cpu); |
178 | break; | 178 | break; |
179 | case CPU_DEAD: | 179 | case CPU_DEAD: |
180 | class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); | 180 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); |
181 | break; | 181 | break; |
182 | } | 182 | } |
183 | return NOTIFY_OK; | 183 | return NOTIFY_OK; |
@@ -206,7 +206,7 @@ static int __init cpuid_init(void) | |||
206 | goto out_chrdev; | 206 | goto out_chrdev; |
207 | } | 207 | } |
208 | for_each_online_cpu(i) { | 208 | for_each_online_cpu(i) { |
209 | err = cpuid_class_device_create(i); | 209 | err = cpuid_device_create(i); |
210 | if (err != 0) | 210 | if (err != 0) |
211 | goto out_class; | 211 | goto out_class; |
212 | } | 212 | } |
@@ -218,7 +218,7 @@ static int __init cpuid_init(void) | |||
218 | out_class: | 218 | out_class: |
219 | i = 0; | 219 | i = 0; |
220 | for_each_online_cpu(i) { | 220 | for_each_online_cpu(i) { |
221 | class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i)); | 221 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i)); |
222 | } | 222 | } |
223 | class_destroy(cpuid_class); | 223 | class_destroy(cpuid_class); |
224 | out_chrdev: | 224 | out_chrdev: |
@@ -232,7 +232,7 @@ static void __exit cpuid_exit(void) | |||
232 | int cpu = 0; | 232 | int cpu = 0; |
233 | 233 | ||
234 | for_each_online_cpu(cpu) | 234 | for_each_online_cpu(cpu) |
235 | class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); | 235 | device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); |
236 | class_destroy(cpuid_class); | 236 | class_destroy(cpuid_class); |
237 | unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); | 237 | unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); |
238 | unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); | 238 | unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); |
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index d535cdbbfd25..a773f776c9ea 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c | |||
@@ -239,14 +239,14 @@ static struct file_operations msr_fops = { | |||
239 | .open = msr_open, | 239 | .open = msr_open, |
240 | }; | 240 | }; |
241 | 241 | ||
242 | static int msr_class_device_create(int i) | 242 | static int msr_device_create(int i) |
243 | { | 243 | { |
244 | int err = 0; | 244 | int err = 0; |
245 | struct class_device *class_err; | 245 | struct device *dev; |
246 | 246 | ||
247 | class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); | 247 | dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); |
248 | if (IS_ERR(class_err)) | 248 | if (IS_ERR(dev)) |
249 | err = PTR_ERR(class_err); | 249 | err = PTR_ERR(dev); |
250 | return err; | 250 | return err; |
251 | } | 251 | } |
252 | 252 | ||
@@ -258,10 +258,10 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, | |||
258 | 258 | ||
259 | switch (action) { | 259 | switch (action) { |
260 | case CPU_ONLINE: | 260 | case CPU_ONLINE: |
261 | msr_class_device_create(cpu); | 261 | msr_device_create(cpu); |
262 | break; | 262 | break; |
263 | case CPU_DEAD: | 263 | case CPU_DEAD: |
264 | class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 264 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); |
265 | break; | 265 | break; |
266 | } | 266 | } |
267 | return NOTIFY_OK; | 267 | return NOTIFY_OK; |
@@ -290,7 +290,7 @@ static int __init msr_init(void) | |||
290 | goto out_chrdev; | 290 | goto out_chrdev; |
291 | } | 291 | } |
292 | for_each_online_cpu(i) { | 292 | for_each_online_cpu(i) { |
293 | err = msr_class_device_create(i); | 293 | err = msr_device_create(i); |
294 | if (err != 0) | 294 | if (err != 0) |
295 | goto out_class; | 295 | goto out_class; |
296 | } | 296 | } |
@@ -302,7 +302,7 @@ static int __init msr_init(void) | |||
302 | out_class: | 302 | out_class: |
303 | i = 0; | 303 | i = 0; |
304 | for_each_online_cpu(i) | 304 | for_each_online_cpu(i) |
305 | class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); | 305 | device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); |
306 | class_destroy(msr_class); | 306 | class_destroy(msr_class); |
307 | out_chrdev: | 307 | out_chrdev: |
308 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 308 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); |
@@ -314,7 +314,7 @@ static void __exit msr_exit(void) | |||
314 | { | 314 | { |
315 | int cpu = 0; | 315 | int cpu = 0; |
316 | for_each_online_cpu(cpu) | 316 | for_each_online_cpu(cpu) |
317 | class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 317 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); |
318 | class_destroy(msr_class); | 318 | class_destroy(msr_class); |
319 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 319 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); |
320 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); | 320 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f160dc75b1..a2f46d587d55 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -267,9 +267,9 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
267 | { | 267 | { |
268 | acpi_status status; | 268 | acpi_status status; |
269 | 269 | ||
270 | if (dev->firmware_data) { | 270 | if (dev->archdata.acpi_handle) { |
271 | printk(KERN_WARNING PREFIX | 271 | printk(KERN_WARNING PREFIX |
272 | "Drivers changed 'firmware_data' for %s\n", dev->bus_id); | 272 | "Drivers changed 'acpi_handle' for %s\n", dev->bus_id); |
273 | return -EINVAL; | 273 | return -EINVAL; |
274 | } | 274 | } |
275 | get_device(dev); | 275 | get_device(dev); |
@@ -278,25 +278,26 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
278 | put_device(dev); | 278 | put_device(dev); |
279 | return -EINVAL; | 279 | return -EINVAL; |
280 | } | 280 | } |
281 | dev->firmware_data = handle; | 281 | dev->archdata.acpi_handle = handle; |
282 | 282 | ||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | static int acpi_unbind_one(struct device *dev) | 286 | static int acpi_unbind_one(struct device *dev) |
287 | { | 287 | { |
288 | if (!dev->firmware_data) | 288 | if (!dev->archdata.acpi_handle) |
289 | return 0; | 289 | return 0; |
290 | if (dev == acpi_get_physical_device(dev->firmware_data)) { | 290 | if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { |
291 | /* acpi_get_physical_device increase refcnt by one */ | 291 | /* acpi_get_physical_device increase refcnt by one */ |
292 | put_device(dev); | 292 | put_device(dev); |
293 | acpi_detach_data(dev->firmware_data, acpi_glue_data_handler); | 293 | acpi_detach_data(dev->archdata.acpi_handle, |
294 | dev->firmware_data = NULL; | 294 | acpi_glue_data_handler); |
295 | dev->archdata.acpi_handle = NULL; | ||
295 | /* acpi_bind_one increase refcnt by one */ | 296 | /* acpi_bind_one increase refcnt by one */ |
296 | put_device(dev); | 297 | put_device(dev); |
297 | } else { | 298 | } else { |
298 | printk(KERN_ERR PREFIX | 299 | printk(KERN_ERR PREFIX |
299 | "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id); | 300 | "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id); |
300 | } | 301 | } |
301 | return 0; | 302 | return 0; |
302 | } | 303 | } |
@@ -328,7 +329,8 @@ static int acpi_platform_notify(struct device *dev) | |||
328 | if (!ret) { | 329 | if (!ret) { |
329 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 330 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
330 | 331 | ||
331 | acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer); | 332 | acpi_get_name(dev->archdata.acpi_handle, |
333 | ACPI_FULL_PATHNAME, &buffer); | ||
332 | DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); | 334 | DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); |
333 | kfree(buffer.pointer); | 335 | kfree(buffer.pointer); |
334 | } else | 336 | } else |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 7d8a7ce73fb3..472810f8e6e7 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -355,6 +355,21 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) | |||
355 | } | 355 | } |
356 | } | 356 | } |
357 | 357 | ||
358 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
359 | static int make_deprecated_bus_links(struct device *dev) | ||
360 | { | ||
361 | return sysfs_create_link(&dev->kobj, | ||
362 | &dev->bus->subsys.kset.kobj, "bus"); | ||
363 | } | ||
364 | |||
365 | static void remove_deprecated_bus_links(struct device *dev) | ||
366 | { | ||
367 | sysfs_remove_link(&dev->kobj, "bus"); | ||
368 | } | ||
369 | #else | ||
370 | static inline int make_deprecated_bus_links(struct device *dev) { return 0; } | ||
371 | static inline void remove_deprecated_bus_links(struct device *dev) { } | ||
372 | #endif | ||
358 | 373 | ||
359 | /** | 374 | /** |
360 | * bus_add_device - add device to bus | 375 | * bus_add_device - add device to bus |
@@ -381,8 +396,7 @@ int bus_add_device(struct device * dev) | |||
381 | &dev->bus->subsys.kset.kobj, "subsystem"); | 396 | &dev->bus->subsys.kset.kobj, "subsystem"); |
382 | if (error) | 397 | if (error) |
383 | goto out_subsys; | 398 | goto out_subsys; |
384 | error = sysfs_create_link(&dev->kobj, | 399 | error = make_deprecated_bus_links(dev); |
385 | &dev->bus->subsys.kset.kobj, "bus"); | ||
386 | if (error) | 400 | if (error) |
387 | goto out_deprecated; | 401 | goto out_deprecated; |
388 | } | 402 | } |
@@ -436,7 +450,7 @@ void bus_remove_device(struct device * dev) | |||
436 | { | 450 | { |
437 | if (dev->bus) { | 451 | if (dev->bus) { |
438 | sysfs_remove_link(&dev->kobj, "subsystem"); | 452 | sysfs_remove_link(&dev->kobj, "subsystem"); |
439 | sysfs_remove_link(&dev->kobj, "bus"); | 453 | remove_deprecated_bus_links(dev); |
440 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 454 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); |
441 | device_remove_attrs(dev->bus, dev); | 455 | device_remove_attrs(dev->bus, dev); |
442 | if (dev->is_registered) { | 456 | if (dev->is_registered) { |
@@ -724,6 +738,8 @@ int bus_register(struct bus_type * bus) | |||
724 | { | 738 | { |
725 | int retval; | 739 | int retval; |
726 | 740 | ||
741 | BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); | ||
742 | |||
727 | retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); | 743 | retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); |
728 | if (retval) | 744 | if (retval) |
729 | goto out; | 745 | goto out; |
@@ -782,6 +798,18 @@ void bus_unregister(struct bus_type * bus) | |||
782 | subsystem_unregister(&bus->subsys); | 798 | subsystem_unregister(&bus->subsys); |
783 | } | 799 | } |
784 | 800 | ||
801 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) | ||
802 | { | ||
803 | return blocking_notifier_chain_register(&bus->bus_notifier, nb); | ||
804 | } | ||
805 | EXPORT_SYMBOL_GPL(bus_register_notifier); | ||
806 | |||
807 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) | ||
808 | { | ||
809 | return blocking_notifier_chain_unregister(&bus->bus_notifier, nb); | ||
810 | } | ||
811 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); | ||
812 | |||
785 | int __init buses_init(void) | 813 | int __init buses_init(void) |
786 | { | 814 | { |
787 | return subsystem_register(&bus_subsys); | 815 | return subsystem_register(&bus_subsys); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 0ff267a248db..f098881f45b2 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -352,6 +352,92 @@ static const char *class_uevent_name(struct kset *kset, struct kobject *kobj) | |||
352 | return class_dev->class->name; | 352 | return class_dev->class->name; |
353 | } | 353 | } |
354 | 354 | ||
355 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
356 | char *make_class_name(const char *name, struct kobject *kobj) | ||
357 | { | ||
358 | char *class_name; | ||
359 | int size; | ||
360 | |||
361 | size = strlen(name) + strlen(kobject_name(kobj)) + 2; | ||
362 | |||
363 | class_name = kmalloc(size, GFP_KERNEL); | ||
364 | if (!class_name) | ||
365 | return ERR_PTR(-ENOMEM); | ||
366 | |||
367 | strcpy(class_name, name); | ||
368 | strcat(class_name, ":"); | ||
369 | strcat(class_name, kobject_name(kobj)); | ||
370 | return class_name; | ||
371 | } | ||
372 | |||
373 | static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index, | ||
374 | char *buffer, int buffer_size, | ||
375 | int *cur_len, | ||
376 | struct class_device *class_dev) | ||
377 | { | ||
378 | struct device *dev = class_dev->dev; | ||
379 | char *path; | ||
380 | |||
381 | if (!dev) | ||
382 | return 0; | ||
383 | |||
384 | /* add device, backing this class device (deprecated) */ | ||
385 | path = kobject_get_path(&dev->kobj, GFP_KERNEL); | ||
386 | |||
387 | add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size, | ||
388 | cur_len, "PHYSDEVPATH=%s", path); | ||
389 | kfree(path); | ||
390 | |||
391 | if (dev->bus) | ||
392 | add_uevent_var(envp, num_envp, cur_index, | ||
393 | buffer, buffer_size, cur_len, | ||
394 | "PHYSDEVBUS=%s", dev->bus->name); | ||
395 | |||
396 | if (dev->driver) | ||
397 | add_uevent_var(envp, num_envp, cur_index, | ||
398 | buffer, buffer_size, cur_len, | ||
399 | "PHYSDEVDRIVER=%s", dev->driver->name); | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static int make_deprecated_class_device_links(struct class_device *class_dev) | ||
404 | { | ||
405 | char *class_name; | ||
406 | int error; | ||
407 | |||
408 | if (!class_dev->dev) | ||
409 | return 0; | ||
410 | |||
411 | class_name = make_class_name(class_dev->class->name, &class_dev->kobj); | ||
412 | error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, | ||
413 | class_name); | ||
414 | kfree(class_name); | ||
415 | return error; | ||
416 | } | ||
417 | |||
418 | static void remove_deprecated_class_device_links(struct class_device *class_dev) | ||
419 | { | ||
420 | char *class_name; | ||
421 | |||
422 | if (!class_dev->dev) | ||
423 | return; | ||
424 | |||
425 | class_name = make_class_name(class_dev->class->name, &class_dev->kobj); | ||
426 | sysfs_remove_link(&class_dev->dev->kobj, class_name); | ||
427 | kfree(class_name); | ||
428 | } | ||
429 | #else | ||
430 | static inline int deprecated_class_uevent(char **envp, int num_envp, | ||
431 | int *cur_index, char *buffer, | ||
432 | int buffer_size, int *cur_len, | ||
433 | struct class_device *class_dev) | ||
434 | { return 0; } | ||
435 | static inline int make_deprecated_class_device_links(struct class_device *cd) | ||
436 | { return 0; } | ||
437 | static void remove_deprecated_class_device_links(struct class_device *cd) | ||
438 | { } | ||
439 | #endif | ||
440 | |||
355 | static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, | 441 | static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, |
356 | int num_envp, char *buffer, int buffer_size) | 442 | int num_envp, char *buffer, int buffer_size) |
357 | { | 443 | { |
@@ -362,25 +448,8 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
362 | 448 | ||
363 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); | 449 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); |
364 | 450 | ||
365 | if (class_dev->dev) { | 451 | deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size, |
366 | /* add device, backing this class device (deprecated) */ | 452 | &length, class_dev); |
367 | struct device *dev = class_dev->dev; | ||
368 | char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); | ||
369 | |||
370 | add_uevent_var(envp, num_envp, &i, buffer, buffer_size, | ||
371 | &length, "PHYSDEVPATH=%s", path); | ||
372 | kfree(path); | ||
373 | |||
374 | if (dev->bus) | ||
375 | add_uevent_var(envp, num_envp, &i, | ||
376 | buffer, buffer_size, &length, | ||
377 | "PHYSDEVBUS=%s", dev->bus->name); | ||
378 | |||
379 | if (dev->driver) | ||
380 | add_uevent_var(envp, num_envp, &i, | ||
381 | buffer, buffer_size, &length, | ||
382 | "PHYSDEVDRIVER=%s", dev->driver->name); | ||
383 | } | ||
384 | 453 | ||
385 | if (MAJOR(class_dev->devt)) { | 454 | if (MAJOR(class_dev->devt)) { |
386 | add_uevent_var(envp, num_envp, &i, | 455 | add_uevent_var(envp, num_envp, &i, |
@@ -506,29 +575,11 @@ void class_device_initialize(struct class_device *class_dev) | |||
506 | INIT_LIST_HEAD(&class_dev->node); | 575 | INIT_LIST_HEAD(&class_dev->node); |
507 | } | 576 | } |
508 | 577 | ||
509 | char *make_class_name(const char *name, struct kobject *kobj) | ||
510 | { | ||
511 | char *class_name; | ||
512 | int size; | ||
513 | |||
514 | size = strlen(name) + strlen(kobject_name(kobj)) + 2; | ||
515 | |||
516 | class_name = kmalloc(size, GFP_KERNEL); | ||
517 | if (!class_name) | ||
518 | return ERR_PTR(-ENOMEM); | ||
519 | |||
520 | strcpy(class_name, name); | ||
521 | strcat(class_name, ":"); | ||
522 | strcat(class_name, kobject_name(kobj)); | ||
523 | return class_name; | ||
524 | } | ||
525 | |||
526 | int class_device_add(struct class_device *class_dev) | 578 | int class_device_add(struct class_device *class_dev) |
527 | { | 579 | { |
528 | struct class *parent_class = NULL; | 580 | struct class *parent_class = NULL; |
529 | struct class_device *parent_class_dev = NULL; | 581 | struct class_device *parent_class_dev = NULL; |
530 | struct class_interface *class_intf; | 582 | struct class_interface *class_intf; |
531 | char *class_name = NULL; | ||
532 | int error = -EINVAL; | 583 | int error = -EINVAL; |
533 | 584 | ||
534 | class_dev = class_device_get(class_dev); | 585 | class_dev = class_device_get(class_dev); |
@@ -599,20 +650,18 @@ int class_device_add(struct class_device *class_dev) | |||
599 | goto out5; | 650 | goto out5; |
600 | 651 | ||
601 | if (class_dev->dev) { | 652 | if (class_dev->dev) { |
602 | class_name = make_class_name(class_dev->class->name, | ||
603 | &class_dev->kobj); | ||
604 | error = sysfs_create_link(&class_dev->kobj, | 653 | error = sysfs_create_link(&class_dev->kobj, |
605 | &class_dev->dev->kobj, "device"); | 654 | &class_dev->dev->kobj, "device"); |
606 | if (error) | 655 | if (error) |
607 | goto out6; | 656 | goto out6; |
608 | error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, | ||
609 | class_name); | ||
610 | if (error) | ||
611 | goto out7; | ||
612 | } | 657 | } |
613 | 658 | ||
614 | error = class_device_add_groups(class_dev); | 659 | error = class_device_add_groups(class_dev); |
615 | if (error) | 660 | if (error) |
661 | goto out7; | ||
662 | |||
663 | error = make_deprecated_class_device_links(class_dev); | ||
664 | if (error) | ||
616 | goto out8; | 665 | goto out8; |
617 | 666 | ||
618 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 667 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); |
@@ -629,8 +678,7 @@ int class_device_add(struct class_device *class_dev) | |||
629 | goto out1; | 678 | goto out1; |
630 | 679 | ||
631 | out8: | 680 | out8: |
632 | if (class_dev->dev) | 681 | class_device_remove_groups(class_dev); |
633 | sysfs_remove_link(&class_dev->kobj, class_name); | ||
634 | out7: | 682 | out7: |
635 | if (class_dev->dev) | 683 | if (class_dev->dev) |
636 | sysfs_remove_link(&class_dev->kobj, "device"); | 684 | sysfs_remove_link(&class_dev->kobj, "device"); |
@@ -649,7 +697,6 @@ int class_device_add(struct class_device *class_dev) | |||
649 | class_put(parent_class); | 697 | class_put(parent_class); |
650 | out1: | 698 | out1: |
651 | class_device_put(class_dev); | 699 | class_device_put(class_dev); |
652 | kfree(class_name); | ||
653 | return error; | 700 | return error; |
654 | } | 701 | } |
655 | 702 | ||
@@ -726,7 +773,6 @@ void class_device_del(struct class_device *class_dev) | |||
726 | struct class *parent_class = class_dev->class; | 773 | struct class *parent_class = class_dev->class; |
727 | struct class_device *parent_device = class_dev->parent; | 774 | struct class_device *parent_device = class_dev->parent; |
728 | struct class_interface *class_intf; | 775 | struct class_interface *class_intf; |
729 | char *class_name = NULL; | ||
730 | 776 | ||
731 | if (parent_class) { | 777 | if (parent_class) { |
732 | down(&parent_class->sem); | 778 | down(&parent_class->sem); |
@@ -738,10 +784,8 @@ void class_device_del(struct class_device *class_dev) | |||
738 | } | 784 | } |
739 | 785 | ||
740 | if (class_dev->dev) { | 786 | if (class_dev->dev) { |
741 | class_name = make_class_name(class_dev->class->name, | 787 | remove_deprecated_class_device_links(class_dev); |
742 | &class_dev->kobj); | ||
743 | sysfs_remove_link(&class_dev->kobj, "device"); | 788 | sysfs_remove_link(&class_dev->kobj, "device"); |
744 | sysfs_remove_link(&class_dev->dev->kobj, class_name); | ||
745 | } | 789 | } |
746 | sysfs_remove_link(&class_dev->kobj, "subsystem"); | 790 | sysfs_remove_link(&class_dev->kobj, "subsystem"); |
747 | class_device_remove_file(class_dev, &class_dev->uevent_attr); | 791 | class_device_remove_file(class_dev, &class_dev->uevent_attr); |
@@ -755,7 +799,6 @@ void class_device_del(struct class_device *class_dev) | |||
755 | 799 | ||
756 | class_device_put(parent_device); | 800 | class_device_put(parent_device); |
757 | class_put(parent_class); | 801 | class_put(parent_class); |
758 | kfree(class_name); | ||
759 | } | 802 | } |
760 | 803 | ||
761 | void class_device_unregister(struct class_device *class_dev) | 804 | void class_device_unregister(struct class_device *class_dev) |
@@ -804,14 +847,17 @@ int class_device_rename(struct class_device *class_dev, char *new_name) | |||
804 | pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id, | 847 | pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id, |
805 | new_name); | 848 | new_name); |
806 | 849 | ||
850 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
807 | if (class_dev->dev) | 851 | if (class_dev->dev) |
808 | old_class_name = make_class_name(class_dev->class->name, | 852 | old_class_name = make_class_name(class_dev->class->name, |
809 | &class_dev->kobj); | 853 | &class_dev->kobj); |
854 | #endif | ||
810 | 855 | ||
811 | strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); | 856 | strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); |
812 | 857 | ||
813 | error = kobject_rename(&class_dev->kobj, new_name); | 858 | error = kobject_rename(&class_dev->kobj, new_name); |
814 | 859 | ||
860 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
815 | if (class_dev->dev) { | 861 | if (class_dev->dev) { |
816 | new_class_name = make_class_name(class_dev->class->name, | 862 | new_class_name = make_class_name(class_dev->class->name, |
817 | &class_dev->kobj); | 863 | &class_dev->kobj); |
@@ -819,6 +865,7 @@ int class_device_rename(struct class_device *class_dev, char *new_name) | |||
819 | new_class_name); | 865 | new_class_name); |
820 | sysfs_remove_link(&class_dev->dev->kobj, old_class_name); | 866 | sysfs_remove_link(&class_dev->dev->kobj, old_class_name); |
821 | } | 867 | } |
868 | #endif | ||
822 | class_device_put(class_dev); | 869 | class_device_put(class_dev); |
823 | 870 | ||
824 | kfree(old_class_name); | 871 | kfree(old_class_name); |
@@ -893,23 +940,6 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
893 | class_put(parent); | 940 | class_put(parent); |
894 | } | 941 | } |
895 | 942 | ||
896 | int virtual_device_parent(struct device *dev) | ||
897 | { | ||
898 | if (!dev->class) | ||
899 | return -ENODEV; | ||
900 | |||
901 | if (!dev->class->virtual_dir) { | ||
902 | static struct kobject *virtual_dir = NULL; | ||
903 | |||
904 | if (!virtual_dir) | ||
905 | virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); | ||
906 | dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); | ||
907 | } | ||
908 | |||
909 | dev->kobj.parent = dev->class->virtual_dir; | ||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | int __init classes_init(void) | 943 | int __init classes_init(void) |
914 | { | 944 | { |
915 | int retval; | 945 | int retval; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 002fde46d38d..e4b530ef757d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/kdev_t.h> | 19 | #include <linux/kdev_t.h> |
20 | #include <linux/notifier.h> | ||
20 | 21 | ||
21 | #include <asm/semaphore.h> | 22 | #include <asm/semaphore.h> |
22 | 23 | ||
@@ -153,20 +154,24 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
153 | "MINOR=%u", MINOR(dev->devt)); | 154 | "MINOR=%u", MINOR(dev->devt)); |
154 | } | 155 | } |
155 | 156 | ||
157 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
156 | /* add bus name (same as SUBSYSTEM, deprecated) */ | 158 | /* add bus name (same as SUBSYSTEM, deprecated) */ |
157 | if (dev->bus) | 159 | if (dev->bus) |
158 | add_uevent_var(envp, num_envp, &i, | 160 | add_uevent_var(envp, num_envp, &i, |
159 | buffer, buffer_size, &length, | 161 | buffer, buffer_size, &length, |
160 | "PHYSDEVBUS=%s", dev->bus->name); | 162 | "PHYSDEVBUS=%s", dev->bus->name); |
163 | #endif | ||
161 | 164 | ||
162 | /* add driver name (PHYSDEV* values are deprecated)*/ | 165 | /* add driver name (PHYSDEV* values are deprecated)*/ |
163 | if (dev->driver) { | 166 | if (dev->driver) { |
164 | add_uevent_var(envp, num_envp, &i, | 167 | add_uevent_var(envp, num_envp, &i, |
165 | buffer, buffer_size, &length, | 168 | buffer, buffer_size, &length, |
166 | "DRIVER=%s", dev->driver->name); | 169 | "DRIVER=%s", dev->driver->name); |
170 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
167 | add_uevent_var(envp, num_envp, &i, | 171 | add_uevent_var(envp, num_envp, &i, |
168 | buffer, buffer_size, &length, | 172 | buffer, buffer_size, &length, |
169 | "PHYSDEVDRIVER=%s", dev->driver->name); | 173 | "PHYSDEVDRIVER=%s", dev->driver->name); |
174 | #endif | ||
170 | } | 175 | } |
171 | 176 | ||
172 | /* terminate, set to next free slot, shrink available space */ | 177 | /* terminate, set to next free slot, shrink available space */ |
@@ -383,6 +388,52 @@ void device_initialize(struct device *dev) | |||
383 | device_init_wakeup(dev, 0); | 388 | device_init_wakeup(dev, 0); |
384 | } | 389 | } |
385 | 390 | ||
391 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
392 | static int setup_parent(struct device *dev, struct device *parent) | ||
393 | { | ||
394 | /* Set the parent to the class, not the parent device */ | ||
395 | /* this keeps sysfs from having a symlink to make old udevs happy */ | ||
396 | if (dev->class) | ||
397 | dev->kobj.parent = &dev->class->subsys.kset.kobj; | ||
398 | else if (parent) | ||
399 | dev->kobj.parent = &parent->kobj; | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | #else | ||
404 | static int virtual_device_parent(struct device *dev) | ||
405 | { | ||
406 | if (!dev->class) | ||
407 | return -ENODEV; | ||
408 | |||
409 | if (!dev->class->virtual_dir) { | ||
410 | static struct kobject *virtual_dir = NULL; | ||
411 | |||
412 | if (!virtual_dir) | ||
413 | virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); | ||
414 | dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); | ||
415 | } | ||
416 | |||
417 | dev->kobj.parent = dev->class->virtual_dir; | ||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | static int setup_parent(struct device *dev, struct device *parent) | ||
422 | { | ||
423 | int error; | ||
424 | |||
425 | /* if this is a class device, and has no parent, create one */ | ||
426 | if ((dev->class) && (parent == NULL)) { | ||
427 | error = virtual_device_parent(dev); | ||
428 | if (error) | ||
429 | return error; | ||
430 | } else if (parent) | ||
431 | dev->kobj.parent = &parent->kobj; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | #endif | ||
436 | |||
386 | /** | 437 | /** |
387 | * device_add - add device to device hierarchy. | 438 | * device_add - add device to device hierarchy. |
388 | * @dev: device. | 439 | * @dev: device. |
@@ -405,29 +456,29 @@ int device_add(struct device *dev) | |||
405 | if (!dev || !strlen(dev->bus_id)) | 456 | if (!dev || !strlen(dev->bus_id)) |
406 | goto Error; | 457 | goto Error; |
407 | 458 | ||
408 | /* if this is a class device, and has no parent, create one */ | 459 | pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); |
409 | if ((dev->class) && (dev->parent == NULL)) { | ||
410 | error = virtual_device_parent(dev); | ||
411 | if (error) | ||
412 | goto Error; | ||
413 | } | ||
414 | 460 | ||
415 | parent = get_device(dev->parent); | 461 | parent = get_device(dev->parent); |
416 | 462 | ||
417 | pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); | 463 | error = setup_parent(dev, parent); |
464 | if (error) | ||
465 | goto Error; | ||
418 | 466 | ||
419 | /* first, register with generic layer. */ | 467 | /* first, register with generic layer. */ |
420 | kobject_set_name(&dev->kobj, "%s", dev->bus_id); | 468 | kobject_set_name(&dev->kobj, "%s", dev->bus_id); |
421 | if (parent) | 469 | error = kobject_add(&dev->kobj); |
422 | dev->kobj.parent = &parent->kobj; | 470 | if (error) |
423 | |||
424 | if ((error = kobject_add(&dev->kobj))) | ||
425 | goto Error; | 471 | goto Error; |
426 | 472 | ||
427 | /* notify platform of device entry */ | 473 | /* notify platform of device entry */ |
428 | if (platform_notify) | 474 | if (platform_notify) |
429 | platform_notify(dev); | 475 | platform_notify(dev); |
430 | 476 | ||
477 | /* notify clients of device entry (new way) */ | ||
478 | if (dev->bus) | ||
479 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | ||
480 | BUS_NOTIFY_ADD_DEVICE, dev); | ||
481 | |||
431 | dev->uevent_attr.attr.name = "uevent"; | 482 | dev->uevent_attr.attr.name = "uevent"; |
432 | dev->uevent_attr.attr.mode = S_IWUSR; | 483 | dev->uevent_attr.attr.mode = S_IWUSR; |
433 | if (dev->driver) | 484 | if (dev->driver) |
@@ -461,13 +512,18 @@ int device_add(struct device *dev) | |||
461 | if (dev->class) { | 512 | if (dev->class) { |
462 | sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, | 513 | sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, |
463 | "subsystem"); | 514 | "subsystem"); |
464 | sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, | 515 | /* If this is not a "fake" compatible device, then create the |
465 | dev->bus_id); | 516 | * symlink from the class to the device. */ |
517 | if (dev->kobj.parent != &dev->class->subsys.kset.kobj) | ||
518 | sysfs_create_link(&dev->class->subsys.kset.kobj, | ||
519 | &dev->kobj, dev->bus_id); | ||
520 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
466 | if (parent) { | 521 | if (parent) { |
467 | sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); | 522 | sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); |
468 | class_name = make_class_name(dev->class->name, &dev->kobj); | 523 | class_name = make_class_name(dev->class->name, &dev->kobj); |
469 | sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); | 524 | sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); |
470 | } | 525 | } |
526 | #endif | ||
471 | } | 527 | } |
472 | 528 | ||
473 | if ((error = device_add_attrs(dev))) | 529 | if ((error = device_add_attrs(dev))) |
@@ -504,6 +560,9 @@ int device_add(struct device *dev) | |||
504 | BusError: | 560 | BusError: |
505 | device_pm_remove(dev); | 561 | device_pm_remove(dev); |
506 | PMError: | 562 | PMError: |
563 | if (dev->bus) | ||
564 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | ||
565 | BUS_NOTIFY_DEL_DEVICE, dev); | ||
507 | device_remove_groups(dev); | 566 | device_remove_groups(dev); |
508 | GroupError: | 567 | GroupError: |
509 | device_remove_attrs(dev); | 568 | device_remove_attrs(dev); |
@@ -586,7 +645,6 @@ void put_device(struct device * dev) | |||
586 | void device_del(struct device * dev) | 645 | void device_del(struct device * dev) |
587 | { | 646 | { |
588 | struct device * parent = dev->parent; | 647 | struct device * parent = dev->parent; |
589 | char *class_name = NULL; | ||
590 | struct class_interface *class_intf; | 648 | struct class_interface *class_intf; |
591 | 649 | ||
592 | if (parent) | 650 | if (parent) |
@@ -597,13 +655,21 @@ void device_del(struct device * dev) | |||
597 | } | 655 | } |
598 | if (dev->class) { | 656 | if (dev->class) { |
599 | sysfs_remove_link(&dev->kobj, "subsystem"); | 657 | sysfs_remove_link(&dev->kobj, "subsystem"); |
600 | sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); | 658 | /* If this is not a "fake" compatible device, remove the |
601 | class_name = make_class_name(dev->class->name, &dev->kobj); | 659 | * symlink from the class to the device. */ |
660 | if (dev->kobj.parent != &dev->class->subsys.kset.kobj) | ||
661 | sysfs_remove_link(&dev->class->subsys.kset.kobj, | ||
662 | dev->bus_id); | ||
663 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
602 | if (parent) { | 664 | if (parent) { |
603 | sysfs_remove_link(&dev->kobj, "device"); | 665 | char *class_name = make_class_name(dev->class->name, |
666 | &dev->kobj); | ||
604 | sysfs_remove_link(&dev->parent->kobj, class_name); | 667 | sysfs_remove_link(&dev->parent->kobj, class_name); |
668 | kfree(class_name); | ||
669 | sysfs_remove_link(&dev->kobj, "device"); | ||
605 | } | 670 | } |
606 | kfree(class_name); | 671 | #endif |
672 | |||
607 | down(&dev->class->sem); | 673 | down(&dev->class->sem); |
608 | /* notify any interfaces that the device is now gone */ | 674 | /* notify any interfaces that the device is now gone */ |
609 | list_for_each_entry(class_intf, &dev->class->interfaces, node) | 675 | list_for_each_entry(class_intf, &dev->class->interfaces, node) |
@@ -616,13 +682,16 @@ void device_del(struct device * dev) | |||
616 | device_remove_file(dev, &dev->uevent_attr); | 682 | device_remove_file(dev, &dev->uevent_attr); |
617 | device_remove_groups(dev); | 683 | device_remove_groups(dev); |
618 | device_remove_attrs(dev); | 684 | device_remove_attrs(dev); |
685 | bus_remove_device(dev); | ||
619 | 686 | ||
620 | /* Notify the platform of the removal, in case they | 687 | /* Notify the platform of the removal, in case they |
621 | * need to do anything... | 688 | * need to do anything... |
622 | */ | 689 | */ |
623 | if (platform_notify_remove) | 690 | if (platform_notify_remove) |
624 | platform_notify_remove(dev); | 691 | platform_notify_remove(dev); |
625 | bus_remove_device(dev); | 692 | if (dev->bus) |
693 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | ||
694 | BUS_NOTIFY_DEL_DEVICE, dev); | ||
626 | device_pm_remove(dev); | 695 | device_pm_remove(dev); |
627 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 696 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
628 | kobject_del(&dev->kobj); | 697 | kobject_del(&dev->kobj); |
@@ -681,12 +750,45 @@ int device_for_each_child(struct device * parent, void * data, | |||
681 | return error; | 750 | return error; |
682 | } | 751 | } |
683 | 752 | ||
753 | /** | ||
754 | * device_find_child - device iterator for locating a particular device. | ||
755 | * @parent: parent struct device | ||
756 | * @data: Data to pass to match function | ||
757 | * @match: Callback function to check device | ||
758 | * | ||
759 | * This is similar to the device_for_each_child() function above, but it | ||
760 | * returns a reference to a device that is 'found' for later use, as | ||
761 | * determined by the @match callback. | ||
762 | * | ||
763 | * The callback should return 0 if the device doesn't match and non-zero | ||
764 | * if it does. If the callback returns non-zero and a reference to the | ||
765 | * current device can be obtained, this function will return to the caller | ||
766 | * and not iterate over any more devices. | ||
767 | */ | ||
768 | struct device * device_find_child(struct device *parent, void *data, | ||
769 | int (*match)(struct device *, void *)) | ||
770 | { | ||
771 | struct klist_iter i; | ||
772 | struct device *child; | ||
773 | |||
774 | if (!parent) | ||
775 | return NULL; | ||
776 | |||
777 | klist_iter_init(&parent->klist_children, &i); | ||
778 | while ((child = next_device(&i))) | ||
779 | if (match(child, data) && get_device(child)) | ||
780 | break; | ||
781 | klist_iter_exit(&i); | ||
782 | return child; | ||
783 | } | ||
784 | |||
684 | int __init devices_init(void) | 785 | int __init devices_init(void) |
685 | { | 786 | { |
686 | return subsystem_register(&devices_subsys); | 787 | return subsystem_register(&devices_subsys); |
687 | } | 788 | } |
688 | 789 | ||
689 | EXPORT_SYMBOL_GPL(device_for_each_child); | 790 | EXPORT_SYMBOL_GPL(device_for_each_child); |
791 | EXPORT_SYMBOL_GPL(device_find_child); | ||
690 | 792 | ||
691 | EXPORT_SYMBOL_GPL(device_initialize); | 793 | EXPORT_SYMBOL_GPL(device_initialize); |
692 | EXPORT_SYMBOL_GPL(device_add); | 794 | EXPORT_SYMBOL_GPL(device_add); |
@@ -809,8 +911,10 @@ int device_rename(struct device *dev, char *new_name) | |||
809 | 911 | ||
810 | pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name); | 912 | pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name); |
811 | 913 | ||
914 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
812 | if ((dev->class) && (dev->parent)) | 915 | if ((dev->class) && (dev->parent)) |
813 | old_class_name = make_class_name(dev->class->name, &dev->kobj); | 916 | old_class_name = make_class_name(dev->class->name, &dev->kobj); |
917 | #endif | ||
814 | 918 | ||
815 | if (dev->class) { | 919 | if (dev->class) { |
816 | old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); | 920 | old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); |
@@ -825,6 +929,7 @@ int device_rename(struct device *dev, char *new_name) | |||
825 | 929 | ||
826 | error = kobject_rename(&dev->kobj, new_name); | 930 | error = kobject_rename(&dev->kobj, new_name); |
827 | 931 | ||
932 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
828 | if (old_class_name) { | 933 | if (old_class_name) { |
829 | new_class_name = make_class_name(dev->class->name, &dev->kobj); | 934 | new_class_name = make_class_name(dev->class->name, &dev->kobj); |
830 | if (new_class_name) { | 935 | if (new_class_name) { |
@@ -833,6 +938,8 @@ int device_rename(struct device *dev, char *new_name) | |||
833 | sysfs_remove_link(&dev->parent->kobj, old_class_name); | 938 | sysfs_remove_link(&dev->parent->kobj, old_class_name); |
834 | } | 939 | } |
835 | } | 940 | } |
941 | #endif | ||
942 | |||
836 | if (dev->class) { | 943 | if (dev->class) { |
837 | sysfs_remove_link(&dev->class->subsys.kset.kobj, | 944 | sysfs_remove_link(&dev->class->subsys.kset.kobj, |
838 | old_symlink_name); | 945 | old_symlink_name); |
@@ -848,3 +955,95 @@ int device_rename(struct device *dev, char *new_name) | |||
848 | 955 | ||
849 | return error; | 956 | return error; |
850 | } | 957 | } |
958 | |||
959 | |||
960 | static int device_move_class_links(struct device *dev, | ||
961 | struct device *old_parent, | ||
962 | struct device *new_parent) | ||
963 | { | ||
964 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
965 | int error; | ||
966 | char *class_name; | ||
967 | |||
968 | class_name = make_class_name(dev->class->name, &dev->kobj); | ||
969 | if (!class_name) { | ||
970 | error = PTR_ERR(class_name); | ||
971 | class_name = NULL; | ||
972 | goto out; | ||
973 | } | ||
974 | if (old_parent) { | ||
975 | sysfs_remove_link(&dev->kobj, "device"); | ||
976 | sysfs_remove_link(&old_parent->kobj, class_name); | ||
977 | } | ||
978 | error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device"); | ||
979 | if (error) | ||
980 | goto out; | ||
981 | error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name); | ||
982 | if (error) | ||
983 | sysfs_remove_link(&dev->kobj, "device"); | ||
984 | out: | ||
985 | kfree(class_name); | ||
986 | return error; | ||
987 | #else | ||
988 | return 0; | ||
989 | #endif | ||
990 | } | ||
991 | |||
992 | /** | ||
993 | * device_move - moves a device to a new parent | ||
994 | * @dev: the pointer to the struct device to be moved | ||
995 | * @new_parent: the new parent of the device | ||
996 | */ | ||
997 | int device_move(struct device *dev, struct device *new_parent) | ||
998 | { | ||
999 | int error; | ||
1000 | struct device *old_parent; | ||
1001 | |||
1002 | dev = get_device(dev); | ||
1003 | if (!dev) | ||
1004 | return -EINVAL; | ||
1005 | |||
1006 | if (!device_is_registered(dev)) { | ||
1007 | error = -EINVAL; | ||
1008 | goto out; | ||
1009 | } | ||
1010 | new_parent = get_device(new_parent); | ||
1011 | if (!new_parent) { | ||
1012 | error = -EINVAL; | ||
1013 | goto out; | ||
1014 | } | ||
1015 | pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, | ||
1016 | new_parent->bus_id); | ||
1017 | error = kobject_move(&dev->kobj, &new_parent->kobj); | ||
1018 | if (error) { | ||
1019 | put_device(new_parent); | ||
1020 | goto out; | ||
1021 | } | ||
1022 | old_parent = dev->parent; | ||
1023 | dev->parent = new_parent; | ||
1024 | if (old_parent) | ||
1025 | klist_remove(&dev->knode_parent); | ||
1026 | klist_add_tail(&dev->knode_parent, &new_parent->klist_children); | ||
1027 | if (!dev->class) | ||
1028 | goto out_put; | ||
1029 | error = device_move_class_links(dev, old_parent, new_parent); | ||
1030 | if (error) { | ||
1031 | /* We ignore errors on cleanup since we're hosed anyway... */ | ||
1032 | device_move_class_links(dev, new_parent, old_parent); | ||
1033 | if (!kobject_move(&dev->kobj, &old_parent->kobj)) { | ||
1034 | klist_remove(&dev->knode_parent); | ||
1035 | if (old_parent) | ||
1036 | klist_add_tail(&dev->knode_parent, | ||
1037 | &old_parent->klist_children); | ||
1038 | } | ||
1039 | put_device(new_parent); | ||
1040 | goto out; | ||
1041 | } | ||
1042 | out_put: | ||
1043 | put_device(old_parent); | ||
1044 | out: | ||
1045 | put_device(dev); | ||
1046 | return error; | ||
1047 | } | ||
1048 | |||
1049 | EXPORT_SYMBOL_GPL(device_move); | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index c5d6bb4290ad..510e7884975f 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -26,33 +26,28 @@ | |||
26 | #define to_drv(node) container_of(node, struct device_driver, kobj.entry) | 26 | #define to_drv(node) container_of(node, struct device_driver, kobj.entry) |
27 | 27 | ||
28 | 28 | ||
29 | /** | 29 | static void driver_bound(struct device *dev) |
30 | * device_bind_driver - bind a driver to one device. | ||
31 | * @dev: device. | ||
32 | * | ||
33 | * Allow manual attachment of a driver to a device. | ||
34 | * Caller must have already set @dev->driver. | ||
35 | * | ||
36 | * Note that this does not modify the bus reference count | ||
37 | * nor take the bus's rwsem. Please verify those are accounted | ||
38 | * for before calling this. (It is ok to call with no other effort | ||
39 | * from a driver's probe() method.) | ||
40 | * | ||
41 | * This function must be called with @dev->sem held. | ||
42 | */ | ||
43 | int device_bind_driver(struct device *dev) | ||
44 | { | 30 | { |
45 | int ret; | ||
46 | |||
47 | if (klist_node_attached(&dev->knode_driver)) { | 31 | if (klist_node_attached(&dev->knode_driver)) { |
48 | printk(KERN_WARNING "%s: device %s already bound\n", | 32 | printk(KERN_WARNING "%s: device %s already bound\n", |
49 | __FUNCTION__, kobject_name(&dev->kobj)); | 33 | __FUNCTION__, kobject_name(&dev->kobj)); |
50 | return 0; | 34 | return; |
51 | } | 35 | } |
52 | 36 | ||
53 | pr_debug("bound device '%s' to driver '%s'\n", | 37 | pr_debug("bound device '%s' to driver '%s'\n", |
54 | dev->bus_id, dev->driver->name); | 38 | dev->bus_id, dev->driver->name); |
39 | |||
40 | if (dev->bus) | ||
41 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | ||
42 | BUS_NOTIFY_BOUND_DRIVER, dev); | ||
43 | |||
55 | klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); | 44 | klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); |
45 | } | ||
46 | |||
47 | static int driver_sysfs_add(struct device *dev) | ||
48 | { | ||
49 | int ret; | ||
50 | |||
56 | ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, | 51 | ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, |
57 | kobject_name(&dev->kobj)); | 52 | kobject_name(&dev->kobj)); |
58 | if (ret == 0) { | 53 | if (ret == 0) { |
@@ -65,6 +60,36 @@ int device_bind_driver(struct device *dev) | |||
65 | return ret; | 60 | return ret; |
66 | } | 61 | } |
67 | 62 | ||
63 | static void driver_sysfs_remove(struct device *dev) | ||
64 | { | ||
65 | struct device_driver *drv = dev->driver; | ||
66 | |||
67 | if (drv) { | ||
68 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); | ||
69 | sysfs_remove_link(&dev->kobj, "driver"); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * device_bind_driver - bind a driver to one device. | ||
75 | * @dev: device. | ||
76 | * | ||
77 | * Allow manual attachment of a driver to a device. | ||
78 | * Caller must have already set @dev->driver. | ||
79 | * | ||
80 | * Note that this does not modify the bus reference count | ||
81 | * nor take the bus's rwsem. Please verify those are accounted | ||
82 | * for before calling this. (It is ok to call with no other effort | ||
83 | * from a driver's probe() method.) | ||
84 | * | ||
85 | * This function must be called with @dev->sem held. | ||
86 | */ | ||
87 | int device_bind_driver(struct device *dev) | ||
88 | { | ||
89 | driver_bound(dev); | ||
90 | return driver_sysfs_add(dev); | ||
91 | } | ||
92 | |||
68 | struct stupid_thread_structure { | 93 | struct stupid_thread_structure { |
69 | struct device_driver *drv; | 94 | struct device_driver *drv; |
70 | struct device *dev; | 95 | struct device *dev; |
@@ -85,30 +110,32 @@ static int really_probe(void *void_data) | |||
85 | drv->bus->name, drv->name, dev->bus_id); | 110 | drv->bus->name, drv->name, dev->bus_id); |
86 | 111 | ||
87 | dev->driver = drv; | 112 | dev->driver = drv; |
113 | if (driver_sysfs_add(dev)) { | ||
114 | printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", | ||
115 | __FUNCTION__, dev->bus_id); | ||
116 | goto probe_failed; | ||
117 | } | ||
118 | |||
88 | if (dev->bus->probe) { | 119 | if (dev->bus->probe) { |
89 | ret = dev->bus->probe(dev); | 120 | ret = dev->bus->probe(dev); |
90 | if (ret) { | 121 | if (ret) |
91 | dev->driver = NULL; | ||
92 | goto probe_failed; | 122 | goto probe_failed; |
93 | } | ||
94 | } else if (drv->probe) { | 123 | } else if (drv->probe) { |
95 | ret = drv->probe(dev); | 124 | ret = drv->probe(dev); |
96 | if (ret) { | 125 | if (ret) |
97 | dev->driver = NULL; | ||
98 | goto probe_failed; | 126 | goto probe_failed; |
99 | } | ||
100 | } | ||
101 | if (device_bind_driver(dev)) { | ||
102 | printk(KERN_ERR "%s: device_bind_driver(%s) failed\n", | ||
103 | __FUNCTION__, dev->bus_id); | ||
104 | /* How does undo a ->probe? We're screwed. */ | ||
105 | } | 127 | } |
128 | |||
129 | driver_bound(dev); | ||
106 | ret = 1; | 130 | ret = 1; |
107 | pr_debug("%s: Bound Device %s to Driver %s\n", | 131 | pr_debug("%s: Bound Device %s to Driver %s\n", |
108 | drv->bus->name, dev->bus_id, drv->name); | 132 | drv->bus->name, dev->bus_id, drv->name); |
109 | goto done; | 133 | goto done; |
110 | 134 | ||
111 | probe_failed: | 135 | probe_failed: |
136 | driver_sysfs_remove(dev); | ||
137 | dev->driver = NULL; | ||
138 | |||
112 | if (ret == -ENODEV || ret == -ENXIO) { | 139 | if (ret == -ENODEV || ret == -ENXIO) { |
113 | /* Driver matched, but didn't support device | 140 | /* Driver matched, but didn't support device |
114 | * or device not found. | 141 | * or device not found. |
@@ -284,10 +311,15 @@ static void __device_release_driver(struct device * dev) | |||
284 | drv = dev->driver; | 311 | drv = dev->driver; |
285 | if (drv) { | 312 | if (drv) { |
286 | get_driver(drv); | 313 | get_driver(drv); |
287 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); | 314 | driver_sysfs_remove(dev); |
288 | sysfs_remove_link(&dev->kobj, "driver"); | 315 | sysfs_remove_link(&dev->kobj, "driver"); |
289 | klist_remove(&dev->knode_driver); | 316 | klist_remove(&dev->knode_driver); |
290 | 317 | ||
318 | if (dev->bus) | ||
319 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | ||
320 | BUS_NOTIFY_UNBIND_DRIVER, | ||
321 | dev); | ||
322 | |||
291 | if (dev->bus && dev->bus->remove) | 323 | if (dev->bus && dev->bus->remove) |
292 | dev->bus->remove(dev); | 324 | dev->bus->remove(dev); |
293 | else if (drv->remove) | 325 | else if (drv->remove) |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 14615694ae9a..4bad2870c485 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include "base.h" | 22 | #include "base.h" |
23 | 23 | ||
24 | #define to_dev(obj) container_of(obj, struct device, kobj) | ||
25 | |||
24 | MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); | 26 | MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); |
25 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); | 27 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); |
26 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
@@ -86,12 +88,12 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count) | |||
86 | 88 | ||
87 | static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); | 89 | static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store); |
88 | 90 | ||
89 | static void fw_class_dev_release(struct class_device *class_dev); | 91 | static void fw_dev_release(struct device *dev); |
90 | 92 | ||
91 | static int firmware_class_uevent(struct class_device *class_dev, char **envp, | 93 | static int firmware_uevent(struct device *dev, char **envp, int num_envp, |
92 | int num_envp, char *buffer, int buffer_size) | 94 | char *buffer, int buffer_size) |
93 | { | 95 | { |
94 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 96 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
95 | int i = 0, len = 0; | 97 | int i = 0, len = 0; |
96 | 98 | ||
97 | if (!test_bit(FW_STATUS_READY, &fw_priv->status)) | 99 | if (!test_bit(FW_STATUS_READY, &fw_priv->status)) |
@@ -110,21 +112,21 @@ static int firmware_class_uevent(struct class_device *class_dev, char **envp, | |||
110 | 112 | ||
111 | static struct class firmware_class = { | 113 | static struct class firmware_class = { |
112 | .name = "firmware", | 114 | .name = "firmware", |
113 | .uevent = firmware_class_uevent, | 115 | .dev_uevent = firmware_uevent, |
114 | .release = fw_class_dev_release, | 116 | .dev_release = fw_dev_release, |
115 | }; | 117 | }; |
116 | 118 | ||
117 | static ssize_t | 119 | static ssize_t firmware_loading_show(struct device *dev, |
118 | firmware_loading_show(struct class_device *class_dev, char *buf) | 120 | struct device_attribute *attr, char *buf) |
119 | { | 121 | { |
120 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 122 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
121 | int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); | 123 | int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); |
122 | return sprintf(buf, "%d\n", loading); | 124 | return sprintf(buf, "%d\n", loading); |
123 | } | 125 | } |
124 | 126 | ||
125 | /** | 127 | /** |
126 | * firmware_loading_store - set value in the 'loading' control file | 128 | * firmware_loading_store - set value in the 'loading' control file |
127 | * @class_dev: class_device pointer | 129 | * @dev: device pointer |
128 | * @buf: buffer to scan for loading control value | 130 | * @buf: buffer to scan for loading control value |
129 | * @count: number of bytes in @buf | 131 | * @count: number of bytes in @buf |
130 | * | 132 | * |
@@ -134,11 +136,11 @@ firmware_loading_show(struct class_device *class_dev, char *buf) | |||
134 | * 0: Conclude the load and hand the data to the driver code. | 136 | * 0: Conclude the load and hand the data to the driver code. |
135 | * -1: Conclude the load with an error and discard any written data. | 137 | * -1: Conclude the load with an error and discard any written data. |
136 | **/ | 138 | **/ |
137 | static ssize_t | 139 | static ssize_t firmware_loading_store(struct device *dev, |
138 | firmware_loading_store(struct class_device *class_dev, | 140 | struct device_attribute *attr, |
139 | const char *buf, size_t count) | 141 | const char *buf, size_t count) |
140 | { | 142 | { |
141 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 143 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
142 | int loading = simple_strtol(buf, NULL, 10); | 144 | int loading = simple_strtol(buf, NULL, 10); |
143 | 145 | ||
144 | switch (loading) { | 146 | switch (loading) { |
@@ -174,15 +176,14 @@ firmware_loading_store(struct class_device *class_dev, | |||
174 | return count; | 176 | return count; |
175 | } | 177 | } |
176 | 178 | ||
177 | static CLASS_DEVICE_ATTR(loading, 0644, | 179 | static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); |
178 | firmware_loading_show, firmware_loading_store); | ||
179 | 180 | ||
180 | static ssize_t | 181 | static ssize_t |
181 | firmware_data_read(struct kobject *kobj, | 182 | firmware_data_read(struct kobject *kobj, |
182 | char *buffer, loff_t offset, size_t count) | 183 | char *buffer, loff_t offset, size_t count) |
183 | { | 184 | { |
184 | struct class_device *class_dev = to_class_dev(kobj); | 185 | struct device *dev = to_dev(kobj); |
185 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 186 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
186 | struct firmware *fw; | 187 | struct firmware *fw; |
187 | ssize_t ret_count = count; | 188 | ssize_t ret_count = count; |
188 | 189 | ||
@@ -234,7 +235,7 @@ fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) | |||
234 | 235 | ||
235 | /** | 236 | /** |
236 | * firmware_data_write - write method for firmware | 237 | * firmware_data_write - write method for firmware |
237 | * @kobj: kobject for the class_device | 238 | * @kobj: kobject for the device |
238 | * @buffer: buffer being written | 239 | * @buffer: buffer being written |
239 | * @offset: buffer offset for write in total data store area | 240 | * @offset: buffer offset for write in total data store area |
240 | * @count: buffer size | 241 | * @count: buffer size |
@@ -246,8 +247,8 @@ static ssize_t | |||
246 | firmware_data_write(struct kobject *kobj, | 247 | firmware_data_write(struct kobject *kobj, |
247 | char *buffer, loff_t offset, size_t count) | 248 | char *buffer, loff_t offset, size_t count) |
248 | { | 249 | { |
249 | struct class_device *class_dev = to_class_dev(kobj); | 250 | struct device *dev = to_dev(kobj); |
250 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 251 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
251 | struct firmware *fw; | 252 | struct firmware *fw; |
252 | ssize_t retval; | 253 | ssize_t retval; |
253 | 254 | ||
@@ -280,13 +281,12 @@ static struct bin_attribute firmware_attr_data_tmpl = { | |||
280 | .write = firmware_data_write, | 281 | .write = firmware_data_write, |
281 | }; | 282 | }; |
282 | 283 | ||
283 | static void | 284 | static void fw_dev_release(struct device *dev) |
284 | fw_class_dev_release(struct class_device *class_dev) | ||
285 | { | 285 | { |
286 | struct firmware_priv *fw_priv = class_get_devdata(class_dev); | 286 | struct firmware_priv *fw_priv = dev_get_drvdata(dev); |
287 | 287 | ||
288 | kfree(fw_priv); | 288 | kfree(fw_priv); |
289 | kfree(class_dev); | 289 | kfree(dev); |
290 | 290 | ||
291 | module_put(THIS_MODULE); | 291 | module_put(THIS_MODULE); |
292 | } | 292 | } |
@@ -298,26 +298,23 @@ firmware_class_timeout(u_long data) | |||
298 | fw_load_abort(fw_priv); | 298 | fw_load_abort(fw_priv); |
299 | } | 299 | } |
300 | 300 | ||
301 | static inline void | 301 | static inline void fw_setup_device_id(struct device *f_dev, struct device *dev) |
302 | fw_setup_class_device_id(struct class_device *class_dev, struct device *dev) | ||
303 | { | 302 | { |
304 | /* XXX warning we should watch out for name collisions */ | 303 | /* XXX warning we should watch out for name collisions */ |
305 | strlcpy(class_dev->class_id, dev->bus_id, BUS_ID_SIZE); | 304 | strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE); |
306 | } | 305 | } |
307 | 306 | ||
308 | static int | 307 | static int fw_register_device(struct device **dev_p, const char *fw_name, |
309 | fw_register_class_device(struct class_device **class_dev_p, | 308 | struct device *device) |
310 | const char *fw_name, struct device *device) | ||
311 | { | 309 | { |
312 | int retval; | 310 | int retval; |
313 | struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv), | 311 | struct firmware_priv *fw_priv = kzalloc(sizeof(*fw_priv), |
314 | GFP_KERNEL); | 312 | GFP_KERNEL); |
315 | struct class_device *class_dev = kzalloc(sizeof(*class_dev), | 313 | struct device *f_dev = kzalloc(sizeof(*f_dev), GFP_KERNEL); |
316 | GFP_KERNEL); | ||
317 | 314 | ||
318 | *class_dev_p = NULL; | 315 | *dev_p = NULL; |
319 | 316 | ||
320 | if (!fw_priv || !class_dev) { | 317 | if (!fw_priv || !f_dev) { |
321 | printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); | 318 | printk(KERN_ERR "%s: kmalloc failed\n", __FUNCTION__); |
322 | retval = -ENOMEM; | 319 | retval = -ENOMEM; |
323 | goto error_kfree; | 320 | goto error_kfree; |
@@ -331,55 +328,54 @@ fw_register_class_device(struct class_device **class_dev_p, | |||
331 | fw_priv->timeout.data = (u_long) fw_priv; | 328 | fw_priv->timeout.data = (u_long) fw_priv; |
332 | init_timer(&fw_priv->timeout); | 329 | init_timer(&fw_priv->timeout); |
333 | 330 | ||
334 | fw_setup_class_device_id(class_dev, device); | 331 | fw_setup_device_id(f_dev, device); |
335 | class_dev->dev = device; | 332 | f_dev->parent = device; |
336 | class_dev->class = &firmware_class; | 333 | f_dev->class = &firmware_class; |
337 | class_set_devdata(class_dev, fw_priv); | 334 | dev_set_drvdata(f_dev, fw_priv); |
338 | retval = class_device_register(class_dev); | 335 | retval = device_register(f_dev); |
339 | if (retval) { | 336 | if (retval) { |
340 | printk(KERN_ERR "%s: class_device_register failed\n", | 337 | printk(KERN_ERR "%s: device_register failed\n", |
341 | __FUNCTION__); | 338 | __FUNCTION__); |
342 | goto error_kfree; | 339 | goto error_kfree; |
343 | } | 340 | } |
344 | *class_dev_p = class_dev; | 341 | *dev_p = f_dev; |
345 | return 0; | 342 | return 0; |
346 | 343 | ||
347 | error_kfree: | 344 | error_kfree: |
348 | kfree(fw_priv); | 345 | kfree(fw_priv); |
349 | kfree(class_dev); | 346 | kfree(f_dev); |
350 | return retval; | 347 | return retval; |
351 | } | 348 | } |
352 | 349 | ||
353 | static int | 350 | static int fw_setup_device(struct firmware *fw, struct device **dev_p, |
354 | fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, | 351 | const char *fw_name, struct device *device, |
355 | const char *fw_name, struct device *device, int uevent) | 352 | int uevent) |
356 | { | 353 | { |
357 | struct class_device *class_dev; | 354 | struct device *f_dev; |
358 | struct firmware_priv *fw_priv; | 355 | struct firmware_priv *fw_priv; |
359 | int retval; | 356 | int retval; |
360 | 357 | ||
361 | *class_dev_p = NULL; | 358 | *dev_p = NULL; |
362 | retval = fw_register_class_device(&class_dev, fw_name, device); | 359 | retval = fw_register_device(&f_dev, fw_name, device); |
363 | if (retval) | 360 | if (retval) |
364 | goto out; | 361 | goto out; |
365 | 362 | ||
366 | /* Need to pin this module until class device is destroyed */ | 363 | /* Need to pin this module until class device is destroyed */ |
367 | __module_get(THIS_MODULE); | 364 | __module_get(THIS_MODULE); |
368 | 365 | ||
369 | fw_priv = class_get_devdata(class_dev); | 366 | fw_priv = dev_get_drvdata(f_dev); |
370 | 367 | ||
371 | fw_priv->fw = fw; | 368 | fw_priv->fw = fw; |
372 | retval = sysfs_create_bin_file(&class_dev->kobj, &fw_priv->attr_data); | 369 | retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data); |
373 | if (retval) { | 370 | if (retval) { |
374 | printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", | 371 | printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", |
375 | __FUNCTION__); | 372 | __FUNCTION__); |
376 | goto error_unreg; | 373 | goto error_unreg; |
377 | } | 374 | } |
378 | 375 | ||
379 | retval = class_device_create_file(class_dev, | 376 | retval = device_create_file(f_dev, &dev_attr_loading); |
380 | &class_device_attr_loading); | ||
381 | if (retval) { | 377 | if (retval) { |
382 | printk(KERN_ERR "%s: class_device_create_file failed\n", | 378 | printk(KERN_ERR "%s: device_create_file failed\n", |
383 | __FUNCTION__); | 379 | __FUNCTION__); |
384 | goto error_unreg; | 380 | goto error_unreg; |
385 | } | 381 | } |
@@ -388,11 +384,11 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, | |||
388 | set_bit(FW_STATUS_READY, &fw_priv->status); | 384 | set_bit(FW_STATUS_READY, &fw_priv->status); |
389 | else | 385 | else |
390 | set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); | 386 | set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); |
391 | *class_dev_p = class_dev; | 387 | *dev_p = f_dev; |
392 | goto out; | 388 | goto out; |
393 | 389 | ||
394 | error_unreg: | 390 | error_unreg: |
395 | class_device_unregister(class_dev); | 391 | device_unregister(f_dev); |
396 | out: | 392 | out: |
397 | return retval; | 393 | return retval; |
398 | } | 394 | } |
@@ -401,7 +397,7 @@ static int | |||
401 | _request_firmware(const struct firmware **firmware_p, const char *name, | 397 | _request_firmware(const struct firmware **firmware_p, const char *name, |
402 | struct device *device, int uevent) | 398 | struct device *device, int uevent) |
403 | { | 399 | { |
404 | struct class_device *class_dev; | 400 | struct device *f_dev; |
405 | struct firmware_priv *fw_priv; | 401 | struct firmware_priv *fw_priv; |
406 | struct firmware *firmware; | 402 | struct firmware *firmware; |
407 | int retval; | 403 | int retval; |
@@ -417,12 +413,11 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
417 | goto out; | 413 | goto out; |
418 | } | 414 | } |
419 | 415 | ||
420 | retval = fw_setup_class_device(firmware, &class_dev, name, device, | 416 | retval = fw_setup_device(firmware, &f_dev, name, device, uevent); |
421 | uevent); | ||
422 | if (retval) | 417 | if (retval) |
423 | goto error_kfree_fw; | 418 | goto error_kfree_fw; |
424 | 419 | ||
425 | fw_priv = class_get_devdata(class_dev); | 420 | fw_priv = dev_get_drvdata(f_dev); |
426 | 421 | ||
427 | if (uevent) { | 422 | if (uevent) { |
428 | if (loading_timeout > 0) { | 423 | if (loading_timeout > 0) { |
@@ -430,7 +425,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
430 | add_timer(&fw_priv->timeout); | 425 | add_timer(&fw_priv->timeout); |
431 | } | 426 | } |
432 | 427 | ||
433 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 428 | kobject_uevent(&f_dev->kobj, KOBJ_ADD); |
434 | wait_for_completion(&fw_priv->completion); | 429 | wait_for_completion(&fw_priv->completion); |
435 | set_bit(FW_STATUS_DONE, &fw_priv->status); | 430 | set_bit(FW_STATUS_DONE, &fw_priv->status); |
436 | del_timer_sync(&fw_priv->timeout); | 431 | del_timer_sync(&fw_priv->timeout); |
@@ -445,7 +440,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, | |||
445 | } | 440 | } |
446 | fw_priv->fw = NULL; | 441 | fw_priv->fw = NULL; |
447 | mutex_unlock(&fw_lock); | 442 | mutex_unlock(&fw_lock); |
448 | class_device_unregister(class_dev); | 443 | device_unregister(f_dev); |
449 | goto out; | 444 | goto out; |
450 | 445 | ||
451 | error_kfree_fw: | 446 | error_kfree_fw: |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 940ce41f1887..d1df4a087924 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -388,6 +388,11 @@ static int platform_drv_probe(struct device *_dev) | |||
388 | return drv->probe(dev); | 388 | return drv->probe(dev); |
389 | } | 389 | } |
390 | 390 | ||
391 | static int platform_drv_probe_fail(struct device *_dev) | ||
392 | { | ||
393 | return -ENXIO; | ||
394 | } | ||
395 | |||
391 | static int platform_drv_remove(struct device *_dev) | 396 | static int platform_drv_remove(struct device *_dev) |
392 | { | 397 | { |
393 | struct platform_driver *drv = to_platform_driver(_dev->driver); | 398 | struct platform_driver *drv = to_platform_driver(_dev->driver); |
@@ -451,6 +456,49 @@ void platform_driver_unregister(struct platform_driver *drv) | |||
451 | } | 456 | } |
452 | EXPORT_SYMBOL_GPL(platform_driver_unregister); | 457 | EXPORT_SYMBOL_GPL(platform_driver_unregister); |
453 | 458 | ||
459 | /** | ||
460 | * platform_driver_probe - register driver for non-hotpluggable device | ||
461 | * @drv: platform driver structure | ||
462 | * @probe: the driver probe routine, probably from an __init section | ||
463 | * | ||
464 | * Use this instead of platform_driver_register() when you know the device | ||
465 | * is not hotpluggable and has already been registered, and you want to | ||
466 | * remove its run-once probe() infrastructure from memory after the driver | ||
467 | * has bound to the device. | ||
468 | * | ||
469 | * One typical use for this would be with drivers for controllers integrated | ||
470 | * into system-on-chip processors, where the controller devices have been | ||
471 | * configured as part of board setup. | ||
472 | * | ||
473 | * Returns zero if the driver registered and bound to a device, else returns | ||
474 | * a negative error code and with the driver not registered. | ||
475 | */ | ||
476 | int platform_driver_probe(struct platform_driver *drv, | ||
477 | int (*probe)(struct platform_device *)) | ||
478 | { | ||
479 | int retval, code; | ||
480 | |||
481 | /* temporary section violation during probe() */ | ||
482 | drv->probe = probe; | ||
483 | retval = code = platform_driver_register(drv); | ||
484 | |||
485 | /* Fixup that section violation, being paranoid about code scanning | ||
486 | * the list of drivers in order to probe new devices. Check to see | ||
487 | * if the probe was successful, and make sure any forced probes of | ||
488 | * new devices fail. | ||
489 | */ | ||
490 | spin_lock(&platform_bus_type.klist_drivers.k_lock); | ||
491 | drv->probe = NULL; | ||
492 | if (code == 0 && list_empty(&drv->driver.klist_devices.k_list)) | ||
493 | retval = -ENODEV; | ||
494 | drv->driver.probe = platform_drv_probe_fail; | ||
495 | spin_unlock(&platform_bus_type.klist_drivers.k_lock); | ||
496 | |||
497 | if (code != retval) | ||
498 | platform_driver_unregister(drv); | ||
499 | return retval; | ||
500 | } | ||
501 | EXPORT_SYMBOL_GPL(platform_driver_probe); | ||
454 | 502 | ||
455 | /* modalias support enables more hands-off userspace setup: | 503 | /* modalias support enables more hands-off userspace setup: |
456 | * (a) environment variable lets new-style hotplug events work once system is | 504 | * (a) environment variable lets new-style hotplug events work once system is |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 28dccb730af9..3d12b85b0962 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -94,54 +94,63 @@ static struct attribute_group topology_attr_group = { | |||
94 | .name = "topology" | 94 | .name = "topology" |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static cpumask_t topology_dev_map = CPU_MASK_NONE; | ||
98 | |||
97 | /* Add/Remove cpu_topology interface for CPU device */ | 99 | /* Add/Remove cpu_topology interface for CPU device */ |
98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) | 100 | static int __cpuinit topology_add_dev(unsigned int cpu) |
99 | { | 101 | { |
100 | return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | 102 | int rc; |
103 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); | ||
104 | |||
105 | rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | ||
106 | if (!rc) | ||
107 | cpu_set(cpu, topology_dev_map); | ||
108 | return rc; | ||
101 | } | 109 | } |
102 | 110 | ||
103 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | 111 | #ifdef CONFIG_HOTPLUG_CPU |
112 | static void __cpuinit topology_remove_dev(unsigned int cpu) | ||
104 | { | 113 | { |
114 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); | ||
115 | |||
116 | if (!cpu_isset(cpu, topology_dev_map)) | ||
117 | return; | ||
118 | cpu_clear(cpu, topology_dev_map); | ||
105 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); | 119 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); |
106 | return 0; | ||
107 | } | 120 | } |
108 | 121 | ||
109 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | 122 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, |
110 | unsigned long action, void *hcpu) | 123 | unsigned long action, void *hcpu) |
111 | { | 124 | { |
112 | unsigned int cpu = (unsigned long)hcpu; | 125 | unsigned int cpu = (unsigned long)hcpu; |
113 | struct sys_device *sys_dev; | 126 | int rc = 0; |
114 | 127 | ||
115 | sys_dev = get_cpu_sysdev(cpu); | ||
116 | switch (action) { | 128 | switch (action) { |
117 | case CPU_ONLINE: | 129 | case CPU_UP_PREPARE: |
118 | topology_add_dev(sys_dev); | 130 | rc = topology_add_dev(cpu); |
119 | break; | 131 | break; |
132 | case CPU_UP_CANCELED: | ||
120 | case CPU_DEAD: | 133 | case CPU_DEAD: |
121 | topology_remove_dev(sys_dev); | 134 | topology_remove_dev(cpu); |
122 | break; | 135 | break; |
123 | } | 136 | } |
124 | return NOTIFY_OK; | 137 | return rc ? NOTIFY_BAD : NOTIFY_OK; |
125 | } | 138 | } |
126 | 139 | #endif | |
127 | static struct notifier_block __cpuinitdata topology_cpu_notifier = | ||
128 | { | ||
129 | .notifier_call = topology_cpu_callback, | ||
130 | }; | ||
131 | 140 | ||
132 | static int __cpuinit topology_sysfs_init(void) | 141 | static int __cpuinit topology_sysfs_init(void) |
133 | { | 142 | { |
134 | int i; | 143 | int cpu; |
144 | int rc; | ||
135 | 145 | ||
136 | for_each_online_cpu(i) { | 146 | for_each_online_cpu(cpu) { |
137 | topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE, | 147 | rc = topology_add_dev(cpu); |
138 | (void *)(long)i); | 148 | if (rc) |
149 | return rc; | ||
139 | } | 150 | } |
140 | 151 | hotcpu_notifier(topology_cpu_callback, 0); | |
141 | register_hotcpu_notifier(&topology_cpu_notifier); | ||
142 | 152 | ||
143 | return 0; | 153 | return 0; |
144 | } | 154 | } |
145 | 155 | ||
146 | device_initcall(topology_sysfs_init); | 156 | device_initcall(topology_sysfs_init); |
147 | |||
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 154a81d328c1..ebace201bec6 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
@@ -162,7 +162,8 @@ static struct miscdevice rng_miscdev = { | |||
162 | }; | 162 | }; |
163 | 163 | ||
164 | 164 | ||
165 | static ssize_t hwrng_attr_current_store(struct class_device *class, | 165 | static ssize_t hwrng_attr_current_store(struct device *dev, |
166 | struct device_attribute *attr, | ||
166 | const char *buf, size_t len) | 167 | const char *buf, size_t len) |
167 | { | 168 | { |
168 | int err; | 169 | int err; |
@@ -192,7 +193,8 @@ static ssize_t hwrng_attr_current_store(struct class_device *class, | |||
192 | return err ? : len; | 193 | return err ? : len; |
193 | } | 194 | } |
194 | 195 | ||
195 | static ssize_t hwrng_attr_current_show(struct class_device *class, | 196 | static ssize_t hwrng_attr_current_show(struct device *dev, |
197 | struct device_attribute *attr, | ||
196 | char *buf) | 198 | char *buf) |
197 | { | 199 | { |
198 | int err; | 200 | int err; |
@@ -210,7 +212,8 @@ static ssize_t hwrng_attr_current_show(struct class_device *class, | |||
210 | return ret; | 212 | return ret; |
211 | } | 213 | } |
212 | 214 | ||
213 | static ssize_t hwrng_attr_available_show(struct class_device *class, | 215 | static ssize_t hwrng_attr_available_show(struct device *dev, |
216 | struct device_attribute *attr, | ||
214 | char *buf) | 217 | char *buf) |
215 | { | 218 | { |
216 | int err; | 219 | int err; |
@@ -234,20 +237,18 @@ static ssize_t hwrng_attr_available_show(struct class_device *class, | |||
234 | return ret; | 237 | return ret; |
235 | } | 238 | } |
236 | 239 | ||
237 | static CLASS_DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR, | 240 | static DEVICE_ATTR(rng_current, S_IRUGO | S_IWUSR, |
238 | hwrng_attr_current_show, | 241 | hwrng_attr_current_show, |
239 | hwrng_attr_current_store); | 242 | hwrng_attr_current_store); |
240 | static CLASS_DEVICE_ATTR(rng_available, S_IRUGO, | 243 | static DEVICE_ATTR(rng_available, S_IRUGO, |
241 | hwrng_attr_available_show, | 244 | hwrng_attr_available_show, |
242 | NULL); | 245 | NULL); |
243 | 246 | ||
244 | 247 | ||
245 | static void unregister_miscdev(void) | 248 | static void unregister_miscdev(void) |
246 | { | 249 | { |
247 | class_device_remove_file(rng_miscdev.class, | 250 | device_remove_file(rng_miscdev.this_device, &dev_attr_rng_available); |
248 | &class_device_attr_rng_available); | 251 | device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current); |
249 | class_device_remove_file(rng_miscdev.class, | ||
250 | &class_device_attr_rng_current); | ||
251 | misc_deregister(&rng_miscdev); | 252 | misc_deregister(&rng_miscdev); |
252 | } | 253 | } |
253 | 254 | ||
@@ -258,20 +259,19 @@ static int register_miscdev(void) | |||
258 | err = misc_register(&rng_miscdev); | 259 | err = misc_register(&rng_miscdev); |
259 | if (err) | 260 | if (err) |
260 | goto out; | 261 | goto out; |
261 | err = class_device_create_file(rng_miscdev.class, | 262 | err = device_create_file(rng_miscdev.this_device, |
262 | &class_device_attr_rng_current); | 263 | &dev_attr_rng_current); |
263 | if (err) | 264 | if (err) |
264 | goto err_misc_dereg; | 265 | goto err_misc_dereg; |
265 | err = class_device_create_file(rng_miscdev.class, | 266 | err = device_create_file(rng_miscdev.this_device, |
266 | &class_device_attr_rng_available); | 267 | &dev_attr_rng_available); |
267 | if (err) | 268 | if (err) |
268 | goto err_remove_current; | 269 | goto err_remove_current; |
269 | out: | 270 | out: |
270 | return err; | 271 | return err; |
271 | 272 | ||
272 | err_remove_current: | 273 | err_remove_current: |
273 | class_device_remove_file(rng_miscdev.class, | 274 | device_remove_file(rng_miscdev.this_device, &dev_attr_rng_current); |
274 | &class_device_attr_rng_current); | ||
275 | err_misc_dereg: | 275 | err_misc_dereg: |
276 | misc_deregister(&rng_miscdev); | 276 | misc_deregister(&rng_miscdev); |
277 | goto out; | 277 | goto out; |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 55473371b7c6..e67eef4867ba 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -980,10 +980,10 @@ static int __init chr_dev_init(void) | |||
980 | 980 | ||
981 | mem_class = class_create(THIS_MODULE, "mem"); | 981 | mem_class = class_create(THIS_MODULE, "mem"); |
982 | for (i = 0; i < ARRAY_SIZE(devlist); i++) | 982 | for (i = 0; i < ARRAY_SIZE(devlist); i++) |
983 | class_device_create(mem_class, NULL, | 983 | device_create(mem_class, NULL, |
984 | MKDEV(MEM_MAJOR, devlist[i].minor), | 984 | MKDEV(MEM_MAJOR, devlist[i].minor), |
985 | NULL, devlist[i].name); | 985 | devlist[i].name); |
986 | 986 | ||
987 | return 0; | 987 | return 0; |
988 | } | 988 | } |
989 | 989 | ||
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 62ebe09656e3..7a484fc7cb9e 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -169,11 +169,6 @@ fail: | |||
169 | return err; | 169 | return err; |
170 | } | 170 | } |
171 | 171 | ||
172 | /* | ||
173 | * TODO for 2.7: | ||
174 | * - add a struct kref to struct miscdevice and make all usages of | ||
175 | * them dynamic. | ||
176 | */ | ||
177 | static struct class *misc_class; | 172 | static struct class *misc_class; |
178 | 173 | ||
179 | static const struct file_operations misc_fops = { | 174 | static const struct file_operations misc_fops = { |
@@ -228,10 +223,10 @@ int misc_register(struct miscdevice * misc) | |||
228 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); | 223 | misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7); |
229 | dev = MKDEV(MISC_MAJOR, misc->minor); | 224 | dev = MKDEV(MISC_MAJOR, misc->minor); |
230 | 225 | ||
231 | misc->class = class_device_create(misc_class, NULL, dev, misc->dev, | 226 | misc->this_device = device_create(misc_class, misc->parent, dev, |
232 | "%s", misc->name); | 227 | "%s", misc->name); |
233 | if (IS_ERR(misc->class)) { | 228 | if (IS_ERR(misc->this_device)) { |
234 | err = PTR_ERR(misc->class); | 229 | err = PTR_ERR(misc->this_device); |
235 | goto out; | 230 | goto out; |
236 | } | 231 | } |
237 | 232 | ||
@@ -264,7 +259,7 @@ int misc_deregister(struct miscdevice * misc) | |||
264 | 259 | ||
265 | down(&misc_sem); | 260 | down(&misc_sem); |
266 | list_del(&misc->list); | 261 | list_del(&misc->list); |
267 | class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 262 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
268 | if (i < DYNAMIC_MINORS && i>0) { | 263 | if (i < DYNAMIC_MINORS && i>0) { |
269 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); | 264 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); |
270 | } | 265 | } |
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index efc485edad1c..c1e3dd837fc8 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -752,13 +752,13 @@ static const struct file_operations pp_fops = { | |||
752 | 752 | ||
753 | static void pp_attach(struct parport *port) | 753 | static void pp_attach(struct parport *port) |
754 | { | 754 | { |
755 | class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), | 755 | device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), |
756 | NULL, "parport%d", port->number); | 756 | "parport%d", port->number); |
757 | } | 757 | } |
758 | 758 | ||
759 | static void pp_detach(struct parport *port) | 759 | static void pp_detach(struct parport *port) |
760 | { | 760 | { |
761 | class_device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); | 761 | device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); |
762 | } | 762 | } |
763 | 763 | ||
764 | static struct parport_driver pp_driver = { | 764 | static struct parport_driver pp_driver = { |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 89b718e326e5..3b32313f6eb4 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -127,9 +127,9 @@ raw_ioctl(struct inode *inode, struct file *filp, | |||
127 | 127 | ||
128 | static void bind_device(struct raw_config_request *rq) | 128 | static void bind_device(struct raw_config_request *rq) |
129 | { | 129 | { |
130 | class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); | 130 | device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); |
131 | class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), | 131 | device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), |
132 | NULL, "raw%d", rq->raw_minor); | 132 | "raw%d", rq->raw_minor); |
133 | } | 133 | } |
134 | 134 | ||
135 | /* | 135 | /* |
@@ -200,7 +200,7 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, | |||
200 | if (rq.block_major == 0 && rq.block_minor == 0) { | 200 | if (rq.block_major == 0 && rq.block_minor == 0) { |
201 | /* unbind */ | 201 | /* unbind */ |
202 | rawdev->binding = NULL; | 202 | rawdev->binding = NULL; |
203 | class_device_destroy(raw_class, | 203 | device_destroy(raw_class, |
204 | MKDEV(RAW_MAJOR, rq.raw_minor)); | 204 | MKDEV(RAW_MAJOR, rq.raw_minor)); |
205 | } else { | 205 | } else { |
206 | rawdev->binding = bdget(dev); | 206 | rawdev->binding = bdget(dev); |
@@ -283,7 +283,7 @@ static int __init raw_init(void) | |||
283 | ret = PTR_ERR(raw_class); | 283 | ret = PTR_ERR(raw_class); |
284 | goto error_region; | 284 | goto error_region; |
285 | } | 285 | } |
286 | class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); | 286 | device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), "rawctl"); |
287 | 287 | ||
288 | return 0; | 288 | return 0; |
289 | 289 | ||
@@ -295,7 +295,7 @@ error: | |||
295 | 295 | ||
296 | static void __exit raw_exit(void) | 296 | static void __exit raw_exit(void) |
297 | { | 297 | { |
298 | class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); | 298 | device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); |
299 | class_destroy(raw_class); | 299 | class_destroy(raw_class); |
300 | cdev_del(&raw_cdev); | 300 | cdev_del(&raw_cdev); |
301 | unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); | 301 | unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 6ad2d3bb945c..6e1329d404d2 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -1130,7 +1130,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1130 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 1130 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); |
1131 | chip->vendor.miscdev.name = devname; | 1131 | chip->vendor.miscdev.name = devname; |
1132 | 1132 | ||
1133 | chip->vendor.miscdev.dev = dev; | 1133 | chip->vendor.miscdev.parent = dev; |
1134 | chip->dev = get_device(dev); | 1134 | chip->dev = get_device(dev); |
1135 | 1135 | ||
1136 | if (misc_register(&chip->vendor.miscdev)) { | 1136 | if (misc_register(&chip->vendor.miscdev)) { |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e90ea39c7c4b..50dc49205a23 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -3612,7 +3612,8 @@ static struct class *tty_class; | |||
3612 | * This field is optional, if there is no known struct device | 3612 | * This field is optional, if there is no known struct device |
3613 | * for this tty device it can be set to NULL safely. | 3613 | * for this tty device it can be set to NULL safely. |
3614 | * | 3614 | * |
3615 | * Returns a pointer to the class device (or ERR_PTR(-EFOO) on error). | 3615 | * Returns a pointer to the struct device for this tty device |
3616 | * (or ERR_PTR(-EFOO) on error). | ||
3616 | * | 3617 | * |
3617 | * This call is required to be made to register an individual tty device | 3618 | * This call is required to be made to register an individual tty device |
3618 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | 3619 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If |
@@ -3622,8 +3623,8 @@ static struct class *tty_class; | |||
3622 | * Locking: ?? | 3623 | * Locking: ?? |
3623 | */ | 3624 | */ |
3624 | 3625 | ||
3625 | struct class_device *tty_register_device(struct tty_driver *driver, | 3626 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, |
3626 | unsigned index, struct device *device) | 3627 | struct device *device) |
3627 | { | 3628 | { |
3628 | char name[64]; | 3629 | char name[64]; |
3629 | dev_t dev = MKDEV(driver->major, driver->minor_start) + index; | 3630 | dev_t dev = MKDEV(driver->major, driver->minor_start) + index; |
@@ -3639,7 +3640,7 @@ struct class_device *tty_register_device(struct tty_driver *driver, | |||
3639 | else | 3640 | else |
3640 | tty_line_name(driver, index, name); | 3641 | tty_line_name(driver, index, name); |
3641 | 3642 | ||
3642 | return class_device_create(tty_class, NULL, dev, device, "%s", name); | 3643 | return device_create(tty_class, device, dev, name); |
3643 | } | 3644 | } |
3644 | 3645 | ||
3645 | /** | 3646 | /** |
@@ -3655,7 +3656,7 @@ struct class_device *tty_register_device(struct tty_driver *driver, | |||
3655 | 3656 | ||
3656 | void tty_unregister_device(struct tty_driver *driver, unsigned index) | 3657 | void tty_unregister_device(struct tty_driver *driver, unsigned index) |
3657 | { | 3658 | { |
3658 | class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); | 3659 | device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); |
3659 | } | 3660 | } |
3660 | 3661 | ||
3661 | EXPORT_SYMBOL(tty_register_device); | 3662 | EXPORT_SYMBOL(tty_register_device); |
@@ -3895,20 +3896,20 @@ static int __init tty_init(void) | |||
3895 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | 3896 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || |
3896 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | 3897 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) |
3897 | panic("Couldn't register /dev/tty driver\n"); | 3898 | panic("Couldn't register /dev/tty driver\n"); |
3898 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); | 3899 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), "tty"); |
3899 | 3900 | ||
3900 | cdev_init(&console_cdev, &console_fops); | 3901 | cdev_init(&console_cdev, &console_fops); |
3901 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || | 3902 | if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || |
3902 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) | 3903 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) |
3903 | panic("Couldn't register /dev/console driver\n"); | 3904 | panic("Couldn't register /dev/console driver\n"); |
3904 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); | 3905 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console"); |
3905 | 3906 | ||
3906 | #ifdef CONFIG_UNIX98_PTYS | 3907 | #ifdef CONFIG_UNIX98_PTYS |
3907 | cdev_init(&ptmx_cdev, &ptmx_fops); | 3908 | cdev_init(&ptmx_cdev, &ptmx_fops); |
3908 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || | 3909 | if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) || |
3909 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) | 3910 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) |
3910 | panic("Couldn't register /dev/ptmx driver\n"); | 3911 | panic("Couldn't register /dev/ptmx driver\n"); |
3911 | class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); | 3912 | device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), "ptmx"); |
3912 | #endif | 3913 | #endif |
3913 | 3914 | ||
3914 | #ifdef CONFIG_VT | 3915 | #ifdef CONFIG_VT |
@@ -3916,7 +3917,7 @@ static int __init tty_init(void) | |||
3916 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || | 3917 | if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || |
3917 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) | 3918 | register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) |
3918 | panic("Couldn't register /dev/tty0 driver\n"); | 3919 | panic("Couldn't register /dev/tty0 driver\n"); |
3919 | class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); | 3920 | device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), "tty0"); |
3920 | 3921 | ||
3921 | vty_init(); | 3922 | vty_init(); |
3922 | #endif | 3923 | #endif |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index bd7a98c6ea7a..f442b574b44a 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -476,16 +476,16 @@ static struct class *vc_class; | |||
476 | 476 | ||
477 | void vcs_make_sysfs(struct tty_struct *tty) | 477 | void vcs_make_sysfs(struct tty_struct *tty) |
478 | { | 478 | { |
479 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), | 479 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), |
480 | NULL, "vcs%u", tty->index + 1); | 480 | "vcs%u", tty->index + 1); |
481 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), | 481 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), |
482 | NULL, "vcsa%u", tty->index + 1); | 482 | "vcsa%u", tty->index + 1); |
483 | } | 483 | } |
484 | 484 | ||
485 | void vcs_remove_sysfs(struct tty_struct *tty) | 485 | void vcs_remove_sysfs(struct tty_struct *tty) |
486 | { | 486 | { |
487 | class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); | 487 | device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); |
488 | class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); | 488 | device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); |
489 | } | 489 | } |
490 | 490 | ||
491 | int __init vcs_init(void) | 491 | int __init vcs_init(void) |
@@ -494,7 +494,7 @@ int __init vcs_init(void) | |||
494 | panic("unable to get major %d for vcs device", VCS_MAJOR); | 494 | panic("unable to get major %d for vcs device", VCS_MAJOR); |
495 | vc_class = class_create(THIS_MODULE, "vc"); | 495 | vc_class = class_create(THIS_MODULE, "vc"); |
496 | 496 | ||
497 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); | 497 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), "vcs"); |
498 | class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); | 498 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), "vcsa"); |
499 | return 0; | 499 | return 0; |
500 | } | 500 | } |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 8e4413f6fbaf..87587b4385ab 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -112,7 +112,7 @@ | |||
112 | struct con_driver { | 112 | struct con_driver { |
113 | const struct consw *con; | 113 | const struct consw *con; |
114 | const char *desc; | 114 | const char *desc; |
115 | struct class_device *class_dev; | 115 | struct device *dev; |
116 | int node; | 116 | int node; |
117 | int first; | 117 | int first; |
118 | int last; | 118 | int last; |
@@ -3023,10 +3023,10 @@ static inline int vt_unbind(struct con_driver *con) | |||
3023 | } | 3023 | } |
3024 | #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ | 3024 | #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ |
3025 | 3025 | ||
3026 | static ssize_t store_bind(struct class_device *class_device, | 3026 | static ssize_t store_bind(struct device *dev, struct device_attribute *attr, |
3027 | const char *buf, size_t count) | 3027 | const char *buf, size_t count) |
3028 | { | 3028 | { |
3029 | struct con_driver *con = class_get_devdata(class_device); | 3029 | struct con_driver *con = dev_get_drvdata(dev); |
3030 | int bind = simple_strtoul(buf, NULL, 0); | 3030 | int bind = simple_strtoul(buf, NULL, 0); |
3031 | 3031 | ||
3032 | if (bind) | 3032 | if (bind) |
@@ -3037,17 +3037,19 @@ static ssize_t store_bind(struct class_device *class_device, | |||
3037 | return count; | 3037 | return count; |
3038 | } | 3038 | } |
3039 | 3039 | ||
3040 | static ssize_t show_bind(struct class_device *class_device, char *buf) | 3040 | static ssize_t show_bind(struct device *dev, struct device_attribute *attr, |
3041 | char *buf) | ||
3041 | { | 3042 | { |
3042 | struct con_driver *con = class_get_devdata(class_device); | 3043 | struct con_driver *con = dev_get_drvdata(dev); |
3043 | int bind = con_is_bound(con->con); | 3044 | int bind = con_is_bound(con->con); |
3044 | 3045 | ||
3045 | return snprintf(buf, PAGE_SIZE, "%i\n", bind); | 3046 | return snprintf(buf, PAGE_SIZE, "%i\n", bind); |
3046 | } | 3047 | } |
3047 | 3048 | ||
3048 | static ssize_t show_name(struct class_device *class_device, char *buf) | 3049 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, |
3050 | char *buf) | ||
3049 | { | 3051 | { |
3050 | struct con_driver *con = class_get_devdata(class_device); | 3052 | struct con_driver *con = dev_get_drvdata(dev); |
3051 | 3053 | ||
3052 | return snprintf(buf, PAGE_SIZE, "%s %s\n", | 3054 | return snprintf(buf, PAGE_SIZE, "%s %s\n", |
3053 | (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)", | 3055 | (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)", |
@@ -3055,43 +3057,40 @@ static ssize_t show_name(struct class_device *class_device, char *buf) | |||
3055 | 3057 | ||
3056 | } | 3058 | } |
3057 | 3059 | ||
3058 | static struct class_device_attribute class_device_attrs[] = { | 3060 | static struct device_attribute device_attrs[] = { |
3059 | __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind), | 3061 | __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind), |
3060 | __ATTR(name, S_IRUGO, show_name, NULL), | 3062 | __ATTR(name, S_IRUGO, show_name, NULL), |
3061 | }; | 3063 | }; |
3062 | 3064 | ||
3063 | static int vtconsole_init_class_device(struct con_driver *con) | 3065 | static int vtconsole_init_device(struct con_driver *con) |
3064 | { | 3066 | { |
3065 | int i; | 3067 | int i; |
3066 | int error = 0; | 3068 | int error = 0; |
3067 | 3069 | ||
3068 | con->flag |= CON_DRIVER_FLAG_ATTR; | 3070 | con->flag |= CON_DRIVER_FLAG_ATTR; |
3069 | class_set_devdata(con->class_dev, con); | 3071 | dev_set_drvdata(con->dev, con); |
3070 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { | 3072 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { |
3071 | error = class_device_create_file(con->class_dev, | 3073 | error = device_create_file(con->dev, &device_attrs[i]); |
3072 | &class_device_attrs[i]); | ||
3073 | if (error) | 3074 | if (error) |
3074 | break; | 3075 | break; |
3075 | } | 3076 | } |
3076 | 3077 | ||
3077 | if (error) { | 3078 | if (error) { |
3078 | while (--i >= 0) | 3079 | while (--i >= 0) |
3079 | class_device_remove_file(con->class_dev, | 3080 | device_remove_file(con->dev, &device_attrs[i]); |
3080 | &class_device_attrs[i]); | ||
3081 | con->flag &= ~CON_DRIVER_FLAG_ATTR; | 3081 | con->flag &= ~CON_DRIVER_FLAG_ATTR; |
3082 | } | 3082 | } |
3083 | 3083 | ||
3084 | return error; | 3084 | return error; |
3085 | } | 3085 | } |
3086 | 3086 | ||
3087 | static void vtconsole_deinit_class_device(struct con_driver *con) | 3087 | static void vtconsole_deinit_device(struct con_driver *con) |
3088 | { | 3088 | { |
3089 | int i; | 3089 | int i; |
3090 | 3090 | ||
3091 | if (con->flag & CON_DRIVER_FLAG_ATTR) { | 3091 | if (con->flag & CON_DRIVER_FLAG_ATTR) { |
3092 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 3092 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) |
3093 | class_device_remove_file(con->class_dev, | 3093 | device_remove_file(con->dev, &device_attrs[i]); |
3094 | &class_device_attrs[i]); | ||
3095 | con->flag &= ~CON_DRIVER_FLAG_ATTR; | 3094 | con->flag &= ~CON_DRIVER_FLAG_ATTR; |
3096 | } | 3095 | } |
3097 | } | 3096 | } |
@@ -3179,18 +3178,17 @@ int register_con_driver(const struct consw *csw, int first, int last) | |||
3179 | if (retval) | 3178 | if (retval) |
3180 | goto err; | 3179 | goto err; |
3181 | 3180 | ||
3182 | con_driver->class_dev = class_device_create(vtconsole_class, NULL, | 3181 | con_driver->dev = device_create(vtconsole_class, NULL, |
3183 | MKDEV(0, con_driver->node), | 3182 | MKDEV(0, con_driver->node), |
3184 | NULL, "vtcon%i", | 3183 | "vtcon%i", con_driver->node); |
3185 | con_driver->node); | ||
3186 | 3184 | ||
3187 | if (IS_ERR(con_driver->class_dev)) { | 3185 | if (IS_ERR(con_driver->dev)) { |
3188 | printk(KERN_WARNING "Unable to create class_device for %s; " | 3186 | printk(KERN_WARNING "Unable to create device for %s; " |
3189 | "errno = %ld\n", con_driver->desc, | 3187 | "errno = %ld\n", con_driver->desc, |
3190 | PTR_ERR(con_driver->class_dev)); | 3188 | PTR_ERR(con_driver->dev)); |
3191 | con_driver->class_dev = NULL; | 3189 | con_driver->dev = NULL; |
3192 | } else { | 3190 | } else { |
3193 | vtconsole_init_class_device(con_driver); | 3191 | vtconsole_init_device(con_driver); |
3194 | } | 3192 | } |
3195 | 3193 | ||
3196 | err: | 3194 | err: |
@@ -3226,12 +3224,12 @@ int unregister_con_driver(const struct consw *csw) | |||
3226 | 3224 | ||
3227 | if (con_driver->con == csw && | 3225 | if (con_driver->con == csw && |
3228 | con_driver->flag & CON_DRIVER_FLAG_MODULE) { | 3226 | con_driver->flag & CON_DRIVER_FLAG_MODULE) { |
3229 | vtconsole_deinit_class_device(con_driver); | 3227 | vtconsole_deinit_device(con_driver); |
3230 | class_device_destroy(vtconsole_class, | 3228 | device_destroy(vtconsole_class, |
3231 | MKDEV(0, con_driver->node)); | 3229 | MKDEV(0, con_driver->node)); |
3232 | con_driver->con = NULL; | 3230 | con_driver->con = NULL; |
3233 | con_driver->desc = NULL; | 3231 | con_driver->desc = NULL; |
3234 | con_driver->class_dev = NULL; | 3232 | con_driver->dev = NULL; |
3235 | con_driver->node = 0; | 3233 | con_driver->node = 0; |
3236 | con_driver->flag = 0; | 3234 | con_driver->flag = 0; |
3237 | con_driver->first = 0; | 3235 | con_driver->first = 0; |
@@ -3289,19 +3287,18 @@ static int __init vtconsole_class_init(void) | |||
3289 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { | 3287 | for (i = 0; i < MAX_NR_CON_DRIVER; i++) { |
3290 | struct con_driver *con = ®istered_con_driver[i]; | 3288 | struct con_driver *con = ®istered_con_driver[i]; |
3291 | 3289 | ||
3292 | if (con->con && !con->class_dev) { | 3290 | if (con->con && !con->dev) { |
3293 | con->class_dev = | 3291 | con->dev = device_create(vtconsole_class, NULL, |
3294 | class_device_create(vtconsole_class, NULL, | 3292 | MKDEV(0, con->node), |
3295 | MKDEV(0, con->node), NULL, | 3293 | "vtcon%i", con->node); |
3296 | "vtcon%i", con->node); | ||
3297 | 3294 | ||
3298 | if (IS_ERR(con->class_dev)) { | 3295 | if (IS_ERR(con->dev)) { |
3299 | printk(KERN_WARNING "Unable to create " | 3296 | printk(KERN_WARNING "Unable to create " |
3300 | "class_device for %s; errno = %ld\n", | 3297 | "device for %s; errno = %ld\n", |
3301 | con->desc, PTR_ERR(con->class_dev)); | 3298 | con->desc, PTR_ERR(con->dev)); |
3302 | con->class_dev = NULL; | 3299 | con->dev = NULL; |
3303 | } else { | 3300 | } else { |
3304 | vtconsole_init_class_device(con); | 3301 | vtconsole_init_device(con); |
3305 | } | 3302 | } |
3306 | } | 3303 | } |
3307 | } | 3304 | } |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 3f869033ed70..94a4e9a3013c 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -42,7 +42,7 @@ static struct i2c_driver i2cdev_driver; | |||
42 | struct i2c_dev { | 42 | struct i2c_dev { |
43 | struct list_head list; | 43 | struct list_head list; |
44 | struct i2c_adapter *adap; | 44 | struct i2c_adapter *adap; |
45 | struct class_device *class_dev; | 45 | struct device *dev; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | #define I2C_MINORS 256 | 48 | #define I2C_MINORS 256 |
@@ -92,15 +92,16 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) | |||
92 | spin_unlock(&i2c_dev_list_lock); | 92 | spin_unlock(&i2c_dev_list_lock); |
93 | } | 93 | } |
94 | 94 | ||
95 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) | 95 | static ssize_t show_adapter_name(struct device *dev, |
96 | struct device_attribute *attr, char *buf) | ||
96 | { | 97 | { |
97 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt)); | 98 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(dev->devt)); |
98 | 99 | ||
99 | if (!i2c_dev) | 100 | if (!i2c_dev) |
100 | return -ENODEV; | 101 | return -ENODEV; |
101 | return sprintf(buf, "%s\n", i2c_dev->adap->name); | 102 | return sprintf(buf, "%s\n", i2c_dev->adap->name); |
102 | } | 103 | } |
103 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 104 | static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
104 | 105 | ||
105 | static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, | 106 | static ssize_t i2cdev_read (struct file *file, char __user *buf, size_t count, |
106 | loff_t *offset) | 107 | loff_t *offset) |
@@ -413,15 +414,14 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
413 | return PTR_ERR(i2c_dev); | 414 | return PTR_ERR(i2c_dev); |
414 | 415 | ||
415 | /* register this i2c device with the driver core */ | 416 | /* register this i2c device with the driver core */ |
416 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, | 417 | i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, |
417 | MKDEV(I2C_MAJOR, adap->nr), | 418 | MKDEV(I2C_MAJOR, adap->nr), |
418 | &adap->dev, "i2c-%d", | 419 | "i2c-%d", adap->nr); |
419 | adap->nr); | 420 | if (!i2c_dev->dev) { |
420 | if (!i2c_dev->class_dev) { | ||
421 | res = -ENODEV; | 421 | res = -ENODEV; |
422 | goto error; | 422 | goto error; |
423 | } | 423 | } |
424 | res = class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); | 424 | res = device_create_file(i2c_dev->dev, &dev_attr_name); |
425 | if (res) | 425 | if (res) |
426 | goto error_destroy; | 426 | goto error_destroy; |
427 | 427 | ||
@@ -429,7 +429,7 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
429 | adap->name, adap->nr); | 429 | adap->name, adap->nr); |
430 | return 0; | 430 | return 0; |
431 | error_destroy: | 431 | error_destroy: |
432 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); | 432 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); |
433 | error: | 433 | error: |
434 | return_i2c_dev(i2c_dev); | 434 | return_i2c_dev(i2c_dev); |
435 | kfree(i2c_dev); | 435 | kfree(i2c_dev); |
@@ -444,9 +444,9 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
444 | if (!i2c_dev) /* attach_adapter must have failed */ | 444 | if (!i2c_dev) /* attach_adapter must have failed */ |
445 | return 0; | 445 | return 0; |
446 | 446 | ||
447 | class_device_remove_file(i2c_dev->class_dev, &class_device_attr_name); | 447 | device_remove_file(i2c_dev->dev, &dev_attr_name); |
448 | return_i2c_dev(i2c_dev); | 448 | return_i2c_dev(i2c_dev); |
449 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); | 449 | device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); |
450 | kfree(i2c_dev); | 450 | kfree(i2c_dev); |
451 | 451 | ||
452 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); | 452 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index ba2a2035d648..7c8d0399ae82 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -297,7 +297,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) | |||
297 | 297 | ||
298 | serio_raw->dev.minor = PSMOUSE_MINOR; | 298 | serio_raw->dev.minor = PSMOUSE_MINOR; |
299 | serio_raw->dev.name = serio_raw->name; | 299 | serio_raw->dev.name = serio_raw->name; |
300 | serio_raw->dev.dev = &serio->dev; | 300 | serio_raw->dev.parent = &serio->dev; |
301 | serio_raw->dev.fops = &serio_raw_fops; | 301 | serio_raw->dev.fops = &serio_raw_fops; |
302 | 302 | ||
303 | err = misc_register(&serio_raw->dev); | 303 | err = misc_register(&serio_raw->dev); |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 5800beeebb85..defd5743dba6 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -702,7 +702,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
702 | cs->open_count = 0; | 702 | cs->open_count = 0; |
703 | cs->dev = NULL; | 703 | cs->dev = NULL; |
704 | cs->tty = NULL; | 704 | cs->tty = NULL; |
705 | cs->class = NULL; | 705 | cs->tty_dev = NULL; |
706 | cs->cidmode = cidmode != 0; | 706 | cs->cidmode = cidmode != 0; |
707 | 707 | ||
708 | //if(onechannel) { //FIXME | 708 | //if(onechannel) { //FIXME |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 884bd72c1bf4..06298cc52bf5 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -444,7 +444,7 @@ struct cardstate { | |||
444 | struct gigaset_driver *driver; | 444 | struct gigaset_driver *driver; |
445 | unsigned minor_index; | 445 | unsigned minor_index; |
446 | struct device *dev; | 446 | struct device *dev; |
447 | struct class_device *class; | 447 | struct device *tty_dev; |
448 | 448 | ||
449 | const struct gigaset_ops *ops; | 449 | const struct gigaset_ops *ops; |
450 | 450 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 596f3aebe2f7..7edea015867e 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -625,13 +625,13 @@ void gigaset_if_init(struct cardstate *cs) | |||
625 | return; | 625 | return; |
626 | 626 | ||
627 | tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); | 627 | tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); |
628 | cs->class = tty_register_device(drv->tty, cs->minor_index, NULL); | 628 | cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL); |
629 | 629 | ||
630 | if (!IS_ERR(cs->class)) | 630 | if (!IS_ERR(cs->tty_dev)) |
631 | class_set_devdata(cs->class, cs); | 631 | dev_set_drvdata(cs->tty_dev, cs); |
632 | else { | 632 | else { |
633 | warn("could not register device to the tty subsystem"); | 633 | warn("could not register device to the tty subsystem"); |
634 | cs->class = NULL; | 634 | cs->tty_dev = NULL; |
635 | } | 635 | } |
636 | } | 636 | } |
637 | 637 | ||
@@ -645,7 +645,7 @@ void gigaset_if_free(struct cardstate *cs) | |||
645 | 645 | ||
646 | tasklet_disable(&cs->if_wake_tasklet); | 646 | tasklet_disable(&cs->if_wake_tasklet); |
647 | tasklet_kill(&cs->if_wake_tasklet); | 647 | tasklet_kill(&cs->if_wake_tasklet); |
648 | cs->class = NULL; | 648 | cs->tty_dev = NULL; |
649 | tty_unregister_device(drv->tty, cs->minor_index); | 649 | tty_unregister_device(drv->tty, cs->minor_index); |
650 | } | 650 | } |
651 | 651 | ||
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c index 9ad840e95dbe..e767afa55abf 100644 --- a/drivers/isdn/gigaset/proc.c +++ b/drivers/isdn/gigaset/proc.c | |||
@@ -16,11 +16,12 @@ | |||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
18 | 18 | ||
19 | static ssize_t show_cidmode(struct class_device *class, char *buf) | 19 | static ssize_t show_cidmode(struct device *dev, |
20 | struct device_attribute *attr, char *buf) | ||
20 | { | 21 | { |
21 | int ret; | 22 | int ret; |
22 | unsigned long flags; | 23 | unsigned long flags; |
23 | struct cardstate *cs = class_get_devdata(class); | 24 | struct cardstate *cs = dev_get_drvdata(dev); |
24 | 25 | ||
25 | spin_lock_irqsave(&cs->lock, flags); | 26 | spin_lock_irqsave(&cs->lock, flags); |
26 | ret = sprintf(buf, "%u\n", cs->cidmode); | 27 | ret = sprintf(buf, "%u\n", cs->cidmode); |
@@ -29,10 +30,10 @@ static ssize_t show_cidmode(struct class_device *class, char *buf) | |||
29 | return ret; | 30 | return ret; |
30 | } | 31 | } |
31 | 32 | ||
32 | static ssize_t set_cidmode(struct class_device *class, | 33 | static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, |
33 | const char *buf, size_t count) | 34 | const char *buf, size_t count) |
34 | { | 35 | { |
35 | struct cardstate *cs = class_get_devdata(class); | 36 | struct cardstate *cs = dev_get_drvdata(dev); |
36 | long int value; | 37 | long int value; |
37 | char *end; | 38 | char *end; |
38 | 39 | ||
@@ -64,25 +65,25 @@ static ssize_t set_cidmode(struct class_device *class, | |||
64 | return count; | 65 | return count; |
65 | } | 66 | } |
66 | 67 | ||
67 | static CLASS_DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); | 68 | static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); |
68 | 69 | ||
69 | /* free sysfs for device */ | 70 | /* free sysfs for device */ |
70 | void gigaset_free_dev_sysfs(struct cardstate *cs) | 71 | void gigaset_free_dev_sysfs(struct cardstate *cs) |
71 | { | 72 | { |
72 | if (!cs->class) | 73 | if (!cs->tty_dev) |
73 | return; | 74 | return; |
74 | 75 | ||
75 | gig_dbg(DEBUG_INIT, "removing sysfs entries"); | 76 | gig_dbg(DEBUG_INIT, "removing sysfs entries"); |
76 | class_device_remove_file(cs->class, &class_device_attr_cidmode); | 77 | device_remove_file(cs->tty_dev, &dev_attr_cidmode); |
77 | } | 78 | } |
78 | 79 | ||
79 | /* initialize sysfs for device */ | 80 | /* initialize sysfs for device */ |
80 | void gigaset_init_dev_sysfs(struct cardstate *cs) | 81 | void gigaset_init_dev_sysfs(struct cardstate *cs) |
81 | { | 82 | { |
82 | if (!cs->class) | 83 | if (!cs->tty_dev) |
83 | return; | 84 | return; |
84 | 85 | ||
85 | gig_dbg(DEBUG_INIT, "setting up sysfs"); | 86 | gig_dbg(DEBUG_INIT, "setting up sysfs"); |
86 | if (class_device_create_file(cs->class, &class_device_attr_cidmode)) | 87 | if (device_create_file(cs->tty_dev, &dev_attr_cidmode)) |
87 | dev_err(cs->dev, "could not create sysfs attribute\n"); | 88 | dev_err(cs->dev, "could not create sysfs attribute\n"); |
88 | } | 89 | } |
diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c index 4ccdd82b680f..61a1de85cb23 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/mmc_queue.c | |||
@@ -130,8 +130,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
130 | u64 limit = BLK_BOUNCE_HIGH; | 130 | u64 limit = BLK_BOUNCE_HIGH; |
131 | int ret; | 131 | int ret; |
132 | 132 | ||
133 | if (host->dev->dma_mask && *host->dev->dma_mask) | 133 | if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask) |
134 | limit = *host->dev->dma_mask; | 134 | limit = *mmc_dev(host)->dma_mask; |
135 | 135 | ||
136 | mq->card = card; | 136 | mq->card = card; |
137 | mq->queue = blk_init_queue(mmc_request, lock); | 137 | mq->queue = blk_init_queue(mmc_request, lock); |
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c index 10cc9734eaa0..ac5329636045 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/mmc_sysfs.c | |||
@@ -199,7 +199,7 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host) | |||
199 | memset(card, 0, sizeof(struct mmc_card)); | 199 | memset(card, 0, sizeof(struct mmc_card)); |
200 | card->host = host; | 200 | card->host = host; |
201 | device_initialize(&card->dev); | 201 | device_initialize(&card->dev); |
202 | card->dev.parent = card->host->dev; | 202 | card->dev.parent = mmc_dev(host); |
203 | card->dev.bus = &mmc_bus_type; | 203 | card->dev.bus = &mmc_bus_type; |
204 | card->dev.release = mmc_release_card; | 204 | card->dev.release = mmc_release_card; |
205 | } | 205 | } |
@@ -242,7 +242,7 @@ void mmc_remove_card(struct mmc_card *card) | |||
242 | } | 242 | } |
243 | 243 | ||
244 | 244 | ||
245 | static void mmc_host_classdev_release(struct class_device *dev) | 245 | static void mmc_host_classdev_release(struct device *dev) |
246 | { | 246 | { |
247 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | 247 | struct mmc_host *host = cls_dev_to_mmc_host(dev); |
248 | kfree(host); | 248 | kfree(host); |
@@ -250,7 +250,7 @@ static void mmc_host_classdev_release(struct class_device *dev) | |||
250 | 250 | ||
251 | static struct class mmc_host_class = { | 251 | static struct class mmc_host_class = { |
252 | .name = "mmc_host", | 252 | .name = "mmc_host", |
253 | .release = mmc_host_classdev_release, | 253 | .dev_release = mmc_host_classdev_release, |
254 | }; | 254 | }; |
255 | 255 | ||
256 | static DEFINE_IDR(mmc_host_idr); | 256 | static DEFINE_IDR(mmc_host_idr); |
@@ -267,10 +267,10 @@ struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev) | |||
267 | if (host) { | 267 | if (host) { |
268 | memset(host, 0, sizeof(struct mmc_host) + extra); | 268 | memset(host, 0, sizeof(struct mmc_host) + extra); |
269 | 269 | ||
270 | host->dev = dev; | 270 | host->parent = dev; |
271 | host->class_dev.dev = host->dev; | 271 | host->class_dev.parent = dev; |
272 | host->class_dev.class = &mmc_host_class; | 272 | host->class_dev.class = &mmc_host_class; |
273 | class_device_initialize(&host->class_dev); | 273 | device_initialize(&host->class_dev); |
274 | } | 274 | } |
275 | 275 | ||
276 | return host; | 276 | return host; |
@@ -292,10 +292,10 @@ int mmc_add_host_sysfs(struct mmc_host *host) | |||
292 | if (err) | 292 | if (err) |
293 | return err; | 293 | return err; |
294 | 294 | ||
295 | snprintf(host->class_dev.class_id, BUS_ID_SIZE, | 295 | snprintf(host->class_dev.bus_id, BUS_ID_SIZE, |
296 | "mmc%d", host->index); | 296 | "mmc%d", host->index); |
297 | 297 | ||
298 | return class_device_add(&host->class_dev); | 298 | return device_add(&host->class_dev); |
299 | } | 299 | } |
300 | 300 | ||
301 | /* | 301 | /* |
@@ -303,7 +303,7 @@ int mmc_add_host_sysfs(struct mmc_host *host) | |||
303 | */ | 303 | */ |
304 | void mmc_remove_host_sysfs(struct mmc_host *host) | 304 | void mmc_remove_host_sysfs(struct mmc_host *host) |
305 | { | 305 | { |
306 | class_device_del(&host->class_dev); | 306 | device_del(&host->class_dev); |
307 | 307 | ||
308 | spin_lock(&mmc_host_lock); | 308 | spin_lock(&mmc_host_lock); |
309 | idr_remove(&mmc_host_idr, host->index); | 309 | idr_remove(&mmc_host_idr, host->index); |
@@ -315,7 +315,7 @@ void mmc_remove_host_sysfs(struct mmc_host *host) | |||
315 | */ | 315 | */ |
316 | void mmc_free_host_sysfs(struct mmc_host *host) | 316 | void mmc_free_host_sysfs(struct mmc_host *host) |
317 | { | 317 | { |
318 | class_device_put(&host->class_dev); | 318 | put_device(&host->class_dev); |
319 | } | 319 | } |
320 | 320 | ||
321 | static struct workqueue_struct *workqueue; | 321 | static struct workqueue_struct *workqueue; |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index ced309b37a8f..682e62b0b09d 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -1488,7 +1488,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) | |||
1488 | /* | 1488 | /* |
1489 | * Translate the address to a physical address. | 1489 | * Translate the address to a physical address. |
1490 | */ | 1490 | */ |
1491 | host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer, | 1491 | host->dma_addr = dma_map_single(mmc_dev(host->mmc), host->dma_buffer, |
1492 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); | 1492 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1493 | 1493 | ||
1494 | /* | 1494 | /* |
@@ -1512,7 +1512,7 @@ kfree: | |||
1512 | */ | 1512 | */ |
1513 | BUG_ON(1); | 1513 | BUG_ON(1); |
1514 | 1514 | ||
1515 | dma_unmap_single(host->mmc->dev, host->dma_addr, | 1515 | dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, |
1516 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); | 1516 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1517 | host->dma_addr = (dma_addr_t)NULL; | 1517 | host->dma_addr = (dma_addr_t)NULL; |
1518 | 1518 | ||
@@ -1530,7 +1530,7 @@ err: | |||
1530 | static void __devexit wbsd_release_dma(struct wbsd_host *host) | 1530 | static void __devexit wbsd_release_dma(struct wbsd_host *host) |
1531 | { | 1531 | { |
1532 | if (host->dma_addr) { | 1532 | if (host->dma_addr) { |
1533 | dma_unmap_single(host->mmc->dev, host->dma_addr, | 1533 | dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, |
1534 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); | 1534 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); |
1535 | } | 1535 | } |
1536 | kfree(host->dma_buffer); | 1536 | kfree(host->dma_buffer); |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index f5802e7b08e9..c6de566188e4 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -860,7 +860,7 @@ static int __init ppp_init(void) | |||
860 | err = PTR_ERR(ppp_class); | 860 | err = PTR_ERR(ppp_class); |
861 | goto out_chrdev; | 861 | goto out_chrdev; |
862 | } | 862 | } |
863 | class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp"); | 863 | device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), "ppp"); |
864 | } | 864 | } |
865 | 865 | ||
866 | out: | 866 | out: |
@@ -2675,7 +2675,7 @@ static void __exit ppp_cleanup(void) | |||
2675 | cardmap_destroy(&all_ppp_units); | 2675 | cardmap_destroy(&all_ppp_units); |
2676 | if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) | 2676 | if (unregister_chrdev(PPP_MAJOR, "ppp") != 0) |
2677 | printk(KERN_ERR "PPP: failed to unregister PPP device\n"); | 2677 | printk(KERN_ERR "PPP: failed to unregister PPP device\n"); |
2678 | class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); | 2678 | device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0)); |
2679 | class_destroy(ppp_class); | 2679 | class_destroy(ppp_class); |
2680 | } | 2680 | } |
2681 | 2681 | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 93ffcdd95f50..e973a87fbb01 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1296,14 +1296,14 @@ register_framebuffer(struct fb_info *fb_info) | |||
1296 | break; | 1296 | break; |
1297 | fb_info->node = i; | 1297 | fb_info->node = i; |
1298 | 1298 | ||
1299 | fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i), | 1299 | fb_info->dev = device_create(fb_class, fb_info->device, |
1300 | fb_info->device, "fb%d", i); | 1300 | MKDEV(FB_MAJOR, i), "fb%d", i); |
1301 | if (IS_ERR(fb_info->class_device)) { | 1301 | if (IS_ERR(fb_info->dev)) { |
1302 | /* Not fatal */ | 1302 | /* Not fatal */ |
1303 | printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->class_device)); | 1303 | printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev)); |
1304 | fb_info->class_device = NULL; | 1304 | fb_info->dev = NULL; |
1305 | } else | 1305 | } else |
1306 | fb_init_class_device(fb_info); | 1306 | fb_init_device(fb_info); |
1307 | 1307 | ||
1308 | if (fb_info->pixmap.addr == NULL) { | 1308 | if (fb_info->pixmap.addr == NULL) { |
1309 | fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL); | 1309 | fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL); |
@@ -1356,8 +1356,8 @@ unregister_framebuffer(struct fb_info *fb_info) | |||
1356 | fb_destroy_modelist(&fb_info->modelist); | 1356 | fb_destroy_modelist(&fb_info->modelist); |
1357 | registered_fb[i]=NULL; | 1357 | registered_fb[i]=NULL; |
1358 | num_registered_fb--; | 1358 | num_registered_fb--; |
1359 | fb_cleanup_class_device(fb_info); | 1359 | fb_cleanup_device(fb_info); |
1360 | class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); | 1360 | device_destroy(fb_class, MKDEV(FB_MAJOR, i)); |
1361 | event.info = fb_info; | 1361 | event.info = fb_info; |
1362 | fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); | 1362 | fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); |
1363 | return 0; | 1363 | return 0; |
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index d3a50417ed9a..323bdf6fc7d5 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -73,7 +73,7 @@ EXPORT_SYMBOL(framebuffer_alloc); | |||
73 | * | 73 | * |
74 | * @info: frame buffer info structure | 74 | * @info: frame buffer info structure |
75 | * | 75 | * |
76 | * Drop the reference count of the class_device embedded in the | 76 | * Drop the reference count of the device embedded in the |
77 | * framebuffer info structure. | 77 | * framebuffer info structure. |
78 | * | 78 | * |
79 | */ | 79 | */ |
@@ -120,10 +120,10 @@ static int mode_string(char *buf, unsigned int offset, | |||
120 | m, mode->xres, mode->yres, v, mode->refresh); | 120 | m, mode->xres, mode->yres, v, mode->refresh); |
121 | } | 121 | } |
122 | 122 | ||
123 | static ssize_t store_mode(struct class_device *class_device, const char * buf, | 123 | static ssize_t store_mode(struct device *device, struct device_attribute *attr, |
124 | size_t count) | 124 | const char *buf, size_t count) |
125 | { | 125 | { |
126 | struct fb_info *fb_info = class_get_devdata(class_device); | 126 | struct fb_info *fb_info = dev_get_drvdata(device); |
127 | char mstr[100]; | 127 | char mstr[100]; |
128 | struct fb_var_screeninfo var; | 128 | struct fb_var_screeninfo var; |
129 | struct fb_modelist *modelist; | 129 | struct fb_modelist *modelist; |
@@ -151,9 +151,10 @@ static ssize_t store_mode(struct class_device *class_device, const char * buf, | |||
151 | return -EINVAL; | 151 | return -EINVAL; |
152 | } | 152 | } |
153 | 153 | ||
154 | static ssize_t show_mode(struct class_device *class_device, char *buf) | 154 | static ssize_t show_mode(struct device *device, struct device_attribute *attr, |
155 | char *buf) | ||
155 | { | 156 | { |
156 | struct fb_info *fb_info = class_get_devdata(class_device); | 157 | struct fb_info *fb_info = dev_get_drvdata(device); |
157 | 158 | ||
158 | if (!fb_info->mode) | 159 | if (!fb_info->mode) |
159 | return 0; | 160 | return 0; |
@@ -161,10 +162,11 @@ static ssize_t show_mode(struct class_device *class_device, char *buf) | |||
161 | return mode_string(buf, 0, fb_info->mode); | 162 | return mode_string(buf, 0, fb_info->mode); |
162 | } | 163 | } |
163 | 164 | ||
164 | static ssize_t store_modes(struct class_device *class_device, const char * buf, | 165 | static ssize_t store_modes(struct device *device, |
165 | size_t count) | 166 | struct device_attribute *attr, |
167 | const char *buf, size_t count) | ||
166 | { | 168 | { |
167 | struct fb_info *fb_info = class_get_devdata(class_device); | 169 | struct fb_info *fb_info = dev_get_drvdata(device); |
168 | LIST_HEAD(old_list); | 170 | LIST_HEAD(old_list); |
169 | int i = count / sizeof(struct fb_videomode); | 171 | int i = count / sizeof(struct fb_videomode); |
170 | 172 | ||
@@ -186,9 +188,10 @@ static ssize_t store_modes(struct class_device *class_device, const char * buf, | |||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | 190 | ||
189 | static ssize_t show_modes(struct class_device *class_device, char *buf) | 191 | static ssize_t show_modes(struct device *device, struct device_attribute *attr, |
192 | char *buf) | ||
190 | { | 193 | { |
191 | struct fb_info *fb_info = class_get_devdata(class_device); | 194 | struct fb_info *fb_info = dev_get_drvdata(device); |
192 | unsigned int i; | 195 | unsigned int i; |
193 | struct list_head *pos; | 196 | struct list_head *pos; |
194 | struct fb_modelist *modelist; | 197 | struct fb_modelist *modelist; |
@@ -203,10 +206,10 @@ static ssize_t show_modes(struct class_device *class_device, char *buf) | |||
203 | return i; | 206 | return i; |
204 | } | 207 | } |
205 | 208 | ||
206 | static ssize_t store_bpp(struct class_device *class_device, const char * buf, | 209 | static ssize_t store_bpp(struct device *device, struct device_attribute *attr, |
207 | size_t count) | 210 | const char *buf, size_t count) |
208 | { | 211 | { |
209 | struct fb_info *fb_info = class_get_devdata(class_device); | 212 | struct fb_info *fb_info = dev_get_drvdata(device); |
210 | struct fb_var_screeninfo var; | 213 | struct fb_var_screeninfo var; |
211 | char ** last = NULL; | 214 | char ** last = NULL; |
212 | int err; | 215 | int err; |
@@ -218,16 +221,18 @@ static ssize_t store_bpp(struct class_device *class_device, const char * buf, | |||
218 | return count; | 221 | return count; |
219 | } | 222 | } |
220 | 223 | ||
221 | static ssize_t show_bpp(struct class_device *class_device, char *buf) | 224 | static ssize_t show_bpp(struct device *device, struct device_attribute *attr, |
225 | char *buf) | ||
222 | { | 226 | { |
223 | struct fb_info *fb_info = class_get_devdata(class_device); | 227 | struct fb_info *fb_info = dev_get_drvdata(device); |
224 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); | 228 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); |
225 | } | 229 | } |
226 | 230 | ||
227 | static ssize_t store_rotate(struct class_device *class_device, const char *buf, | 231 | static ssize_t store_rotate(struct device *device, |
228 | size_t count) | 232 | struct device_attribute *attr, |
233 | const char *buf, size_t count) | ||
229 | { | 234 | { |
230 | struct fb_info *fb_info = class_get_devdata(class_device); | 235 | struct fb_info *fb_info = dev_get_drvdata(device); |
231 | struct fb_var_screeninfo var; | 236 | struct fb_var_screeninfo var; |
232 | char **last = NULL; | 237 | char **last = NULL; |
233 | int err; | 238 | int err; |
@@ -242,17 +247,19 @@ static ssize_t store_rotate(struct class_device *class_device, const char *buf, | |||
242 | } | 247 | } |
243 | 248 | ||
244 | 249 | ||
245 | static ssize_t show_rotate(struct class_device *class_device, char *buf) | 250 | static ssize_t show_rotate(struct device *device, |
251 | struct device_attribute *attr, char *buf) | ||
246 | { | 252 | { |
247 | struct fb_info *fb_info = class_get_devdata(class_device); | 253 | struct fb_info *fb_info = dev_get_drvdata(device); |
248 | 254 | ||
249 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); | 255 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate); |
250 | } | 256 | } |
251 | 257 | ||
252 | static ssize_t store_virtual(struct class_device *class_device, | 258 | static ssize_t store_virtual(struct device *device, |
253 | const char * buf, size_t count) | 259 | struct device_attribute *attr, |
260 | const char *buf, size_t count) | ||
254 | { | 261 | { |
255 | struct fb_info *fb_info = class_get_devdata(class_device); | 262 | struct fb_info *fb_info = dev_get_drvdata(device); |
256 | struct fb_var_screeninfo var; | 263 | struct fb_var_screeninfo var; |
257 | char *last = NULL; | 264 | char *last = NULL; |
258 | int err; | 265 | int err; |
@@ -269,23 +276,26 @@ static ssize_t store_virtual(struct class_device *class_device, | |||
269 | return count; | 276 | return count; |
270 | } | 277 | } |
271 | 278 | ||
272 | static ssize_t show_virtual(struct class_device *class_device, char *buf) | 279 | static ssize_t show_virtual(struct device *device, |
280 | struct device_attribute *attr, char *buf) | ||
273 | { | 281 | { |
274 | struct fb_info *fb_info = class_get_devdata(class_device); | 282 | struct fb_info *fb_info = dev_get_drvdata(device); |
275 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, | 283 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, |
276 | fb_info->var.yres_virtual); | 284 | fb_info->var.yres_virtual); |
277 | } | 285 | } |
278 | 286 | ||
279 | static ssize_t show_stride(struct class_device *class_device, char *buf) | 287 | static ssize_t show_stride(struct device *device, |
288 | struct device_attribute *attr, char *buf) | ||
280 | { | 289 | { |
281 | struct fb_info *fb_info = class_get_devdata(class_device); | 290 | struct fb_info *fb_info = dev_get_drvdata(device); |
282 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); | 291 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->fix.line_length); |
283 | } | 292 | } |
284 | 293 | ||
285 | static ssize_t store_blank(struct class_device *class_device, const char * buf, | 294 | static ssize_t store_blank(struct device *device, |
286 | size_t count) | 295 | struct device_attribute *attr, |
296 | const char *buf, size_t count) | ||
287 | { | 297 | { |
288 | struct fb_info *fb_info = class_get_devdata(class_device); | 298 | struct fb_info *fb_info = dev_get_drvdata(device); |
289 | char *last = NULL; | 299 | char *last = NULL; |
290 | int err; | 300 | int err; |
291 | 301 | ||
@@ -299,42 +309,48 @@ static ssize_t store_blank(struct class_device *class_device, const char * buf, | |||
299 | return count; | 309 | return count; |
300 | } | 310 | } |
301 | 311 | ||
302 | static ssize_t show_blank(struct class_device *class_device, char *buf) | 312 | static ssize_t show_blank(struct device *device, |
313 | struct device_attribute *attr, char *buf) | ||
303 | { | 314 | { |
304 | // struct fb_info *fb_info = class_get_devdata(class_device); | 315 | // struct fb_info *fb_info = dev_get_drvdata(device); |
305 | return 0; | 316 | return 0; |
306 | } | 317 | } |
307 | 318 | ||
308 | static ssize_t store_console(struct class_device *class_device, | 319 | static ssize_t store_console(struct device *device, |
309 | const char * buf, size_t count) | 320 | struct device_attribute *attr, |
321 | const char *buf, size_t count) | ||
310 | { | 322 | { |
311 | // struct fb_info *fb_info = class_get_devdata(class_device); | 323 | // struct fb_info *fb_info = dev_get_drvdata(device); |
312 | return 0; | 324 | return 0; |
313 | } | 325 | } |
314 | 326 | ||
315 | static ssize_t show_console(struct class_device *class_device, char *buf) | 327 | static ssize_t show_console(struct device *device, |
328 | struct device_attribute *attr, char *buf) | ||
316 | { | 329 | { |
317 | // struct fb_info *fb_info = class_get_devdata(class_device); | 330 | // struct fb_info *fb_info = dev_get_drvdata(device); |
318 | return 0; | 331 | return 0; |
319 | } | 332 | } |
320 | 333 | ||
321 | static ssize_t store_cursor(struct class_device *class_device, | 334 | static ssize_t store_cursor(struct device *device, |
322 | const char * buf, size_t count) | 335 | struct device_attribute *attr, |
336 | const char *buf, size_t count) | ||
323 | { | 337 | { |
324 | // struct fb_info *fb_info = class_get_devdata(class_device); | 338 | // struct fb_info *fb_info = dev_get_drvdata(device); |
325 | return 0; | 339 | return 0; |
326 | } | 340 | } |
327 | 341 | ||
328 | static ssize_t show_cursor(struct class_device *class_device, char *buf) | 342 | static ssize_t show_cursor(struct device *device, |
343 | struct device_attribute *attr, char *buf) | ||
329 | { | 344 | { |
330 | // struct fb_info *fb_info = class_get_devdata(class_device); | 345 | // struct fb_info *fb_info = dev_get_drvdata(device); |
331 | return 0; | 346 | return 0; |
332 | } | 347 | } |
333 | 348 | ||
334 | static ssize_t store_pan(struct class_device *class_device, const char * buf, | 349 | static ssize_t store_pan(struct device *device, |
335 | size_t count) | 350 | struct device_attribute *attr, |
351 | const char *buf, size_t count) | ||
336 | { | 352 | { |
337 | struct fb_info *fb_info = class_get_devdata(class_device); | 353 | struct fb_info *fb_info = dev_get_drvdata(device); |
338 | struct fb_var_screeninfo var; | 354 | struct fb_var_screeninfo var; |
339 | char *last = NULL; | 355 | char *last = NULL; |
340 | int err; | 356 | int err; |
@@ -355,24 +371,27 @@ static ssize_t store_pan(struct class_device *class_device, const char * buf, | |||
355 | return count; | 371 | return count; |
356 | } | 372 | } |
357 | 373 | ||
358 | static ssize_t show_pan(struct class_device *class_device, char *buf) | 374 | static ssize_t show_pan(struct device *device, |
375 | struct device_attribute *attr, char *buf) | ||
359 | { | 376 | { |
360 | struct fb_info *fb_info = class_get_devdata(class_device); | 377 | struct fb_info *fb_info = dev_get_drvdata(device); |
361 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, | 378 | return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, |
362 | fb_info->var.xoffset); | 379 | fb_info->var.xoffset); |
363 | } | 380 | } |
364 | 381 | ||
365 | static ssize_t show_name(struct class_device *class_device, char *buf) | 382 | static ssize_t show_name(struct device *device, |
383 | struct device_attribute *attr, char *buf) | ||
366 | { | 384 | { |
367 | struct fb_info *fb_info = class_get_devdata(class_device); | 385 | struct fb_info *fb_info = dev_get_drvdata(device); |
368 | 386 | ||
369 | return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); | 387 | return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); |
370 | } | 388 | } |
371 | 389 | ||
372 | static ssize_t store_fbstate(struct class_device *class_device, | 390 | static ssize_t store_fbstate(struct device *device, |
373 | const char *buf, size_t count) | 391 | struct device_attribute *attr, |
392 | const char *buf, size_t count) | ||
374 | { | 393 | { |
375 | struct fb_info *fb_info = class_get_devdata(class_device); | 394 | struct fb_info *fb_info = dev_get_drvdata(device); |
376 | u32 state; | 395 | u32 state; |
377 | char *last = NULL; | 396 | char *last = NULL; |
378 | 397 | ||
@@ -385,17 +404,19 @@ static ssize_t store_fbstate(struct class_device *class_device, | |||
385 | return count; | 404 | return count; |
386 | } | 405 | } |
387 | 406 | ||
388 | static ssize_t show_fbstate(struct class_device *class_device, char *buf) | 407 | static ssize_t show_fbstate(struct device *device, |
408 | struct device_attribute *attr, char *buf) | ||
389 | { | 409 | { |
390 | struct fb_info *fb_info = class_get_devdata(class_device); | 410 | struct fb_info *fb_info = dev_get_drvdata(device); |
391 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); | 411 | return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); |
392 | } | 412 | } |
393 | 413 | ||
394 | #ifdef CONFIG_FB_BACKLIGHT | 414 | #ifdef CONFIG_FB_BACKLIGHT |
395 | static ssize_t store_bl_curve(struct class_device *class_device, | 415 | static ssize_t store_bl_curve(struct device *device, |
396 | const char *buf, size_t count) | 416 | struct device_attribute *attr, |
417 | const char *buf, size_t count) | ||
397 | { | 418 | { |
398 | struct fb_info *fb_info = class_get_devdata(class_device); | 419 | struct fb_info *fb_info = dev_get_drvdata(device); |
399 | u8 tmp_curve[FB_BACKLIGHT_LEVELS]; | 420 | u8 tmp_curve[FB_BACKLIGHT_LEVELS]; |
400 | unsigned int i; | 421 | unsigned int i; |
401 | 422 | ||
@@ -432,9 +453,10 @@ static ssize_t store_bl_curve(struct class_device *class_device, | |||
432 | return count; | 453 | return count; |
433 | } | 454 | } |
434 | 455 | ||
435 | static ssize_t show_bl_curve(struct class_device *class_device, char *buf) | 456 | static ssize_t show_bl_curve(struct device *device, |
457 | struct device_attribute *attr, char *buf) | ||
436 | { | 458 | { |
437 | struct fb_info *fb_info = class_get_devdata(class_device); | 459 | struct fb_info *fb_info = dev_get_drvdata(device); |
438 | ssize_t len = 0; | 460 | ssize_t len = 0; |
439 | unsigned int i; | 461 | unsigned int i; |
440 | 462 | ||
@@ -465,7 +487,7 @@ static ssize_t show_bl_curve(struct class_device *class_device, char *buf) | |||
465 | /* When cmap is added back in it should be a binary attribute | 487 | /* When cmap is added back in it should be a binary attribute |
466 | * not a text one. Consideration should also be given to converting | 488 | * not a text one. Consideration should also be given to converting |
467 | * fbdev to use configfs instead of sysfs */ | 489 | * fbdev to use configfs instead of sysfs */ |
468 | static struct class_device_attribute class_device_attrs[] = { | 490 | static struct device_attribute device_attrs[] = { |
469 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), | 491 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), |
470 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), | 492 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), |
471 | __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console), | 493 | __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console), |
@@ -483,17 +505,16 @@ static struct class_device_attribute class_device_attrs[] = { | |||
483 | #endif | 505 | #endif |
484 | }; | 506 | }; |
485 | 507 | ||
486 | int fb_init_class_device(struct fb_info *fb_info) | 508 | int fb_init_device(struct fb_info *fb_info) |
487 | { | 509 | { |
488 | int i, error = 0; | 510 | int i, error = 0; |
489 | 511 | ||
490 | class_set_devdata(fb_info->class_device, fb_info); | 512 | dev_set_drvdata(fb_info->dev, fb_info); |
491 | 513 | ||
492 | fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; | 514 | fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; |
493 | 515 | ||
494 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { | 516 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { |
495 | error = class_device_create_file(fb_info->class_device, | 517 | error = device_create_file(fb_info->dev, &device_attrs[i]); |
496 | &class_device_attrs[i]); | ||
497 | 518 | ||
498 | if (error) | 519 | if (error) |
499 | break; | 520 | break; |
@@ -501,22 +522,20 @@ int fb_init_class_device(struct fb_info *fb_info) | |||
501 | 522 | ||
502 | if (error) { | 523 | if (error) { |
503 | while (--i >= 0) | 524 | while (--i >= 0) |
504 | class_device_remove_file(fb_info->class_device, | 525 | device_remove_file(fb_info->dev, &device_attrs[i]); |
505 | &class_device_attrs[i]); | ||
506 | fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; | 526 | fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; |
507 | } | 527 | } |
508 | 528 | ||
509 | return 0; | 529 | return 0; |
510 | } | 530 | } |
511 | 531 | ||
512 | void fb_cleanup_class_device(struct fb_info *fb_info) | 532 | void fb_cleanup_device(struct fb_info *fb_info) |
513 | { | 533 | { |
514 | unsigned int i; | 534 | unsigned int i; |
515 | 535 | ||
516 | if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { | 536 | if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { |
517 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 537 | for (i = 0; i < ARRAY_SIZE(device_attrs); i++) |
518 | class_device_remove_file(fb_info->class_device, | 538 | device_remove_file(fb_info->dev, &device_attrs[i]); |
519 | &class_device_attrs[i]); | ||
520 | 539 | ||
521 | fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; | 540 | fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; |
522 | } | 541 | } |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 3aa3434621ca..a5782e8c7f07 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -372,6 +372,51 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
372 | return error; | 372 | return error; |
373 | } | 373 | } |
374 | 374 | ||
375 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) | ||
376 | { | ||
377 | struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry; | ||
378 | struct sysfs_dirent *new_parent_sd, *sd; | ||
379 | int error; | ||
380 | |||
381 | if (!new_parent) | ||
382 | return -EINVAL; | ||
383 | |||
384 | old_parent_dentry = kobj->parent ? | ||
385 | kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; | ||
386 | new_parent_dentry = new_parent->dentry; | ||
387 | |||
388 | again: | ||
389 | mutex_lock(&old_parent_dentry->d_inode->i_mutex); | ||
390 | if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { | ||
391 | mutex_unlock(&old_parent_dentry->d_inode->i_mutex); | ||
392 | goto again; | ||
393 | } | ||
394 | |||
395 | new_parent_sd = new_parent_dentry->d_fsdata; | ||
396 | sd = kobj->dentry->d_fsdata; | ||
397 | |||
398 | new_dentry = lookup_one_len(kobj->name, new_parent_dentry, | ||
399 | strlen(kobj->name)); | ||
400 | if (IS_ERR(new_dentry)) { | ||
401 | error = PTR_ERR(new_dentry); | ||
402 | goto out; | ||
403 | } else | ||
404 | error = 0; | ||
405 | d_add(new_dentry, NULL); | ||
406 | d_move(kobj->dentry, new_dentry); | ||
407 | dput(new_dentry); | ||
408 | |||
409 | /* Remove from old parent's list and insert into new parent's list. */ | ||
410 | list_del_init(&sd->s_sibling); | ||
411 | list_add(&sd->s_sibling, &new_parent_sd->s_children); | ||
412 | |||
413 | out: | ||
414 | mutex_unlock(&new_parent_dentry->d_inode->i_mutex); | ||
415 | mutex_unlock(&old_parent_dentry->d_inode->i_mutex); | ||
416 | |||
417 | return error; | ||
418 | } | ||
419 | |||
375 | static int sysfs_dir_open(struct inode *inode, struct file *file) | 420 | static int sysfs_dir_open(struct inode *inode, struct file *file) |
376 | { | 421 | { |
377 | struct dentry * dentry = file->f_dentry; | 422 | struct dentry * dentry = file->f_dentry; |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 298303b5a716..95c165101c98 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -190,6 +190,9 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t | |||
190 | count = PAGE_SIZE - 1; | 190 | count = PAGE_SIZE - 1; |
191 | error = copy_from_user(buffer->page,buf,count); | 191 | error = copy_from_user(buffer->page,buf,count); |
192 | buffer->needs_read_fill = 1; | 192 | buffer->needs_read_fill = 1; |
193 | /* if buf is assumed to contain a string, terminate it by \0, | ||
194 | so e.g. sscanf() can scan the string easily */ | ||
195 | buffer->page[count] = 0; | ||
193 | return error ? -EFAULT : count; | 196 | return error ? -EFAULT : count; |
194 | } | 197 | } |
195 | 198 | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f338e40bd544..fdd10953b2b6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -357,7 +357,7 @@ struct device *acpi_get_physical_device(acpi_handle); | |||
357 | /* helper */ | 357 | /* helper */ |
358 | acpi_handle acpi_get_child(acpi_handle, acpi_integer); | 358 | acpi_handle acpi_get_child(acpi_handle, acpi_integer); |
359 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); | 359 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); |
360 | #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data)) | 360 | #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) |
361 | 361 | ||
362 | #endif /* CONFIG_ACPI */ | 362 | #endif /* CONFIG_ACPI */ |
363 | 363 | ||
diff --git a/include/asm-alpha/device.h b/include/asm-alpha/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-alpha/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-arm/device.h b/include/asm-arm/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-arm/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-arm26/device.h b/include/asm-arm26/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-arm26/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-avr32/device.h b/include/asm-avr32/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-avr32/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-cris/device.h b/include/asm-cris/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-cris/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-frv/device.h b/include/asm-frv/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-frv/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-generic/device.h b/include/asm-generic/device.h new file mode 100644 index 000000000000..c17c9600f220 --- /dev/null +++ b/include/asm-generic/device.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #ifndef _ASM_GENERIC_DEVICE_H | ||
7 | #define _ASM_GENERIC_DEVICE_H | ||
8 | |||
9 | struct dev_archdata { | ||
10 | }; | ||
11 | |||
12 | #endif /* _ASM_GENERIC_DEVICE_H */ | ||
diff --git a/include/asm-h8300/device.h b/include/asm-h8300/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-h8300/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-i386/device.h b/include/asm-i386/device.h new file mode 100644 index 000000000000..849604c70e6b --- /dev/null +++ b/include/asm-i386/device.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #ifndef _ASM_I386_DEVICE_H | ||
7 | #define _ASM_I386_DEVICE_H | ||
8 | |||
9 | struct dev_archdata { | ||
10 | #ifdef CONFIG_ACPI | ||
11 | void *acpi_handle; | ||
12 | #endif | ||
13 | }; | ||
14 | |||
15 | #endif /* _ASM_I386_DEVICE_H */ | ||
diff --git a/include/asm-ia64/device.h b/include/asm-ia64/device.h new file mode 100644 index 000000000000..3db6daf7f251 --- /dev/null +++ b/include/asm-ia64/device.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #ifndef _ASM_IA64_DEVICE_H | ||
7 | #define _ASM_IA64_DEVICE_H | ||
8 | |||
9 | struct dev_archdata { | ||
10 | #ifdef CONFIG_ACPI | ||
11 | void *acpi_handle; | ||
12 | #endif | ||
13 | }; | ||
14 | |||
15 | #endif /* _ASM_IA64_DEVICE_H */ | ||
diff --git a/include/asm-m32r/device.h b/include/asm-m32r/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-m32r/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-m68k/device.h b/include/asm-m68k/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-m68k/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-m68knommu/device.h b/include/asm-m68knommu/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-m68knommu/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-mips/device.h b/include/asm-mips/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-mips/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-parisc/device.h b/include/asm-parisc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-parisc/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-powerpc/device.h b/include/asm-powerpc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-powerpc/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-ppc/device.h b/include/asm-ppc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-ppc/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-s390/device.h b/include/asm-s390/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-s390/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-sh/device.h b/include/asm-sh/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sh/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-sh64/device.h b/include/asm-sh64/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sh64/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-sparc/device.h b/include/asm-sparc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sparc/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-sparc64/device.h b/include/asm-sparc64/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sparc64/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-um/device.h b/include/asm-um/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-um/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-v850/device.h b/include/asm-v850/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-v850/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/asm-x86_64/device.h b/include/asm-x86_64/device.h new file mode 100644 index 000000000000..3afa03f33a36 --- /dev/null +++ b/include/asm-x86_64/device.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #ifndef _ASM_X86_64_DEVICE_H | ||
7 | #define _ASM_X86_64_DEVICE_H | ||
8 | |||
9 | struct dev_archdata { | ||
10 | #ifdef CONFIG_ACPI | ||
11 | void *acpi_handle; | ||
12 | #endif | ||
13 | }; | ||
14 | |||
15 | #endif /* _ASM_X86_64_DEVICE_H */ | ||
diff --git a/include/asm-xtensa/device.h b/include/asm-xtensa/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-xtensa/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/include/linux/device.h b/include/linux/device.h index 9d4f6a963936..583a341e016c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/pm.h> | 21 | #include <linux/pm.h> |
22 | #include <asm/semaphore.h> | 22 | #include <asm/semaphore.h> |
23 | #include <asm/atomic.h> | 23 | #include <asm/atomic.h> |
24 | #include <asm/device.h> | ||
24 | 25 | ||
25 | #define DEVICE_NAME_SIZE 50 | 26 | #define DEVICE_NAME_SIZE 50 |
26 | #define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */ | 27 | #define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */ |
@@ -42,6 +43,8 @@ struct bus_type { | |||
42 | struct klist klist_devices; | 43 | struct klist klist_devices; |
43 | struct klist klist_drivers; | 44 | struct klist klist_drivers; |
44 | 45 | ||
46 | struct blocking_notifier_head bus_notifier; | ||
47 | |||
45 | struct bus_attribute * bus_attrs; | 48 | struct bus_attribute * bus_attrs; |
46 | struct device_attribute * dev_attrs; | 49 | struct device_attribute * dev_attrs; |
47 | struct driver_attribute * drv_attrs; | 50 | struct driver_attribute * drv_attrs; |
@@ -75,6 +78,29 @@ int __must_check bus_for_each_drv(struct bus_type *bus, | |||
75 | struct device_driver *start, void *data, | 78 | struct device_driver *start, void *data, |
76 | int (*fn)(struct device_driver *, void *)); | 79 | int (*fn)(struct device_driver *, void *)); |
77 | 80 | ||
81 | /* | ||
82 | * Bus notifiers: Get notified of addition/removal of devices | ||
83 | * and binding/unbinding of drivers to devices. | ||
84 | * In the long run, it should be a replacement for the platform | ||
85 | * notify hooks. | ||
86 | */ | ||
87 | struct notifier_block; | ||
88 | |||
89 | extern int bus_register_notifier(struct bus_type *bus, | ||
90 | struct notifier_block *nb); | ||
91 | extern int bus_unregister_notifier(struct bus_type *bus, | ||
92 | struct notifier_block *nb); | ||
93 | |||
94 | /* All 4 notifers below get called with the target struct device * | ||
95 | * as an argument. Note that those functions are likely to be called | ||
96 | * with the device semaphore held in the core, so be careful. | ||
97 | */ | ||
98 | #define BUS_NOTIFY_ADD_DEVICE 0x00000001 /* device added */ | ||
99 | #define BUS_NOTIFY_DEL_DEVICE 0x00000002 /* device removed */ | ||
100 | #define BUS_NOTIFY_BOUND_DRIVER 0x00000003 /* driver bound to device */ | ||
101 | #define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be | ||
102 | unbound */ | ||
103 | |||
78 | /* driverfs interface for exporting bus attributes */ | 104 | /* driverfs interface for exporting bus attributes */ |
79 | 105 | ||
80 | struct bus_attribute { | 106 | struct bus_attribute { |
@@ -343,8 +369,6 @@ struct device { | |||
343 | void *driver_data; /* data private to the driver */ | 369 | void *driver_data; /* data private to the driver */ |
344 | void *platform_data; /* Platform specific data, device | 370 | void *platform_data; /* Platform specific data, device |
345 | core doesn't touch it */ | 371 | core doesn't touch it */ |
346 | void *firmware_data; /* Firmware specific data (e.g. ACPI, | ||
347 | BIOS data),reserved for device core*/ | ||
348 | struct dev_pm_info power; | 372 | struct dev_pm_info power; |
349 | 373 | ||
350 | u64 *dma_mask; /* dma mask (if dma'able device) */ | 374 | u64 *dma_mask; /* dma mask (if dma'able device) */ |
@@ -358,6 +382,8 @@ struct device { | |||
358 | 382 | ||
359 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem | 383 | struct dma_coherent_mem *dma_mem; /* internal for coherent mem |
360 | override */ | 384 | override */ |
385 | /* arch specific additions */ | ||
386 | struct dev_archdata archdata; | ||
361 | 387 | ||
362 | /* class_device migration path */ | 388 | /* class_device migration path */ |
363 | struct list_head node; | 389 | struct list_head node; |
@@ -395,7 +421,10 @@ extern int __must_check device_add(struct device * dev); | |||
395 | extern void device_del(struct device * dev); | 421 | extern void device_del(struct device * dev); |
396 | extern int device_for_each_child(struct device *, void *, | 422 | extern int device_for_each_child(struct device *, void *, |
397 | int (*fn)(struct device *, void *)); | 423 | int (*fn)(struct device *, void *)); |
424 | extern struct device *device_find_child(struct device *, void *data, | ||
425 | int (*match)(struct device *, void *)); | ||
398 | extern int device_rename(struct device *dev, char *new_name); | 426 | extern int device_rename(struct device *dev, char *new_name); |
427 | extern int device_move(struct device *dev, struct device *new_parent); | ||
399 | 428 | ||
400 | /* | 429 | /* |
401 | * Manual binding of a device to driver. See drivers/base/bus.c | 430 | * Manual binding of a device to driver. See drivers/base/bus.c |
@@ -415,8 +444,6 @@ extern struct device *device_create(struct class *cls, struct device *parent, | |||
415 | __attribute__((format(printf,4,5))); | 444 | __attribute__((format(printf,4,5))); |
416 | extern void device_destroy(struct class *cls, dev_t devt); | 445 | extern void device_destroy(struct class *cls, dev_t devt); |
417 | 446 | ||
418 | extern int virtual_device_parent(struct device *dev); | ||
419 | |||
420 | /* | 447 | /* |
421 | * Platform "fixup" functions - allow the platform to have their say | 448 | * Platform "fixup" functions - allow the platform to have their say |
422 | * about devices and actions that the general device layer doesn't | 449 | * about devices and actions that the general device layer doesn't |
diff --git a/include/linux/fb.h b/include/linux/fb.h index 3e69241e6a81..fa23e0671bb3 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -774,8 +774,8 @@ struct fb_info { | |||
774 | #endif | 774 | #endif |
775 | 775 | ||
776 | struct fb_ops *fbops; | 776 | struct fb_ops *fbops; |
777 | struct device *device; | 777 | struct device *device; /* This is the parent */ |
778 | struct class_device *class_device; /* sysfs per device attrs */ | 778 | struct device *dev; /* This is this fb device */ |
779 | int class_flag; /* private sysfs flags */ | 779 | int class_flag; /* private sysfs flags */ |
780 | #ifdef CONFIG_FB_TILEBLITTING | 780 | #ifdef CONFIG_FB_TILEBLITTING |
781 | struct fb_tile_ops *tileops; /* Tile Blitting */ | 781 | struct fb_tile_ops *tileops; /* Tile Blitting */ |
@@ -910,8 +910,8 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, | |||
910 | /* drivers/video/fbsysfs.c */ | 910 | /* drivers/video/fbsysfs.c */ |
911 | extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); | 911 | extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev); |
912 | extern void framebuffer_release(struct fb_info *info); | 912 | extern void framebuffer_release(struct fb_info *info); |
913 | extern int fb_init_class_device(struct fb_info *fb_info); | 913 | extern int fb_init_device(struct fb_info *fb_info); |
914 | extern void fb_cleanup_class_device(struct fb_info *head); | 914 | extern void fb_cleanup_device(struct fb_info *head); |
915 | extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max); | 915 | extern void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max); |
916 | 916 | ||
917 | /* drivers/video/fbmon.c */ | 917 | /* drivers/video/fbmon.c */ |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index bcd9cd173c2c..d1c8d28fa92e 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -47,6 +47,7 @@ enum kobject_action { | |||
47 | KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ | 47 | KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ |
48 | KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ | 48 | KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ |
49 | KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ | 49 | KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ |
50 | KOBJ_MOVE = (__force kobject_action_t) 0x08, /* device move */ | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | struct kobject { | 53 | struct kobject { |
@@ -76,6 +77,7 @@ extern int __must_check kobject_add(struct kobject *); | |||
76 | extern void kobject_del(struct kobject *); | 77 | extern void kobject_del(struct kobject *); |
77 | 78 | ||
78 | extern int __must_check kobject_rename(struct kobject *, const char *new_name); | 79 | extern int __must_check kobject_rename(struct kobject *, const char *new_name); |
80 | extern int __must_check kobject_move(struct kobject *, struct kobject *); | ||
79 | 81 | ||
80 | extern int __must_check kobject_register(struct kobject *); | 82 | extern int __must_check kobject_register(struct kobject *); |
81 | extern void kobject_unregister(struct kobject *); | 83 | extern void kobject_unregister(struct kobject *); |
@@ -264,6 +266,8 @@ extern int __must_check subsys_create_file(struct subsystem * , | |||
264 | 266 | ||
265 | #if defined(CONFIG_HOTPLUG) | 267 | #if defined(CONFIG_HOTPLUG) |
266 | void kobject_uevent(struct kobject *kobj, enum kobject_action action); | 268 | void kobject_uevent(struct kobject *kobj, enum kobject_action action); |
269 | void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, | ||
270 | char *envp[]); | ||
267 | 271 | ||
268 | int add_uevent_var(char **envp, int num_envp, int *cur_index, | 272 | int add_uevent_var(char **envp, int num_envp, int *cur_index, |
269 | char *buffer, int buffer_size, int *cur_len, | 273 | char *buffer, int buffer_size, int *cur_len, |
@@ -271,6 +275,10 @@ int add_uevent_var(char **envp, int num_envp, int *cur_index, | |||
271 | __attribute__((format (printf, 7, 8))); | 275 | __attribute__((format (printf, 7, 8))); |
272 | #else | 276 | #else |
273 | static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { } | 277 | static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { } |
278 | static inline void kobject_uevent_env(struct kobject *kobj, | ||
279 | enum kobject_action action, | ||
280 | char *envp[]) | ||
281 | { } | ||
274 | 282 | ||
275 | static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, | 283 | static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, |
276 | char *buffer, int buffer_size, int *cur_len, | 284 | char *buffer, int buffer_size, int *cur_len, |
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index b03cfb91e228..326da7d500c7 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h | |||
@@ -31,15 +31,14 @@ | |||
31 | #define HPET_MINOR 228 | 31 | #define HPET_MINOR 228 |
32 | 32 | ||
33 | struct device; | 33 | struct device; |
34 | struct class_device; | ||
35 | 34 | ||
36 | struct miscdevice { | 35 | struct miscdevice { |
37 | int minor; | 36 | int minor; |
38 | const char *name; | 37 | const char *name; |
39 | const struct file_operations *fops; | 38 | const struct file_operations *fops; |
40 | struct list_head list; | 39 | struct list_head list; |
41 | struct device *dev; | 40 | struct device *parent; |
42 | struct class_device *class; | 41 | struct device *this_device; |
43 | }; | 42 | }; |
44 | 43 | ||
45 | extern int misc_register(struct miscdevice * misc); | 44 | extern int misc_register(struct miscdevice * misc); |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 587264a58d56..528e7d3fecb1 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -74,8 +74,8 @@ struct mmc_card; | |||
74 | struct device; | 74 | struct device; |
75 | 75 | ||
76 | struct mmc_host { | 76 | struct mmc_host { |
77 | struct device *dev; | 77 | struct device *parent; |
78 | struct class_device class_dev; | 78 | struct device class_dev; |
79 | int index; | 79 | int index; |
80 | const struct mmc_host_ops *ops; | 80 | const struct mmc_host_ops *ops; |
81 | unsigned int f_min; | 81 | unsigned int f_min; |
@@ -125,8 +125,8 @@ static inline void *mmc_priv(struct mmc_host *host) | |||
125 | return (void *)host->private; | 125 | return (void *)host->private; |
126 | } | 126 | } |
127 | 127 | ||
128 | #define mmc_dev(x) ((x)->dev) | 128 | #define mmc_dev(x) ((x)->parent) |
129 | #define mmc_hostname(x) ((x)->class_dev.class_id) | 129 | #define mmc_hostname(x) ((x)->class_dev.bus_id) |
130 | 130 | ||
131 | extern int mmc_suspend_host(struct mmc_host *, pm_message_t); | 131 | extern int mmc_suspend_host(struct mmc_host *, pm_message_t); |
132 | extern int mmc_resume_host(struct mmc_host *); | 132 | extern int mmc_resume_host(struct mmc_host *); |
diff --git a/include/linux/module.h b/include/linux/module.h index d1d00ce8f4ed..9258ffd8a7f0 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -264,6 +264,7 @@ struct module | |||
264 | struct module_attribute *modinfo_attrs; | 264 | struct module_attribute *modinfo_attrs; |
265 | const char *version; | 265 | const char *version; |
266 | const char *srcversion; | 266 | const char *srcversion; |
267 | struct kobject *drivers_dir; | ||
267 | 268 | ||
268 | /* Exported symbols */ | 269 | /* Exported symbols */ |
269 | const struct kernel_symbol *syms; | 270 | const struct kernel_symbol *syms; |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 29cd6dee13db..20f47b81d3fa 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -58,6 +58,12 @@ struct platform_driver { | |||
58 | extern int platform_driver_register(struct platform_driver *); | 58 | extern int platform_driver_register(struct platform_driver *); |
59 | extern void platform_driver_unregister(struct platform_driver *); | 59 | extern void platform_driver_unregister(struct platform_driver *); |
60 | 60 | ||
61 | /* non-hotpluggable platform devices may use this so that probe() and | ||
62 | * its support may live in __init sections, conserving runtime memory. | ||
63 | */ | ||
64 | extern int platform_driver_probe(struct platform_driver *driver, | ||
65 | int (*probe)(struct platform_device *)); | ||
66 | |||
61 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) | 67 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) |
62 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) | 68 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) |
63 | 69 | ||
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 6d5c43d31dec..2129d1b6c874 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -97,6 +97,9 @@ extern int __must_check | |||
97 | sysfs_rename_dir(struct kobject *, const char *new_name); | 97 | sysfs_rename_dir(struct kobject *, const char *new_name); |
98 | 98 | ||
99 | extern int __must_check | 99 | extern int __must_check |
100 | sysfs_move_dir(struct kobject *, struct kobject *); | ||
101 | |||
102 | extern int __must_check | ||
100 | sysfs_create_file(struct kobject *, const struct attribute *); | 103 | sysfs_create_file(struct kobject *, const struct attribute *); |
101 | 104 | ||
102 | extern int __must_check | 105 | extern int __must_check |
@@ -142,6 +145,11 @@ static inline int sysfs_rename_dir(struct kobject * k, const char *new_name) | |||
142 | return 0; | 145 | return 0; |
143 | } | 146 | } |
144 | 147 | ||
148 | static inline int sysfs_move_dir(struct kobject * k, struct kobject * new_parent) | ||
149 | { | ||
150 | return 0; | ||
151 | } | ||
152 | |||
145 | static inline int sysfs_create_file(struct kobject * k, const struct attribute * a) | 153 | static inline int sysfs_create_file(struct kobject * k, const struct attribute * a) |
146 | { | 154 | { |
147 | return 0; | 155 | return 0; |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 44091c0db0b4..65321f911c1e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -276,9 +276,8 @@ extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); | |||
276 | extern int tty_unregister_ldisc(int disc); | 276 | extern int tty_unregister_ldisc(int disc); |
277 | extern int tty_register_driver(struct tty_driver *driver); | 277 | extern int tty_register_driver(struct tty_driver *driver); |
278 | extern int tty_unregister_driver(struct tty_driver *driver); | 278 | extern int tty_unregister_driver(struct tty_driver *driver); |
279 | extern struct class_device *tty_register_device(struct tty_driver *driver, | 279 | extern struct device *tty_register_device(struct tty_driver *driver, |
280 | unsigned index, | 280 | unsigned index, struct device *dev); |
281 | struct device *dev); | ||
282 | extern void tty_unregister_device(struct tty_driver *driver, unsigned index); | 281 | extern void tty_unregister_device(struct tty_driver *driver, unsigned index); |
283 | extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, | 282 | extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, |
284 | int buflen); | 283 | int buflen); |
diff --git a/include/sound/core.h b/include/sound/core.h index fa1ca0127bab..a994bea09cd6 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -132,6 +132,7 @@ struct snd_card { | |||
132 | int shutdown; /* this card is going down */ | 132 | int shutdown; /* this card is going down */ |
133 | int free_on_last_close; /* free in context of file_release */ | 133 | int free_on_last_close; /* free in context of file_release */ |
134 | wait_queue_head_t shutdown_sleep; | 134 | wait_queue_head_t shutdown_sleep; |
135 | struct device *parent; | ||
135 | struct device *dev; | 136 | struct device *dev; |
136 | 137 | ||
137 | #ifdef CONFIG_PM | 138 | #ifdef CONFIG_PM |
@@ -187,13 +188,14 @@ struct snd_minor { | |||
187 | int device; /* device number */ | 188 | int device; /* device number */ |
188 | const struct file_operations *f_ops; /* file operations */ | 189 | const struct file_operations *f_ops; /* file operations */ |
189 | void *private_data; /* private data for f_ops->open */ | 190 | void *private_data; /* private data for f_ops->open */ |
190 | struct class_device *class_dev; /* class device for sysfs */ | 191 | struct device *dev; /* device for sysfs */ |
191 | }; | 192 | }; |
192 | 193 | ||
193 | /* sound.c */ | 194 | /* sound.c */ |
194 | 195 | ||
195 | extern int snd_major; | 196 | extern int snd_major; |
196 | extern int snd_ecards_limit; | 197 | extern int snd_ecards_limit; |
198 | extern struct class *sound_class; | ||
197 | 199 | ||
198 | void snd_request_card(int card); | 200 | void snd_request_card(int card); |
199 | 201 | ||
@@ -203,7 +205,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
203 | int snd_unregister_device(int type, struct snd_card *card, int dev); | 205 | int snd_unregister_device(int type, struct snd_card *card, int dev); |
204 | void *snd_lookup_minor_data(unsigned int minor, int type); | 206 | void *snd_lookup_minor_data(unsigned int minor, int type); |
205 | int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, | 207 | int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, |
206 | const struct class_device_attribute *attr); | 208 | struct device_attribute *attr); |
207 | 209 | ||
208 | #ifdef CONFIG_SND_OSSEMUL | 210 | #ifdef CONFIG_SND_OSSEMUL |
209 | int snd_register_oss_device(int type, struct snd_card *card, int dev, | 211 | int snd_register_oss_device(int type, struct snd_card *card, int dev, |
@@ -255,7 +257,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file); | |||
255 | int snd_card_file_remove(struct snd_card *card, struct file *file); | 257 | int snd_card_file_remove(struct snd_card *card, struct file *file); |
256 | 258 | ||
257 | #ifndef snd_card_set_dev | 259 | #ifndef snd_card_set_dev |
258 | #define snd_card_set_dev(card,devptr) ((card)->dev = (devptr)) | 260 | #define snd_card_set_dev(card,devptr) ((card)->parent = (devptr)) |
259 | #endif | 261 | #endif |
260 | 262 | ||
261 | /* device.c */ | 263 | /* device.c */ |
diff --git a/init/Kconfig b/init/Kconfig index 176f7e5136c7..14d484606fab 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -249,6 +249,26 @@ config CPUSETS | |||
249 | 249 | ||
250 | Say N if unsure. | 250 | Say N if unsure. |
251 | 251 | ||
252 | config SYSFS_DEPRECATED | ||
253 | bool "Create deprecated sysfs files" | ||
254 | default y | ||
255 | help | ||
256 | This option creates deprecated symlinks such as the | ||
257 | "device"-link, the <subsystem>:<name>-link, and the | ||
258 | "bus"-link. It may also add deprecated key in the | ||
259 | uevent environment. | ||
260 | None of these features or values should be used today, as | ||
261 | they export driver core implementation details to userspace | ||
262 | or export properties which can't be kept stable across kernel | ||
263 | releases. | ||
264 | |||
265 | If enabled, this option will also move any device structures | ||
266 | that belong to a class, back into the /sys/class heirachy, in | ||
267 | order to support older versions of udev. | ||
268 | |||
269 | If you are using a distro that was released in 2006 or later, | ||
270 | it should be safe to say N here. | ||
271 | |||
252 | config RELAY | 272 | config RELAY |
253 | bool "Kernel->user space relay support (formerly relayfs)" | 273 | bool "Kernel->user space relay support (formerly relayfs)" |
254 | help | 274 | help |
diff --git a/kernel/module.c b/kernel/module.c index f0166563c602..45e01cb60101 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -1086,22 +1086,35 @@ static int mod_sysfs_setup(struct module *mod, | |||
1086 | goto out; | 1086 | goto out; |
1087 | kobj_set_kset_s(&mod->mkobj, module_subsys); | 1087 | kobj_set_kset_s(&mod->mkobj, module_subsys); |
1088 | mod->mkobj.mod = mod; | 1088 | mod->mkobj.mod = mod; |
1089 | err = kobject_register(&mod->mkobj.kobj); | 1089 | |
1090 | /* delay uevent until full sysfs population */ | ||
1091 | kobject_init(&mod->mkobj.kobj); | ||
1092 | err = kobject_add(&mod->mkobj.kobj); | ||
1090 | if (err) | 1093 | if (err) |
1091 | goto out; | 1094 | goto out; |
1092 | 1095 | ||
1096 | mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); | ||
1097 | if (!mod->drivers_dir) | ||
1098 | goto out_unreg; | ||
1099 | |||
1093 | err = module_param_sysfs_setup(mod, kparam, num_params); | 1100 | err = module_param_sysfs_setup(mod, kparam, num_params); |
1094 | if (err) | 1101 | if (err) |
1095 | goto out_unreg; | 1102 | goto out_unreg_drivers; |
1096 | 1103 | ||
1097 | err = module_add_modinfo_attrs(mod); | 1104 | err = module_add_modinfo_attrs(mod); |
1098 | if (err) | 1105 | if (err) |
1099 | goto out_unreg; | 1106 | goto out_unreg_param; |
1100 | 1107 | ||
1108 | kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); | ||
1101 | return 0; | 1109 | return 0; |
1102 | 1110 | ||
1111 | out_unreg_drivers: | ||
1112 | kobject_unregister(mod->drivers_dir); | ||
1113 | out_unreg_param: | ||
1114 | module_param_sysfs_remove(mod); | ||
1103 | out_unreg: | 1115 | out_unreg: |
1104 | kobject_unregister(&mod->mkobj.kobj); | 1116 | kobject_del(&mod->mkobj.kobj); |
1117 | kobject_put(&mod->mkobj.kobj); | ||
1105 | out: | 1118 | out: |
1106 | return err; | 1119 | return err; |
1107 | } | 1120 | } |
@@ -1110,6 +1123,7 @@ static void mod_kobject_remove(struct module *mod) | |||
1110 | { | 1123 | { |
1111 | module_remove_modinfo_attrs(mod); | 1124 | module_remove_modinfo_attrs(mod); |
1112 | module_param_sysfs_remove(mod); | 1125 | module_param_sysfs_remove(mod); |
1126 | kobject_unregister(mod->drivers_dir); | ||
1113 | 1127 | ||
1114 | kobject_unregister(&mod->mkobj.kobj); | 1128 | kobject_unregister(&mod->mkobj.kobj); |
1115 | } | 1129 | } |
@@ -2275,11 +2289,14 @@ void print_modules(void) | |||
2275 | 2289 | ||
2276 | void module_add_driver(struct module *mod, struct device_driver *drv) | 2290 | void module_add_driver(struct module *mod, struct device_driver *drv) |
2277 | { | 2291 | { |
2292 | int no_warn; | ||
2293 | |||
2278 | if (!mod || !drv) | 2294 | if (!mod || !drv) |
2279 | return; | 2295 | return; |
2280 | 2296 | ||
2281 | /* Don't check return code; this call is idempotent */ | 2297 | /* Don't check return codes; these calls are idempotent */ |
2282 | sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); | 2298 | no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module"); |
2299 | no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj, drv->name); | ||
2283 | } | 2300 | } |
2284 | EXPORT_SYMBOL(module_add_driver); | 2301 | EXPORT_SYMBOL(module_add_driver); |
2285 | 2302 | ||
@@ -2288,6 +2305,8 @@ void module_remove_driver(struct device_driver *drv) | |||
2288 | if (!drv) | 2305 | if (!drv) |
2289 | return; | 2306 | return; |
2290 | sysfs_remove_link(&drv->kobj, "module"); | 2307 | sysfs_remove_link(&drv->kobj, "module"); |
2308 | if (drv->owner && drv->owner->drivers_dir) | ||
2309 | sysfs_remove_link(drv->owner->drivers_dir, drv->name); | ||
2291 | } | 2310 | } |
2292 | EXPORT_SYMBOL(module_remove_driver); | 2311 | EXPORT_SYMBOL(module_remove_driver); |
2293 | 2312 | ||
diff --git a/lib/kobject.c b/lib/kobject.c index 7dd5c0e9d996..744a4b102c7f 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -311,6 +311,56 @@ int kobject_rename(struct kobject * kobj, const char *new_name) | |||
311 | } | 311 | } |
312 | 312 | ||
313 | /** | 313 | /** |
314 | * kobject_move - move object to another parent | ||
315 | * @kobj: object in question. | ||
316 | * @new_parent: object's new parent | ||
317 | */ | ||
318 | |||
319 | int kobject_move(struct kobject *kobj, struct kobject *new_parent) | ||
320 | { | ||
321 | int error; | ||
322 | struct kobject *old_parent; | ||
323 | const char *devpath = NULL; | ||
324 | char *devpath_string = NULL; | ||
325 | char *envp[2]; | ||
326 | |||
327 | kobj = kobject_get(kobj); | ||
328 | if (!kobj) | ||
329 | return -EINVAL; | ||
330 | new_parent = kobject_get(new_parent); | ||
331 | if (!new_parent) { | ||
332 | error = -EINVAL; | ||
333 | goto out; | ||
334 | } | ||
335 | /* old object path */ | ||
336 | devpath = kobject_get_path(kobj, GFP_KERNEL); | ||
337 | if (!devpath) { | ||
338 | error = -ENOMEM; | ||
339 | goto out; | ||
340 | } | ||
341 | devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL); | ||
342 | if (!devpath_string) { | ||
343 | error = -ENOMEM; | ||
344 | goto out; | ||
345 | } | ||
346 | sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); | ||
347 | envp[0] = devpath_string; | ||
348 | envp[1] = NULL; | ||
349 | error = sysfs_move_dir(kobj, new_parent); | ||
350 | if (error) | ||
351 | goto out; | ||
352 | old_parent = kobj->parent; | ||
353 | kobj->parent = new_parent; | ||
354 | kobject_put(old_parent); | ||
355 | kobject_uevent_env(kobj, KOBJ_MOVE, envp); | ||
356 | out: | ||
357 | kobject_put(kobj); | ||
358 | kfree(devpath_string); | ||
359 | kfree(devpath); | ||
360 | return error; | ||
361 | } | ||
362 | |||
363 | /** | ||
314 | * kobject_del - unlink kobject from hierarchy. | 364 | * kobject_del - unlink kobject from hierarchy. |
315 | * @kobj: object. | 365 | * @kobj: object. |
316 | */ | 366 | */ |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 7f20e7b857cb..a1922765ff31 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -50,18 +50,22 @@ static char *action_to_string(enum kobject_action action) | |||
50 | return "offline"; | 50 | return "offline"; |
51 | case KOBJ_ONLINE: | 51 | case KOBJ_ONLINE: |
52 | return "online"; | 52 | return "online"; |
53 | case KOBJ_MOVE: | ||
54 | return "move"; | ||
53 | default: | 55 | default: |
54 | return NULL; | 56 | return NULL; |
55 | } | 57 | } |
56 | } | 58 | } |
57 | 59 | ||
58 | /** | 60 | /** |
59 | * kobject_uevent - notify userspace by ending an uevent | 61 | * kobject_uevent_env - send an uevent with environmental data |
60 | * | 62 | * |
61 | * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) | 63 | * @action: action that is happening (usually KOBJ_MOVE) |
62 | * @kobj: struct kobject that the action is happening to | 64 | * @kobj: struct kobject that the action is happening to |
65 | * @envp_ext: pointer to environmental data | ||
63 | */ | 66 | */ |
64 | void kobject_uevent(struct kobject *kobj, enum kobject_action action) | 67 | void kobject_uevent_env(struct kobject *kobj, enum kobject_action action, |
68 | char *envp_ext[]) | ||
65 | { | 69 | { |
66 | char **envp; | 70 | char **envp; |
67 | char *buffer; | 71 | char *buffer; |
@@ -76,6 +80,7 @@ void kobject_uevent(struct kobject *kobj, enum kobject_action action) | |||
76 | char *seq_buff; | 80 | char *seq_buff; |
77 | int i = 0; | 81 | int i = 0; |
78 | int retval; | 82 | int retval; |
83 | int j; | ||
79 | 84 | ||
80 | pr_debug("%s\n", __FUNCTION__); | 85 | pr_debug("%s\n", __FUNCTION__); |
81 | 86 | ||
@@ -134,7 +139,8 @@ void kobject_uevent(struct kobject *kobj, enum kobject_action action) | |||
134 | scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1; | 139 | scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1; |
135 | envp [i++] = scratch; | 140 | envp [i++] = scratch; |
136 | scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1; | 141 | scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1; |
137 | 142 | for (j = 0; envp_ext && envp_ext[j]; j++) | |
143 | envp[i++] = envp_ext[j]; | ||
138 | /* just reserve the space, overwrite it after kset call has returned */ | 144 | /* just reserve the space, overwrite it after kset call has returned */ |
139 | envp[i++] = seq_buff = scratch; | 145 | envp[i++] = seq_buff = scratch; |
140 | scratch += strlen("SEQNUM=18446744073709551616") + 1; | 146 | scratch += strlen("SEQNUM=18446744073709551616") + 1; |
@@ -200,6 +206,20 @@ exit: | |||
200 | kfree(envp); | 206 | kfree(envp); |
201 | return; | 207 | return; |
202 | } | 208 | } |
209 | |||
210 | EXPORT_SYMBOL_GPL(kobject_uevent_env); | ||
211 | |||
212 | /** | ||
213 | * kobject_uevent - notify userspace by ending an uevent | ||
214 | * | ||
215 | * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) | ||
216 | * @kobj: struct kobject that the action is happening to | ||
217 | */ | ||
218 | void kobject_uevent(struct kobject *kobj, enum kobject_action action) | ||
219 | { | ||
220 | kobject_uevent_env(kobj, action, NULL); | ||
221 | } | ||
222 | |||
203 | EXPORT_SYMBOL_GPL(kobject_uevent); | 223 | EXPORT_SYMBOL_GPL(kobject_uevent); |
204 | 224 | ||
205 | /** | 225 | /** |
diff --git a/sound/core/init.c b/sound/core/init.c index 3058d626a90a..6152a7554dfd 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -361,6 +361,8 @@ static int snd_card_do_free(struct snd_card *card) | |||
361 | snd_printk(KERN_WARNING "unable to free card info\n"); | 361 | snd_printk(KERN_WARNING "unable to free card info\n"); |
362 | /* Not fatal error */ | 362 | /* Not fatal error */ |
363 | } | 363 | } |
364 | if (card->dev) | ||
365 | device_unregister(card->dev); | ||
364 | kfree(card); | 366 | kfree(card); |
365 | return 0; | 367 | return 0; |
366 | } | 368 | } |
@@ -495,6 +497,12 @@ int snd_card_register(struct snd_card *card) | |||
495 | int err; | 497 | int err; |
496 | 498 | ||
497 | snd_assert(card != NULL, return -EINVAL); | 499 | snd_assert(card != NULL, return -EINVAL); |
500 | if (!card->dev) { | ||
501 | card->dev = device_create(sound_class, card->parent, 0, | ||
502 | "card%i", card->number); | ||
503 | if (IS_ERR(card->dev)) | ||
504 | card->dev = NULL; | ||
505 | } | ||
498 | if ((err = snd_device_register_all(card)) < 0) | 506 | if ((err = snd_device_register_all(card)) < 0) |
499 | return err; | 507 | return err; |
500 | mutex_lock(&snd_card_mutex); | 508 | mutex_lock(&snd_card_mutex); |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index fbbbcd20c4cc..5ac6e19ccb41 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -910,7 +910,8 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) | |||
910 | substream->pstr->substream_opened--; | 910 | substream->pstr->substream_opened--; |
911 | } | 911 | } |
912 | 912 | ||
913 | static ssize_t show_pcm_class(struct class_device *class_device, char *buf) | 913 | static ssize_t show_pcm_class(struct device *dev, |
914 | struct device_attribute *attr, char *buf) | ||
914 | { | 915 | { |
915 | struct snd_pcm *pcm; | 916 | struct snd_pcm *pcm; |
916 | const char *str; | 917 | const char *str; |
@@ -921,7 +922,7 @@ static ssize_t show_pcm_class(struct class_device *class_device, char *buf) | |||
921 | [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer", | 922 | [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer", |
922 | }; | 923 | }; |
923 | 924 | ||
924 | if (! (pcm = class_get_devdata(class_device)) || | 925 | if (! (pcm = dev_get_drvdata(dev)) || |
925 | pcm->dev_class > SNDRV_PCM_CLASS_LAST) | 926 | pcm->dev_class > SNDRV_PCM_CLASS_LAST) |
926 | str = "none"; | 927 | str = "none"; |
927 | else | 928 | else |
@@ -929,7 +930,7 @@ static ssize_t show_pcm_class(struct class_device *class_device, char *buf) | |||
929 | return snprintf(buf, PAGE_SIZE, "%s\n", str); | 930 | return snprintf(buf, PAGE_SIZE, "%s\n", str); |
930 | } | 931 | } |
931 | 932 | ||
932 | static struct class_device_attribute pcm_attrs = | 933 | static struct device_attribute pcm_attrs = |
933 | __ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); | 934 | __ATTR(pcm_class, S_IRUGO, show_pcm_class, NULL); |
934 | 935 | ||
935 | static int snd_pcm_dev_register(struct snd_device *device) | 936 | static int snd_pcm_dev_register(struct snd_device *device) |
diff --git a/sound/core/sound.c b/sound/core/sound.c index efa476c5210a..282742022de6 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -61,9 +61,6 @@ EXPORT_SYMBOL(snd_ecards_limit); | |||
61 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; | 61 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
62 | static DEFINE_MUTEX(sound_mutex); | 62 | static DEFINE_MUTEX(sound_mutex); |
63 | 63 | ||
64 | extern struct class *sound_class; | ||
65 | |||
66 | |||
67 | #ifdef CONFIG_KMOD | 64 | #ifdef CONFIG_KMOD |
68 | 65 | ||
69 | /** | 66 | /** |
@@ -268,11 +265,10 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
268 | snd_minors[minor] = preg; | 265 | snd_minors[minor] = preg; |
269 | if (card) | 266 | if (card) |
270 | device = card->dev; | 267 | device = card->dev; |
271 | preg->class_dev = class_device_create(sound_class, NULL, | 268 | preg->dev = device_create(sound_class, device, MKDEV(major, minor), |
272 | MKDEV(major, minor), | 269 | "%s", name); |
273 | device, "%s", name); | 270 | if (preg->dev) |
274 | if (preg->class_dev) | 271 | dev_set_drvdata(preg->dev, private_data); |
275 | class_set_devdata(preg->class_dev, private_data); | ||
276 | 272 | ||
277 | mutex_unlock(&sound_mutex); | 273 | mutex_unlock(&sound_mutex); |
278 | return 0; | 274 | return 0; |
@@ -320,7 +316,7 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
320 | return -EINVAL; | 316 | return -EINVAL; |
321 | } | 317 | } |
322 | 318 | ||
323 | class_device_destroy(sound_class, MKDEV(major, minor)); | 319 | device_destroy(sound_class, MKDEV(major, minor)); |
324 | 320 | ||
325 | kfree(snd_minors[minor]); | 321 | kfree(snd_minors[minor]); |
326 | snd_minors[minor] = NULL; | 322 | snd_minors[minor] = NULL; |
@@ -331,15 +327,15 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) | |||
331 | EXPORT_SYMBOL(snd_unregister_device); | 327 | EXPORT_SYMBOL(snd_unregister_device); |
332 | 328 | ||
333 | int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, | 329 | int snd_add_device_sysfs_file(int type, struct snd_card *card, int dev, |
334 | const struct class_device_attribute *attr) | 330 | struct device_attribute *attr) |
335 | { | 331 | { |
336 | int minor, ret = -EINVAL; | 332 | int minor, ret = -EINVAL; |
337 | struct class_device *cdev; | 333 | struct device *d; |
338 | 334 | ||
339 | mutex_lock(&sound_mutex); | 335 | mutex_lock(&sound_mutex); |
340 | minor = find_snd_minor(type, card, dev); | 336 | minor = find_snd_minor(type, card, dev); |
341 | if (minor >= 0 && (cdev = snd_minors[minor]->class_dev) != NULL) | 337 | if (minor >= 0 && (d = snd_minors[minor]->dev) != NULL) |
342 | ret = class_device_create_file(cdev, attr); | 338 | ret = device_create_file(d, attr); |
343 | mutex_unlock(&sound_mutex); | 339 | mutex_unlock(&sound_mutex); |
344 | return ret; | 340 | return ret; |
345 | 341 | ||
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 2344d09c7114..75c5e745705f 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c | |||
@@ -557,17 +557,17 @@ static int __init oss_init(void) | |||
557 | sound_dmap_flag = (dmabuf > 0 ? 1 : 0); | 557 | sound_dmap_flag = (dmabuf > 0 ? 1 : 0); |
558 | 558 | ||
559 | for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) { | 559 | for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) { |
560 | class_device_create(sound_class, NULL, | 560 | device_create(sound_class, NULL, |
561 | MKDEV(SOUND_MAJOR, dev_list[i].minor), | 561 | MKDEV(SOUND_MAJOR, dev_list[i].minor), |
562 | NULL, "%s", dev_list[i].name); | 562 | "%s", dev_list[i].name); |
563 | 563 | ||
564 | if (!dev_list[i].num) | 564 | if (!dev_list[i].num) |
565 | continue; | 565 | continue; |
566 | 566 | ||
567 | for (j = 1; j < *dev_list[i].num; j++) | 567 | for (j = 1; j < *dev_list[i].num; j++) |
568 | class_device_create(sound_class, NULL, | 568 | device_create(sound_class, NULL, |
569 | MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)), | 569 | MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)), |
570 | NULL, "%s%d", dev_list[i].name, j); | 570 | "%s%d", dev_list[i].name, j); |
571 | } | 571 | } |
572 | 572 | ||
573 | if (sound_nblocks >= 1024) | 573 | if (sound_nblocks >= 1024) |
@@ -581,11 +581,11 @@ static void __exit oss_cleanup(void) | |||
581 | int i, j; | 581 | int i, j; |
582 | 582 | ||
583 | for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) { | 583 | for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) { |
584 | class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor)); | 584 | device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor)); |
585 | if (!dev_list[i].num) | 585 | if (!dev_list[i].num) |
586 | continue; | 586 | continue; |
587 | for (j = 1; j < *dev_list[i].num; j++) | 587 | for (j = 1; j < *dev_list[i].num; j++) |
588 | class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10))); | 588 | device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10))); |
589 | } | 589 | } |
590 | 590 | ||
591 | unregister_sound_special(1); | 591 | unregister_sound_special(1); |
diff --git a/sound/sound_core.c b/sound/sound_core.c index 5322c50c9617..8f1ced4ab34c 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c | |||
@@ -170,8 +170,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati | |||
170 | else | 170 | else |
171 | sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP); | 171 | sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP); |
172 | 172 | ||
173 | class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor), | 173 | device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor), |
174 | dev, s->name+6); | 174 | s->name+6); |
175 | return r; | 175 | return r; |
176 | 176 | ||
177 | fail: | 177 | fail: |
@@ -193,7 +193,7 @@ static void sound_remove_unit(struct sound_unit **list, int unit) | |||
193 | p = __sound_remove_unit(list, unit); | 193 | p = __sound_remove_unit(list, unit); |
194 | spin_unlock(&sound_loader_lock); | 194 | spin_unlock(&sound_loader_lock); |
195 | if (p) { | 195 | if (p) { |
196 | class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor)); | 196 | device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor)); |
197 | kfree(p); | 197 | kfree(p); |
198 | } | 198 | } |
199 | } | 199 | } |