aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/Kconfig4
-rw-r--r--drivers/base/Makefile2
-rw-r--r--drivers/base/attribute_container.c8
-rw-r--r--drivers/base/base.h9
-rw-r--r--drivers/base/bus.c28
-rw-r--r--drivers/base/class.c112
-rw-r--r--drivers/base/core.c200
-rw-r--r--drivers/base/firmware_class.c22
-rw-r--r--drivers/base/hypervisor.c19
-rw-r--r--drivers/base/init.c1
-rw-r--r--drivers/base/isa.c180
-rw-r--r--drivers/base/platform.c35
-rw-r--r--drivers/base/power/Makefile3
-rw-r--r--drivers/base/power/suspend.c17
-rw-r--r--drivers/base/sys.c51
15 files changed, 622 insertions, 69 deletions
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index f0eff3dac58d..80502dc6ed66 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -38,3 +38,7 @@ config DEBUG_DRIVER
38 If you are unsure about this, say N here. 38 If you are unsure about this, say N here.
39 39
40endmenu 40endmenu
41
42config SYS_HYPERVISOR
43 bool
44 default n
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index e99471d3232b..b539e5e75b56 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -5,10 +5,12 @@ obj-y := core.o sys.o bus.o dd.o \
5 cpu.o firmware.o init.o map.o dmapool.o \ 5 cpu.o firmware.o init.o map.o dmapool.o \
6 attribute_container.o transport_class.o 6 attribute_container.o transport_class.o
7obj-y += power/ 7obj-y += power/
8obj-$(CONFIG_ISA) += isa.o
8obj-$(CONFIG_FW_LOADER) += firmware_class.o 9obj-$(CONFIG_FW_LOADER) += firmware_class.o
9obj-$(CONFIG_NUMA) += node.o 10obj-$(CONFIG_NUMA) += node.o
10obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o 11obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o
11obj-$(CONFIG_SMP) += topology.o 12obj-$(CONFIG_SMP) += topology.o
13obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
12 14
13ifeq ($(CONFIG_DEBUG_DRIVER),y) 15ifeq ($(CONFIG_DEBUG_DRIVER),y)
14EXTRA_CFLAGS += -DDEBUG 16EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 2a7d7ae83e1e..22220733f76f 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -236,7 +236,6 @@ attribute_container_remove_device(struct device *dev,
236 } 236 }
237 up(&attribute_container_mutex); 237 up(&attribute_container_mutex);
238} 238}
239EXPORT_SYMBOL_GPL(attribute_container_remove_device);
240 239
241/** 240/**
242 * attribute_container_device_trigger - execute a trigger for each matching classdev 241 * attribute_container_device_trigger - execute a trigger for each matching classdev
@@ -276,7 +275,6 @@ attribute_container_device_trigger(struct device *dev,
276 } 275 }
277 up(&attribute_container_mutex); 276 up(&attribute_container_mutex);
278} 277}
279EXPORT_SYMBOL_GPL(attribute_container_device_trigger);
280 278
281/** 279/**
282 * attribute_container_trigger - trigger a function for each matching container 280 * attribute_container_trigger - trigger a function for each matching container
@@ -304,7 +302,6 @@ attribute_container_trigger(struct device *dev,
304 } 302 }
305 up(&attribute_container_mutex); 303 up(&attribute_container_mutex);
306} 304}
307EXPORT_SYMBOL_GPL(attribute_container_trigger);
308 305
309/** 306/**
310 * attribute_container_add_attrs - add attributes 307 * attribute_container_add_attrs - add attributes
@@ -333,7 +330,6 @@ attribute_container_add_attrs(struct class_device *classdev)
333 330
334 return 0; 331 return 0;
335} 332}
336EXPORT_SYMBOL_GPL(attribute_container_add_attrs);
337 333
338/** 334/**
339 * attribute_container_add_class_device - same function as class_device_add 335 * attribute_container_add_class_device - same function as class_device_add
@@ -352,7 +348,6 @@ attribute_container_add_class_device(struct class_device *classdev)
352 return error; 348 return error;
353 return attribute_container_add_attrs(classdev); 349 return attribute_container_add_attrs(classdev);
354} 350}
355EXPORT_SYMBOL_GPL(attribute_container_add_class_device);
356 351
357/** 352/**
358 * attribute_container_add_class_device_adapter - simple adapter for triggers 353 * attribute_container_add_class_device_adapter - simple adapter for triggers
@@ -367,7 +362,6 @@ attribute_container_add_class_device_adapter(struct attribute_container *cont,
367{ 362{
368 return attribute_container_add_class_device(classdev); 363 return attribute_container_add_class_device(classdev);
369} 364}
370EXPORT_SYMBOL_GPL(attribute_container_add_class_device_adapter);
371 365
372/** 366/**
373 * attribute_container_remove_attrs - remove any attribute files 367 * attribute_container_remove_attrs - remove any attribute files
@@ -389,7 +383,6 @@ attribute_container_remove_attrs(struct class_device *classdev)
389 for (i = 0; attrs[i]; i++) 383 for (i = 0; attrs[i]; i++)
390 class_device_remove_file(classdev, attrs[i]); 384 class_device_remove_file(classdev, attrs[i]);
391} 385}
392EXPORT_SYMBOL_GPL(attribute_container_remove_attrs);
393 386
394/** 387/**
395 * attribute_container_class_device_del - equivalent of class_device_del 388 * attribute_container_class_device_del - equivalent of class_device_del
@@ -405,7 +398,6 @@ attribute_container_class_device_del(struct class_device *classdev)
405 attribute_container_remove_attrs(classdev); 398 attribute_container_remove_attrs(classdev);
406 class_device_del(classdev); 399 class_device_del(classdev);
407} 400}
408EXPORT_SYMBOL_GPL(attribute_container_class_device_del);
409 401
410/** 402/**
411 * attribute_container_find_class_device - find the corresponding class_device 403 * attribute_container_find_class_device - find the corresponding class_device
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 5735b38582d0..c3b8dc98b8a7 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -5,13 +5,21 @@ extern int devices_init(void);
5extern int buses_init(void); 5extern int buses_init(void);
6extern int classes_init(void); 6extern int classes_init(void);
7extern int firmware_init(void); 7extern int firmware_init(void);
8#ifdef CONFIG_SYS_HYPERVISOR
9extern int hypervisor_init(void);
10#else
11static inline int hypervisor_init(void) { return 0; }
12#endif
8extern int platform_bus_init(void); 13extern int platform_bus_init(void);
9extern int system_bus_init(void); 14extern int system_bus_init(void);
10extern int cpu_dev_init(void); 15extern int cpu_dev_init(void);
11extern int attribute_container_init(void); 16extern int attribute_container_init(void);
12 17
13extern int bus_add_device(struct device * dev); 18extern int bus_add_device(struct device * dev);
19extern void bus_attach_device(struct device * dev);
14extern void bus_remove_device(struct device * dev); 20extern void bus_remove_device(struct device * dev);
21extern struct bus_type *get_bus(struct bus_type * bus);
22extern void put_bus(struct bus_type * bus);
15 23
16extern int bus_add_driver(struct device_driver *); 24extern int bus_add_driver(struct device_driver *);
17extern void bus_remove_driver(struct device_driver *); 25extern void bus_remove_driver(struct device_driver *);
@@ -34,4 +42,5 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
34 return container_of(_attr, struct class_device_attribute, attr); 42 return container_of(_attr, struct class_device_attribute, attr);
35} 43}
36 44
45extern char *make_class_name(const char *name, struct kobject *kobj);
37 46
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 76656acd00d4..050d86d0b872 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -362,8 +362,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev)
362 * @dev: device being added 362 * @dev: device being added
363 * 363 *
364 * - Add the device to its bus's list of devices. 364 * - Add the device to its bus's list of devices.
365 * - Try to attach to driver. 365 * - Create link to device's bus.
366 * - Create link to device's physical location.
367 */ 366 */
368int bus_add_device(struct device * dev) 367int bus_add_device(struct device * dev)
369{ 368{
@@ -372,11 +371,10 @@ int bus_add_device(struct device * dev)
372 371
373 if (bus) { 372 if (bus) {
374 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); 373 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
375 device_attach(dev);
376 klist_add_tail(&dev->knode_bus, &bus->klist_devices);
377 error = device_add_attrs(bus, dev); 374 error = device_add_attrs(bus, dev);
378 if (!error) { 375 if (!error) {
379 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); 376 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
377 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem");
380 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); 378 sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
381 } 379 }
382 } 380 }
@@ -384,6 +382,22 @@ int bus_add_device(struct device * dev)
384} 382}
385 383
386/** 384/**
385 * bus_attach_device - add device to bus
386 * @dev: device tried to attach to a driver
387 *
388 * - Try to attach to driver.
389 */
390void bus_attach_device(struct device * dev)
391{
392 struct bus_type * bus = dev->bus;
393
394 if (bus) {
395 device_attach(dev);
396 klist_add_tail(&dev->knode_bus, &bus->klist_devices);
397 }
398}
399
400/**
387 * bus_remove_device - remove device from bus 401 * bus_remove_device - remove device from bus
388 * @dev: device to be removed 402 * @dev: device to be removed
389 * 403 *
@@ -395,6 +409,7 @@ int bus_add_device(struct device * dev)
395void bus_remove_device(struct device * dev) 409void bus_remove_device(struct device * dev)
396{ 410{
397 if (dev->bus) { 411 if (dev->bus) {
412 sysfs_remove_link(&dev->kobj, "subsystem");
398 sysfs_remove_link(&dev->kobj, "bus"); 413 sysfs_remove_link(&dev->kobj, "bus");
399 sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); 414 sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
400 device_remove_attrs(dev->bus, dev); 415 device_remove_attrs(dev->bus, dev);
@@ -732,14 +747,9 @@ EXPORT_SYMBOL_GPL(bus_for_each_dev);
732EXPORT_SYMBOL_GPL(bus_find_device); 747EXPORT_SYMBOL_GPL(bus_find_device);
733EXPORT_SYMBOL_GPL(bus_for_each_drv); 748EXPORT_SYMBOL_GPL(bus_for_each_drv);
734 749
735EXPORT_SYMBOL_GPL(bus_add_device);
736EXPORT_SYMBOL_GPL(bus_remove_device);
737EXPORT_SYMBOL_GPL(bus_register); 750EXPORT_SYMBOL_GPL(bus_register);
738EXPORT_SYMBOL_GPL(bus_unregister); 751EXPORT_SYMBOL_GPL(bus_unregister);
739EXPORT_SYMBOL_GPL(bus_rescan_devices); 752EXPORT_SYMBOL_GPL(bus_rescan_devices);
740EXPORT_SYMBOL_GPL(get_bus);
741EXPORT_SYMBOL_GPL(put_bus);
742EXPORT_SYMBOL_GPL(find_bus);
743 753
744EXPORT_SYMBOL_GPL(bus_create_file); 754EXPORT_SYMBOL_GPL(bus_create_file);
745EXPORT_SYMBOL_GPL(bus_remove_file); 755EXPORT_SYMBOL_GPL(bus_remove_file);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index b1ea4df85c7d..9aa127460262 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -91,14 +91,14 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr)
91 sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); 91 sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr);
92} 92}
93 93
94struct class * class_get(struct class * cls) 94static struct class *class_get(struct class *cls)
95{ 95{
96 if (cls) 96 if (cls)
97 return container_of(subsys_get(&cls->subsys), struct class, subsys); 97 return container_of(subsys_get(&cls->subsys), struct class, subsys);
98 return NULL; 98 return NULL;
99} 99}
100 100
101void class_put(struct class * cls) 101static void class_put(struct class * cls)
102{ 102{
103 if (cls) 103 if (cls)
104 subsys_put(&cls->subsys); 104 subsys_put(&cls->subsys);
@@ -142,6 +142,7 @@ int class_register(struct class * cls)
142 pr_debug("device class '%s': registering\n", cls->name); 142 pr_debug("device class '%s': registering\n", cls->name);
143 143
144 INIT_LIST_HEAD(&cls->children); 144 INIT_LIST_HEAD(&cls->children);
145 INIT_LIST_HEAD(&cls->devices);
145 INIT_LIST_HEAD(&cls->interfaces); 146 INIT_LIST_HEAD(&cls->interfaces);
146 init_MUTEX(&cls->sem); 147 init_MUTEX(&cls->sem);
147 error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); 148 error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name);
@@ -504,22 +505,21 @@ void class_device_initialize(struct class_device *class_dev)
504 INIT_LIST_HEAD(&class_dev->node); 505 INIT_LIST_HEAD(&class_dev->node);
505} 506}
506 507
507static char *make_class_name(struct class_device *class_dev) 508char *make_class_name(const char *name, struct kobject *kobj)
508{ 509{
509 char *name; 510 char *class_name;
510 int size; 511 int size;
511 512
512 size = strlen(class_dev->class->name) + 513 size = strlen(name) + strlen(kobject_name(kobj)) + 2;
513 strlen(kobject_name(&class_dev->kobj)) + 2;
514 514
515 name = kmalloc(size, GFP_KERNEL); 515 class_name = kmalloc(size, GFP_KERNEL);
516 if (!name) 516 if (!class_name)
517 return ERR_PTR(-ENOMEM); 517 return ERR_PTR(-ENOMEM);
518 518
519 strcpy(name, class_dev->class->name); 519 strcpy(class_name, name);
520 strcat(name, ":"); 520 strcat(class_name, ":");
521 strcat(name, kobject_name(&class_dev->kobj)); 521 strcat(class_name, kobject_name(kobj));
522 return name; 522 return class_name;
523} 523}
524 524
525int class_device_add(struct class_device *class_dev) 525int class_device_add(struct class_device *class_dev)
@@ -535,18 +535,22 @@ int class_device_add(struct class_device *class_dev)
535 return -EINVAL; 535 return -EINVAL;
536 536
537 if (!strlen(class_dev->class_id)) 537 if (!strlen(class_dev->class_id))
538 goto register_done; 538 goto out1;
539 539
540 parent_class = class_get(class_dev->class); 540 parent_class = class_get(class_dev->class);
541 if (!parent_class) 541 if (!parent_class)
542 goto register_done; 542 goto out1;
543
543 parent_class_dev = class_device_get(class_dev->parent); 544 parent_class_dev = class_device_get(class_dev->parent);
544 545
545 pr_debug("CLASS: registering class device: ID = '%s'\n", 546 pr_debug("CLASS: registering class device: ID = '%s'\n",
546 class_dev->class_id); 547 class_dev->class_id);
547 548
548 /* first, register with generic layer. */ 549 /* first, register with generic layer. */
549 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 550 error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
551 if (error)
552 goto out2;
553
550 if (parent_class_dev) 554 if (parent_class_dev)
551 class_dev->kobj.parent = &parent_class_dev->kobj; 555 class_dev->kobj.parent = &parent_class_dev->kobj;
552 else 556 else
@@ -554,41 +558,58 @@ int class_device_add(struct class_device *class_dev)
554 558
555 error = kobject_add(&class_dev->kobj); 559 error = kobject_add(&class_dev->kobj);
556 if (error) 560 if (error)
557 goto register_done; 561 goto out2;
558 562
559 /* add the needed attributes to this device */ 563 /* add the needed attributes to this device */
564 sysfs_create_link(&class_dev->kobj, &parent_class->subsys.kset.kobj, "subsystem");
560 class_dev->uevent_attr.attr.name = "uevent"; 565 class_dev->uevent_attr.attr.name = "uevent";
561 class_dev->uevent_attr.attr.mode = S_IWUSR; 566 class_dev->uevent_attr.attr.mode = S_IWUSR;
562 class_dev->uevent_attr.attr.owner = parent_class->owner; 567 class_dev->uevent_attr.attr.owner = parent_class->owner;
563 class_dev->uevent_attr.store = store_uevent; 568 class_dev->uevent_attr.store = store_uevent;
564 class_device_create_file(class_dev, &class_dev->uevent_attr); 569 error = class_device_create_file(class_dev, &class_dev->uevent_attr);
570 if (error)
571 goto out3;
565 572
566 if (MAJOR(class_dev->devt)) { 573 if (MAJOR(class_dev->devt)) {
567 struct class_device_attribute *attr; 574 struct class_device_attribute *attr;
568 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 575 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
569 if (!attr) { 576 if (!attr) {
570 error = -ENOMEM; 577 error = -ENOMEM;
571 kobject_del(&class_dev->kobj); 578 goto out4;
572 goto register_done;
573 } 579 }
574 attr->attr.name = "dev"; 580 attr->attr.name = "dev";
575 attr->attr.mode = S_IRUGO; 581 attr->attr.mode = S_IRUGO;
576 attr->attr.owner = parent_class->owner; 582 attr->attr.owner = parent_class->owner;
577 attr->show = show_dev; 583 attr->show = show_dev;
578 class_device_create_file(class_dev, attr); 584 error = class_device_create_file(class_dev, attr);
585 if (error) {
586 kfree(attr);
587 goto out4;
588 }
589
579 class_dev->devt_attr = attr; 590 class_dev->devt_attr = attr;
580 } 591 }
581 592
582 class_device_add_attrs(class_dev); 593 error = class_device_add_attrs(class_dev);
594 if (error)
595 goto out5;
596
583 if (class_dev->dev) { 597 if (class_dev->dev) {
584 class_name = make_class_name(class_dev); 598 class_name = make_class_name(class_dev->class->name,
585 sysfs_create_link(&class_dev->kobj, 599 &class_dev->kobj);
586 &class_dev->dev->kobj, "device"); 600 error = sysfs_create_link(&class_dev->kobj,
587 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 601 &class_dev->dev->kobj, "device");
588 class_name); 602 if (error)
603 goto out6;
604 error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
605 class_name);
606 if (error)
607 goto out7;
589 } 608 }
590 609
591 class_device_add_groups(class_dev); 610 error = class_device_add_groups(class_dev);
611 if (error)
612 goto out8;
592 613
593 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 614 kobject_uevent(&class_dev->kobj, KOBJ_ADD);
594 615
@@ -601,11 +622,28 @@ int class_device_add(struct class_device *class_dev)
601 } 622 }
602 up(&parent_class->sem); 623 up(&parent_class->sem);
603 624
604 register_done: 625 goto out1;
605 if (error) { 626
606 class_put(parent_class); 627 out8:
628 if (class_dev->dev)
629 sysfs_remove_link(&class_dev->kobj, class_name);
630 out7:
631 if (class_dev->dev)
632 sysfs_remove_link(&class_dev->kobj, "device");
633 out6:
634 class_device_remove_attrs(class_dev);
635 out5:
636 if (class_dev->devt_attr)
637 class_device_remove_file(class_dev, class_dev->devt_attr);
638 out4:
639 class_device_remove_file(class_dev, &class_dev->uevent_attr);
640 out3:
641 kobject_del(&class_dev->kobj);
642 out2:
643 if(parent_class_dev)
607 class_device_put(parent_class_dev); 644 class_device_put(parent_class_dev);
608 } 645 class_put(parent_class);
646 out1:
609 class_device_put(class_dev); 647 class_device_put(class_dev);
610 kfree(class_name); 648 kfree(class_name);
611 return error; 649 return error;
@@ -695,10 +733,12 @@ void class_device_del(struct class_device *class_dev)
695 } 733 }
696 734
697 if (class_dev->dev) { 735 if (class_dev->dev) {
698 class_name = make_class_name(class_dev); 736 class_name = make_class_name(class_dev->class->name,
737 &class_dev->kobj);
699 sysfs_remove_link(&class_dev->kobj, "device"); 738 sysfs_remove_link(&class_dev->kobj, "device");
700 sysfs_remove_link(&class_dev->dev->kobj, class_name); 739 sysfs_remove_link(&class_dev->dev->kobj, class_name);
701 } 740 }
741 sysfs_remove_link(&class_dev->kobj, "subsystem");
702 class_device_remove_file(class_dev, &class_dev->uevent_attr); 742 class_device_remove_file(class_dev, &class_dev->uevent_attr);
703 if (class_dev->devt_attr) 743 if (class_dev->devt_attr)
704 class_device_remove_file(class_dev, class_dev->devt_attr); 744 class_device_remove_file(class_dev, class_dev->devt_attr);
@@ -760,14 +800,16 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
760 new_name); 800 new_name);
761 801
762 if (class_dev->dev) 802 if (class_dev->dev)
763 old_class_name = make_class_name(class_dev); 803 old_class_name = make_class_name(class_dev->class->name,
804 &class_dev->kobj);
764 805
765 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN); 806 strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
766 807
767 error = kobject_rename(&class_dev->kobj, new_name); 808 error = kobject_rename(&class_dev->kobj, new_name);
768 809
769 if (class_dev->dev) { 810 if (class_dev->dev) {
770 new_class_name = make_class_name(class_dev); 811 new_class_name = make_class_name(class_dev->class->name,
812 &class_dev->kobj);
771 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, 813 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
772 new_class_name); 814 new_class_name);
773 sysfs_remove_link(&class_dev->dev->kobj, old_class_name); 815 sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
@@ -858,8 +900,6 @@ EXPORT_SYMBOL_GPL(class_create_file);
858EXPORT_SYMBOL_GPL(class_remove_file); 900EXPORT_SYMBOL_GPL(class_remove_file);
859EXPORT_SYMBOL_GPL(class_register); 901EXPORT_SYMBOL_GPL(class_register);
860EXPORT_SYMBOL_GPL(class_unregister); 902EXPORT_SYMBOL_GPL(class_unregister);
861EXPORT_SYMBOL_GPL(class_get);
862EXPORT_SYMBOL_GPL(class_put);
863EXPORT_SYMBOL_GPL(class_create); 903EXPORT_SYMBOL_GPL(class_create);
864EXPORT_SYMBOL_GPL(class_destroy); 904EXPORT_SYMBOL_GPL(class_destroy);
865 905
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6b355bd7816d..27c2176895de 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/kdev_t.h>
18 19
19#include <asm/semaphore.h> 20#include <asm/semaphore.h>
20 21
@@ -28,6 +29,22 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
28 * sysfs bindings for devices. 29 * sysfs bindings for devices.
29 */ 30 */
30 31
32/**
33 * dev_driver_string - Return a device's driver name, if at all possible
34 * @dev: struct device to get the name of
35 *
36 * Will return the device's driver's name if it is bound to a device. If
37 * the device is not bound to a device, it will return the name of the bus
38 * it is attached to. If it is not attached to a bus either, an empty
39 * string will be returned.
40 */
41const char *dev_driver_string(struct device *dev)
42{
43 return dev->driver ? dev->driver->name :
44 (dev->bus ? dev->bus->name : "");
45}
46EXPORT_SYMBOL_GPL(dev_driver_string);
47
31#define to_dev(obj) container_of(obj, struct device, kobj) 48#define to_dev(obj) container_of(obj, struct device, kobj)
32#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) 49#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
33 50
@@ -98,6 +115,8 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
98 struct device *dev = to_dev(kobj); 115 struct device *dev = to_dev(kobj);
99 if (dev->bus) 116 if (dev->bus)
100 return 1; 117 return 1;
118 if (dev->class)
119 return 1;
101 } 120 }
102 return 0; 121 return 0;
103} 122}
@@ -106,7 +125,11 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
106{ 125{
107 struct device *dev = to_dev(kobj); 126 struct device *dev = to_dev(kobj);
108 127
109 return dev->bus->name; 128 if (dev->bus)
129 return dev->bus->name;
130 if (dev->class)
131 return dev->class->name;
132 return NULL;
110} 133}
111 134
112static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, 135static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
@@ -117,6 +140,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
117 int length = 0; 140 int length = 0;
118 int retval = 0; 141 int retval = 0;
119 142
143 /* add the major/minor if present */
144 if (MAJOR(dev->devt)) {
145 add_uevent_var(envp, num_envp, &i,
146 buffer, buffer_size, &length,
147 "MAJOR=%u", MAJOR(dev->devt));
148 add_uevent_var(envp, num_envp, &i,
149 buffer, buffer_size, &length,
150 "MINOR=%u", MINOR(dev->devt));
151 }
152
120 /* add bus name of physical device */ 153 /* add bus name of physical device */
121 if (dev->bus) 154 if (dev->bus)
122 add_uevent_var(envp, num_envp, &i, 155 add_uevent_var(envp, num_envp, &i,
@@ -161,6 +194,12 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
161 return count; 194 return count;
162} 195}
163 196
197static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
198 char *buf)
199{
200 return print_dev_t(buf, dev->devt);
201}
202
164/* 203/*
165 * devices_subsys - structure to be registered with kobject core. 204 * devices_subsys - structure to be registered with kobject core.
166 */ 205 */
@@ -231,6 +270,7 @@ void device_initialize(struct device *dev)
231 klist_init(&dev->klist_children, klist_children_get, 270 klist_init(&dev->klist_children, klist_children_get,
232 klist_children_put); 271 klist_children_put);
233 INIT_LIST_HEAD(&dev->dma_pools); 272 INIT_LIST_HEAD(&dev->dma_pools);
273 INIT_LIST_HEAD(&dev->node);
234 init_MUTEX(&dev->sem); 274 init_MUTEX(&dev->sem);
235 device_init_wakeup(dev, 0); 275 device_init_wakeup(dev, 0);
236} 276}
@@ -249,6 +289,7 @@ void device_initialize(struct device *dev)
249int device_add(struct device *dev) 289int device_add(struct device *dev)
250{ 290{
251 struct device *parent = NULL; 291 struct device *parent = NULL;
292 char *class_name = NULL;
252 int error = -EINVAL; 293 int error = -EINVAL;
253 294
254 dev = get_device(dev); 295 dev = get_device(dev);
@@ -274,23 +315,69 @@ int device_add(struct device *dev)
274 dev->uevent_attr.store = store_uevent; 315 dev->uevent_attr.store = store_uevent;
275 device_create_file(dev, &dev->uevent_attr); 316 device_create_file(dev, &dev->uevent_attr);
276 317
277 kobject_uevent(&dev->kobj, KOBJ_ADD); 318 if (MAJOR(dev->devt)) {
319 struct device_attribute *attr;
320 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
321 if (!attr) {
322 error = -ENOMEM;
323 goto PMError;
324 }
325 attr->attr.name = "dev";
326 attr->attr.mode = S_IRUGO;
327 if (dev->driver)
328 attr->attr.owner = dev->driver->owner;
329 attr->show = show_dev;
330 error = device_create_file(dev, attr);
331 if (error) {
332 kfree(attr);
333 goto attrError;
334 }
335
336 dev->devt_attr = attr;
337 }
338
339 if (dev->class) {
340 sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj,
341 "subsystem");
342 sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj,
343 dev->bus_id);
344
345 sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
346 class_name = make_class_name(dev->class->name, &dev->kobj);
347 sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
348 }
349
278 if ((error = device_pm_add(dev))) 350 if ((error = device_pm_add(dev)))
279 goto PMError; 351 goto PMError;
280 if ((error = bus_add_device(dev))) 352 if ((error = bus_add_device(dev)))
281 goto BusError; 353 goto BusError;
354 kobject_uevent(&dev->kobj, KOBJ_ADD);
355 bus_attach_device(dev);
282 if (parent) 356 if (parent)
283 klist_add_tail(&dev->knode_parent, &parent->klist_children); 357 klist_add_tail(&dev->knode_parent, &parent->klist_children);
284 358
359 if (dev->class) {
360 /* tie the class to the device */
361 down(&dev->class->sem);
362 list_add_tail(&dev->node, &dev->class->devices);
363 up(&dev->class->sem);
364 }
365
285 /* notify platform of device entry */ 366 /* notify platform of device entry */
286 if (platform_notify) 367 if (platform_notify)
287 platform_notify(dev); 368 platform_notify(dev);
288 Done: 369 Done:
370 kfree(class_name);
289 put_device(dev); 371 put_device(dev);
290 return error; 372 return error;
291 BusError: 373 BusError:
292 device_pm_remove(dev); 374 device_pm_remove(dev);
293 PMError: 375 PMError:
376 if (dev->devt_attr) {
377 device_remove_file(dev, dev->devt_attr);
378 kfree(dev->devt_attr);
379 }
380 attrError:
294 kobject_uevent(&dev->kobj, KOBJ_REMOVE); 381 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
295 kobject_del(&dev->kobj); 382 kobject_del(&dev->kobj);
296 Error: 383 Error:
@@ -362,9 +449,23 @@ void put_device(struct device * dev)
362void device_del(struct device * dev) 449void device_del(struct device * dev)
363{ 450{
364 struct device * parent = dev->parent; 451 struct device * parent = dev->parent;
452 char *class_name = NULL;
365 453
366 if (parent) 454 if (parent)
367 klist_del(&dev->knode_parent); 455 klist_del(&dev->knode_parent);
456 if (dev->devt_attr)
457 device_remove_file(dev, dev->devt_attr);
458 if (dev->class) {
459 sysfs_remove_link(&dev->kobj, "subsystem");
460 sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id);
461 class_name = make_class_name(dev->class->name, &dev->kobj);
462 sysfs_remove_link(&dev->kobj, "device");
463 sysfs_remove_link(&dev->parent->kobj, class_name);
464 kfree(class_name);
465 down(&dev->class->sem);
466 list_del_init(&dev->node);
467 up(&dev->class->sem);
468 }
368 device_remove_file(dev, &dev->uevent_attr); 469 device_remove_file(dev, &dev->uevent_attr);
369 470
370 /* Notify the platform of the removal, in case they 471 /* Notify the platform of the removal, in case they
@@ -449,3 +550,98 @@ EXPORT_SYMBOL_GPL(put_device);
449 550
450EXPORT_SYMBOL_GPL(device_create_file); 551EXPORT_SYMBOL_GPL(device_create_file);
451EXPORT_SYMBOL_GPL(device_remove_file); 552EXPORT_SYMBOL_GPL(device_remove_file);
553
554
555static void device_create_release(struct device *dev)
556{
557 pr_debug("%s called for %s\n", __FUNCTION__, dev->bus_id);
558 kfree(dev);
559}
560
561/**
562 * device_create - creates a device and registers it with sysfs
563 * @cs: pointer to the struct class that this device should be registered to.
564 * @parent: pointer to the parent struct device of this new device, if any.
565 * @dev: the dev_t for the char device to be added.
566 * @fmt: string for the class device's name
567 *
568 * This function can be used by char device classes. A struct
569 * device will be created in sysfs, registered to the specified
570 * class.
571 * A "dev" file will be created, showing the dev_t for the device, if
572 * the dev_t is not 0,0.
573 * If a pointer to a parent struct device is passed in, the newly
574 * created struct device will be a child of that device in sysfs. The
575 * pointer to the struct device will be returned from the call. Any
576 * further sysfs files that might be required can be created using this
577 * pointer.
578 *
579 * Note: the struct class passed to this function must have previously
580 * been created with a call to class_create().
581 */
582struct device *device_create(struct class *class, struct device *parent,
583 dev_t devt, char *fmt, ...)
584{
585 va_list args;
586 struct device *dev = NULL;
587 int retval = -ENODEV;
588
589 if (class == NULL || IS_ERR(class))
590 goto error;
591 if (parent == NULL) {
592 printk(KERN_WARNING "%s does not work yet for NULL parents\n", __FUNCTION__);
593 goto error;
594 }
595
596 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
597 if (!dev) {
598 retval = -ENOMEM;
599 goto error;
600 }
601
602 dev->devt = devt;
603 dev->class = class;
604 dev->parent = parent;
605 dev->release = device_create_release;
606
607 va_start(args, fmt);
608 vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
609 va_end(args);
610 retval = device_register(dev);
611 if (retval)
612 goto error;
613
614 return dev;
615
616error:
617 kfree(dev);
618 return ERR_PTR(retval);
619}
620EXPORT_SYMBOL_GPL(device_create);
621
622/**
623 * device_destroy - removes a device that was created with device_create()
624 * @class: the pointer to the struct class that this device was registered * with.
625 * @dev: the dev_t of the device that was previously registered.
626 *
627 * This call unregisters and cleans up a class device that was created with a
628 * call to class_device_create()
629 */
630void device_destroy(struct class *class, dev_t devt)
631{
632 struct device *dev = NULL;
633 struct device *dev_tmp;
634
635 down(&class->sem);
636 list_for_each_entry(dev_tmp, &class->devices, node) {
637 if (dev_tmp->devt == devt) {
638 dev = dev_tmp;
639 break;
640 }
641 }
642 up(&class->sem);
643
644 if (dev)
645 device_unregister(dev);
646}
647EXPORT_SYMBOL_GPL(device_destroy);
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 0c99ae6a3407..5d6c011183f5 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -15,7 +15,7 @@
15#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/bitops.h> 17#include <linux/bitops.h>
18#include <asm/semaphore.h> 18#include <linux/mutex.h>
19 19
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include "base.h" 21#include "base.h"
@@ -36,7 +36,7 @@ static int loading_timeout = 10; /* In seconds */
36 36
37/* fw_lock could be moved to 'struct firmware_priv' but since it is just 37/* fw_lock could be moved to 'struct firmware_priv' but since it is just
38 * guarding for corner cases a global lock should be OK */ 38 * guarding for corner cases a global lock should be OK */
39static DECLARE_MUTEX(fw_lock); 39static DEFINE_MUTEX(fw_lock);
40 40
41struct firmware_priv { 41struct firmware_priv {
42 char fw_id[FIRMWARE_NAME_MAX]; 42 char fw_id[FIRMWARE_NAME_MAX];
@@ -142,9 +142,9 @@ firmware_loading_store(struct class_device *class_dev,
142 142
143 switch (loading) { 143 switch (loading) {
144 case 1: 144 case 1:
145 down(&fw_lock); 145 mutex_lock(&fw_lock);
146 if (!fw_priv->fw) { 146 if (!fw_priv->fw) {
147 up(&fw_lock); 147 mutex_unlock(&fw_lock);
148 break; 148 break;
149 } 149 }
150 vfree(fw_priv->fw->data); 150 vfree(fw_priv->fw->data);
@@ -152,7 +152,7 @@ firmware_loading_store(struct class_device *class_dev,
152 fw_priv->fw->size = 0; 152 fw_priv->fw->size = 0;
153 fw_priv->alloc_size = 0; 153 fw_priv->alloc_size = 0;
154 set_bit(FW_STATUS_LOADING, &fw_priv->status); 154 set_bit(FW_STATUS_LOADING, &fw_priv->status);
155 up(&fw_lock); 155 mutex_unlock(&fw_lock);
156 break; 156 break;
157 case 0: 157 case 0:
158 if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { 158 if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
@@ -185,7 +185,7 @@ firmware_data_read(struct kobject *kobj,
185 struct firmware *fw; 185 struct firmware *fw;
186 ssize_t ret_count = count; 186 ssize_t ret_count = count;
187 187
188 down(&fw_lock); 188 mutex_lock(&fw_lock);
189 fw = fw_priv->fw; 189 fw = fw_priv->fw;
190 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { 190 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
191 ret_count = -ENODEV; 191 ret_count = -ENODEV;
@@ -200,7 +200,7 @@ firmware_data_read(struct kobject *kobj,
200 200
201 memcpy(buffer, fw->data + offset, ret_count); 201 memcpy(buffer, fw->data + offset, ret_count);
202out: 202out:
203 up(&fw_lock); 203 mutex_unlock(&fw_lock);
204 return ret_count; 204 return ret_count;
205} 205}
206 206
@@ -253,7 +253,7 @@ firmware_data_write(struct kobject *kobj,
253 if (!capable(CAP_SYS_RAWIO)) 253 if (!capable(CAP_SYS_RAWIO))
254 return -EPERM; 254 return -EPERM;
255 255
256 down(&fw_lock); 256 mutex_lock(&fw_lock);
257 fw = fw_priv->fw; 257 fw = fw_priv->fw;
258 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { 258 if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) {
259 retval = -ENODEV; 259 retval = -ENODEV;
@@ -268,7 +268,7 @@ firmware_data_write(struct kobject *kobj,
268 fw->size = max_t(size_t, offset + count, fw->size); 268 fw->size = max_t(size_t, offset + count, fw->size);
269 retval = count; 269 retval = count;
270out: 270out:
271 up(&fw_lock); 271 mutex_unlock(&fw_lock);
272 return retval; 272 return retval;
273} 273}
274 274
@@ -436,14 +436,14 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
436 } else 436 } else
437 wait_for_completion(&fw_priv->completion); 437 wait_for_completion(&fw_priv->completion);
438 438
439 down(&fw_lock); 439 mutex_lock(&fw_lock);
440 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { 440 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
441 retval = -ENOENT; 441 retval = -ENOENT;
442 release_firmware(fw_priv->fw); 442 release_firmware(fw_priv->fw);
443 *firmware_p = NULL; 443 *firmware_p = NULL;
444 } 444 }
445 fw_priv->fw = NULL; 445 fw_priv->fw = NULL;
446 up(&fw_lock); 446 mutex_unlock(&fw_lock);
447 class_device_unregister(class_dev); 447 class_device_unregister(class_dev);
448 goto out; 448 goto out;
449 449
diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c
new file mode 100644
index 000000000000..0c85e9d6a448
--- /dev/null
+++ b/drivers/base/hypervisor.c
@@ -0,0 +1,19 @@
1/*
2 * hypervisor.c - /sys/hypervisor subsystem.
3 *
4 * This file is released under the GPLv2
5 *
6 */
7
8#include <linux/kobject.h>
9#include <linux/device.h>
10
11#include "base.h"
12
13decl_subsys(hypervisor, NULL, NULL);
14EXPORT_SYMBOL_GPL(hypervisor_subsys);
15
16int __init hypervisor_init(void)
17{
18 return subsystem_register(&hypervisor_subsys);
19}
diff --git a/drivers/base/init.c b/drivers/base/init.c
index c648914b9cde..37138154f9e8 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -27,6 +27,7 @@ void __init driver_init(void)
27 buses_init(); 27 buses_init();
28 classes_init(); 28 classes_init();
29 firmware_init(); 29 firmware_init();
30 hypervisor_init();
30 31
31 /* These are also core pieces, but must come after the 32 /* These are also core pieces, but must come after the
32 * core core pieces. 33 * core core pieces.
diff --git a/drivers/base/isa.c b/drivers/base/isa.c
new file mode 100644
index 000000000000..d2222397a401
--- /dev/null
+++ b/drivers/base/isa.c
@@ -0,0 +1,180 @@
1/*
2 * ISA bus.
3 */
4
5#include <linux/device.h>
6#include <linux/kernel.h>
7#include <linux/slab.h>
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/isa.h>
11
12static struct device isa_bus = {
13 .bus_id = "isa"
14};
15
16struct isa_dev {
17 struct device dev;
18 struct device *next;
19 unsigned int id;
20};
21
22#define to_isa_dev(x) container_of((x), struct isa_dev, dev)
23
24static int isa_bus_match(struct device *dev, struct device_driver *driver)
25{
26 struct isa_driver *isa_driver = to_isa_driver(driver);
27
28 if (dev->platform_data == isa_driver) {
29 if (!isa_driver->match ||
30 isa_driver->match(dev, to_isa_dev(dev)->id))
31 return 1;
32 dev->platform_data = NULL;
33 }
34 return 0;
35}
36
37static int isa_bus_probe(struct device *dev)
38{
39 struct isa_driver *isa_driver = dev->platform_data;
40
41 if (isa_driver->probe)
42 return isa_driver->probe(dev, to_isa_dev(dev)->id);
43
44 return 0;
45}
46
47static int isa_bus_remove(struct device *dev)
48{
49 struct isa_driver *isa_driver = dev->platform_data;
50
51 if (isa_driver->remove)
52 return isa_driver->remove(dev, to_isa_dev(dev)->id);
53
54 return 0;
55}
56
57static void isa_bus_shutdown(struct device *dev)
58{
59 struct isa_driver *isa_driver = dev->platform_data;
60
61 if (isa_driver->shutdown)
62 isa_driver->shutdown(dev, to_isa_dev(dev)->id);
63}
64
65static int isa_bus_suspend(struct device *dev, pm_message_t state)
66{
67 struct isa_driver *isa_driver = dev->platform_data;
68
69 if (isa_driver->suspend)
70 return isa_driver->suspend(dev, to_isa_dev(dev)->id, state);
71
72 return 0;
73}
74
75static int isa_bus_resume(struct device *dev)
76{
77 struct isa_driver *isa_driver = dev->platform_data;
78
79 if (isa_driver->resume)
80 return isa_driver->resume(dev, to_isa_dev(dev)->id);
81
82 return 0;
83}
84
85static struct bus_type isa_bus_type = {
86 .name = "isa",
87 .match = isa_bus_match,
88 .probe = isa_bus_probe,
89 .remove = isa_bus_remove,
90 .shutdown = isa_bus_shutdown,
91 .suspend = isa_bus_suspend,
92 .resume = isa_bus_resume
93};
94
95static void isa_dev_release(struct device *dev)
96{
97 kfree(to_isa_dev(dev));
98}
99
100void isa_unregister_driver(struct isa_driver *isa_driver)
101{
102 struct device *dev = isa_driver->devices;
103
104 while (dev) {
105 struct device *tmp = to_isa_dev(dev)->next;
106 device_unregister(dev);
107 dev = tmp;
108 }
109 driver_unregister(&isa_driver->driver);
110}
111EXPORT_SYMBOL_GPL(isa_unregister_driver);
112
113int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev)
114{
115 int error;
116 unsigned int id;
117
118 isa_driver->driver.bus = &isa_bus_type;
119 isa_driver->devices = NULL;
120
121 error = driver_register(&isa_driver->driver);
122 if (error)
123 return error;
124
125 for (id = 0; id < ndev; id++) {
126 struct isa_dev *isa_dev;
127
128 isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL);
129 if (!isa_dev) {
130 error = -ENOMEM;
131 break;
132 }
133
134 isa_dev->dev.parent = &isa_bus;
135 isa_dev->dev.bus = &isa_bus_type;
136
137 snprintf(isa_dev->dev.bus_id, BUS_ID_SIZE, "%s.%u",
138 isa_driver->driver.name, id);
139
140 isa_dev->dev.platform_data = isa_driver;
141 isa_dev->dev.release = isa_dev_release;
142 isa_dev->id = id;
143
144 error = device_register(&isa_dev->dev);
145 if (error) {
146 put_device(&isa_dev->dev);
147 break;
148 }
149
150 if (isa_dev->dev.platform_data) {
151 isa_dev->next = isa_driver->devices;
152 isa_driver->devices = &isa_dev->dev;
153 } else
154 device_unregister(&isa_dev->dev);
155 }
156
157 if (!error && !isa_driver->devices)
158 error = -ENODEV;
159
160 if (error)
161 isa_unregister_driver(isa_driver);
162
163 return error;
164}
165EXPORT_SYMBOL_GPL(isa_register_driver);
166
167static int __init isa_bus_init(void)
168{
169 int error;
170
171 error = bus_register(&isa_bus_type);
172 if (!error) {
173 error = device_register(&isa_bus);
174 if (error)
175 bus_unregister(&isa_bus_type);
176 }
177 return error;
178}
179
180device_initcall(isa_bus_init);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 83f5c5984d1a..2b8755db76c6 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -275,7 +275,7 @@ int platform_device_add(struct platform_device *pdev)
275 pr_debug("Registering platform device '%s'. Parent at %s\n", 275 pr_debug("Registering platform device '%s'. Parent at %s\n",
276 pdev->dev.bus_id, pdev->dev.parent->bus_id); 276 pdev->dev.bus_id, pdev->dev.parent->bus_id);
277 277
278 ret = device_register(&pdev->dev); 278 ret = device_add(&pdev->dev);
279 if (ret == 0) 279 if (ret == 0)
280 return ret; 280 return ret;
281 281
@@ -452,6 +452,37 @@ void platform_driver_unregister(struct platform_driver *drv)
452EXPORT_SYMBOL_GPL(platform_driver_unregister); 452EXPORT_SYMBOL_GPL(platform_driver_unregister);
453 453
454 454
455/* modalias support enables more hands-off userspace setup:
456 * (a) environment variable lets new-style hotplug events work once system is
457 * fully running: "modprobe $MODALIAS"
458 * (b) sysfs attribute lets new-style coldplug recover from hotplug events
459 * mishandled before system is fully running: "modprobe $(cat modalias)"
460 */
461static ssize_t
462modalias_show(struct device *dev, struct device_attribute *a, char *buf)
463{
464 struct platform_device *pdev = to_platform_device(dev);
465 int len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->name);
466
467 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
468}
469
470static struct device_attribute platform_dev_attrs[] = {
471 __ATTR_RO(modalias),
472 __ATTR_NULL,
473};
474
475static int platform_uevent(struct device *dev, char **envp, int num_envp,
476 char *buffer, int buffer_size)
477{
478 struct platform_device *pdev = to_platform_device(dev);
479
480 envp[0] = buffer;
481 snprintf(buffer, buffer_size, "MODALIAS=%s", pdev->name);
482 return 0;
483}
484
485
455/** 486/**
456 * platform_match - bind platform device to platform driver. 487 * platform_match - bind platform device to platform driver.
457 * @dev: device. 488 * @dev: device.
@@ -496,7 +527,9 @@ static int platform_resume(struct device * dev)
496 527
497struct bus_type platform_bus_type = { 528struct bus_type platform_bus_type = {
498 .name = "platform", 529 .name = "platform",
530 .dev_attrs = platform_dev_attrs,
499 .match = platform_match, 531 .match = platform_match,
532 .uevent = platform_uevent,
500 .suspend = platform_suspend, 533 .suspend = platform_suspend,
501 .resume = platform_resume, 534 .resume = platform_resume,
502}; 535};
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index c0219ad94aca..ceeeba2c56c7 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -4,3 +4,6 @@ obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o
4ifeq ($(CONFIG_DEBUG_DRIVER),y) 4ifeq ($(CONFIG_DEBUG_DRIVER),y)
5EXTRA_CFLAGS += -DDEBUG 5EXTRA_CFLAGS += -DDEBUG
6endif 6endif
7ifeq ($(CONFIG_PM_DEBUG),y)
8EXTRA_CFLAGS += -DDEBUG
9endif
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 2a769cc6f5f9..1a1fe43a3057 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -29,6 +29,15 @@
29 * lists. This way, the ancestors will be accessed before their descendents. 29 * lists. This way, the ancestors will be accessed before their descendents.
30 */ 30 */
31 31
32static inline char *suspend_verb(u32 event)
33{
34 switch (event) {
35 case PM_EVENT_SUSPEND: return "suspend";
36 case PM_EVENT_FREEZE: return "freeze";
37 default: return "(unknown suspend event)";
38 }
39}
40
32 41
33/** 42/**
34 * suspend_device - Save state of one device. 43 * suspend_device - Save state of one device.
@@ -57,7 +66,13 @@ int suspend_device(struct device * dev, pm_message_t state)
57 dev->power.prev_state = dev->power.power_state; 66 dev->power.prev_state = dev->power.power_state;
58 67
59 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { 68 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
60 dev_dbg(dev, "suspending\n"); 69 dev_dbg(dev, "%s%s\n",
70 suspend_verb(state.event),
71 ((state.event == PM_EVENT_SUSPEND)
72 && device_may_wakeup(dev))
73 ? ", may wakeup"
74 : ""
75 );
61 error = dev->bus->suspend(dev, state); 76 error = dev->bus->suspend(dev, state);
62 suspend_report_result(dev->bus->suspend, error); 77 suspend_report_result(dev->bus->suspend, error);
63 } 78 }
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 6fc23ab127bd..6858178b3aff 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -80,10 +80,59 @@ void sysdev_remove_file(struct sys_device * s, struct sysdev_attribute * a)
80EXPORT_SYMBOL_GPL(sysdev_create_file); 80EXPORT_SYMBOL_GPL(sysdev_create_file);
81EXPORT_SYMBOL_GPL(sysdev_remove_file); 81EXPORT_SYMBOL_GPL(sysdev_remove_file);
82 82
83#define to_sysdev_class(k) container_of(k, struct sysdev_class, kset.kobj)
84#define to_sysdev_class_attr(a) container_of(a, \
85 struct sysdev_class_attribute, attr)
86
87static ssize_t sysdev_class_show(struct kobject *kobj, struct attribute *attr,
88 char *buffer)
89{
90 struct sysdev_class * class = to_sysdev_class(kobj);
91 struct sysdev_class_attribute *class_attr = to_sysdev_class_attr(attr);
92
93 if (class_attr->show)
94 return class_attr->show(class, buffer);
95 return -EIO;
96}
97
98static ssize_t sysdev_class_store(struct kobject *kobj, struct attribute *attr,
99 const char *buffer, size_t count)
100{
101 struct sysdev_class * class = to_sysdev_class(kobj);
102 struct sysdev_class_attribute * class_attr = to_sysdev_class_attr(attr);
103
104 if (class_attr->store)
105 return class_attr->store(class, buffer, count);
106 return -EIO;
107}
108
109static struct sysfs_ops sysfs_class_ops = {
110 .show = sysdev_class_show,
111 .store = sysdev_class_store,
112};
113
114static struct kobj_type ktype_sysdev_class = {
115 .sysfs_ops = &sysfs_class_ops,
116};
117
118int sysdev_class_create_file(struct sysdev_class *c,
119 struct sysdev_class_attribute *a)
120{
121 return sysfs_create_file(&c->kset.kobj, &a->attr);
122}
123EXPORT_SYMBOL_GPL(sysdev_class_create_file);
124
125void sysdev_class_remove_file(struct sysdev_class *c,
126 struct sysdev_class_attribute *a)
127{
128 sysfs_remove_file(&c->kset.kobj, &a->attr);
129}
130EXPORT_SYMBOL_GPL(sysdev_class_remove_file);
131
83/* 132/*
84 * declare system_subsys 133 * declare system_subsys
85 */ 134 */
86static decl_subsys(system, &ktype_sysdev, NULL); 135static decl_subsys(system, &ktype_sysdev_class, NULL);
87 136
88int sysdev_class_register(struct sysdev_class * cls) 137int sysdev_class_register(struct sysdev_class * cls)
89{ 138{