diff options
Diffstat (limited to 'drivers')
92 files changed, 4671 insertions, 2356 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index f4487c38d9f2..1b4cf984b081 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -743,7 +743,7 @@ static int __init acpi_bus_init(void) | |||
743 | return -ENODEV; | 743 | return -ENODEV; |
744 | } | 744 | } |
745 | 745 | ||
746 | decl_subsys(acpi, NULL, NULL); | 746 | struct kobject *acpi_kobj; |
747 | 747 | ||
748 | static int __init acpi_init(void) | 748 | static int __init acpi_init(void) |
749 | { | 749 | { |
@@ -755,10 +755,11 @@ static int __init acpi_init(void) | |||
755 | return -ENODEV; | 755 | return -ENODEV; |
756 | } | 756 | } |
757 | 757 | ||
758 | result = firmware_register(&acpi_subsys); | 758 | acpi_kobj = kobject_create_and_add("acpi", firmware_kobj); |
759 | if (result < 0) | 759 | if (!acpi_kobj) { |
760 | printk(KERN_WARNING "%s: firmware_register error: %d\n", | 760 | printk(KERN_WARNING "%s: kset create error\n", __FUNCTION__); |
761 | __FUNCTION__, result); | 761 | acpi_kobj = NULL; |
762 | } | ||
762 | 763 | ||
763 | result = acpi_bus_init(); | 764 | result = acpi_bus_init(); |
764 | 765 | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index c9f526e55392..5400ea173f6f 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -911,7 +911,7 @@ __setup("acpi_irq_balance", acpi_irq_balance_set); | |||
911 | 911 | ||
912 | /* FIXME: we will remove this interface after all drivers call pci_disable_device */ | 912 | /* FIXME: we will remove this interface after all drivers call pci_disable_device */ |
913 | static struct sysdev_class irqrouter_sysdev_class = { | 913 | static struct sysdev_class irqrouter_sysdev_class = { |
914 | set_kset_name("irqrouter"), | 914 | .name = "irqrouter", |
915 | .resume = irqrouter_resume, | 915 | .resume = irqrouter_resume, |
916 | }; | 916 | }; |
917 | 917 | ||
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index edee2806e37b..5ffe0ea18967 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -58,7 +58,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); | |||
58 | FS Interface (/sys) | 58 | FS Interface (/sys) |
59 | -------------------------------------------------------------------------- */ | 59 | -------------------------------------------------------------------------- */ |
60 | static LIST_HEAD(acpi_table_attr_list); | 60 | static LIST_HEAD(acpi_table_attr_list); |
61 | static struct kobject tables_kobj; | 61 | static struct kobject *tables_kobj; |
62 | 62 | ||
63 | struct acpi_table_attr { | 63 | struct acpi_table_attr { |
64 | struct bin_attribute attr; | 64 | struct bin_attribute attr; |
@@ -135,11 +135,9 @@ static int acpi_system_sysfs_init(void) | |||
135 | int table_index = 0; | 135 | int table_index = 0; |
136 | int result; | 136 | int result; |
137 | 137 | ||
138 | tables_kobj.parent = &acpi_subsys.kobj; | 138 | tables_kobj = kobject_create_and_add("tables", acpi_kobj); |
139 | kobject_set_name(&tables_kobj, "tables"); | 139 | if (!tables_kobj) |
140 | result = kobject_register(&tables_kobj); | 140 | return -ENOMEM; |
141 | if (result) | ||
142 | return result; | ||
143 | 141 | ||
144 | do { | 142 | do { |
145 | result = acpi_get_table_by_index(table_index, &table_header); | 143 | result = acpi_get_table_by_index(table_index, &table_header); |
@@ -153,7 +151,7 @@ static int acpi_system_sysfs_init(void) | |||
153 | 151 | ||
154 | acpi_table_attr_init(table_attr, table_header); | 152 | acpi_table_attr_init(table_attr, table_header); |
155 | result = | 153 | result = |
156 | sysfs_create_bin_file(&tables_kobj, | 154 | sysfs_create_bin_file(tables_kobj, |
157 | &table_attr->attr); | 155 | &table_attr->attr); |
158 | if (result) { | 156 | if (result) { |
159 | kfree(table_attr); | 157 | kfree(table_attr); |
@@ -163,6 +161,7 @@ static int acpi_system_sysfs_init(void) | |||
163 | &acpi_table_attr_list); | 161 | &acpi_table_attr_list); |
164 | } | 162 | } |
165 | } while (!result); | 163 | } while (!result); |
164 | kobject_uevent(tables_kobj, KOBJ_ADD); | ||
166 | 165 | ||
167 | return 0; | 166 | return 0; |
168 | } | 167 | } |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index b39ea3f59c9b..63e09c015ca0 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -11,6 +11,9 @@ obj-$(CONFIG_FW_LOADER) += firmware_class.o | |||
11 | obj-$(CONFIG_NUMA) += node.o | 11 | obj-$(CONFIG_NUMA) += node.o |
12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o | 12 | obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o |
13 | obj-$(CONFIG_SMP) += topology.o | 13 | obj-$(CONFIG_SMP) += topology.o |
14 | ifeq ($(CONFIG_SYSFS),y) | ||
15 | obj-$(CONFIG_MODULES) += module.o | ||
16 | endif | ||
14 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o | 17 | obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o |
15 | 18 | ||
16 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 19 | ifeq ($(CONFIG_DEBUG_DRIVER),y) |
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 7370d7cf5988..d4dfb97de3b0 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c | |||
@@ -61,7 +61,7 @@ attribute_container_classdev_to_container(struct class_device *classdev) | |||
61 | } | 61 | } |
62 | EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container); | 62 | EXPORT_SYMBOL_GPL(attribute_container_classdev_to_container); |
63 | 63 | ||
64 | static struct list_head attribute_container_list; | 64 | static LIST_HEAD(attribute_container_list); |
65 | 65 | ||
66 | static DEFINE_MUTEX(attribute_container_mutex); | 66 | static DEFINE_MUTEX(attribute_container_mutex); |
67 | 67 | ||
@@ -429,10 +429,3 @@ attribute_container_find_class_device(struct attribute_container *cont, | |||
429 | return cdev; | 429 | return cdev; |
430 | } | 430 | } |
431 | EXPORT_SYMBOL_GPL(attribute_container_find_class_device); | 431 | EXPORT_SYMBOL_GPL(attribute_container_find_class_device); |
432 | |||
433 | int __init | ||
434 | attribute_container_init(void) | ||
435 | { | ||
436 | INIT_LIST_HEAD(&attribute_container_list); | ||
437 | return 0; | ||
438 | } | ||
diff --git a/drivers/base/base.h b/drivers/base/base.h index 10b2fb6c9ce6..c0444146c09a 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -1,6 +1,42 @@ | |||
1 | 1 | ||
2 | /* initialisation functions */ | 2 | /** |
3 | * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. | ||
4 | * | ||
5 | * @subsys - the struct kset that defines this bus. This is the main kobject | ||
6 | * @drivers_kset - the list of drivers associated with this bus | ||
7 | * @devices_kset - the list of devices associated with this bus | ||
8 | * @klist_devices - the klist to iterate over the @devices_kset | ||
9 | * @klist_drivers - the klist to iterate over the @drivers_kset | ||
10 | * @bus_notifier - the bus notifier list for anything that cares about things | ||
11 | * on this bus. | ||
12 | * @bus - pointer back to the struct bus_type that this structure is associated | ||
13 | * with. | ||
14 | * | ||
15 | * This structure is the one that is the actual kobject allowing struct | ||
16 | * bus_type to be statically allocated safely. Nothing outside of the driver | ||
17 | * core should ever touch these fields. | ||
18 | */ | ||
19 | struct bus_type_private { | ||
20 | struct kset subsys; | ||
21 | struct kset *drivers_kset; | ||
22 | struct kset *devices_kset; | ||
23 | struct klist klist_devices; | ||
24 | struct klist klist_drivers; | ||
25 | struct blocking_notifier_head bus_notifier; | ||
26 | unsigned int drivers_autoprobe:1; | ||
27 | struct bus_type *bus; | ||
28 | }; | ||
29 | |||
30 | struct driver_private { | ||
31 | struct kobject kobj; | ||
32 | struct klist klist_devices; | ||
33 | struct klist_node knode_bus; | ||
34 | struct module_kobject *mkobj; | ||
35 | struct device_driver *driver; | ||
36 | }; | ||
37 | #define to_driver(obj) container_of(obj, struct driver_private, kobj) | ||
3 | 38 | ||
39 | /* initialisation functions */ | ||
4 | extern int devices_init(void); | 40 | extern int devices_init(void); |
5 | extern int buses_init(void); | 41 | extern int buses_init(void); |
6 | extern int classes_init(void); | 42 | extern int classes_init(void); |
@@ -13,17 +49,16 @@ static inline int hypervisor_init(void) { return 0; } | |||
13 | extern int platform_bus_init(void); | 49 | extern int platform_bus_init(void); |
14 | extern int system_bus_init(void); | 50 | extern int system_bus_init(void); |
15 | extern int cpu_dev_init(void); | 51 | extern int cpu_dev_init(void); |
16 | extern int attribute_container_init(void); | ||
17 | 52 | ||
18 | extern int bus_add_device(struct device * dev); | 53 | extern int bus_add_device(struct device *dev); |
19 | extern void bus_attach_device(struct device * dev); | 54 | extern void bus_attach_device(struct device *dev); |
20 | extern void bus_remove_device(struct device * dev); | 55 | extern void bus_remove_device(struct device *dev); |
21 | 56 | ||
22 | extern int bus_add_driver(struct device_driver *); | 57 | extern int bus_add_driver(struct device_driver *drv); |
23 | extern void bus_remove_driver(struct device_driver *); | 58 | extern void bus_remove_driver(struct device_driver *drv); |
24 | 59 | ||
25 | extern void driver_detach(struct device_driver * drv); | 60 | extern void driver_detach(struct device_driver *drv); |
26 | extern int driver_probe_device(struct device_driver *, struct device *); | 61 | extern int driver_probe_device(struct device_driver *drv, struct device *dev); |
27 | 62 | ||
28 | extern void sysdev_shutdown(void); | 63 | extern void sysdev_shutdown(void); |
29 | extern int sysdev_suspend(pm_message_t state); | 64 | extern int sysdev_suspend(pm_message_t state); |
@@ -44,4 +79,13 @@ extern char *make_class_name(const char *name, struct kobject *kobj); | |||
44 | 79 | ||
45 | extern int devres_release_all(struct device *dev); | 80 | extern int devres_release_all(struct device *dev); |
46 | 81 | ||
47 | extern struct kset devices_subsys; | 82 | extern struct kset *devices_kset; |
83 | |||
84 | #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) | ||
85 | extern void module_add_driver(struct module *mod, struct device_driver *drv); | ||
86 | extern void module_remove_driver(struct device_driver *drv); | ||
87 | #else | ||
88 | static inline void module_add_driver(struct module *mod, | ||
89 | struct device_driver *drv) { } | ||
90 | static inline void module_remove_driver(struct device_driver *drv) { } | ||
91 | #endif | ||
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 9a19b071c573..f484495b2ad1 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | 10 | * |
@@ -17,14 +19,13 @@ | |||
17 | #include "power/power.h" | 19 | #include "power/power.h" |
18 | 20 | ||
19 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 21 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
20 | #define to_bus(obj) container_of(obj, struct bus_type, subsys.kobj) | 22 | #define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) |
21 | 23 | ||
22 | /* | 24 | /* |
23 | * sysfs bindings for drivers | 25 | * sysfs bindings for drivers |
24 | */ | 26 | */ |
25 | 27 | ||
26 | #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) | 28 | #define to_drv_attr(_attr) container_of(_attr, struct driver_attribute, attr) |
27 | #define to_driver(obj) container_of(obj, struct device_driver, kobj) | ||
28 | 29 | ||
29 | 30 | ||
30 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 31 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
@@ -32,37 +33,40 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
32 | 33 | ||
33 | static struct bus_type *bus_get(struct bus_type *bus) | 34 | static struct bus_type *bus_get(struct bus_type *bus) |
34 | { | 35 | { |
35 | return bus ? container_of(kset_get(&bus->subsys), | 36 | if (bus) { |
36 | struct bus_type, subsys) : NULL; | 37 | kset_get(&bus->p->subsys); |
38 | return bus; | ||
39 | } | ||
40 | return NULL; | ||
37 | } | 41 | } |
38 | 42 | ||
39 | static void bus_put(struct bus_type *bus) | 43 | static void bus_put(struct bus_type *bus) |
40 | { | 44 | { |
41 | kset_put(&bus->subsys); | 45 | if (bus) |
46 | kset_put(&bus->p->subsys); | ||
42 | } | 47 | } |
43 | 48 | ||
44 | static ssize_t | 49 | static ssize_t drv_attr_show(struct kobject *kobj, struct attribute *attr, |
45 | drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 50 | char *buf) |
46 | { | 51 | { |
47 | struct driver_attribute * drv_attr = to_drv_attr(attr); | 52 | struct driver_attribute *drv_attr = to_drv_attr(attr); |
48 | struct device_driver * drv = to_driver(kobj); | 53 | struct driver_private *drv_priv = to_driver(kobj); |
49 | ssize_t ret = -EIO; | 54 | ssize_t ret = -EIO; |
50 | 55 | ||
51 | if (drv_attr->show) | 56 | if (drv_attr->show) |
52 | ret = drv_attr->show(drv, buf); | 57 | ret = drv_attr->show(drv_priv->driver, buf); |
53 | return ret; | 58 | return ret; |
54 | } | 59 | } |
55 | 60 | ||
56 | static ssize_t | 61 | static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr, |
57 | drv_attr_store(struct kobject * kobj, struct attribute * attr, | 62 | const char *buf, size_t count) |
58 | const char * buf, size_t count) | ||
59 | { | 63 | { |
60 | struct driver_attribute * drv_attr = to_drv_attr(attr); | 64 | struct driver_attribute *drv_attr = to_drv_attr(attr); |
61 | struct device_driver * drv = to_driver(kobj); | 65 | struct driver_private *drv_priv = to_driver(kobj); |
62 | ssize_t ret = -EIO; | 66 | ssize_t ret = -EIO; |
63 | 67 | ||
64 | if (drv_attr->store) | 68 | if (drv_attr->store) |
65 | ret = drv_attr->store(drv, buf, count); | 69 | ret = drv_attr->store(drv_priv->driver, buf, count); |
66 | return ret; | 70 | return ret; |
67 | } | 71 | } |
68 | 72 | ||
@@ -71,22 +75,12 @@ static struct sysfs_ops driver_sysfs_ops = { | |||
71 | .store = drv_attr_store, | 75 | .store = drv_attr_store, |
72 | }; | 76 | }; |
73 | 77 | ||
74 | 78 | static void driver_release(struct kobject *kobj) | |
75 | static void driver_release(struct kobject * kobj) | ||
76 | { | 79 | { |
77 | /* | 80 | struct driver_private *drv_priv = to_driver(kobj); |
78 | * Yes this is an empty release function, it is this way because struct | 81 | |
79 | * device is always a static object, not a dynamic one. Yes, this is | 82 | pr_debug("driver: '%s': %s\n", kobject_name(kobj), __FUNCTION__); |
80 | * not nice and bad, but remember, drivers are code, reference counted | 83 | kfree(drv_priv); |
81 | * by the module count, not a device, which is really data. And yes, | ||
82 | * in the future I do want to have all drivers be created dynamically, | ||
83 | * and am working toward that goal, but it will take a bit longer... | ||
84 | * | ||
85 | * But do not let this example give _anyone_ the idea that they can | ||
86 | * create a release function without any code in it at all, to do that | ||
87 | * is almost always wrong. If you have any questions about this, | ||
88 | * please send an email to <greg@kroah.com> | ||
89 | */ | ||
90 | } | 84 | } |
91 | 85 | ||
92 | static struct kobj_type driver_ktype = { | 86 | static struct kobj_type driver_ktype = { |
@@ -94,34 +88,30 @@ static struct kobj_type driver_ktype = { | |||
94 | .release = driver_release, | 88 | .release = driver_release, |
95 | }; | 89 | }; |
96 | 90 | ||
97 | |||
98 | /* | 91 | /* |
99 | * sysfs bindings for buses | 92 | * sysfs bindings for buses |
100 | */ | 93 | */ |
101 | 94 | static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, | |
102 | 95 | char *buf) | |
103 | static ssize_t | ||
104 | bus_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | ||
105 | { | 96 | { |
106 | struct bus_attribute * bus_attr = to_bus_attr(attr); | 97 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
107 | struct bus_type * bus = to_bus(kobj); | 98 | struct bus_type_private *bus_priv = to_bus(kobj); |
108 | ssize_t ret = 0; | 99 | ssize_t ret = 0; |
109 | 100 | ||
110 | if (bus_attr->show) | 101 | if (bus_attr->show) |
111 | ret = bus_attr->show(bus, buf); | 102 | ret = bus_attr->show(bus_priv->bus, buf); |
112 | return ret; | 103 | return ret; |
113 | } | 104 | } |
114 | 105 | ||
115 | static ssize_t | 106 | static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, |
116 | bus_attr_store(struct kobject * kobj, struct attribute * attr, | 107 | const char *buf, size_t count) |
117 | const char * buf, size_t count) | ||
118 | { | 108 | { |
119 | struct bus_attribute * bus_attr = to_bus_attr(attr); | 109 | struct bus_attribute *bus_attr = to_bus_attr(attr); |
120 | struct bus_type * bus = to_bus(kobj); | 110 | struct bus_type_private *bus_priv = to_bus(kobj); |
121 | ssize_t ret = 0; | 111 | ssize_t ret = 0; |
122 | 112 | ||
123 | if (bus_attr->store) | 113 | if (bus_attr->store) |
124 | ret = bus_attr->store(bus, buf, count); | 114 | ret = bus_attr->store(bus_priv->bus, buf, count); |
125 | return ret; | 115 | return ret; |
126 | } | 116 | } |
127 | 117 | ||
@@ -130,24 +120,26 @@ static struct sysfs_ops bus_sysfs_ops = { | |||
130 | .store = bus_attr_store, | 120 | .store = bus_attr_store, |
131 | }; | 121 | }; |
132 | 122 | ||
133 | int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) | 123 | int bus_create_file(struct bus_type *bus, struct bus_attribute *attr) |
134 | { | 124 | { |
135 | int error; | 125 | int error; |
136 | if (bus_get(bus)) { | 126 | if (bus_get(bus)) { |
137 | error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); | 127 | error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr); |
138 | bus_put(bus); | 128 | bus_put(bus); |
139 | } else | 129 | } else |
140 | error = -EINVAL; | 130 | error = -EINVAL; |
141 | return error; | 131 | return error; |
142 | } | 132 | } |
133 | EXPORT_SYMBOL_GPL(bus_create_file); | ||
143 | 134 | ||
144 | void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) | 135 | void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr) |
145 | { | 136 | { |
146 | if (bus_get(bus)) { | 137 | if (bus_get(bus)) { |
147 | sysfs_remove_file(&bus->subsys.kobj, &attr->attr); | 138 | sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); |
148 | bus_put(bus); | 139 | bus_put(bus); |
149 | } | 140 | } |
150 | } | 141 | } |
142 | EXPORT_SYMBOL_GPL(bus_remove_file); | ||
151 | 143 | ||
152 | static struct kobj_type bus_ktype = { | 144 | static struct kobj_type bus_ktype = { |
153 | .sysfs_ops = &bus_sysfs_ops, | 145 | .sysfs_ops = &bus_sysfs_ops, |
@@ -166,7 +158,7 @@ static struct kset_uevent_ops bus_uevent_ops = { | |||
166 | .filter = bus_uevent_filter, | 158 | .filter = bus_uevent_filter, |
167 | }; | 159 | }; |
168 | 160 | ||
169 | static decl_subsys(bus, &bus_ktype, &bus_uevent_ops); | 161 | static struct kset *bus_kset; |
170 | 162 | ||
171 | 163 | ||
172 | #ifdef CONFIG_HOTPLUG | 164 | #ifdef CONFIG_HOTPLUG |
@@ -224,10 +216,13 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
224 | if (dev->parent) | 216 | if (dev->parent) |
225 | up(&dev->parent->sem); | 217 | up(&dev->parent->sem); |
226 | 218 | ||
227 | if (err > 0) /* success */ | 219 | if (err > 0) { |
220 | /* success */ | ||
228 | err = count; | 221 | err = count; |
229 | else if (err == 0) /* driver didn't accept device */ | 222 | } else if (err == 0) { |
223 | /* driver didn't accept device */ | ||
230 | err = -ENODEV; | 224 | err = -ENODEV; |
225 | } | ||
231 | } | 226 | } |
232 | put_device(dev); | 227 | put_device(dev); |
233 | bus_put(bus); | 228 | bus_put(bus); |
@@ -237,16 +232,16 @@ static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | |||
237 | 232 | ||
238 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) | 233 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) |
239 | { | 234 | { |
240 | return sprintf(buf, "%d\n", bus->drivers_autoprobe); | 235 | return sprintf(buf, "%d\n", bus->p->drivers_autoprobe); |
241 | } | 236 | } |
242 | 237 | ||
243 | static ssize_t store_drivers_autoprobe(struct bus_type *bus, | 238 | static ssize_t store_drivers_autoprobe(struct bus_type *bus, |
244 | const char *buf, size_t count) | 239 | const char *buf, size_t count) |
245 | { | 240 | { |
246 | if (buf[0] == '0') | 241 | if (buf[0] == '0') |
247 | bus->drivers_autoprobe = 0; | 242 | bus->p->drivers_autoprobe = 0; |
248 | else | 243 | else |
249 | bus->drivers_autoprobe = 1; | 244 | bus->p->drivers_autoprobe = 1; |
250 | return count; | 245 | return count; |
251 | } | 246 | } |
252 | 247 | ||
@@ -264,49 +259,49 @@ static ssize_t store_drivers_probe(struct bus_type *bus, | |||
264 | } | 259 | } |
265 | #endif | 260 | #endif |
266 | 261 | ||
267 | static struct device * next_device(struct klist_iter * i) | 262 | static struct device *next_device(struct klist_iter *i) |
268 | { | 263 | { |
269 | struct klist_node * n = klist_next(i); | 264 | struct klist_node *n = klist_next(i); |
270 | return n ? container_of(n, struct device, knode_bus) : NULL; | 265 | return n ? container_of(n, struct device, knode_bus) : NULL; |
271 | } | 266 | } |
272 | 267 | ||
273 | /** | 268 | /** |
274 | * bus_for_each_dev - device iterator. | 269 | * bus_for_each_dev - device iterator. |
275 | * @bus: bus type. | 270 | * @bus: bus type. |
276 | * @start: device to start iterating from. | 271 | * @start: device to start iterating from. |
277 | * @data: data for the callback. | 272 | * @data: data for the callback. |
278 | * @fn: function to be called for each device. | 273 | * @fn: function to be called for each device. |
279 | * | 274 | * |
280 | * Iterate over @bus's list of devices, and call @fn for each, | 275 | * Iterate over @bus's list of devices, and call @fn for each, |
281 | * passing it @data. If @start is not NULL, we use that device to | 276 | * passing it @data. If @start is not NULL, we use that device to |
282 | * begin iterating from. | 277 | * begin iterating from. |
283 | * | 278 | * |
284 | * We check the return of @fn each time. If it returns anything | 279 | * We check the return of @fn each time. If it returns anything |
285 | * other than 0, we break out and return that value. | 280 | * other than 0, we break out and return that value. |
286 | * | 281 | * |
287 | * NOTE: The device that returns a non-zero value is not retained | 282 | * NOTE: The device that returns a non-zero value is not retained |
288 | * in any way, nor is its refcount incremented. If the caller needs | 283 | * in any way, nor is its refcount incremented. If the caller needs |
289 | * to retain this data, it should do, and increment the reference | 284 | * to retain this data, it should do, and increment the reference |
290 | * count in the supplied callback. | 285 | * count in the supplied callback. |
291 | */ | 286 | */ |
292 | 287 | int bus_for_each_dev(struct bus_type *bus, struct device *start, | |
293 | int bus_for_each_dev(struct bus_type * bus, struct device * start, | 288 | void *data, int (*fn)(struct device *, void *)) |
294 | void * data, int (*fn)(struct device *, void *)) | ||
295 | { | 289 | { |
296 | struct klist_iter i; | 290 | struct klist_iter i; |
297 | struct device * dev; | 291 | struct device *dev; |
298 | int error = 0; | 292 | int error = 0; |
299 | 293 | ||
300 | if (!bus) | 294 | if (!bus) |
301 | return -EINVAL; | 295 | return -EINVAL; |
302 | 296 | ||
303 | klist_iter_init_node(&bus->klist_devices, &i, | 297 | klist_iter_init_node(&bus->p->klist_devices, &i, |
304 | (start ? &start->knode_bus : NULL)); | 298 | (start ? &start->knode_bus : NULL)); |
305 | while ((dev = next_device(&i)) && !error) | 299 | while ((dev = next_device(&i)) && !error) |
306 | error = fn(dev, data); | 300 | error = fn(dev, data); |
307 | klist_iter_exit(&i); | 301 | klist_iter_exit(&i); |
308 | return error; | 302 | return error; |
309 | } | 303 | } |
304 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | ||
310 | 305 | ||
311 | /** | 306 | /** |
312 | * bus_find_device - device iterator for locating a particular device. | 307 | * bus_find_device - device iterator for locating a particular device. |
@@ -323,9 +318,9 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, | |||
323 | * if it does. If the callback returns non-zero, this function will | 318 | * if it does. If the callback returns non-zero, this function will |
324 | * return to the caller and not iterate over any more devices. | 319 | * return to the caller and not iterate over any more devices. |
325 | */ | 320 | */ |
326 | struct device * bus_find_device(struct bus_type *bus, | 321 | struct device *bus_find_device(struct bus_type *bus, |
327 | struct device *start, void *data, | 322 | struct device *start, void *data, |
328 | int (*match)(struct device *, void *)) | 323 | int (*match)(struct device *dev, void *data)) |
329 | { | 324 | { |
330 | struct klist_iter i; | 325 | struct klist_iter i; |
331 | struct device *dev; | 326 | struct device *dev; |
@@ -333,7 +328,7 @@ struct device * bus_find_device(struct bus_type *bus, | |||
333 | if (!bus) | 328 | if (!bus) |
334 | return NULL; | 329 | return NULL; |
335 | 330 | ||
336 | klist_iter_init_node(&bus->klist_devices, &i, | 331 | klist_iter_init_node(&bus->p->klist_devices, &i, |
337 | (start ? &start->knode_bus : NULL)); | 332 | (start ? &start->knode_bus : NULL)); |
338 | while ((dev = next_device(&i))) | 333 | while ((dev = next_device(&i))) |
339 | if (match(dev, data) && get_device(dev)) | 334 | if (match(dev, data) && get_device(dev)) |
@@ -341,51 +336,57 @@ struct device * bus_find_device(struct bus_type *bus, | |||
341 | klist_iter_exit(&i); | 336 | klist_iter_exit(&i); |
342 | return dev; | 337 | return dev; |
343 | } | 338 | } |
339 | EXPORT_SYMBOL_GPL(bus_find_device); | ||
344 | 340 | ||
345 | 341 | static struct device_driver *next_driver(struct klist_iter *i) | |
346 | static struct device_driver * next_driver(struct klist_iter * i) | ||
347 | { | 342 | { |
348 | struct klist_node * n = klist_next(i); | 343 | struct klist_node *n = klist_next(i); |
349 | return n ? container_of(n, struct device_driver, knode_bus) : NULL; | 344 | struct driver_private *drv_priv; |
345 | |||
346 | if (n) { | ||
347 | drv_priv = container_of(n, struct driver_private, knode_bus); | ||
348 | return drv_priv->driver; | ||
349 | } | ||
350 | return NULL; | ||
350 | } | 351 | } |
351 | 352 | ||
352 | /** | 353 | /** |
353 | * bus_for_each_drv - driver iterator | 354 | * bus_for_each_drv - driver iterator |
354 | * @bus: bus we're dealing with. | 355 | * @bus: bus we're dealing with. |
355 | * @start: driver to start iterating on. | 356 | * @start: driver to start iterating on. |
356 | * @data: data to pass to the callback. | 357 | * @data: data to pass to the callback. |
357 | * @fn: function to call for each driver. | 358 | * @fn: function to call for each driver. |
358 | * | 359 | * |
359 | * This is nearly identical to the device iterator above. | 360 | * This is nearly identical to the device iterator above. |
360 | * We iterate over each driver that belongs to @bus, and call | 361 | * We iterate over each driver that belongs to @bus, and call |
361 | * @fn for each. If @fn returns anything but 0, we break out | 362 | * @fn for each. If @fn returns anything but 0, we break out |
362 | * and return it. If @start is not NULL, we use it as the head | 363 | * and return it. If @start is not NULL, we use it as the head |
363 | * of the list. | 364 | * of the list. |
364 | * | 365 | * |
365 | * NOTE: we don't return the driver that returns a non-zero | 366 | * NOTE: we don't return the driver that returns a non-zero |
366 | * value, nor do we leave the reference count incremented for that | 367 | * value, nor do we leave the reference count incremented for that |
367 | * driver. If the caller needs to know that info, it must set it | 368 | * driver. If the caller needs to know that info, it must set it |
368 | * in the callback. It must also be sure to increment the refcount | 369 | * in the callback. It must also be sure to increment the refcount |
369 | * so it doesn't disappear before returning to the caller. | 370 | * so it doesn't disappear before returning to the caller. |
370 | */ | 371 | */ |
371 | 372 | int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, | |
372 | int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, | 373 | void *data, int (*fn)(struct device_driver *, void *)) |
373 | void * data, int (*fn)(struct device_driver *, void *)) | ||
374 | { | 374 | { |
375 | struct klist_iter i; | 375 | struct klist_iter i; |
376 | struct device_driver * drv; | 376 | struct device_driver *drv; |
377 | int error = 0; | 377 | int error = 0; |
378 | 378 | ||
379 | if (!bus) | 379 | if (!bus) |
380 | return -EINVAL; | 380 | return -EINVAL; |
381 | 381 | ||
382 | klist_iter_init_node(&bus->klist_drivers, &i, | 382 | klist_iter_init_node(&bus->p->klist_drivers, &i, |
383 | start ? &start->knode_bus : NULL); | 383 | start ? &start->p->knode_bus : NULL); |
384 | while ((drv = next_driver(&i)) && !error) | 384 | while ((drv = next_driver(&i)) && !error) |
385 | error = fn(drv, data); | 385 | error = fn(drv, data); |
386 | klist_iter_exit(&i); | 386 | klist_iter_exit(&i); |
387 | return error; | 387 | return error; |
388 | } | 388 | } |
389 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | ||
389 | 390 | ||
390 | static int device_add_attrs(struct bus_type *bus, struct device *dev) | 391 | static int device_add_attrs(struct bus_type *bus, struct device *dev) |
391 | { | 392 | { |
@@ -396,7 +397,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
396 | return 0; | 397 | return 0; |
397 | 398 | ||
398 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { | 399 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { |
399 | error = device_create_file(dev,&bus->dev_attrs[i]); | 400 | error = device_create_file(dev, &bus->dev_attrs[i]); |
400 | if (error) { | 401 | if (error) { |
401 | while (--i >= 0) | 402 | while (--i >= 0) |
402 | device_remove_file(dev, &bus->dev_attrs[i]); | 403 | device_remove_file(dev, &bus->dev_attrs[i]); |
@@ -406,13 +407,13 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
406 | return error; | 407 | return error; |
407 | } | 408 | } |
408 | 409 | ||
409 | static void device_remove_attrs(struct bus_type * bus, struct device * dev) | 410 | static void device_remove_attrs(struct bus_type *bus, struct device *dev) |
410 | { | 411 | { |
411 | int i; | 412 | int i; |
412 | 413 | ||
413 | if (bus->dev_attrs) { | 414 | if (bus->dev_attrs) { |
414 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) | 415 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) |
415 | device_remove_file(dev,&bus->dev_attrs[i]); | 416 | device_remove_file(dev, &bus->dev_attrs[i]); |
416 | } | 417 | } |
417 | } | 418 | } |
418 | 419 | ||
@@ -420,7 +421,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) | |||
420 | static int make_deprecated_bus_links(struct device *dev) | 421 | static int make_deprecated_bus_links(struct device *dev) |
421 | { | 422 | { |
422 | return sysfs_create_link(&dev->kobj, | 423 | return sysfs_create_link(&dev->kobj, |
423 | &dev->bus->subsys.kobj, "bus"); | 424 | &dev->bus->p->subsys.kobj, "bus"); |
424 | } | 425 | } |
425 | 426 | ||
426 | static void remove_deprecated_bus_links(struct device *dev) | 427 | static void remove_deprecated_bus_links(struct device *dev) |
@@ -433,28 +434,28 @@ static inline void remove_deprecated_bus_links(struct device *dev) { } | |||
433 | #endif | 434 | #endif |
434 | 435 | ||
435 | /** | 436 | /** |
436 | * bus_add_device - add device to bus | 437 | * bus_add_device - add device to bus |
437 | * @dev: device being added | 438 | * @dev: device being added |
438 | * | 439 | * |
439 | * - Add the device to its bus's list of devices. | 440 | * - Add the device to its bus's list of devices. |
440 | * - Create link to device's bus. | 441 | * - Create link to device's bus. |
441 | */ | 442 | */ |
442 | int bus_add_device(struct device * dev) | 443 | int bus_add_device(struct device *dev) |
443 | { | 444 | { |
444 | struct bus_type * bus = bus_get(dev->bus); | 445 | struct bus_type *bus = bus_get(dev->bus); |
445 | int error = 0; | 446 | int error = 0; |
446 | 447 | ||
447 | if (bus) { | 448 | if (bus) { |
448 | pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); | 449 | pr_debug("bus: '%s': add device %s\n", bus->name, dev->bus_id); |
449 | error = device_add_attrs(bus, dev); | 450 | error = device_add_attrs(bus, dev); |
450 | if (error) | 451 | if (error) |
451 | goto out_put; | 452 | goto out_put; |
452 | error = sysfs_create_link(&bus->devices.kobj, | 453 | error = sysfs_create_link(&bus->p->devices_kset->kobj, |
453 | &dev->kobj, dev->bus_id); | 454 | &dev->kobj, dev->bus_id); |
454 | if (error) | 455 | if (error) |
455 | goto out_id; | 456 | goto out_id; |
456 | error = sysfs_create_link(&dev->kobj, | 457 | error = sysfs_create_link(&dev->kobj, |
457 | &dev->bus->subsys.kobj, "subsystem"); | 458 | &dev->bus->p->subsys.kobj, "subsystem"); |
458 | if (error) | 459 | if (error) |
459 | goto out_subsys; | 460 | goto out_subsys; |
460 | error = make_deprecated_bus_links(dev); | 461 | error = make_deprecated_bus_links(dev); |
@@ -466,7 +467,7 @@ int bus_add_device(struct device * dev) | |||
466 | out_deprecated: | 467 | out_deprecated: |
467 | sysfs_remove_link(&dev->kobj, "subsystem"); | 468 | sysfs_remove_link(&dev->kobj, "subsystem"); |
468 | out_subsys: | 469 | out_subsys: |
469 | sysfs_remove_link(&bus->devices.kobj, dev->bus_id); | 470 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev->bus_id); |
470 | out_id: | 471 | out_id: |
471 | device_remove_attrs(bus, dev); | 472 | device_remove_attrs(bus, dev); |
472 | out_put: | 473 | out_put: |
@@ -475,56 +476,58 @@ out_put: | |||
475 | } | 476 | } |
476 | 477 | ||
477 | /** | 478 | /** |
478 | * bus_attach_device - add device to bus | 479 | * bus_attach_device - add device to bus |
479 | * @dev: device tried to attach to a driver | 480 | * @dev: device tried to attach to a driver |
480 | * | 481 | * |
481 | * - Add device to bus's list of devices. | 482 | * - Add device to bus's list of devices. |
482 | * - Try to attach to driver. | 483 | * - Try to attach to driver. |
483 | */ | 484 | */ |
484 | void bus_attach_device(struct device * dev) | 485 | void bus_attach_device(struct device *dev) |
485 | { | 486 | { |
486 | struct bus_type *bus = dev->bus; | 487 | struct bus_type *bus = dev->bus; |
487 | int ret = 0; | 488 | int ret = 0; |
488 | 489 | ||
489 | if (bus) { | 490 | if (bus) { |
490 | dev->is_registered = 1; | 491 | dev->is_registered = 1; |
491 | if (bus->drivers_autoprobe) | 492 | if (bus->p->drivers_autoprobe) |
492 | ret = device_attach(dev); | 493 | ret = device_attach(dev); |
493 | WARN_ON(ret < 0); | 494 | WARN_ON(ret < 0); |
494 | if (ret >= 0) | 495 | if (ret >= 0) |
495 | klist_add_tail(&dev->knode_bus, &bus->klist_devices); | 496 | klist_add_tail(&dev->knode_bus, &bus->p->klist_devices); |
496 | else | 497 | else |
497 | dev->is_registered = 0; | 498 | dev->is_registered = 0; |
498 | } | 499 | } |
499 | } | 500 | } |
500 | 501 | ||
501 | /** | 502 | /** |
502 | * bus_remove_device - remove device from bus | 503 | * bus_remove_device - remove device from bus |
503 | * @dev: device to be removed | 504 | * @dev: device to be removed |
504 | * | 505 | * |
505 | * - Remove symlink from bus's directory. | 506 | * - Remove symlink from bus's directory. |
506 | * - Delete device from bus's list. | 507 | * - Delete device from bus's list. |
507 | * - Detach from its driver. | 508 | * - Detach from its driver. |
508 | * - Drop reference taken in bus_add_device(). | 509 | * - Drop reference taken in bus_add_device(). |
509 | */ | 510 | */ |
510 | void bus_remove_device(struct device * dev) | 511 | void bus_remove_device(struct device *dev) |
511 | { | 512 | { |
512 | if (dev->bus) { | 513 | if (dev->bus) { |
513 | sysfs_remove_link(&dev->kobj, "subsystem"); | 514 | sysfs_remove_link(&dev->kobj, "subsystem"); |
514 | remove_deprecated_bus_links(dev); | 515 | remove_deprecated_bus_links(dev); |
515 | sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); | 516 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
517 | dev->bus_id); | ||
516 | device_remove_attrs(dev->bus, dev); | 518 | device_remove_attrs(dev->bus, dev); |
517 | if (dev->is_registered) { | 519 | if (dev->is_registered) { |
518 | dev->is_registered = 0; | 520 | dev->is_registered = 0; |
519 | klist_del(&dev->knode_bus); | 521 | klist_del(&dev->knode_bus); |
520 | } | 522 | } |
521 | pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); | 523 | pr_debug("bus: '%s': remove device %s\n", |
524 | dev->bus->name, dev->bus_id); | ||
522 | device_release_driver(dev); | 525 | device_release_driver(dev); |
523 | bus_put(dev->bus); | 526 | bus_put(dev->bus); |
524 | } | 527 | } |
525 | } | 528 | } |
526 | 529 | ||
527 | static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) | 530 | static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) |
528 | { | 531 | { |
529 | int error = 0; | 532 | int error = 0; |
530 | int i; | 533 | int i; |
@@ -533,19 +536,19 @@ static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv) | |||
533 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { | 536 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { |
534 | error = driver_create_file(drv, &bus->drv_attrs[i]); | 537 | error = driver_create_file(drv, &bus->drv_attrs[i]); |
535 | if (error) | 538 | if (error) |
536 | goto Err; | 539 | goto err; |
537 | } | 540 | } |
538 | } | 541 | } |
539 | Done: | 542 | done: |
540 | return error; | 543 | return error; |
541 | Err: | 544 | err: |
542 | while (--i >= 0) | 545 | while (--i >= 0) |
543 | driver_remove_file(drv, &bus->drv_attrs[i]); | 546 | driver_remove_file(drv, &bus->drv_attrs[i]); |
544 | goto Done; | 547 | goto done; |
545 | } | 548 | } |
546 | 549 | ||
547 | 550 | static void driver_remove_attrs(struct bus_type *bus, | |
548 | static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv) | 551 | struct device_driver *drv) |
549 | { | 552 | { |
550 | int i; | 553 | int i; |
551 | 554 | ||
@@ -616,39 +619,46 @@ static ssize_t driver_uevent_store(struct device_driver *drv, | |||
616 | enum kobject_action action; | 619 | enum kobject_action action; |
617 | 620 | ||
618 | if (kobject_action_type(buf, count, &action) == 0) | 621 | if (kobject_action_type(buf, count, &action) == 0) |
619 | kobject_uevent(&drv->kobj, action); | 622 | kobject_uevent(&drv->p->kobj, action); |
620 | return count; | 623 | return count; |
621 | } | 624 | } |
622 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); | 625 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); |
623 | 626 | ||
624 | /** | 627 | /** |
625 | * bus_add_driver - Add a driver to the bus. | 628 | * bus_add_driver - Add a driver to the bus. |
626 | * @drv: driver. | 629 | * @drv: driver. |
627 | * | ||
628 | */ | 630 | */ |
629 | int bus_add_driver(struct device_driver *drv) | 631 | int bus_add_driver(struct device_driver *drv) |
630 | { | 632 | { |
631 | struct bus_type * bus = bus_get(drv->bus); | 633 | struct bus_type *bus; |
634 | struct driver_private *priv; | ||
632 | int error = 0; | 635 | int error = 0; |
633 | 636 | ||
637 | bus = bus_get(drv->bus); | ||
634 | if (!bus) | 638 | if (!bus) |
635 | return -EINVAL; | 639 | return -EINVAL; |
636 | 640 | ||
637 | pr_debug("bus %s: add driver %s\n", bus->name, drv->name); | 641 | pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); |
638 | error = kobject_set_name(&drv->kobj, "%s", drv->name); | 642 | |
639 | if (error) | 643 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
640 | goto out_put_bus; | 644 | if (!priv) |
641 | drv->kobj.kset = &bus->drivers; | 645 | return -ENOMEM; |
642 | error = kobject_register(&drv->kobj); | 646 | |
647 | klist_init(&priv->klist_devices, NULL, NULL); | ||
648 | priv->driver = drv; | ||
649 | drv->p = priv; | ||
650 | priv->kobj.kset = bus->p->drivers_kset; | ||
651 | error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, | ||
652 | "%s", drv->name); | ||
643 | if (error) | 653 | if (error) |
644 | goto out_put_bus; | 654 | goto out_put_bus; |
645 | 655 | ||
646 | if (drv->bus->drivers_autoprobe) { | 656 | if (drv->bus->p->drivers_autoprobe) { |
647 | error = driver_attach(drv); | 657 | error = driver_attach(drv); |
648 | if (error) | 658 | if (error) |
649 | goto out_unregister; | 659 | goto out_unregister; |
650 | } | 660 | } |
651 | klist_add_tail(&drv->knode_bus, &bus->klist_drivers); | 661 | klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); |
652 | module_add_driver(drv->owner, drv); | 662 | module_add_driver(drv->owner, drv); |
653 | 663 | ||
654 | error = driver_create_file(drv, &driver_attr_uevent); | 664 | error = driver_create_file(drv, &driver_attr_uevent); |
@@ -669,24 +679,24 @@ int bus_add_driver(struct device_driver *drv) | |||
669 | __FUNCTION__, drv->name); | 679 | __FUNCTION__, drv->name); |
670 | } | 680 | } |
671 | 681 | ||
682 | kobject_uevent(&priv->kobj, KOBJ_ADD); | ||
672 | return error; | 683 | return error; |
673 | out_unregister: | 684 | out_unregister: |
674 | kobject_unregister(&drv->kobj); | 685 | kobject_put(&priv->kobj); |
675 | out_put_bus: | 686 | out_put_bus: |
676 | bus_put(bus); | 687 | bus_put(bus); |
677 | return error; | 688 | return error; |
678 | } | 689 | } |
679 | 690 | ||
680 | /** | 691 | /** |
681 | * bus_remove_driver - delete driver from bus's knowledge. | 692 | * bus_remove_driver - delete driver from bus's knowledge. |
682 | * @drv: driver. | 693 | * @drv: driver. |
683 | * | 694 | * |
684 | * Detach the driver from the devices it controls, and remove | 695 | * Detach the driver from the devices it controls, and remove |
685 | * it from its bus's list of drivers. Finally, we drop the reference | 696 | * it from its bus's list of drivers. Finally, we drop the reference |
686 | * to the bus we took in bus_add_driver(). | 697 | * to the bus we took in bus_add_driver(). |
687 | */ | 698 | */ |
688 | 699 | void bus_remove_driver(struct device_driver *drv) | |
689 | void bus_remove_driver(struct device_driver * drv) | ||
690 | { | 700 | { |
691 | if (!drv->bus) | 701 | if (!drv->bus) |
692 | return; | 702 | return; |
@@ -694,18 +704,17 @@ void bus_remove_driver(struct device_driver * drv) | |||
694 | remove_bind_files(drv); | 704 | remove_bind_files(drv); |
695 | driver_remove_attrs(drv->bus, drv); | 705 | driver_remove_attrs(drv->bus, drv); |
696 | driver_remove_file(drv, &driver_attr_uevent); | 706 | driver_remove_file(drv, &driver_attr_uevent); |
697 | klist_remove(&drv->knode_bus); | 707 | klist_remove(&drv->p->knode_bus); |
698 | pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); | 708 | pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); |
699 | driver_detach(drv); | 709 | driver_detach(drv); |
700 | module_remove_driver(drv); | 710 | module_remove_driver(drv); |
701 | kobject_unregister(&drv->kobj); | 711 | kobject_put(&drv->p->kobj); |
702 | bus_put(drv->bus); | 712 | bus_put(drv->bus); |
703 | } | 713 | } |
704 | 714 | ||
705 | |||
706 | /* Helper for bus_rescan_devices's iter */ | 715 | /* Helper for bus_rescan_devices's iter */ |
707 | static int __must_check bus_rescan_devices_helper(struct device *dev, | 716 | static int __must_check bus_rescan_devices_helper(struct device *dev, |
708 | void *data) | 717 | void *data) |
709 | { | 718 | { |
710 | int ret = 0; | 719 | int ret = 0; |
711 | 720 | ||
@@ -727,10 +736,11 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, | |||
727 | * attached and rescan it against existing drivers to see if it matches | 736 | * attached and rescan it against existing drivers to see if it matches |
728 | * any by calling device_attach() for the unbound devices. | 737 | * any by calling device_attach() for the unbound devices. |
729 | */ | 738 | */ |
730 | int bus_rescan_devices(struct bus_type * bus) | 739 | int bus_rescan_devices(struct bus_type *bus) |
731 | { | 740 | { |
732 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); | 741 | return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); |
733 | } | 742 | } |
743 | EXPORT_SYMBOL_GPL(bus_rescan_devices); | ||
734 | 744 | ||
735 | /** | 745 | /** |
736 | * device_reprobe - remove driver for a device and probe for a new driver | 746 | * device_reprobe - remove driver for a device and probe for a new driver |
@@ -755,55 +765,55 @@ int device_reprobe(struct device *dev) | |||
755 | EXPORT_SYMBOL_GPL(device_reprobe); | 765 | EXPORT_SYMBOL_GPL(device_reprobe); |
756 | 766 | ||
757 | /** | 767 | /** |
758 | * find_bus - locate bus by name. | 768 | * find_bus - locate bus by name. |
759 | * @name: name of bus. | 769 | * @name: name of bus. |
760 | * | 770 | * |
761 | * Call kset_find_obj() to iterate over list of buses to | 771 | * Call kset_find_obj() to iterate over list of buses to |
762 | * find a bus by name. Return bus if found. | 772 | * find a bus by name. Return bus if found. |
763 | * | 773 | * |
764 | * Note that kset_find_obj increments bus' reference count. | 774 | * Note that kset_find_obj increments bus' reference count. |
765 | */ | 775 | */ |
766 | #if 0 | 776 | #if 0 |
767 | struct bus_type * find_bus(char * name) | 777 | struct bus_type *find_bus(char *name) |
768 | { | 778 | { |
769 | struct kobject * k = kset_find_obj(&bus_subsys.kset, name); | 779 | struct kobject *k = kset_find_obj(bus_kset, name); |
770 | return k ? to_bus(k) : NULL; | 780 | return k ? to_bus(k) : NULL; |
771 | } | 781 | } |
772 | #endif /* 0 */ | 782 | #endif /* 0 */ |
773 | 783 | ||
774 | 784 | ||
775 | /** | 785 | /** |
776 | * bus_add_attrs - Add default attributes for this bus. | 786 | * bus_add_attrs - Add default attributes for this bus. |
777 | * @bus: Bus that has just been registered. | 787 | * @bus: Bus that has just been registered. |
778 | */ | 788 | */ |
779 | 789 | ||
780 | static int bus_add_attrs(struct bus_type * bus) | 790 | static int bus_add_attrs(struct bus_type *bus) |
781 | { | 791 | { |
782 | int error = 0; | 792 | int error = 0; |
783 | int i; | 793 | int i; |
784 | 794 | ||
785 | if (bus->bus_attrs) { | 795 | if (bus->bus_attrs) { |
786 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { | 796 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { |
787 | error = bus_create_file(bus,&bus->bus_attrs[i]); | 797 | error = bus_create_file(bus, &bus->bus_attrs[i]); |
788 | if (error) | 798 | if (error) |
789 | goto Err; | 799 | goto err; |
790 | } | 800 | } |
791 | } | 801 | } |
792 | Done: | 802 | done: |
793 | return error; | 803 | return error; |
794 | Err: | 804 | err: |
795 | while (--i >= 0) | 805 | while (--i >= 0) |
796 | bus_remove_file(bus,&bus->bus_attrs[i]); | 806 | bus_remove_file(bus, &bus->bus_attrs[i]); |
797 | goto Done; | 807 | goto done; |
798 | } | 808 | } |
799 | 809 | ||
800 | static void bus_remove_attrs(struct bus_type * bus) | 810 | static void bus_remove_attrs(struct bus_type *bus) |
801 | { | 811 | { |
802 | int i; | 812 | int i; |
803 | 813 | ||
804 | if (bus->bus_attrs) { | 814 | if (bus->bus_attrs) { |
805 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) | 815 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) |
806 | bus_remove_file(bus,&bus->bus_attrs[i]); | 816 | bus_remove_file(bus, &bus->bus_attrs[i]); |
807 | } | 817 | } |
808 | } | 818 | } |
809 | 819 | ||
@@ -827,32 +837,42 @@ static ssize_t bus_uevent_store(struct bus_type *bus, | |||
827 | enum kobject_action action; | 837 | enum kobject_action action; |
828 | 838 | ||
829 | if (kobject_action_type(buf, count, &action) == 0) | 839 | if (kobject_action_type(buf, count, &action) == 0) |
830 | kobject_uevent(&bus->subsys.kobj, action); | 840 | kobject_uevent(&bus->p->subsys.kobj, action); |
831 | return count; | 841 | return count; |
832 | } | 842 | } |
833 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); | 843 | static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); |
834 | 844 | ||
835 | /** | 845 | /** |
836 | * bus_register - register a bus with the system. | 846 | * bus_register - register a bus with the system. |
837 | * @bus: bus. | 847 | * @bus: bus. |
838 | * | 848 | * |
839 | * Once we have that, we registered the bus with the kobject | 849 | * Once we have that, we registered the bus with the kobject |
840 | * infrastructure, then register the children subsystems it has: | 850 | * infrastructure, then register the children subsystems it has: |
841 | * the devices and drivers that belong to the bus. | 851 | * the devices and drivers that belong to the bus. |
842 | */ | 852 | */ |
843 | int bus_register(struct bus_type * bus) | 853 | int bus_register(struct bus_type *bus) |
844 | { | 854 | { |
845 | int retval; | 855 | int retval; |
856 | struct bus_type_private *priv; | ||
857 | |||
858 | priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); | ||
859 | if (!priv) | ||
860 | return -ENOMEM; | ||
846 | 861 | ||
847 | BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); | 862 | priv->bus = bus; |
863 | bus->p = priv; | ||
848 | 864 | ||
849 | retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name); | 865 | BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); |
866 | |||
867 | retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); | ||
850 | if (retval) | 868 | if (retval) |
851 | goto out; | 869 | goto out; |
852 | 870 | ||
853 | bus->subsys.kobj.kset = &bus_subsys; | 871 | priv->subsys.kobj.kset = bus_kset; |
872 | priv->subsys.kobj.ktype = &bus_ktype; | ||
873 | priv->drivers_autoprobe = 1; | ||
854 | 874 | ||
855 | retval = subsystem_register(&bus->subsys); | 875 | retval = kset_register(&priv->subsys); |
856 | if (retval) | 876 | if (retval) |
857 | goto out; | 877 | goto out; |
858 | 878 | ||
@@ -860,23 +880,23 @@ int bus_register(struct bus_type * bus) | |||
860 | if (retval) | 880 | if (retval) |
861 | goto bus_uevent_fail; | 881 | goto bus_uevent_fail; |
862 | 882 | ||
863 | kobject_set_name(&bus->devices.kobj, "devices"); | 883 | priv->devices_kset = kset_create_and_add("devices", NULL, |
864 | bus->devices.kobj.parent = &bus->subsys.kobj; | 884 | &priv->subsys.kobj); |
865 | retval = kset_register(&bus->devices); | 885 | if (!priv->devices_kset) { |
866 | if (retval) | 886 | retval = -ENOMEM; |
867 | goto bus_devices_fail; | 887 | goto bus_devices_fail; |
888 | } | ||
868 | 889 | ||
869 | kobject_set_name(&bus->drivers.kobj, "drivers"); | 890 | priv->drivers_kset = kset_create_and_add("drivers", NULL, |
870 | bus->drivers.kobj.parent = &bus->subsys.kobj; | 891 | &priv->subsys.kobj); |
871 | bus->drivers.ktype = &driver_ktype; | 892 | if (!priv->drivers_kset) { |
872 | retval = kset_register(&bus->drivers); | 893 | retval = -ENOMEM; |
873 | if (retval) | ||
874 | goto bus_drivers_fail; | 894 | goto bus_drivers_fail; |
895 | } | ||
875 | 896 | ||
876 | klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); | 897 | klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); |
877 | klist_init(&bus->klist_drivers, NULL, NULL); | 898 | klist_init(&priv->klist_drivers, NULL, NULL); |
878 | 899 | ||
879 | bus->drivers_autoprobe = 1; | ||
880 | retval = add_probe_files(bus); | 900 | retval = add_probe_files(bus); |
881 | if (retval) | 901 | if (retval) |
882 | goto bus_probe_files_fail; | 902 | goto bus_probe_files_fail; |
@@ -885,66 +905,73 @@ int bus_register(struct bus_type * bus) | |||
885 | if (retval) | 905 | if (retval) |
886 | goto bus_attrs_fail; | 906 | goto bus_attrs_fail; |
887 | 907 | ||
888 | pr_debug("bus type '%s' registered\n", bus->name); | 908 | pr_debug("bus: '%s': registered\n", bus->name); |
889 | return 0; | 909 | return 0; |
890 | 910 | ||
891 | bus_attrs_fail: | 911 | bus_attrs_fail: |
892 | remove_probe_files(bus); | 912 | remove_probe_files(bus); |
893 | bus_probe_files_fail: | 913 | bus_probe_files_fail: |
894 | kset_unregister(&bus->drivers); | 914 | kset_unregister(bus->p->drivers_kset); |
895 | bus_drivers_fail: | 915 | bus_drivers_fail: |
896 | kset_unregister(&bus->devices); | 916 | kset_unregister(bus->p->devices_kset); |
897 | bus_devices_fail: | 917 | bus_devices_fail: |
898 | bus_remove_file(bus, &bus_attr_uevent); | 918 | bus_remove_file(bus, &bus_attr_uevent); |
899 | bus_uevent_fail: | 919 | bus_uevent_fail: |
900 | subsystem_unregister(&bus->subsys); | 920 | kset_unregister(&bus->p->subsys); |
921 | kfree(bus->p); | ||
901 | out: | 922 | out: |
902 | return retval; | 923 | return retval; |
903 | } | 924 | } |
925 | EXPORT_SYMBOL_GPL(bus_register); | ||
904 | 926 | ||
905 | /** | 927 | /** |
906 | * bus_unregister - remove a bus from the system | 928 | * bus_unregister - remove a bus from the system |
907 | * @bus: bus. | 929 | * @bus: bus. |
908 | * | 930 | * |
909 | * Unregister the child subsystems and the bus itself. | 931 | * Unregister the child subsystems and the bus itself. |
910 | * Finally, we call bus_put() to release the refcount | 932 | * Finally, we call bus_put() to release the refcount |
911 | */ | 933 | */ |
912 | void bus_unregister(struct bus_type * bus) | 934 | void bus_unregister(struct bus_type *bus) |
913 | { | 935 | { |
914 | pr_debug("bus %s: unregistering\n", bus->name); | 936 | pr_debug("bus: '%s': unregistering\n", bus->name); |
915 | bus_remove_attrs(bus); | 937 | bus_remove_attrs(bus); |
916 | remove_probe_files(bus); | 938 | remove_probe_files(bus); |
917 | kset_unregister(&bus->drivers); | 939 | kset_unregister(bus->p->drivers_kset); |
918 | kset_unregister(&bus->devices); | 940 | kset_unregister(bus->p->devices_kset); |
919 | bus_remove_file(bus, &bus_attr_uevent); | 941 | bus_remove_file(bus, &bus_attr_uevent); |
920 | subsystem_unregister(&bus->subsys); | 942 | kset_unregister(&bus->p->subsys); |
943 | kfree(bus->p); | ||
921 | } | 944 | } |
945 | EXPORT_SYMBOL_GPL(bus_unregister); | ||
922 | 946 | ||
923 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) | 947 | int bus_register_notifier(struct bus_type *bus, struct notifier_block *nb) |
924 | { | 948 | { |
925 | return blocking_notifier_chain_register(&bus->bus_notifier, nb); | 949 | return blocking_notifier_chain_register(&bus->p->bus_notifier, nb); |
926 | } | 950 | } |
927 | EXPORT_SYMBOL_GPL(bus_register_notifier); | 951 | EXPORT_SYMBOL_GPL(bus_register_notifier); |
928 | 952 | ||
929 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) | 953 | int bus_unregister_notifier(struct bus_type *bus, struct notifier_block *nb) |
930 | { | 954 | { |
931 | return blocking_notifier_chain_unregister(&bus->bus_notifier, nb); | 955 | return blocking_notifier_chain_unregister(&bus->p->bus_notifier, nb); |
932 | } | 956 | } |
933 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); | 957 | EXPORT_SYMBOL_GPL(bus_unregister_notifier); |
934 | 958 | ||
935 | int __init buses_init(void) | 959 | struct kset *bus_get_kset(struct bus_type *bus) |
936 | { | 960 | { |
937 | return subsystem_register(&bus_subsys); | 961 | return &bus->p->subsys; |
938 | } | 962 | } |
963 | EXPORT_SYMBOL_GPL(bus_get_kset); | ||
939 | 964 | ||
965 | struct klist *bus_get_device_klist(struct bus_type *bus) | ||
966 | { | ||
967 | return &bus->p->klist_devices; | ||
968 | } | ||
969 | EXPORT_SYMBOL_GPL(bus_get_device_klist); | ||
940 | 970 | ||
941 | EXPORT_SYMBOL_GPL(bus_for_each_dev); | 971 | int __init buses_init(void) |
942 | EXPORT_SYMBOL_GPL(bus_find_device); | 972 | { |
943 | EXPORT_SYMBOL_GPL(bus_for_each_drv); | 973 | bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL); |
944 | 974 | if (!bus_kset) | |
945 | EXPORT_SYMBOL_GPL(bus_register); | 975 | return -ENOMEM; |
946 | EXPORT_SYMBOL_GPL(bus_unregister); | 976 | return 0; |
947 | EXPORT_SYMBOL_GPL(bus_rescan_devices); | 977 | } |
948 | |||
949 | EXPORT_SYMBOL_GPL(bus_create_file); | ||
950 | EXPORT_SYMBOL_GPL(bus_remove_file); | ||
diff --git a/drivers/base/class.c b/drivers/base/class.c index a863bb091e11..59cf35894cfc 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -17,16 +17,17 @@ | |||
17 | #include <linux/kdev_t.h> | 17 | #include <linux/kdev_t.h> |
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/genhd.h> | ||
20 | #include "base.h" | 21 | #include "base.h" |
21 | 22 | ||
22 | #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) | 23 | #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) |
23 | #define to_class(obj) container_of(obj, struct class, subsys.kobj) | 24 | #define to_class(obj) container_of(obj, struct class, subsys.kobj) |
24 | 25 | ||
25 | static ssize_t | 26 | static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, |
26 | class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 27 | char *buf) |
27 | { | 28 | { |
28 | struct class_attribute * class_attr = to_class_attr(attr); | 29 | struct class_attribute *class_attr = to_class_attr(attr); |
29 | struct class * dc = to_class(kobj); | 30 | struct class *dc = to_class(kobj); |
30 | ssize_t ret = -EIO; | 31 | ssize_t ret = -EIO; |
31 | 32 | ||
32 | if (class_attr->show) | 33 | if (class_attr->show) |
@@ -34,12 +35,11 @@ class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | |||
34 | return ret; | 35 | return ret; |
35 | } | 36 | } |
36 | 37 | ||
37 | static ssize_t | 38 | static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, |
38 | class_attr_store(struct kobject * kobj, struct attribute * attr, | 39 | const char *buf, size_t count) |
39 | const char * buf, size_t count) | ||
40 | { | 40 | { |
41 | struct class_attribute * class_attr = to_class_attr(attr); | 41 | struct class_attribute *class_attr = to_class_attr(attr); |
42 | struct class * dc = to_class(kobj); | 42 | struct class *dc = to_class(kobj); |
43 | ssize_t ret = -EIO; | 43 | ssize_t ret = -EIO; |
44 | 44 | ||
45 | if (class_attr->store) | 45 | if (class_attr->store) |
@@ -47,7 +47,7 @@ class_attr_store(struct kobject * kobj, struct attribute * attr, | |||
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | static void class_release(struct kobject * kobj) | 50 | static void class_release(struct kobject *kobj) |
51 | { | 51 | { |
52 | struct class *class = to_class(kobj); | 52 | struct class *class = to_class(kobj); |
53 | 53 | ||
@@ -71,20 +71,20 @@ static struct kobj_type class_ktype = { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* Hotplug events for classes go to the class_obj subsys */ | 73 | /* Hotplug events for classes go to the class_obj subsys */ |
74 | static decl_subsys(class, &class_ktype, NULL); | 74 | static struct kset *class_kset; |
75 | 75 | ||
76 | 76 | ||
77 | int class_create_file(struct class * cls, const struct class_attribute * attr) | 77 | int class_create_file(struct class *cls, const struct class_attribute *attr) |
78 | { | 78 | { |
79 | int error; | 79 | int error; |
80 | if (cls) { | 80 | if (cls) |
81 | error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); | 81 | error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); |
82 | } else | 82 | else |
83 | error = -EINVAL; | 83 | error = -EINVAL; |
84 | return error; | 84 | return error; |
85 | } | 85 | } |
86 | 86 | ||
87 | void class_remove_file(struct class * cls, const struct class_attribute * attr) | 87 | void class_remove_file(struct class *cls, const struct class_attribute *attr) |
88 | { | 88 | { |
89 | if (cls) | 89 | if (cls) |
90 | sysfs_remove_file(&cls->subsys.kobj, &attr->attr); | 90 | sysfs_remove_file(&cls->subsys.kobj, &attr->attr); |
@@ -93,48 +93,48 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr) | |||
93 | static struct class *class_get(struct class *cls) | 93 | static struct class *class_get(struct class *cls) |
94 | { | 94 | { |
95 | if (cls) | 95 | if (cls) |
96 | return container_of(kset_get(&cls->subsys), struct class, subsys); | 96 | return container_of(kset_get(&cls->subsys), |
97 | struct class, subsys); | ||
97 | return NULL; | 98 | return NULL; |
98 | } | 99 | } |
99 | 100 | ||
100 | static void class_put(struct class * cls) | 101 | static void class_put(struct class *cls) |
101 | { | 102 | { |
102 | if (cls) | 103 | if (cls) |
103 | kset_put(&cls->subsys); | 104 | kset_put(&cls->subsys); |
104 | } | 105 | } |
105 | 106 | ||
106 | 107 | static int add_class_attrs(struct class *cls) | |
107 | static int add_class_attrs(struct class * cls) | ||
108 | { | 108 | { |
109 | int i; | 109 | int i; |
110 | int error = 0; | 110 | int error = 0; |
111 | 111 | ||
112 | if (cls->class_attrs) { | 112 | if (cls->class_attrs) { |
113 | for (i = 0; attr_name(cls->class_attrs[i]); i++) { | 113 | for (i = 0; attr_name(cls->class_attrs[i]); i++) { |
114 | error = class_create_file(cls,&cls->class_attrs[i]); | 114 | error = class_create_file(cls, &cls->class_attrs[i]); |
115 | if (error) | 115 | if (error) |
116 | goto Err; | 116 | goto error; |
117 | } | 117 | } |
118 | } | 118 | } |
119 | Done: | 119 | done: |
120 | return error; | 120 | return error; |
121 | Err: | 121 | error: |
122 | while (--i >= 0) | 122 | while (--i >= 0) |
123 | class_remove_file(cls,&cls->class_attrs[i]); | 123 | class_remove_file(cls, &cls->class_attrs[i]); |
124 | goto Done; | 124 | goto done; |
125 | } | 125 | } |
126 | 126 | ||
127 | static void remove_class_attrs(struct class * cls) | 127 | static void remove_class_attrs(struct class *cls) |
128 | { | 128 | { |
129 | int i; | 129 | int i; |
130 | 130 | ||
131 | if (cls->class_attrs) { | 131 | if (cls->class_attrs) { |
132 | for (i = 0; attr_name(cls->class_attrs[i]); i++) | 132 | for (i = 0; attr_name(cls->class_attrs[i]); i++) |
133 | class_remove_file(cls,&cls->class_attrs[i]); | 133 | class_remove_file(cls, &cls->class_attrs[i]); |
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | int class_register(struct class * cls) | 137 | int class_register(struct class *cls) |
138 | { | 138 | { |
139 | int error; | 139 | int error; |
140 | 140 | ||
@@ -149,9 +149,16 @@ int class_register(struct class * cls) | |||
149 | if (error) | 149 | if (error) |
150 | return error; | 150 | return error; |
151 | 151 | ||
152 | cls->subsys.kobj.kset = &class_subsys; | 152 | #ifdef CONFIG_SYSFS_DEPRECATED |
153 | /* let the block class directory show up in the root of sysfs */ | ||
154 | if (cls != &block_class) | ||
155 | cls->subsys.kobj.kset = class_kset; | ||
156 | #else | ||
157 | cls->subsys.kobj.kset = class_kset; | ||
158 | #endif | ||
159 | cls->subsys.kobj.ktype = &class_ktype; | ||
153 | 160 | ||
154 | error = subsystem_register(&cls->subsys); | 161 | error = kset_register(&cls->subsys); |
155 | if (!error) { | 162 | if (!error) { |
156 | error = add_class_attrs(class_get(cls)); | 163 | error = add_class_attrs(class_get(cls)); |
157 | class_put(cls); | 164 | class_put(cls); |
@@ -159,11 +166,11 @@ int class_register(struct class * cls) | |||
159 | return error; | 166 | return error; |
160 | } | 167 | } |
161 | 168 | ||
162 | void class_unregister(struct class * cls) | 169 | void class_unregister(struct class *cls) |
163 | { | 170 | { |
164 | pr_debug("device class '%s': unregistering\n", cls->name); | 171 | pr_debug("device class '%s': unregistering\n", cls->name); |
165 | remove_class_attrs(cls); | 172 | remove_class_attrs(cls); |
166 | subsystem_unregister(&cls->subsys); | 173 | kset_unregister(&cls->subsys); |
167 | } | 174 | } |
168 | 175 | ||
169 | static void class_create_release(struct class *cls) | 176 | static void class_create_release(struct class *cls) |
@@ -241,8 +248,8 @@ void class_destroy(struct class *cls) | |||
241 | 248 | ||
242 | /* Class Device Stuff */ | 249 | /* Class Device Stuff */ |
243 | 250 | ||
244 | int class_device_create_file(struct class_device * class_dev, | 251 | int class_device_create_file(struct class_device *class_dev, |
245 | const struct class_device_attribute * attr) | 252 | const struct class_device_attribute *attr) |
246 | { | 253 | { |
247 | int error = -EINVAL; | 254 | int error = -EINVAL; |
248 | if (class_dev) | 255 | if (class_dev) |
@@ -250,8 +257,8 @@ int class_device_create_file(struct class_device * class_dev, | |||
250 | return error; | 257 | return error; |
251 | } | 258 | } |
252 | 259 | ||
253 | void class_device_remove_file(struct class_device * class_dev, | 260 | void class_device_remove_file(struct class_device *class_dev, |
254 | const struct class_device_attribute * attr) | 261 | const struct class_device_attribute *attr) |
255 | { | 262 | { |
256 | if (class_dev) | 263 | if (class_dev) |
257 | sysfs_remove_file(&class_dev->kobj, &attr->attr); | 264 | sysfs_remove_file(&class_dev->kobj, &attr->attr); |
@@ -273,12 +280,11 @@ void class_device_remove_bin_file(struct class_device *class_dev, | |||
273 | sysfs_remove_bin_file(&class_dev->kobj, attr); | 280 | sysfs_remove_bin_file(&class_dev->kobj, attr); |
274 | } | 281 | } |
275 | 282 | ||
276 | static ssize_t | 283 | static ssize_t class_device_attr_show(struct kobject *kobj, |
277 | class_device_attr_show(struct kobject * kobj, struct attribute * attr, | 284 | struct attribute *attr, char *buf) |
278 | char * buf) | ||
279 | { | 285 | { |
280 | struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); | 286 | struct class_device_attribute *class_dev_attr = to_class_dev_attr(attr); |
281 | struct class_device * cd = to_class_dev(kobj); | 287 | struct class_device *cd = to_class_dev(kobj); |
282 | ssize_t ret = 0; | 288 | ssize_t ret = 0; |
283 | 289 | ||
284 | if (class_dev_attr->show) | 290 | if (class_dev_attr->show) |
@@ -286,12 +292,12 @@ class_device_attr_show(struct kobject * kobj, struct attribute * attr, | |||
286 | return ret; | 292 | return ret; |
287 | } | 293 | } |
288 | 294 | ||
289 | static ssize_t | 295 | static ssize_t class_device_attr_store(struct kobject *kobj, |
290 | class_device_attr_store(struct kobject * kobj, struct attribute * attr, | 296 | struct attribute *attr, |
291 | const char * buf, size_t count) | 297 | const char *buf, size_t count) |
292 | { | 298 | { |
293 | struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); | 299 | struct class_device_attribute *class_dev_attr = to_class_dev_attr(attr); |
294 | struct class_device * cd = to_class_dev(kobj); | 300 | struct class_device *cd = to_class_dev(kobj); |
295 | ssize_t ret = 0; | 301 | ssize_t ret = 0; |
296 | 302 | ||
297 | if (class_dev_attr->store) | 303 | if (class_dev_attr->store) |
@@ -304,10 +310,10 @@ static struct sysfs_ops class_dev_sysfs_ops = { | |||
304 | .store = class_device_attr_store, | 310 | .store = class_device_attr_store, |
305 | }; | 311 | }; |
306 | 312 | ||
307 | static void class_dev_release(struct kobject * kobj) | 313 | static void class_dev_release(struct kobject *kobj) |
308 | { | 314 | { |
309 | struct class_device *cd = to_class_dev(kobj); | 315 | struct class_device *cd = to_class_dev(kobj); |
310 | struct class * cls = cd->class; | 316 | struct class *cls = cd->class; |
311 | 317 | ||
312 | pr_debug("device class '%s': release.\n", cd->class_id); | 318 | pr_debug("device class '%s': release.\n", cd->class_id); |
313 | 319 | ||
@@ -316,8 +322,8 @@ static void class_dev_release(struct kobject * kobj) | |||
316 | else if (cls->release) | 322 | else if (cls->release) |
317 | cls->release(cd); | 323 | cls->release(cd); |
318 | else { | 324 | else { |
319 | printk(KERN_ERR "Class Device '%s' does not have a release() function, " | 325 | printk(KERN_ERR "Class Device '%s' does not have a release() " |
320 | "it is broken and must be fixed.\n", | 326 | "function, it is broken and must be fixed.\n", |
321 | cd->class_id); | 327 | cd->class_id); |
322 | WARN_ON(1); | 328 | WARN_ON(1); |
323 | } | 329 | } |
@@ -428,7 +434,8 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, | |||
428 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); | 434 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); |
429 | 435 | ||
430 | if (dev->driver) | 436 | if (dev->driver) |
431 | add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name); | 437 | add_uevent_var(env, "PHYSDEVDRIVER=%s", |
438 | dev->driver->name); | ||
432 | } | 439 | } |
433 | 440 | ||
434 | if (class_dev->uevent) { | 441 | if (class_dev->uevent) { |
@@ -452,43 +459,49 @@ static struct kset_uevent_ops class_uevent_ops = { | |||
452 | .uevent = class_uevent, | 459 | .uevent = class_uevent, |
453 | }; | 460 | }; |
454 | 461 | ||
455 | static decl_subsys(class_obj, &class_device_ktype, &class_uevent_ops); | 462 | /* |
456 | 463 | * DO NOT copy how this is created, kset_create_and_add() should be | |
464 | * called, but this is a hold-over from the old-way and will be deleted | ||
465 | * entirely soon. | ||
466 | */ | ||
467 | static struct kset class_obj_subsys = { | ||
468 | .uevent_ops = &class_uevent_ops, | ||
469 | }; | ||
457 | 470 | ||
458 | static int class_device_add_attrs(struct class_device * cd) | 471 | static int class_device_add_attrs(struct class_device *cd) |
459 | { | 472 | { |
460 | int i; | 473 | int i; |
461 | int error = 0; | 474 | int error = 0; |
462 | struct class * cls = cd->class; | 475 | struct class *cls = cd->class; |
463 | 476 | ||
464 | if (cls->class_dev_attrs) { | 477 | if (cls->class_dev_attrs) { |
465 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { | 478 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { |
466 | error = class_device_create_file(cd, | 479 | error = class_device_create_file(cd, |
467 | &cls->class_dev_attrs[i]); | 480 | &cls->class_dev_attrs[i]); |
468 | if (error) | 481 | if (error) |
469 | goto Err; | 482 | goto err; |
470 | } | 483 | } |
471 | } | 484 | } |
472 | Done: | 485 | done: |
473 | return error; | 486 | return error; |
474 | Err: | 487 | err: |
475 | while (--i >= 0) | 488 | while (--i >= 0) |
476 | class_device_remove_file(cd,&cls->class_dev_attrs[i]); | 489 | class_device_remove_file(cd, &cls->class_dev_attrs[i]); |
477 | goto Done; | 490 | goto done; |
478 | } | 491 | } |
479 | 492 | ||
480 | static void class_device_remove_attrs(struct class_device * cd) | 493 | static void class_device_remove_attrs(struct class_device *cd) |
481 | { | 494 | { |
482 | int i; | 495 | int i; |
483 | struct class * cls = cd->class; | 496 | struct class *cls = cd->class; |
484 | 497 | ||
485 | if (cls->class_dev_attrs) { | 498 | if (cls->class_dev_attrs) { |
486 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) | 499 | for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) |
487 | class_device_remove_file(cd,&cls->class_dev_attrs[i]); | 500 | class_device_remove_file(cd, &cls->class_dev_attrs[i]); |
488 | } | 501 | } |
489 | } | 502 | } |
490 | 503 | ||
491 | static int class_device_add_groups(struct class_device * cd) | 504 | static int class_device_add_groups(struct class_device *cd) |
492 | { | 505 | { |
493 | int i; | 506 | int i; |
494 | int error = 0; | 507 | int error = 0; |
@@ -498,7 +511,8 @@ static int class_device_add_groups(struct class_device * cd) | |||
498 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); | 511 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); |
499 | if (error) { | 512 | if (error) { |
500 | while (--i >= 0) | 513 | while (--i >= 0) |
501 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | 514 | sysfs_remove_group(&cd->kobj, |
515 | cd->groups[i]); | ||
502 | goto out; | 516 | goto out; |
503 | } | 517 | } |
504 | } | 518 | } |
@@ -507,14 +521,12 @@ out: | |||
507 | return error; | 521 | return error; |
508 | } | 522 | } |
509 | 523 | ||
510 | static void class_device_remove_groups(struct class_device * cd) | 524 | static void class_device_remove_groups(struct class_device *cd) |
511 | { | 525 | { |
512 | int i; | 526 | int i; |
513 | if (cd->groups) { | 527 | if (cd->groups) |
514 | for (i = 0; cd->groups[i]; i++) { | 528 | for (i = 0; cd->groups[i]; i++) |
515 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | 529 | sysfs_remove_group(&cd->kobj, cd->groups[i]); |
516 | } | ||
517 | } | ||
518 | } | 530 | } |
519 | 531 | ||
520 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | 532 | static ssize_t show_dev(struct class_device *class_dev, char *buf) |
@@ -537,8 +549,8 @@ static struct class_device_attribute class_uevent_attr = | |||
537 | 549 | ||
538 | void class_device_initialize(struct class_device *class_dev) | 550 | void class_device_initialize(struct class_device *class_dev) |
539 | { | 551 | { |
540 | kobj_set_kset_s(class_dev, class_obj_subsys); | 552 | class_dev->kobj.kset = &class_obj_subsys; |
541 | kobject_init(&class_dev->kobj); | 553 | kobject_init(&class_dev->kobj, &class_device_ktype); |
542 | INIT_LIST_HEAD(&class_dev->node); | 554 | INIT_LIST_HEAD(&class_dev->node); |
543 | } | 555 | } |
544 | 556 | ||
@@ -566,16 +578,13 @@ int class_device_add(struct class_device *class_dev) | |||
566 | class_dev->class_id); | 578 | class_dev->class_id); |
567 | 579 | ||
568 | /* first, register with generic layer. */ | 580 | /* first, register with generic layer. */ |
569 | error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); | ||
570 | if (error) | ||
571 | goto out2; | ||
572 | |||
573 | if (parent_class_dev) | 581 | if (parent_class_dev) |
574 | class_dev->kobj.parent = &parent_class_dev->kobj; | 582 | class_dev->kobj.parent = &parent_class_dev->kobj; |
575 | else | 583 | else |
576 | class_dev->kobj.parent = &parent_class->subsys.kobj; | 584 | class_dev->kobj.parent = &parent_class->subsys.kobj; |
577 | 585 | ||
578 | error = kobject_add(&class_dev->kobj); | 586 | error = kobject_add(&class_dev->kobj, class_dev->kobj.parent, |
587 | "%s", class_dev->class_id); | ||
579 | if (error) | 588 | if (error) |
580 | goto out2; | 589 | goto out2; |
581 | 590 | ||
@@ -642,7 +651,7 @@ int class_device_add(struct class_device *class_dev) | |||
642 | out3: | 651 | out3: |
643 | kobject_del(&class_dev->kobj); | 652 | kobject_del(&class_dev->kobj); |
644 | out2: | 653 | out2: |
645 | if(parent_class_dev) | 654 | if (parent_class_dev) |
646 | class_device_put(parent_class_dev); | 655 | class_device_put(parent_class_dev); |
647 | class_put(parent_class); | 656 | class_put(parent_class); |
648 | out1: | 657 | out1: |
@@ -659,9 +668,11 @@ int class_device_register(struct class_device *class_dev) | |||
659 | /** | 668 | /** |
660 | * class_device_create - creates a class device and registers it with sysfs | 669 | * class_device_create - creates a class device and registers it with sysfs |
661 | * @cls: pointer to the struct class that this device should be registered to. | 670 | * @cls: pointer to the struct class that this device should be registered to. |
662 | * @parent: pointer to the parent struct class_device of this new device, if any. | 671 | * @parent: pointer to the parent struct class_device of this new device, if |
672 | * any. | ||
663 | * @devt: the dev_t for the char device to be added. | 673 | * @devt: the dev_t for the char device to be added. |
664 | * @device: a pointer to a struct device that is assiociated with this class device. | 674 | * @device: a pointer to a struct device that is assiociated with this class |
675 | * device. | ||
665 | * @fmt: string for the class device's name | 676 | * @fmt: string for the class device's name |
666 | * | 677 | * |
667 | * This function can be used by char device classes. A struct | 678 | * This function can be used by char device classes. A struct |
@@ -785,7 +796,7 @@ void class_device_destroy(struct class *cls, dev_t devt) | |||
785 | class_device_unregister(class_dev); | 796 | class_device_unregister(class_dev); |
786 | } | 797 | } |
787 | 798 | ||
788 | struct class_device * class_device_get(struct class_device *class_dev) | 799 | struct class_device *class_device_get(struct class_device *class_dev) |
789 | { | 800 | { |
790 | if (class_dev) | 801 | if (class_dev) |
791 | return to_class_dev(kobject_get(&class_dev->kobj)); | 802 | return to_class_dev(kobject_get(&class_dev->kobj)); |
@@ -798,6 +809,139 @@ void class_device_put(struct class_device *class_dev) | |||
798 | kobject_put(&class_dev->kobj); | 809 | kobject_put(&class_dev->kobj); |
799 | } | 810 | } |
800 | 811 | ||
812 | /** | ||
813 | * class_for_each_device - device iterator | ||
814 | * @class: the class we're iterating | ||
815 | * @data: data for the callback | ||
816 | * @fn: function to be called for each device | ||
817 | * | ||
818 | * Iterate over @class's list of devices, and call @fn for each, | ||
819 | * passing it @data. | ||
820 | * | ||
821 | * We check the return of @fn each time. If it returns anything | ||
822 | * other than 0, we break out and return that value. | ||
823 | * | ||
824 | * Note, we hold class->sem in this function, so it can not be | ||
825 | * re-acquired in @fn, otherwise it will self-deadlocking. For | ||
826 | * example, calls to add or remove class members would be verboten. | ||
827 | */ | ||
828 | int class_for_each_device(struct class *class, void *data, | ||
829 | int (*fn)(struct device *, void *)) | ||
830 | { | ||
831 | struct device *dev; | ||
832 | int error = 0; | ||
833 | |||
834 | if (!class) | ||
835 | return -EINVAL; | ||
836 | down(&class->sem); | ||
837 | list_for_each_entry(dev, &class->devices, node) { | ||
838 | dev = get_device(dev); | ||
839 | if (dev) { | ||
840 | error = fn(dev, data); | ||
841 | put_device(dev); | ||
842 | } else | ||
843 | error = -ENODEV; | ||
844 | if (error) | ||
845 | break; | ||
846 | } | ||
847 | up(&class->sem); | ||
848 | |||
849 | return error; | ||
850 | } | ||
851 | EXPORT_SYMBOL_GPL(class_for_each_device); | ||
852 | |||
853 | /** | ||
854 | * class_find_device - device iterator for locating a particular device | ||
855 | * @class: the class we're iterating | ||
856 | * @data: data for the match function | ||
857 | * @match: function to check device | ||
858 | * | ||
859 | * This is similar to the class_for_each_dev() function above, but it | ||
860 | * returns a reference to a device that is 'found' for later use, as | ||
861 | * determined by the @match callback. | ||
862 | * | ||
863 | * The callback should return 0 if the device doesn't match and non-zero | ||
864 | * if it does. If the callback returns non-zero, this function will | ||
865 | * return to the caller and not iterate over any more devices. | ||
866 | |||
867 | * Note, you will need to drop the reference with put_device() after use. | ||
868 | * | ||
869 | * We hold class->sem in this function, so it can not be | ||
870 | * re-acquired in @match, otherwise it will self-deadlocking. For | ||
871 | * example, calls to add or remove class members would be verboten. | ||
872 | */ | ||
873 | struct device *class_find_device(struct class *class, void *data, | ||
874 | int (*match)(struct device *, void *)) | ||
875 | { | ||
876 | struct device *dev; | ||
877 | int found = 0; | ||
878 | |||
879 | if (!class) | ||
880 | return NULL; | ||
881 | |||
882 | down(&class->sem); | ||
883 | list_for_each_entry(dev, &class->devices, node) { | ||
884 | dev = get_device(dev); | ||
885 | if (dev) { | ||
886 | if (match(dev, data)) { | ||
887 | found = 1; | ||
888 | break; | ||
889 | } else | ||
890 | put_device(dev); | ||
891 | } else | ||
892 | break; | ||
893 | } | ||
894 | up(&class->sem); | ||
895 | |||
896 | return found ? dev : NULL; | ||
897 | } | ||
898 | EXPORT_SYMBOL_GPL(class_find_device); | ||
899 | |||
900 | /** | ||
901 | * class_find_child - device iterator for locating a particular class_device | ||
902 | * @class: the class we're iterating | ||
903 | * @data: data for the match function | ||
904 | * @match: function to check class_device | ||
905 | * | ||
906 | * This function returns a reference to a class_device that is 'found' for | ||
907 | * later use, as determined by the @match callback. | ||
908 | * | ||
909 | * The callback should return 0 if the class_device doesn't match and non-zero | ||
910 | * if it does. If the callback returns non-zero, this function will | ||
911 | * return to the caller and not iterate over any more class_devices. | ||
912 | * | ||
913 | * Note, you will need to drop the reference with class_device_put() after use. | ||
914 | * | ||
915 | * We hold class->sem in this function, so it can not be | ||
916 | * re-acquired in @match, otherwise it will self-deadlocking. For | ||
917 | * example, calls to add or remove class members would be verboten. | ||
918 | */ | ||
919 | struct class_device *class_find_child(struct class *class, void *data, | ||
920 | int (*match)(struct class_device *, void *)) | ||
921 | { | ||
922 | struct class_device *dev; | ||
923 | int found = 0; | ||
924 | |||
925 | if (!class) | ||
926 | return NULL; | ||
927 | |||
928 | down(&class->sem); | ||
929 | list_for_each_entry(dev, &class->children, node) { | ||
930 | dev = class_device_get(dev); | ||
931 | if (dev) { | ||
932 | if (match(dev, data)) { | ||
933 | found = 1; | ||
934 | break; | ||
935 | } else | ||
936 | class_device_put(dev); | ||
937 | } else | ||
938 | break; | ||
939 | } | ||
940 | up(&class->sem); | ||
941 | |||
942 | return found ? dev : NULL; | ||
943 | } | ||
944 | EXPORT_SYMBOL_GPL(class_find_child); | ||
801 | 945 | ||
802 | int class_interface_register(struct class_interface *class_intf) | 946 | int class_interface_register(struct class_interface *class_intf) |
803 | { | 947 | { |
@@ -829,7 +973,7 @@ int class_interface_register(struct class_interface *class_intf) | |||
829 | 973 | ||
830 | void class_interface_unregister(struct class_interface *class_intf) | 974 | void class_interface_unregister(struct class_interface *class_intf) |
831 | { | 975 | { |
832 | struct class * parent = class_intf->class; | 976 | struct class *parent = class_intf->class; |
833 | struct class_device *class_dev; | 977 | struct class_device *class_dev; |
834 | struct device *dev; | 978 | struct device *dev; |
835 | 979 | ||
@@ -853,15 +997,14 @@ void class_interface_unregister(struct class_interface *class_intf) | |||
853 | 997 | ||
854 | int __init classes_init(void) | 998 | int __init classes_init(void) |
855 | { | 999 | { |
856 | int retval; | 1000 | class_kset = kset_create_and_add("class", NULL, NULL); |
857 | 1001 | if (!class_kset) | |
858 | retval = subsystem_register(&class_subsys); | 1002 | return -ENOMEM; |
859 | if (retval) | ||
860 | return retval; | ||
861 | 1003 | ||
862 | /* ick, this is ugly, the things we go through to keep from showing up | 1004 | /* ick, this is ugly, the things we go through to keep from showing up |
863 | * in sysfs... */ | 1005 | * in sysfs... */ |
864 | kset_init(&class_obj_subsys); | 1006 | kset_init(&class_obj_subsys); |
1007 | kobject_set_name(&class_obj_subsys.kobj, "class_obj"); | ||
865 | if (!class_obj_subsys.kobj.parent) | 1008 | if (!class_obj_subsys.kobj.parent) |
866 | class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; | 1009 | class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; |
867 | return 0; | 1010 | return 0; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 2683eac30c68..edf3bbeb8d6a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -18,14 +18,14 @@ | |||
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 | #include <linux/notifier.h> |
21 | 21 | #include <linux/genhd.h> | |
22 | #include <asm/semaphore.h> | 22 | #include <asm/semaphore.h> |
23 | 23 | ||
24 | #include "base.h" | 24 | #include "base.h" |
25 | #include "power/power.h" | 25 | #include "power/power.h" |
26 | 26 | ||
27 | int (*platform_notify)(struct device * dev) = NULL; | 27 | int (*platform_notify)(struct device *dev) = NULL; |
28 | int (*platform_notify_remove)(struct device * dev) = NULL; | 28 | int (*platform_notify_remove)(struct device *dev) = NULL; |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * sysfs bindings for devices. | 31 | * sysfs bindings for devices. |
@@ -51,11 +51,11 @@ EXPORT_SYMBOL(dev_driver_string); | |||
51 | #define to_dev(obj) container_of(obj, struct device, kobj) | 51 | #define to_dev(obj) container_of(obj, struct device, kobj) |
52 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) | 52 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
53 | 53 | ||
54 | static ssize_t | 54 | static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr, |
55 | dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 55 | char *buf) |
56 | { | 56 | { |
57 | struct device_attribute * dev_attr = to_dev_attr(attr); | 57 | struct device_attribute *dev_attr = to_dev_attr(attr); |
58 | struct device * dev = to_dev(kobj); | 58 | struct device *dev = to_dev(kobj); |
59 | ssize_t ret = -EIO; | 59 | ssize_t ret = -EIO; |
60 | 60 | ||
61 | if (dev_attr->show) | 61 | if (dev_attr->show) |
@@ -63,12 +63,11 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | |||
63 | return ret; | 63 | return ret; |
64 | } | 64 | } |
65 | 65 | ||
66 | static ssize_t | 66 | static ssize_t dev_attr_store(struct kobject *kobj, struct attribute *attr, |
67 | dev_attr_store(struct kobject * kobj, struct attribute * attr, | 67 | const char *buf, size_t count) |
68 | const char * buf, size_t count) | ||
69 | { | 68 | { |
70 | struct device_attribute * dev_attr = to_dev_attr(attr); | 69 | struct device_attribute *dev_attr = to_dev_attr(attr); |
71 | struct device * dev = to_dev(kobj); | 70 | struct device *dev = to_dev(kobj); |
72 | ssize_t ret = -EIO; | 71 | ssize_t ret = -EIO; |
73 | 72 | ||
74 | if (dev_attr->store) | 73 | if (dev_attr->store) |
@@ -90,9 +89,9 @@ static struct sysfs_ops dev_sysfs_ops = { | |||
90 | * reaches 0. We forward the call to the device's release | 89 | * reaches 0. We forward the call to the device's release |
91 | * method, which should handle actually freeing the structure. | 90 | * method, which should handle actually freeing the structure. |
92 | */ | 91 | */ |
93 | static void device_release(struct kobject * kobj) | 92 | static void device_release(struct kobject *kobj) |
94 | { | 93 | { |
95 | struct device * dev = to_dev(kobj); | 94 | struct device *dev = to_dev(kobj); |
96 | 95 | ||
97 | if (dev->release) | 96 | if (dev->release) |
98 | dev->release(dev); | 97 | dev->release(dev); |
@@ -101,8 +100,8 @@ static void device_release(struct kobject * kobj) | |||
101 | else if (dev->class && dev->class->dev_release) | 100 | else if (dev->class && dev->class->dev_release) |
102 | dev->class->dev_release(dev); | 101 | dev->class->dev_release(dev); |
103 | else { | 102 | else { |
104 | printk(KERN_ERR "Device '%s' does not have a release() function, " | 103 | printk(KERN_ERR "Device '%s' does not have a release() " |
105 | "it is broken and must be fixed.\n", | 104 | "function, it is broken and must be fixed.\n", |
106 | dev->bus_id); | 105 | dev->bus_id); |
107 | WARN_ON(1); | 106 | WARN_ON(1); |
108 | } | 107 | } |
@@ -185,7 +184,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
185 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); | 184 | add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name); |
186 | 185 | ||
187 | if (dev->driver) | 186 | if (dev->driver) |
188 | add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name); | 187 | add_uevent_var(env, "PHYSDEVDRIVER=%s", |
188 | dev->driver->name); | ||
189 | } | 189 | } |
190 | #endif | 190 | #endif |
191 | 191 | ||
@@ -193,15 +193,16 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
193 | if (dev->bus && dev->bus->uevent) { | 193 | if (dev->bus && dev->bus->uevent) { |
194 | retval = dev->bus->uevent(dev, env); | 194 | retval = dev->bus->uevent(dev, env); |
195 | if (retval) | 195 | if (retval) |
196 | pr_debug ("%s: bus uevent() returned %d\n", | 196 | pr_debug("device: '%s': %s: bus uevent() returned %d\n", |
197 | __FUNCTION__, retval); | 197 | dev->bus_id, __FUNCTION__, retval); |
198 | } | 198 | } |
199 | 199 | ||
200 | /* have the class specific function add its stuff */ | 200 | /* have the class specific function add its stuff */ |
201 | if (dev->class && dev->class->dev_uevent) { | 201 | if (dev->class && dev->class->dev_uevent) { |
202 | retval = dev->class->dev_uevent(dev, env); | 202 | retval = dev->class->dev_uevent(dev, env); |
203 | if (retval) | 203 | if (retval) |
204 | pr_debug("%s: class uevent() returned %d\n", | 204 | pr_debug("device: '%s': %s: class uevent() " |
205 | "returned %d\n", dev->bus_id, | ||
205 | __FUNCTION__, retval); | 206 | __FUNCTION__, retval); |
206 | } | 207 | } |
207 | 208 | ||
@@ -209,7 +210,8 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, | |||
209 | if (dev->type && dev->type->uevent) { | 210 | if (dev->type && dev->type->uevent) { |
210 | retval = dev->type->uevent(dev, env); | 211 | retval = dev->type->uevent(dev, env); |
211 | if (retval) | 212 | if (retval) |
212 | pr_debug("%s: dev_type uevent() returned %d\n", | 213 | pr_debug("device: '%s': %s: dev_type uevent() " |
214 | "returned %d\n", dev->bus_id, | ||
213 | __FUNCTION__, retval); | 215 | __FUNCTION__, retval); |
214 | } | 216 | } |
215 | 217 | ||
@@ -325,7 +327,8 @@ static int device_add_groups(struct device *dev, | |||
325 | error = sysfs_create_group(&dev->kobj, groups[i]); | 327 | error = sysfs_create_group(&dev->kobj, groups[i]); |
326 | if (error) { | 328 | if (error) { |
327 | while (--i >= 0) | 329 | while (--i >= 0) |
328 | sysfs_remove_group(&dev->kobj, groups[i]); | 330 | sysfs_remove_group(&dev->kobj, |
331 | groups[i]); | ||
329 | break; | 332 | break; |
330 | } | 333 | } |
331 | } | 334 | } |
@@ -401,20 +404,15 @@ static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | |||
401 | static struct device_attribute devt_attr = | 404 | static struct device_attribute devt_attr = |
402 | __ATTR(dev, S_IRUGO, show_dev, NULL); | 405 | __ATTR(dev, S_IRUGO, show_dev, NULL); |
403 | 406 | ||
404 | /* | 407 | /* kset to create /sys/devices/ */ |
405 | * devices_subsys - structure to be registered with kobject core. | 408 | struct kset *devices_kset; |
406 | */ | ||
407 | |||
408 | decl_subsys(devices, &device_ktype, &device_uevent_ops); | ||
409 | |||
410 | 409 | ||
411 | /** | 410 | /** |
412 | * device_create_file - create sysfs attribute file for device. | 411 | * device_create_file - create sysfs attribute file for device. |
413 | * @dev: device. | 412 | * @dev: device. |
414 | * @attr: device attribute descriptor. | 413 | * @attr: device attribute descriptor. |
415 | */ | 414 | */ |
416 | 415 | int device_create_file(struct device *dev, struct device_attribute *attr) | |
417 | int device_create_file(struct device * dev, struct device_attribute * attr) | ||
418 | { | 416 | { |
419 | int error = 0; | 417 | int error = 0; |
420 | if (get_device(dev)) { | 418 | if (get_device(dev)) { |
@@ -425,12 +423,11 @@ int device_create_file(struct device * dev, struct device_attribute * attr) | |||
425 | } | 423 | } |
426 | 424 | ||
427 | /** | 425 | /** |
428 | * device_remove_file - remove sysfs attribute file. | 426 | * device_remove_file - remove sysfs attribute file. |
429 | * @dev: device. | 427 | * @dev: device. |
430 | * @attr: device attribute descriptor. | 428 | * @attr: device attribute descriptor. |
431 | */ | 429 | */ |
432 | 430 | void device_remove_file(struct device *dev, struct device_attribute *attr) | |
433 | void device_remove_file(struct device * dev, struct device_attribute * attr) | ||
434 | { | 431 | { |
435 | if (get_device(dev)) { | 432 | if (get_device(dev)) { |
436 | sysfs_remove_file(&dev->kobj, &attr->attr); | 433 | sysfs_remove_file(&dev->kobj, &attr->attr); |
@@ -511,22 +508,20 @@ static void klist_children_put(struct klist_node *n) | |||
511 | put_device(dev); | 508 | put_device(dev); |
512 | } | 509 | } |
513 | 510 | ||
514 | |||
515 | /** | 511 | /** |
516 | * device_initialize - init device structure. | 512 | * device_initialize - init device structure. |
517 | * @dev: device. | 513 | * @dev: device. |
518 | * | 514 | * |
519 | * This prepares the device for use by other layers, | 515 | * This prepares the device for use by other layers, |
520 | * including adding it to the device hierarchy. | 516 | * including adding it to the device hierarchy. |
521 | * It is the first half of device_register(), if called by | 517 | * It is the first half of device_register(), if called by |
522 | * that, though it can also be called separately, so one | 518 | * that, though it can also be called separately, so one |
523 | * may use @dev's fields (e.g. the refcount). | 519 | * may use @dev's fields (e.g. the refcount). |
524 | */ | 520 | */ |
525 | |||
526 | void device_initialize(struct device *dev) | 521 | void device_initialize(struct device *dev) |
527 | { | 522 | { |
528 | kobj_set_kset_s(dev, devices_subsys); | 523 | dev->kobj.kset = devices_kset; |
529 | kobject_init(&dev->kobj); | 524 | kobject_init(&dev->kobj, &device_ktype); |
530 | klist_init(&dev->klist_children, klist_children_get, | 525 | klist_init(&dev->klist_children, klist_children_get, |
531 | klist_children_put); | 526 | klist_children_put); |
532 | INIT_LIST_HEAD(&dev->dma_pools); | 527 | INIT_LIST_HEAD(&dev->dma_pools); |
@@ -539,36 +534,39 @@ void device_initialize(struct device *dev) | |||
539 | } | 534 | } |
540 | 535 | ||
541 | #ifdef CONFIG_SYSFS_DEPRECATED | 536 | #ifdef CONFIG_SYSFS_DEPRECATED |
542 | static struct kobject * get_device_parent(struct device *dev, | 537 | static struct kobject *get_device_parent(struct device *dev, |
543 | struct device *parent) | 538 | struct device *parent) |
544 | { | 539 | { |
545 | /* | 540 | /* class devices without a parent live in /sys/class/<classname>/ */ |
546 | * Set the parent to the class, not the parent device | ||
547 | * for topmost devices in class hierarchy. | ||
548 | * This keeps sysfs from having a symlink to make old | ||
549 | * udevs happy | ||
550 | */ | ||
551 | if (dev->class && (!parent || parent->class != dev->class)) | 541 | if (dev->class && (!parent || parent->class != dev->class)) |
552 | return &dev->class->subsys.kobj; | 542 | return &dev->class->subsys.kobj; |
543 | /* all other devices keep their parent */ | ||
553 | else if (parent) | 544 | else if (parent) |
554 | return &parent->kobj; | 545 | return &parent->kobj; |
555 | 546 | ||
556 | return NULL; | 547 | return NULL; |
557 | } | 548 | } |
549 | |||
550 | static inline void cleanup_device_parent(struct device *dev) {} | ||
551 | static inline void cleanup_glue_dir(struct device *dev, | ||
552 | struct kobject *glue_dir) {} | ||
558 | #else | 553 | #else |
559 | static struct kobject *virtual_device_parent(struct device *dev) | 554 | static struct kobject *virtual_device_parent(struct device *dev) |
560 | { | 555 | { |
561 | static struct kobject *virtual_dir = NULL; | 556 | static struct kobject *virtual_dir = NULL; |
562 | 557 | ||
563 | if (!virtual_dir) | 558 | if (!virtual_dir) |
564 | virtual_dir = kobject_add_dir(&devices_subsys.kobj, "virtual"); | 559 | virtual_dir = kobject_create_and_add("virtual", |
560 | &devices_kset->kobj); | ||
565 | 561 | ||
566 | return virtual_dir; | 562 | return virtual_dir; |
567 | } | 563 | } |
568 | 564 | ||
569 | static struct kobject * get_device_parent(struct device *dev, | 565 | static struct kobject *get_device_parent(struct device *dev, |
570 | struct device *parent) | 566 | struct device *parent) |
571 | { | 567 | { |
568 | int retval; | ||
569 | |||
572 | if (dev->class) { | 570 | if (dev->class) { |
573 | struct kobject *kobj = NULL; | 571 | struct kobject *kobj = NULL; |
574 | struct kobject *parent_kobj; | 572 | struct kobject *parent_kobj; |
@@ -576,8 +574,8 @@ static struct kobject * get_device_parent(struct device *dev, | |||
576 | 574 | ||
577 | /* | 575 | /* |
578 | * If we have no parent, we live in "virtual". | 576 | * If we have no parent, we live in "virtual". |
579 | * Class-devices with a bus-device as parent, live | 577 | * Class-devices with a non class-device as parent, live |
580 | * in a class-directory to prevent namespace collisions. | 578 | * in a "glue" directory to prevent namespace collisions. |
581 | */ | 579 | */ |
582 | if (parent == NULL) | 580 | if (parent == NULL) |
583 | parent_kobj = virtual_device_parent(dev); | 581 | parent_kobj = virtual_device_parent(dev); |
@@ -598,25 +596,45 @@ static struct kobject * get_device_parent(struct device *dev, | |||
598 | return kobj; | 596 | return kobj; |
599 | 597 | ||
600 | /* or create a new class-directory at the parent device */ | 598 | /* or create a new class-directory at the parent device */ |
601 | return kobject_kset_add_dir(&dev->class->class_dirs, | 599 | k = kobject_create(); |
602 | parent_kobj, dev->class->name); | 600 | if (!k) |
601 | return NULL; | ||
602 | k->kset = &dev->class->class_dirs; | ||
603 | retval = kobject_add(k, parent_kobj, "%s", dev->class->name); | ||
604 | if (retval < 0) { | ||
605 | kobject_put(k); | ||
606 | return NULL; | ||
607 | } | ||
608 | /* do not emit an uevent for this simple "glue" directory */ | ||
609 | return k; | ||
603 | } | 610 | } |
604 | 611 | ||
605 | if (parent) | 612 | if (parent) |
606 | return &parent->kobj; | 613 | return &parent->kobj; |
607 | return NULL; | 614 | return NULL; |
608 | } | 615 | } |
616 | |||
617 | static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) | ||
618 | { | ||
619 | /* see if we live in a "glue" directory */ | ||
620 | if (!dev->class || glue_dir->kset != &dev->class->class_dirs) | ||
621 | return; | ||
622 | |||
623 | kobject_put(glue_dir); | ||
624 | } | ||
625 | |||
626 | static void cleanup_device_parent(struct device *dev) | ||
627 | { | ||
628 | cleanup_glue_dir(dev, dev->kobj.parent); | ||
629 | } | ||
609 | #endif | 630 | #endif |
610 | 631 | ||
611 | static int setup_parent(struct device *dev, struct device *parent) | 632 | static void setup_parent(struct device *dev, struct device *parent) |
612 | { | 633 | { |
613 | struct kobject *kobj; | 634 | struct kobject *kobj; |
614 | kobj = get_device_parent(dev, parent); | 635 | kobj = get_device_parent(dev, parent); |
615 | if (IS_ERR(kobj)) | ||
616 | return PTR_ERR(kobj); | ||
617 | if (kobj) | 636 | if (kobj) |
618 | dev->kobj.parent = kobj; | 637 | dev->kobj.parent = kobj; |
619 | return 0; | ||
620 | } | 638 | } |
621 | 639 | ||
622 | static int device_add_class_symlinks(struct device *dev) | 640 | static int device_add_class_symlinks(struct device *dev) |
@@ -625,65 +643,76 @@ static int device_add_class_symlinks(struct device *dev) | |||
625 | 643 | ||
626 | if (!dev->class) | 644 | if (!dev->class) |
627 | return 0; | 645 | return 0; |
646 | |||
628 | error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, | 647 | error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, |
629 | "subsystem"); | 648 | "subsystem"); |
630 | if (error) | 649 | if (error) |
631 | goto out; | 650 | goto out; |
632 | /* | 651 | |
633 | * If this is not a "fake" compatible device, then create the | 652 | #ifdef CONFIG_SYSFS_DEPRECATED |
634 | * symlink from the class to the device. | 653 | /* stacked class devices need a symlink in the class directory */ |
635 | */ | 654 | if (dev->kobj.parent != &dev->class->subsys.kobj && |
636 | if (dev->kobj.parent != &dev->class->subsys.kobj) { | 655 | dev->type != &part_type) { |
637 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | 656 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, |
638 | dev->bus_id); | 657 | dev->bus_id); |
639 | if (error) | 658 | if (error) |
640 | goto out_subsys; | 659 | goto out_subsys; |
641 | } | 660 | } |
642 | if (dev->parent) { | ||
643 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
644 | { | ||
645 | struct device *parent = dev->parent; | ||
646 | char *class_name; | ||
647 | |||
648 | /* | ||
649 | * In old sysfs stacked class devices had 'device' | ||
650 | * link pointing to real device instead of parent | ||
651 | */ | ||
652 | while (parent->class && !parent->bus && parent->parent) | ||
653 | parent = parent->parent; | ||
654 | |||
655 | error = sysfs_create_link(&dev->kobj, | ||
656 | &parent->kobj, | ||
657 | "device"); | ||
658 | if (error) | ||
659 | goto out_busid; | ||
660 | 661 | ||
661 | class_name = make_class_name(dev->class->name, | 662 | if (dev->parent && dev->type != &part_type) { |
662 | &dev->kobj); | 663 | struct device *parent = dev->parent; |
663 | if (class_name) | 664 | char *class_name; |
664 | error = sysfs_create_link(&dev->parent->kobj, | 665 | |
665 | &dev->kobj, class_name); | 666 | /* |
666 | kfree(class_name); | 667 | * stacked class devices have the 'device' link |
667 | if (error) | 668 | * pointing to the bus device instead of the parent |
668 | goto out_device; | 669 | */ |
669 | } | 670 | while (parent->class && !parent->bus && parent->parent) |
670 | #else | 671 | parent = parent->parent; |
671 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, | 672 | |
673 | error = sysfs_create_link(&dev->kobj, | ||
674 | &parent->kobj, | ||
672 | "device"); | 675 | "device"); |
673 | if (error) | 676 | if (error) |
674 | goto out_busid; | 677 | goto out_busid; |
675 | #endif | 678 | |
679 | class_name = make_class_name(dev->class->name, | ||
680 | &dev->kobj); | ||
681 | if (class_name) | ||
682 | error = sysfs_create_link(&dev->parent->kobj, | ||
683 | &dev->kobj, class_name); | ||
684 | kfree(class_name); | ||
685 | if (error) | ||
686 | goto out_device; | ||
676 | } | 687 | } |
677 | return 0; | 688 | return 0; |
678 | 689 | ||
679 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
680 | out_device: | 690 | out_device: |
681 | if (dev->parent) | 691 | if (dev->parent && dev->type != &part_type) |
682 | sysfs_remove_link(&dev->kobj, "device"); | 692 | sysfs_remove_link(&dev->kobj, "device"); |
683 | #endif | ||
684 | out_busid: | 693 | out_busid: |
685 | if (dev->kobj.parent != &dev->class->subsys.kobj) | 694 | if (dev->kobj.parent != &dev->class->subsys.kobj && |
695 | dev->type != &part_type) | ||
686 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 696 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); |
697 | #else | ||
698 | /* link in the class directory pointing to the device */ | ||
699 | error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, | ||
700 | dev->bus_id); | ||
701 | if (error) | ||
702 | goto out_subsys; | ||
703 | |||
704 | if (dev->parent && dev->type != &part_type) { | ||
705 | error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, | ||
706 | "device"); | ||
707 | if (error) | ||
708 | goto out_busid; | ||
709 | } | ||
710 | return 0; | ||
711 | |||
712 | out_busid: | ||
713 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | ||
714 | #endif | ||
715 | |||
687 | out_subsys: | 716 | out_subsys: |
688 | sysfs_remove_link(&dev->kobj, "subsystem"); | 717 | sysfs_remove_link(&dev->kobj, "subsystem"); |
689 | out: | 718 | out: |
@@ -694,8 +723,9 @@ static void device_remove_class_symlinks(struct device *dev) | |||
694 | { | 723 | { |
695 | if (!dev->class) | 724 | if (!dev->class) |
696 | return; | 725 | return; |
697 | if (dev->parent) { | 726 | |
698 | #ifdef CONFIG_SYSFS_DEPRECATED | 727 | #ifdef CONFIG_SYSFS_DEPRECATED |
728 | if (dev->parent && dev->type != &part_type) { | ||
699 | char *class_name; | 729 | char *class_name; |
700 | 730 | ||
701 | class_name = make_class_name(dev->class->name, &dev->kobj); | 731 | class_name = make_class_name(dev->class->name, &dev->kobj); |
@@ -703,45 +733,59 @@ static void device_remove_class_symlinks(struct device *dev) | |||
703 | sysfs_remove_link(&dev->parent->kobj, class_name); | 733 | sysfs_remove_link(&dev->parent->kobj, class_name); |
704 | kfree(class_name); | 734 | kfree(class_name); |
705 | } | 735 | } |
706 | #endif | ||
707 | sysfs_remove_link(&dev->kobj, "device"); | 736 | sysfs_remove_link(&dev->kobj, "device"); |
708 | } | 737 | } |
709 | if (dev->kobj.parent != &dev->class->subsys.kobj) | 738 | |
739 | if (dev->kobj.parent != &dev->class->subsys.kobj && | ||
740 | dev->type != &part_type) | ||
710 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | 741 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); |
742 | #else | ||
743 | if (dev->parent && dev->type != &part_type) | ||
744 | sysfs_remove_link(&dev->kobj, "device"); | ||
745 | |||
746 | sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); | ||
747 | #endif | ||
748 | |||
711 | sysfs_remove_link(&dev->kobj, "subsystem"); | 749 | sysfs_remove_link(&dev->kobj, "subsystem"); |
712 | } | 750 | } |
713 | 751 | ||
714 | /** | 752 | /** |
715 | * device_add - add device to device hierarchy. | 753 | * device_add - add device to device hierarchy. |
716 | * @dev: device. | 754 | * @dev: device. |
717 | * | 755 | * |
718 | * This is part 2 of device_register(), though may be called | 756 | * This is part 2 of device_register(), though may be called |
719 | * separately _iff_ device_initialize() has been called separately. | 757 | * separately _iff_ device_initialize() has been called separately. |
720 | * | 758 | * |
721 | * This adds it to the kobject hierarchy via kobject_add(), adds it | 759 | * This adds it to the kobject hierarchy via kobject_add(), adds it |
722 | * to the global and sibling lists for the device, then | 760 | * to the global and sibling lists for the device, then |
723 | * adds it to the other relevant subsystems of the driver model. | 761 | * adds it to the other relevant subsystems of the driver model. |
724 | */ | 762 | */ |
725 | int device_add(struct device *dev) | 763 | int device_add(struct device *dev) |
726 | { | 764 | { |
727 | struct device *parent = NULL; | 765 | struct device *parent = NULL; |
728 | struct class_interface *class_intf; | 766 | struct class_interface *class_intf; |
729 | int error = -EINVAL; | 767 | int error; |
768 | |||
769 | error = pm_sleep_lock(); | ||
770 | if (error) { | ||
771 | dev_warn(dev, "Suspicious %s during suspend\n", __FUNCTION__); | ||
772 | dump_stack(); | ||
773 | return error; | ||
774 | } | ||
730 | 775 | ||
731 | dev = get_device(dev); | 776 | dev = get_device(dev); |
732 | if (!dev || !strlen(dev->bus_id)) | 777 | if (!dev || !strlen(dev->bus_id)) { |
778 | error = -EINVAL; | ||
733 | goto Error; | 779 | goto Error; |
780 | } | ||
734 | 781 | ||
735 | pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); | 782 | pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); |
736 | 783 | ||
737 | parent = get_device(dev->parent); | 784 | parent = get_device(dev->parent); |
738 | error = setup_parent(dev, parent); | 785 | setup_parent(dev, parent); |
739 | if (error) | ||
740 | goto Error; | ||
741 | 786 | ||
742 | /* first, register with generic layer. */ | 787 | /* first, register with generic layer. */ |
743 | kobject_set_name(&dev->kobj, "%s", dev->bus_id); | 788 | error = kobject_add(&dev->kobj, dev->kobj.parent, "%s", dev->bus_id); |
744 | error = kobject_add(&dev->kobj); | ||
745 | if (error) | 789 | if (error) |
746 | goto Error; | 790 | goto Error; |
747 | 791 | ||
@@ -751,7 +795,7 @@ int device_add(struct device *dev) | |||
751 | 795 | ||
752 | /* notify clients of device entry (new way) */ | 796 | /* notify clients of device entry (new way) */ |
753 | if (dev->bus) | 797 | if (dev->bus) |
754 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 798 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
755 | BUS_NOTIFY_ADD_DEVICE, dev); | 799 | BUS_NOTIFY_ADD_DEVICE, dev); |
756 | 800 | ||
757 | error = device_create_file(dev, &uevent_attr); | 801 | error = device_create_file(dev, &uevent_attr); |
@@ -795,13 +839,14 @@ int device_add(struct device *dev) | |||
795 | } | 839 | } |
796 | Done: | 840 | Done: |
797 | put_device(dev); | 841 | put_device(dev); |
842 | pm_sleep_unlock(); | ||
798 | return error; | 843 | return error; |
799 | BusError: | 844 | BusError: |
800 | device_pm_remove(dev); | 845 | device_pm_remove(dev); |
801 | dpm_sysfs_remove(dev); | 846 | dpm_sysfs_remove(dev); |
802 | PMError: | 847 | PMError: |
803 | if (dev->bus) | 848 | if (dev->bus) |
804 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 849 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
805 | BUS_NOTIFY_DEL_DEVICE, dev); | 850 | BUS_NOTIFY_DEL_DEVICE, dev); |
806 | device_remove_attrs(dev); | 851 | device_remove_attrs(dev); |
807 | AttrsError: | 852 | AttrsError: |
@@ -809,124 +854,84 @@ int device_add(struct device *dev) | |||
809 | SymlinkError: | 854 | SymlinkError: |
810 | if (MAJOR(dev->devt)) | 855 | if (MAJOR(dev->devt)) |
811 | device_remove_file(dev, &devt_attr); | 856 | device_remove_file(dev, &devt_attr); |
812 | |||
813 | if (dev->class) { | ||
814 | sysfs_remove_link(&dev->kobj, "subsystem"); | ||
815 | /* If this is not a "fake" compatible device, remove the | ||
816 | * symlink from the class to the device. */ | ||
817 | if (dev->kobj.parent != &dev->class->subsys.kobj) | ||
818 | sysfs_remove_link(&dev->class->subsys.kobj, | ||
819 | dev->bus_id); | ||
820 | if (parent) { | ||
821 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
822 | char *class_name = make_class_name(dev->class->name, | ||
823 | &dev->kobj); | ||
824 | if (class_name) | ||
825 | sysfs_remove_link(&dev->parent->kobj, | ||
826 | class_name); | ||
827 | kfree(class_name); | ||
828 | #endif | ||
829 | sysfs_remove_link(&dev->kobj, "device"); | ||
830 | } | ||
831 | } | ||
832 | ueventattrError: | 857 | ueventattrError: |
833 | device_remove_file(dev, &uevent_attr); | 858 | device_remove_file(dev, &uevent_attr); |
834 | attrError: | 859 | attrError: |
835 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 860 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
836 | kobject_del(&dev->kobj); | 861 | kobject_del(&dev->kobj); |
837 | Error: | 862 | Error: |
863 | cleanup_device_parent(dev); | ||
838 | if (parent) | 864 | if (parent) |
839 | put_device(parent); | 865 | put_device(parent); |
840 | goto Done; | 866 | goto Done; |
841 | } | 867 | } |
842 | 868 | ||
843 | |||
844 | /** | 869 | /** |
845 | * device_register - register a device with the system. | 870 | * device_register - register a device with the system. |
846 | * @dev: pointer to the device structure | 871 | * @dev: pointer to the device structure |
847 | * | 872 | * |
848 | * This happens in two clean steps - initialize the device | 873 | * This happens in two clean steps - initialize the device |
849 | * and add it to the system. The two steps can be called | 874 | * and add it to the system. The two steps can be called |
850 | * separately, but this is the easiest and most common. | 875 | * separately, but this is the easiest and most common. |
851 | * I.e. you should only call the two helpers separately if | 876 | * I.e. you should only call the two helpers separately if |
852 | * have a clearly defined need to use and refcount the device | 877 | * have a clearly defined need to use and refcount the device |
853 | * before it is added to the hierarchy. | 878 | * before it is added to the hierarchy. |
854 | */ | 879 | */ |
855 | |||
856 | int device_register(struct device *dev) | 880 | int device_register(struct device *dev) |
857 | { | 881 | { |
858 | device_initialize(dev); | 882 | device_initialize(dev); |
859 | return device_add(dev); | 883 | return device_add(dev); |
860 | } | 884 | } |
861 | 885 | ||
862 | |||
863 | /** | 886 | /** |
864 | * get_device - increment reference count for device. | 887 | * get_device - increment reference count for device. |
865 | * @dev: device. | 888 | * @dev: device. |
866 | * | 889 | * |
867 | * This simply forwards the call to kobject_get(), though | 890 | * This simply forwards the call to kobject_get(), though |
868 | * we do take care to provide for the case that we get a NULL | 891 | * we do take care to provide for the case that we get a NULL |
869 | * pointer passed in. | 892 | * pointer passed in. |
870 | */ | 893 | */ |
871 | 894 | struct device *get_device(struct device *dev) | |
872 | struct device * get_device(struct device * dev) | ||
873 | { | 895 | { |
874 | return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; | 896 | return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; |
875 | } | 897 | } |
876 | 898 | ||
877 | |||
878 | /** | 899 | /** |
879 | * put_device - decrement reference count. | 900 | * put_device - decrement reference count. |
880 | * @dev: device in question. | 901 | * @dev: device in question. |
881 | */ | 902 | */ |
882 | void put_device(struct device * dev) | 903 | void put_device(struct device *dev) |
883 | { | 904 | { |
905 | /* might_sleep(); */ | ||
884 | if (dev) | 906 | if (dev) |
885 | kobject_put(&dev->kobj); | 907 | kobject_put(&dev->kobj); |
886 | } | 908 | } |
887 | 909 | ||
888 | |||
889 | /** | 910 | /** |
890 | * device_del - delete device from system. | 911 | * device_del - delete device from system. |
891 | * @dev: device. | 912 | * @dev: device. |
892 | * | 913 | * |
893 | * This is the first part of the device unregistration | 914 | * This is the first part of the device unregistration |
894 | * sequence. This removes the device from the lists we control | 915 | * sequence. This removes the device from the lists we control |
895 | * from here, has it removed from the other driver model | 916 | * from here, has it removed from the other driver model |
896 | * subsystems it was added to in device_add(), and removes it | 917 | * subsystems it was added to in device_add(), and removes it |
897 | * from the kobject hierarchy. | 918 | * from the kobject hierarchy. |
898 | * | 919 | * |
899 | * NOTE: this should be called manually _iff_ device_add() was | 920 | * NOTE: this should be called manually _iff_ device_add() was |
900 | * also called manually. | 921 | * also called manually. |
901 | */ | 922 | */ |
902 | 923 | void device_del(struct device *dev) | |
903 | void device_del(struct device * dev) | ||
904 | { | 924 | { |
905 | struct device * parent = dev->parent; | 925 | struct device *parent = dev->parent; |
906 | struct class_interface *class_intf; | 926 | struct class_interface *class_intf; |
907 | 927 | ||
928 | device_pm_remove(dev); | ||
908 | if (parent) | 929 | if (parent) |
909 | klist_del(&dev->knode_parent); | 930 | klist_del(&dev->knode_parent); |
910 | if (MAJOR(dev->devt)) | 931 | if (MAJOR(dev->devt)) |
911 | device_remove_file(dev, &devt_attr); | 932 | device_remove_file(dev, &devt_attr); |
912 | if (dev->class) { | 933 | if (dev->class) { |
913 | sysfs_remove_link(&dev->kobj, "subsystem"); | 934 | device_remove_class_symlinks(dev); |
914 | /* If this is not a "fake" compatible device, remove the | ||
915 | * symlink from the class to the device. */ | ||
916 | if (dev->kobj.parent != &dev->class->subsys.kobj) | ||
917 | sysfs_remove_link(&dev->class->subsys.kobj, | ||
918 | dev->bus_id); | ||
919 | if (parent) { | ||
920 | #ifdef CONFIG_SYSFS_DEPRECATED | ||
921 | char *class_name = make_class_name(dev->class->name, | ||
922 | &dev->kobj); | ||
923 | if (class_name) | ||
924 | sysfs_remove_link(&dev->parent->kobj, | ||
925 | class_name); | ||
926 | kfree(class_name); | ||
927 | #endif | ||
928 | sysfs_remove_link(&dev->kobj, "device"); | ||
929 | } | ||
930 | 935 | ||
931 | down(&dev->class->sem); | 936 | down(&dev->class->sem); |
932 | /* notify any interfaces that the device is now gone */ | 937 | /* notify any interfaces that the device is now gone */ |
@@ -936,31 +941,6 @@ void device_del(struct device * dev) | |||
936 | /* remove the device from the class list */ | 941 | /* remove the device from the class list */ |
937 | list_del_init(&dev->node); | 942 | list_del_init(&dev->node); |
938 | up(&dev->class->sem); | 943 | up(&dev->class->sem); |
939 | |||
940 | /* If we live in a parent class-directory, unreference it */ | ||
941 | if (dev->kobj.parent->kset == &dev->class->class_dirs) { | ||
942 | struct device *d; | ||
943 | int other = 0; | ||
944 | |||
945 | /* | ||
946 | * if we are the last child of our class, delete | ||
947 | * our class-directory at this parent | ||
948 | */ | ||
949 | down(&dev->class->sem); | ||
950 | list_for_each_entry(d, &dev->class->devices, node) { | ||
951 | if (d == dev) | ||
952 | continue; | ||
953 | if (d->kobj.parent == dev->kobj.parent) { | ||
954 | other = 1; | ||
955 | break; | ||
956 | } | ||
957 | } | ||
958 | if (!other) | ||
959 | kobject_del(dev->kobj.parent); | ||
960 | |||
961 | kobject_put(dev->kobj.parent); | ||
962 | up(&dev->class->sem); | ||
963 | } | ||
964 | } | 944 | } |
965 | device_remove_file(dev, &uevent_attr); | 945 | device_remove_file(dev, &uevent_attr); |
966 | device_remove_attrs(dev); | 946 | device_remove_attrs(dev); |
@@ -979,57 +959,55 @@ void device_del(struct device * dev) | |||
979 | if (platform_notify_remove) | 959 | if (platform_notify_remove) |
980 | platform_notify_remove(dev); | 960 | platform_notify_remove(dev); |
981 | if (dev->bus) | 961 | if (dev->bus) |
982 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 962 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
983 | BUS_NOTIFY_DEL_DEVICE, dev); | 963 | BUS_NOTIFY_DEL_DEVICE, dev); |
984 | device_pm_remove(dev); | ||
985 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 964 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
965 | cleanup_device_parent(dev); | ||
986 | kobject_del(&dev->kobj); | 966 | kobject_del(&dev->kobj); |
987 | if (parent) | 967 | put_device(parent); |
988 | put_device(parent); | ||
989 | } | 968 | } |
990 | 969 | ||
991 | /** | 970 | /** |
992 | * device_unregister - unregister device from system. | 971 | * device_unregister - unregister device from system. |
993 | * @dev: device going away. | 972 | * @dev: device going away. |
994 | * | 973 | * |
995 | * We do this in two parts, like we do device_register(). First, | 974 | * We do this in two parts, like we do device_register(). First, |
996 | * we remove it from all the subsystems with device_del(), then | 975 | * we remove it from all the subsystems with device_del(), then |
997 | * we decrement the reference count via put_device(). If that | 976 | * we decrement the reference count via put_device(). If that |
998 | * is the final reference count, the device will be cleaned up | 977 | * is the final reference count, the device will be cleaned up |
999 | * via device_release() above. Otherwise, the structure will | 978 | * via device_release() above. Otherwise, the structure will |
1000 | * stick around until the final reference to the device is dropped. | 979 | * stick around until the final reference to the device is dropped. |
1001 | */ | 980 | */ |
1002 | void device_unregister(struct device * dev) | 981 | void device_unregister(struct device *dev) |
1003 | { | 982 | { |
1004 | pr_debug("DEV: Unregistering device. ID = '%s'\n", dev->bus_id); | 983 | pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); |
1005 | device_del(dev); | 984 | device_del(dev); |
1006 | put_device(dev); | 985 | put_device(dev); |
1007 | } | 986 | } |
1008 | 987 | ||
1009 | 988 | static struct device *next_device(struct klist_iter *i) | |
1010 | static struct device * next_device(struct klist_iter * i) | ||
1011 | { | 989 | { |
1012 | struct klist_node * n = klist_next(i); | 990 | struct klist_node *n = klist_next(i); |
1013 | return n ? container_of(n, struct device, knode_parent) : NULL; | 991 | return n ? container_of(n, struct device, knode_parent) : NULL; |
1014 | } | 992 | } |
1015 | 993 | ||
1016 | /** | 994 | /** |
1017 | * device_for_each_child - device child iterator. | 995 | * device_for_each_child - device child iterator. |
1018 | * @parent: parent struct device. | 996 | * @parent: parent struct device. |
1019 | * @data: data for the callback. | 997 | * @data: data for the callback. |
1020 | * @fn: function to be called for each device. | 998 | * @fn: function to be called for each device. |
1021 | * | 999 | * |
1022 | * Iterate over @parent's child devices, and call @fn for each, | 1000 | * Iterate over @parent's child devices, and call @fn for each, |
1023 | * passing it @data. | 1001 | * passing it @data. |
1024 | * | 1002 | * |
1025 | * We check the return of @fn each time. If it returns anything | 1003 | * We check the return of @fn each time. If it returns anything |
1026 | * other than 0, we break out and return that value. | 1004 | * other than 0, we break out and return that value. |
1027 | */ | 1005 | */ |
1028 | int device_for_each_child(struct device * parent, void * data, | 1006 | int device_for_each_child(struct device *parent, void *data, |
1029 | int (*fn)(struct device *, void *)) | 1007 | int (*fn)(struct device *dev, void *data)) |
1030 | { | 1008 | { |
1031 | struct klist_iter i; | 1009 | struct klist_iter i; |
1032 | struct device * child; | 1010 | struct device *child; |
1033 | int error = 0; | 1011 | int error = 0; |
1034 | 1012 | ||
1035 | klist_iter_init(&parent->klist_children, &i); | 1013 | klist_iter_init(&parent->klist_children, &i); |
@@ -1054,8 +1032,8 @@ int device_for_each_child(struct device * parent, void * data, | |||
1054 | * current device can be obtained, this function will return to the caller | 1032 | * current device can be obtained, this function will return to the caller |
1055 | * and not iterate over any more devices. | 1033 | * and not iterate over any more devices. |
1056 | */ | 1034 | */ |
1057 | struct device * device_find_child(struct device *parent, void *data, | 1035 | struct device *device_find_child(struct device *parent, void *data, |
1058 | int (*match)(struct device *, void *)) | 1036 | int (*match)(struct device *dev, void *data)) |
1059 | { | 1037 | { |
1060 | struct klist_iter i; | 1038 | struct klist_iter i; |
1061 | struct device *child; | 1039 | struct device *child; |
@@ -1073,7 +1051,10 @@ struct device * device_find_child(struct device *parent, void *data, | |||
1073 | 1051 | ||
1074 | int __init devices_init(void) | 1052 | int __init devices_init(void) |
1075 | { | 1053 | { |
1076 | return subsystem_register(&devices_subsys); | 1054 | devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); |
1055 | if (!devices_kset) | ||
1056 | return -ENOMEM; | ||
1057 | return 0; | ||
1077 | } | 1058 | } |
1078 | 1059 | ||
1079 | EXPORT_SYMBOL_GPL(device_for_each_child); | 1060 | EXPORT_SYMBOL_GPL(device_for_each_child); |
@@ -1094,7 +1075,7 @@ EXPORT_SYMBOL_GPL(device_remove_file); | |||
1094 | 1075 | ||
1095 | static void device_create_release(struct device *dev) | 1076 | static void device_create_release(struct device *dev) |
1096 | { | 1077 | { |
1097 | pr_debug("%s called for %s\n", __FUNCTION__, dev->bus_id); | 1078 | pr_debug("device: '%s': %s\n", dev->bus_id, __FUNCTION__); |
1098 | kfree(dev); | 1079 | kfree(dev); |
1099 | } | 1080 | } |
1100 | 1081 | ||
@@ -1156,14 +1137,11 @@ error: | |||
1156 | EXPORT_SYMBOL_GPL(device_create); | 1137 | EXPORT_SYMBOL_GPL(device_create); |
1157 | 1138 | ||
1158 | /** | 1139 | /** |
1159 | * device_destroy - removes a device that was created with device_create() | 1140 | * find_device - finds a device that was created with device_create() |
1160 | * @class: pointer to the struct class that this device was registered with | 1141 | * @class: pointer to the struct class that this device was registered with |
1161 | * @devt: the dev_t of the device that was previously registered | 1142 | * @devt: the dev_t of the device that was previously registered |
1162 | * | ||
1163 | * This call unregisters and cleans up a device that was created with a | ||
1164 | * call to device_create(). | ||
1165 | */ | 1143 | */ |
1166 | void device_destroy(struct class *class, dev_t devt) | 1144 | static struct device *find_device(struct class *class, dev_t devt) |
1167 | { | 1145 | { |
1168 | struct device *dev = NULL; | 1146 | struct device *dev = NULL; |
1169 | struct device *dev_tmp; | 1147 | struct device *dev_tmp; |
@@ -1176,12 +1154,54 @@ void device_destroy(struct class *class, dev_t devt) | |||
1176 | } | 1154 | } |
1177 | } | 1155 | } |
1178 | up(&class->sem); | 1156 | up(&class->sem); |
1157 | return dev; | ||
1158 | } | ||
1159 | |||
1160 | /** | ||
1161 | * device_destroy - removes a device that was created with device_create() | ||
1162 | * @class: pointer to the struct class that this device was registered with | ||
1163 | * @devt: the dev_t of the device that was previously registered | ||
1164 | * | ||
1165 | * This call unregisters and cleans up a device that was created with a | ||
1166 | * call to device_create(). | ||
1167 | */ | ||
1168 | void device_destroy(struct class *class, dev_t devt) | ||
1169 | { | ||
1170 | struct device *dev; | ||
1179 | 1171 | ||
1172 | dev = find_device(class, devt); | ||
1180 | if (dev) | 1173 | if (dev) |
1181 | device_unregister(dev); | 1174 | device_unregister(dev); |
1182 | } | 1175 | } |
1183 | EXPORT_SYMBOL_GPL(device_destroy); | 1176 | EXPORT_SYMBOL_GPL(device_destroy); |
1184 | 1177 | ||
1178 | #ifdef CONFIG_PM_SLEEP | ||
1179 | /** | ||
1180 | * destroy_suspended_device - asks the PM core to remove a suspended device | ||
1181 | * @class: pointer to the struct class that this device was registered with | ||
1182 | * @devt: the dev_t of the device that was previously registered | ||
1183 | * | ||
1184 | * This call notifies the PM core of the necessity to unregister a suspended | ||
1185 | * device created with a call to device_create() (devices cannot be | ||
1186 | * unregistered directly while suspended, since the PM core holds their | ||
1187 | * semaphores at that time). | ||
1188 | * | ||
1189 | * It can only be called within the scope of a system sleep transition. In | ||
1190 | * practice this means it has to be directly or indirectly invoked either by | ||
1191 | * a suspend or resume method, or by the PM core (e.g. via | ||
1192 | * disable_nonboot_cpus() or enable_nonboot_cpus()). | ||
1193 | */ | ||
1194 | void destroy_suspended_device(struct class *class, dev_t devt) | ||
1195 | { | ||
1196 | struct device *dev; | ||
1197 | |||
1198 | dev = find_device(class, devt); | ||
1199 | if (dev) | ||
1200 | device_pm_schedule_removal(dev); | ||
1201 | } | ||
1202 | EXPORT_SYMBOL_GPL(destroy_suspended_device); | ||
1203 | #endif /* CONFIG_PM_SLEEP */ | ||
1204 | |||
1185 | /** | 1205 | /** |
1186 | * device_rename - renames a device | 1206 | * device_rename - renames a device |
1187 | * @dev: the pointer to the struct device to be renamed | 1207 | * @dev: the pointer to the struct device to be renamed |
@@ -1198,7 +1218,8 @@ int device_rename(struct device *dev, char *new_name) | |||
1198 | if (!dev) | 1218 | if (!dev) |
1199 | return -EINVAL; | 1219 | return -EINVAL; |
1200 | 1220 | ||
1201 | pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name); | 1221 | pr_debug("device: '%s': %s: renaming to '%s'\n", dev->bus_id, |
1222 | __FUNCTION__, new_name); | ||
1202 | 1223 | ||
1203 | #ifdef CONFIG_SYSFS_DEPRECATED | 1224 | #ifdef CONFIG_SYSFS_DEPRECATED |
1204 | if ((dev->class) && (dev->parent)) | 1225 | if ((dev->class) && (dev->parent)) |
@@ -1279,8 +1300,7 @@ static int device_move_class_links(struct device *dev, | |||
1279 | class_name); | 1300 | class_name); |
1280 | if (error) | 1301 | if (error) |
1281 | sysfs_remove_link(&dev->kobj, "device"); | 1302 | sysfs_remove_link(&dev->kobj, "device"); |
1282 | } | 1303 | } else |
1283 | else | ||
1284 | error = 0; | 1304 | error = 0; |
1285 | out: | 1305 | out: |
1286 | kfree(class_name); | 1306 | kfree(class_name); |
@@ -1311,16 +1331,13 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1311 | return -EINVAL; | 1331 | return -EINVAL; |
1312 | 1332 | ||
1313 | new_parent = get_device(new_parent); | 1333 | new_parent = get_device(new_parent); |
1314 | new_parent_kobj = get_device_parent (dev, new_parent); | 1334 | new_parent_kobj = get_device_parent(dev, new_parent); |
1315 | if (IS_ERR(new_parent_kobj)) { | 1335 | |
1316 | error = PTR_ERR(new_parent_kobj); | 1336 | pr_debug("device: '%s': %s: moving to '%s'\n", dev->bus_id, |
1317 | put_device(new_parent); | 1337 | __FUNCTION__, new_parent ? new_parent->bus_id : "<NULL>"); |
1318 | goto out; | ||
1319 | } | ||
1320 | pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, | ||
1321 | new_parent ? new_parent->bus_id : "<NULL>"); | ||
1322 | error = kobject_move(&dev->kobj, new_parent_kobj); | 1338 | error = kobject_move(&dev->kobj, new_parent_kobj); |
1323 | if (error) { | 1339 | if (error) { |
1340 | cleanup_glue_dir(dev, new_parent_kobj); | ||
1324 | put_device(new_parent); | 1341 | put_device(new_parent); |
1325 | goto out; | 1342 | goto out; |
1326 | } | 1343 | } |
@@ -1343,6 +1360,7 @@ int device_move(struct device *dev, struct device *new_parent) | |||
1343 | klist_add_tail(&dev->knode_parent, | 1360 | klist_add_tail(&dev->knode_parent, |
1344 | &old_parent->klist_children); | 1361 | &old_parent->klist_children); |
1345 | } | 1362 | } |
1363 | cleanup_glue_dir(dev, new_parent_kobj); | ||
1346 | put_device(new_parent); | 1364 | put_device(new_parent); |
1347 | goto out; | 1365 | goto out; |
1348 | } | 1366 | } |
@@ -1352,5 +1370,23 @@ out: | |||
1352 | put_device(dev); | 1370 | put_device(dev); |
1353 | return error; | 1371 | return error; |
1354 | } | 1372 | } |
1355 | |||
1356 | EXPORT_SYMBOL_GPL(device_move); | 1373 | EXPORT_SYMBOL_GPL(device_move); |
1374 | |||
1375 | /** | ||
1376 | * device_shutdown - call ->shutdown() on each device to shutdown. | ||
1377 | */ | ||
1378 | void device_shutdown(void) | ||
1379 | { | ||
1380 | struct device *dev, *devn; | ||
1381 | |||
1382 | list_for_each_entry_safe_reverse(dev, devn, &devices_kset->list, | ||
1383 | kobj.entry) { | ||
1384 | if (dev->bus && dev->bus->shutdown) { | ||
1385 | dev_dbg(dev, "shutdown\n"); | ||
1386 | dev->bus->shutdown(dev); | ||
1387 | } else if (dev->driver && dev->driver->shutdown) { | ||
1388 | dev_dbg(dev, "shutdown\n"); | ||
1389 | dev->driver->shutdown(dev); | ||
1390 | } | ||
1391 | } | ||
1392 | } | ||
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 40545071e3c9..c5885f5ce0ac 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include "base.h" | 14 | #include "base.h" |
15 | 15 | ||
16 | struct sysdev_class cpu_sysdev_class = { | 16 | struct sysdev_class cpu_sysdev_class = { |
17 | set_kset_name("cpu"), | 17 | .name = "cpu", |
18 | }; | 18 | }; |
19 | EXPORT_SYMBOL(cpu_sysdev_class); | 19 | EXPORT_SYMBOL(cpu_sysdev_class); |
20 | 20 | ||
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 7ac474db88c5..a5cde94bb982 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -1,18 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/base/dd.c - The core device/driver interactions. | 2 | * drivers/base/dd.c - The core device/driver interactions. |
3 | * | 3 | * |
4 | * This file contains the (sometimes tricky) code that controls the | 4 | * This file contains the (sometimes tricky) code that controls the |
5 | * interactions between devices and drivers, which primarily includes | 5 | * interactions between devices and drivers, which primarily includes |
6 | * driver binding and unbinding. | 6 | * driver binding and unbinding. |
7 | * | 7 | * |
8 | * All of this code used to exist in drivers/base/bus.c, but was | 8 | * All of this code used to exist in drivers/base/bus.c, but was |
9 | * relocated to here in the name of compartmentalization (since it wasn't | 9 | * relocated to here in the name of compartmentalization (since it wasn't |
10 | * strictly code just for the 'struct bus_type'. | 10 | * strictly code just for the 'struct bus_type'. |
11 | * | 11 | * |
12 | * Copyright (c) 2002-5 Patrick Mochel | 12 | * Copyright (c) 2002-5 Patrick Mochel |
13 | * Copyright (c) 2002-3 Open Source Development Labs | 13 | * Copyright (c) 2002-3 Open Source Development Labs |
14 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
15 | * Copyright (c) 2007 Novell Inc. | ||
14 | * | 16 | * |
15 | * This file is released under the GPLv2 | 17 | * This file is released under the GPLv2 |
16 | */ | 18 | */ |
17 | 19 | ||
18 | #include <linux/device.h> | 20 | #include <linux/device.h> |
@@ -23,8 +25,6 @@ | |||
23 | #include "base.h" | 25 | #include "base.h" |
24 | #include "power/power.h" | 26 | #include "power/power.h" |
25 | 27 | ||
26 | #define to_drv(node) container_of(node, struct device_driver, kobj.entry) | ||
27 | |||
28 | 28 | ||
29 | static void driver_bound(struct device *dev) | 29 | static void driver_bound(struct device *dev) |
30 | { | 30 | { |
@@ -34,27 +34,27 @@ static void driver_bound(struct device *dev) | |||
34 | return; | 34 | return; |
35 | } | 35 | } |
36 | 36 | ||
37 | pr_debug("bound device '%s' to driver '%s'\n", | 37 | pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->bus_id, |
38 | dev->bus_id, dev->driver->name); | 38 | __FUNCTION__, dev->driver->name); |
39 | 39 | ||
40 | if (dev->bus) | 40 | if (dev->bus) |
41 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 41 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
42 | BUS_NOTIFY_BOUND_DRIVER, dev); | 42 | BUS_NOTIFY_BOUND_DRIVER, dev); |
43 | 43 | ||
44 | klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); | 44 | klist_add_tail(&dev->knode_driver, &dev->driver->p->klist_devices); |
45 | } | 45 | } |
46 | 46 | ||
47 | static int driver_sysfs_add(struct device *dev) | 47 | static int driver_sysfs_add(struct device *dev) |
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, | 51 | ret = sysfs_create_link(&dev->driver->p->kobj, &dev->kobj, |
52 | kobject_name(&dev->kobj)); | 52 | kobject_name(&dev->kobj)); |
53 | if (ret == 0) { | 53 | if (ret == 0) { |
54 | ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj, | 54 | ret = sysfs_create_link(&dev->kobj, &dev->driver->p->kobj, |
55 | "driver"); | 55 | "driver"); |
56 | if (ret) | 56 | if (ret) |
57 | sysfs_remove_link(&dev->driver->kobj, | 57 | sysfs_remove_link(&dev->driver->p->kobj, |
58 | kobject_name(&dev->kobj)); | 58 | kobject_name(&dev->kobj)); |
59 | } | 59 | } |
60 | return ret; | 60 | return ret; |
@@ -65,24 +65,24 @@ static void driver_sysfs_remove(struct device *dev) | |||
65 | struct device_driver *drv = dev->driver; | 65 | struct device_driver *drv = dev->driver; |
66 | 66 | ||
67 | if (drv) { | 67 | if (drv) { |
68 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); | 68 | sysfs_remove_link(&drv->p->kobj, kobject_name(&dev->kobj)); |
69 | sysfs_remove_link(&dev->kobj, "driver"); | 69 | sysfs_remove_link(&dev->kobj, "driver"); |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | /** | 73 | /** |
74 | * device_bind_driver - bind a driver to one device. | 74 | * device_bind_driver - bind a driver to one device. |
75 | * @dev: device. | 75 | * @dev: device. |
76 | * | 76 | * |
77 | * Allow manual attachment of a driver to a device. | 77 | * Allow manual attachment of a driver to a device. |
78 | * Caller must have already set @dev->driver. | 78 | * Caller must have already set @dev->driver. |
79 | * | 79 | * |
80 | * Note that this does not modify the bus reference count | 80 | * Note that this does not modify the bus reference count |
81 | * nor take the bus's rwsem. Please verify those are accounted | 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 | 82 | * for before calling this. (It is ok to call with no other effort |
83 | * from a driver's probe() method.) | 83 | * from a driver's probe() method.) |
84 | * | 84 | * |
85 | * This function must be called with @dev->sem held. | 85 | * This function must be called with @dev->sem held. |
86 | */ | 86 | */ |
87 | int device_bind_driver(struct device *dev) | 87 | int device_bind_driver(struct device *dev) |
88 | { | 88 | { |
@@ -93,6 +93,7 @@ int device_bind_driver(struct device *dev) | |||
93 | driver_bound(dev); | 93 | driver_bound(dev); |
94 | return ret; | 94 | return ret; |
95 | } | 95 | } |
96 | EXPORT_SYMBOL_GPL(device_bind_driver); | ||
96 | 97 | ||
97 | static atomic_t probe_count = ATOMIC_INIT(0); | 98 | static atomic_t probe_count = ATOMIC_INIT(0); |
98 | static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); | 99 | static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); |
@@ -102,8 +103,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) | |||
102 | int ret = 0; | 103 | int ret = 0; |
103 | 104 | ||
104 | atomic_inc(&probe_count); | 105 | atomic_inc(&probe_count); |
105 | pr_debug("%s: Probing driver %s with device %s\n", | 106 | pr_debug("bus: '%s': %s: probing driver %s with device %s\n", |
106 | drv->bus->name, drv->name, dev->bus_id); | 107 | drv->bus->name, __FUNCTION__, drv->name, dev->bus_id); |
107 | WARN_ON(!list_empty(&dev->devres_head)); | 108 | WARN_ON(!list_empty(&dev->devres_head)); |
108 | 109 | ||
109 | dev->driver = drv; | 110 | dev->driver = drv; |
@@ -125,8 +126,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) | |||
125 | 126 | ||
126 | driver_bound(dev); | 127 | driver_bound(dev); |
127 | ret = 1; | 128 | ret = 1; |
128 | pr_debug("%s: Bound Device %s to Driver %s\n", | 129 | pr_debug("bus: '%s': %s: bound device %s to driver %s\n", |
129 | drv->bus->name, dev->bus_id, drv->name); | 130 | drv->bus->name, __FUNCTION__, dev->bus_id, drv->name); |
130 | goto done; | 131 | goto done; |
131 | 132 | ||
132 | probe_failed: | 133 | probe_failed: |
@@ -183,7 +184,7 @@ int driver_probe_done(void) | |||
183 | * This function must be called with @dev->sem held. When called for a | 184 | * This function must be called with @dev->sem held. When called for a |
184 | * USB interface, @dev->parent->sem must be held as well. | 185 | * USB interface, @dev->parent->sem must be held as well. |
185 | */ | 186 | */ |
186 | int driver_probe_device(struct device_driver * drv, struct device * dev) | 187 | int driver_probe_device(struct device_driver *drv, struct device *dev) |
187 | { | 188 | { |
188 | int ret = 0; | 189 | int ret = 0; |
189 | 190 | ||
@@ -192,8 +193,8 @@ int driver_probe_device(struct device_driver * drv, struct device * dev) | |||
192 | if (drv->bus->match && !drv->bus->match(dev, drv)) | 193 | if (drv->bus->match && !drv->bus->match(dev, drv)) |
193 | goto done; | 194 | goto done; |
194 | 195 | ||
195 | pr_debug("%s: Matched Device %s with Driver %s\n", | 196 | pr_debug("bus: '%s': %s: matched device %s with driver %s\n", |
196 | drv->bus->name, dev->bus_id, drv->name); | 197 | drv->bus->name, __FUNCTION__, dev->bus_id, drv->name); |
197 | 198 | ||
198 | ret = really_probe(dev, drv); | 199 | ret = really_probe(dev, drv); |
199 | 200 | ||
@@ -201,27 +202,27 @@ done: | |||
201 | return ret; | 202 | return ret; |
202 | } | 203 | } |
203 | 204 | ||
204 | static int __device_attach(struct device_driver * drv, void * data) | 205 | static int __device_attach(struct device_driver *drv, void *data) |
205 | { | 206 | { |
206 | struct device * dev = data; | 207 | struct device *dev = data; |
207 | return driver_probe_device(drv, dev); | 208 | return driver_probe_device(drv, dev); |
208 | } | 209 | } |
209 | 210 | ||
210 | /** | 211 | /** |
211 | * device_attach - try to attach device to a driver. | 212 | * device_attach - try to attach device to a driver. |
212 | * @dev: device. | 213 | * @dev: device. |
213 | * | 214 | * |
214 | * Walk the list of drivers that the bus has and call | 215 | * Walk the list of drivers that the bus has and call |
215 | * driver_probe_device() for each pair. If a compatible | 216 | * driver_probe_device() for each pair. If a compatible |
216 | * pair is found, break out and return. | 217 | * pair is found, break out and return. |
217 | * | 218 | * |
218 | * Returns 1 if the device was bound to a driver; | 219 | * Returns 1 if the device was bound to a driver; |
219 | * 0 if no matching device was found; | 220 | * 0 if no matching device was found; |
220 | * -ENODEV if the device is not registered. | 221 | * -ENODEV if the device is not registered. |
221 | * | 222 | * |
222 | * When called for a USB interface, @dev->parent->sem must be held. | 223 | * When called for a USB interface, @dev->parent->sem must be held. |
223 | */ | 224 | */ |
224 | int device_attach(struct device * dev) | 225 | int device_attach(struct device *dev) |
225 | { | 226 | { |
226 | int ret = 0; | 227 | int ret = 0; |
227 | 228 | ||
@@ -240,10 +241,11 @@ int device_attach(struct device * dev) | |||
240 | up(&dev->sem); | 241 | up(&dev->sem); |
241 | return ret; | 242 | return ret; |
242 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(device_attach); | ||
243 | 245 | ||
244 | static int __driver_attach(struct device * dev, void * data) | 246 | static int __driver_attach(struct device *dev, void *data) |
245 | { | 247 | { |
246 | struct device_driver * drv = data; | 248 | struct device_driver *drv = data; |
247 | 249 | ||
248 | /* | 250 | /* |
249 | * Lock device and try to bind to it. We drop the error | 251 | * Lock device and try to bind to it. We drop the error |
@@ -268,35 +270,35 @@ static int __driver_attach(struct device * dev, void * data) | |||
268 | } | 270 | } |
269 | 271 | ||
270 | /** | 272 | /** |
271 | * driver_attach - try to bind driver to devices. | 273 | * driver_attach - try to bind driver to devices. |
272 | * @drv: driver. | 274 | * @drv: driver. |
273 | * | 275 | * |
274 | * Walk the list of devices that the bus has on it and try to | 276 | * Walk the list of devices that the bus has on it and try to |
275 | * match the driver with each one. If driver_probe_device() | 277 | * match the driver with each one. If driver_probe_device() |
276 | * returns 0 and the @dev->driver is set, we've found a | 278 | * returns 0 and the @dev->driver is set, we've found a |
277 | * compatible pair. | 279 | * compatible pair. |
278 | */ | 280 | */ |
279 | int driver_attach(struct device_driver * drv) | 281 | int driver_attach(struct device_driver *drv) |
280 | { | 282 | { |
281 | return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); | 283 | return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); |
282 | } | 284 | } |
285 | EXPORT_SYMBOL_GPL(driver_attach); | ||
283 | 286 | ||
284 | /* | 287 | /* |
285 | * __device_release_driver() must be called with @dev->sem held. | 288 | * __device_release_driver() must be called with @dev->sem held. |
286 | * When called for a USB interface, @dev->parent->sem must be held as well. | 289 | * When called for a USB interface, @dev->parent->sem must be held as well. |
287 | */ | 290 | */ |
288 | static void __device_release_driver(struct device * dev) | 291 | static void __device_release_driver(struct device *dev) |
289 | { | 292 | { |
290 | struct device_driver * drv; | 293 | struct device_driver *drv; |
291 | 294 | ||
292 | drv = get_driver(dev->driver); | 295 | drv = dev->driver; |
293 | if (drv) { | 296 | if (drv) { |
294 | driver_sysfs_remove(dev); | 297 | driver_sysfs_remove(dev); |
295 | sysfs_remove_link(&dev->kobj, "driver"); | 298 | sysfs_remove_link(&dev->kobj, "driver"); |
296 | klist_remove(&dev->knode_driver); | ||
297 | 299 | ||
298 | if (dev->bus) | 300 | if (dev->bus) |
299 | blocking_notifier_call_chain(&dev->bus->bus_notifier, | 301 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
300 | BUS_NOTIFY_UNBIND_DRIVER, | 302 | BUS_NOTIFY_UNBIND_DRIVER, |
301 | dev); | 303 | dev); |
302 | 304 | ||
@@ -306,18 +308,18 @@ static void __device_release_driver(struct device * dev) | |||
306 | drv->remove(dev); | 308 | drv->remove(dev); |
307 | devres_release_all(dev); | 309 | devres_release_all(dev); |
308 | dev->driver = NULL; | 310 | dev->driver = NULL; |
309 | put_driver(drv); | 311 | klist_remove(&dev->knode_driver); |
310 | } | 312 | } |
311 | } | 313 | } |
312 | 314 | ||
313 | /** | 315 | /** |
314 | * device_release_driver - manually detach device from driver. | 316 | * device_release_driver - manually detach device from driver. |
315 | * @dev: device. | 317 | * @dev: device. |
316 | * | 318 | * |
317 | * Manually detach device from driver. | 319 | * Manually detach device from driver. |
318 | * When called for a USB interface, @dev->parent->sem must be held. | 320 | * When called for a USB interface, @dev->parent->sem must be held. |
319 | */ | 321 | */ |
320 | void device_release_driver(struct device * dev) | 322 | void device_release_driver(struct device *dev) |
321 | { | 323 | { |
322 | /* | 324 | /* |
323 | * If anyone calls device_release_driver() recursively from | 325 | * If anyone calls device_release_driver() recursively from |
@@ -328,26 +330,26 @@ void device_release_driver(struct device * dev) | |||
328 | __device_release_driver(dev); | 330 | __device_release_driver(dev); |
329 | up(&dev->sem); | 331 | up(&dev->sem); |
330 | } | 332 | } |
331 | 333 | EXPORT_SYMBOL_GPL(device_release_driver); | |
332 | 334 | ||
333 | /** | 335 | /** |
334 | * driver_detach - detach driver from all devices it controls. | 336 | * driver_detach - detach driver from all devices it controls. |
335 | * @drv: driver. | 337 | * @drv: driver. |
336 | */ | 338 | */ |
337 | void driver_detach(struct device_driver * drv) | 339 | void driver_detach(struct device_driver *drv) |
338 | { | 340 | { |
339 | struct device * dev; | 341 | struct device *dev; |
340 | 342 | ||
341 | for (;;) { | 343 | for (;;) { |
342 | spin_lock(&drv->klist_devices.k_lock); | 344 | spin_lock(&drv->p->klist_devices.k_lock); |
343 | if (list_empty(&drv->klist_devices.k_list)) { | 345 | if (list_empty(&drv->p->klist_devices.k_list)) { |
344 | spin_unlock(&drv->klist_devices.k_lock); | 346 | spin_unlock(&drv->p->klist_devices.k_lock); |
345 | break; | 347 | break; |
346 | } | 348 | } |
347 | dev = list_entry(drv->klist_devices.k_list.prev, | 349 | dev = list_entry(drv->p->klist_devices.k_list.prev, |
348 | struct device, knode_driver.n_node); | 350 | struct device, knode_driver.n_node); |
349 | get_device(dev); | 351 | get_device(dev); |
350 | spin_unlock(&drv->klist_devices.k_lock); | 352 | spin_unlock(&drv->p->klist_devices.k_lock); |
351 | 353 | ||
352 | if (dev->parent) /* Needed for USB */ | 354 | if (dev->parent) /* Needed for USB */ |
353 | down(&dev->parent->sem); | 355 | down(&dev->parent->sem); |
@@ -360,9 +362,3 @@ void driver_detach(struct device_driver * drv) | |||
360 | put_device(dev); | 362 | put_device(dev); |
361 | } | 363 | } |
362 | } | 364 | } |
363 | |||
364 | EXPORT_SYMBOL_GPL(device_bind_driver); | ||
365 | EXPORT_SYMBOL_GPL(device_release_driver); | ||
366 | EXPORT_SYMBOL_GPL(device_attach); | ||
367 | EXPORT_SYMBOL_GPL(driver_attach); | ||
368 | |||
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index eb11475293ed..a35f04121a00 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -3,6 +3,8 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | 10 | * |
@@ -15,46 +17,42 @@ | |||
15 | #include "base.h" | 17 | #include "base.h" |
16 | 18 | ||
17 | #define to_dev(node) container_of(node, struct device, driver_list) | 19 | #define to_dev(node) container_of(node, struct device, driver_list) |
18 | #define to_drv(obj) container_of(obj, struct device_driver, kobj) | ||
19 | 20 | ||
20 | 21 | ||
21 | static struct device * next_device(struct klist_iter * i) | 22 | static struct device *next_device(struct klist_iter *i) |
22 | { | 23 | { |
23 | struct klist_node * n = klist_next(i); | 24 | struct klist_node *n = klist_next(i); |
24 | return n ? container_of(n, struct device, knode_driver) : NULL; | 25 | return n ? container_of(n, struct device, knode_driver) : NULL; |
25 | } | 26 | } |
26 | 27 | ||
27 | /** | 28 | /** |
28 | * driver_for_each_device - Iterator for devices bound to a driver. | 29 | * driver_for_each_device - Iterator for devices bound to a driver. |
29 | * @drv: Driver we're iterating. | 30 | * @drv: Driver we're iterating. |
30 | * @start: Device to begin with | 31 | * @start: Device to begin with |
31 | * @data: Data to pass to the callback. | 32 | * @data: Data to pass to the callback. |
32 | * @fn: Function to call for each device. | 33 | * @fn: Function to call for each device. |
33 | * | 34 | * |
34 | * Iterate over the @drv's list of devices calling @fn for each one. | 35 | * Iterate over the @drv's list of devices calling @fn for each one. |
35 | */ | 36 | */ |
36 | 37 | int driver_for_each_device(struct device_driver *drv, struct device *start, | |
37 | int driver_for_each_device(struct device_driver * drv, struct device * start, | 38 | void *data, int (*fn)(struct device *, void *)) |
38 | void * data, int (*fn)(struct device *, void *)) | ||
39 | { | 39 | { |
40 | struct klist_iter i; | 40 | struct klist_iter i; |
41 | struct device * dev; | 41 | struct device *dev; |
42 | int error = 0; | 42 | int error = 0; |
43 | 43 | ||
44 | if (!drv) | 44 | if (!drv) |
45 | return -EINVAL; | 45 | return -EINVAL; |
46 | 46 | ||
47 | klist_iter_init_node(&drv->klist_devices, &i, | 47 | klist_iter_init_node(&drv->p->klist_devices, &i, |
48 | start ? &start->knode_driver : NULL); | 48 | start ? &start->knode_driver : NULL); |
49 | while ((dev = next_device(&i)) && !error) | 49 | while ((dev = next_device(&i)) && !error) |
50 | error = fn(dev, data); | 50 | error = fn(dev, data); |
51 | klist_iter_exit(&i); | 51 | klist_iter_exit(&i); |
52 | return error; | 52 | return error; |
53 | } | 53 | } |
54 | |||
55 | EXPORT_SYMBOL_GPL(driver_for_each_device); | 54 | EXPORT_SYMBOL_GPL(driver_for_each_device); |
56 | 55 | ||
57 | |||
58 | /** | 56 | /** |
59 | * driver_find_device - device iterator for locating a particular device. | 57 | * driver_find_device - device iterator for locating a particular device. |
60 | * @drv: The device's driver | 58 | * @drv: The device's driver |
@@ -70,9 +68,9 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); | |||
70 | * if it does. If the callback returns non-zero, this function will | 68 | * if it does. If the callback returns non-zero, this function will |
71 | * return to the caller and not iterate over any more devices. | 69 | * return to the caller and not iterate over any more devices. |
72 | */ | 70 | */ |
73 | struct device * driver_find_device(struct device_driver *drv, | 71 | struct device *driver_find_device(struct device_driver *drv, |
74 | struct device * start, void * data, | 72 | struct device *start, void *data, |
75 | int (*match)(struct device *, void *)) | 73 | int (*match)(struct device *dev, void *data)) |
76 | { | 74 | { |
77 | struct klist_iter i; | 75 | struct klist_iter i; |
78 | struct device *dev; | 76 | struct device *dev; |
@@ -80,7 +78,7 @@ struct device * driver_find_device(struct device_driver *drv, | |||
80 | if (!drv) | 78 | if (!drv) |
81 | return NULL; | 79 | return NULL; |
82 | 80 | ||
83 | klist_iter_init_node(&drv->klist_devices, &i, | 81 | klist_iter_init_node(&drv->p->klist_devices, &i, |
84 | (start ? &start->knode_driver : NULL)); | 82 | (start ? &start->knode_driver : NULL)); |
85 | while ((dev = next_device(&i))) | 83 | while ((dev = next_device(&i))) |
86 | if (match(dev, data) && get_device(dev)) | 84 | if (match(dev, data) && get_device(dev)) |
@@ -91,111 +89,179 @@ struct device * driver_find_device(struct device_driver *drv, | |||
91 | EXPORT_SYMBOL_GPL(driver_find_device); | 89 | EXPORT_SYMBOL_GPL(driver_find_device); |
92 | 90 | ||
93 | /** | 91 | /** |
94 | * driver_create_file - create sysfs file for driver. | 92 | * driver_create_file - create sysfs file for driver. |
95 | * @drv: driver. | 93 | * @drv: driver. |
96 | * @attr: driver attribute descriptor. | 94 | * @attr: driver attribute descriptor. |
97 | */ | 95 | */ |
98 | 96 | int driver_create_file(struct device_driver *drv, | |
99 | int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) | 97 | struct driver_attribute *attr) |
100 | { | 98 | { |
101 | int error; | 99 | int error; |
102 | if (get_driver(drv)) { | 100 | if (get_driver(drv)) { |
103 | error = sysfs_create_file(&drv->kobj, &attr->attr); | 101 | error = sysfs_create_file(&drv->p->kobj, &attr->attr); |
104 | put_driver(drv); | 102 | put_driver(drv); |
105 | } else | 103 | } else |
106 | error = -EINVAL; | 104 | error = -EINVAL; |
107 | return error; | 105 | return error; |
108 | } | 106 | } |
109 | 107 | EXPORT_SYMBOL_GPL(driver_create_file); | |
110 | 108 | ||
111 | /** | 109 | /** |
112 | * driver_remove_file - remove sysfs file for driver. | 110 | * driver_remove_file - remove sysfs file for driver. |
113 | * @drv: driver. | 111 | * @drv: driver. |
114 | * @attr: driver attribute descriptor. | 112 | * @attr: driver attribute descriptor. |
115 | */ | 113 | */ |
116 | 114 | void driver_remove_file(struct device_driver *drv, | |
117 | void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) | 115 | struct driver_attribute *attr) |
118 | { | 116 | { |
119 | if (get_driver(drv)) { | 117 | if (get_driver(drv)) { |
120 | sysfs_remove_file(&drv->kobj, &attr->attr); | 118 | sysfs_remove_file(&drv->p->kobj, &attr->attr); |
121 | put_driver(drv); | 119 | put_driver(drv); |
122 | } | 120 | } |
123 | } | 121 | } |
124 | 122 | EXPORT_SYMBOL_GPL(driver_remove_file); | |
125 | 123 | ||
126 | /** | 124 | /** |
127 | * get_driver - increment driver reference count. | 125 | * driver_add_kobj - add a kobject below the specified driver |
128 | * @drv: driver. | 126 | * |
127 | * You really don't want to do this, this is only here due to one looney | ||
128 | * iseries driver, go poke those developers if you are annoyed about | ||
129 | * this... | ||
129 | */ | 130 | */ |
130 | struct device_driver * get_driver(struct device_driver * drv) | 131 | int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, |
132 | const char *fmt, ...) | ||
131 | { | 133 | { |
132 | return drv ? to_drv(kobject_get(&drv->kobj)) : NULL; | 134 | va_list args; |
135 | char *name; | ||
136 | |||
137 | va_start(args, fmt); | ||
138 | name = kvasprintf(GFP_KERNEL, fmt, args); | ||
139 | va_end(args); | ||
140 | |||
141 | if (!name) | ||
142 | return -ENOMEM; | ||
143 | |||
144 | return kobject_add(kobj, &drv->p->kobj, "%s", name); | ||
133 | } | 145 | } |
146 | EXPORT_SYMBOL_GPL(driver_add_kobj); | ||
147 | |||
148 | /** | ||
149 | * get_driver - increment driver reference count. | ||
150 | * @drv: driver. | ||
151 | */ | ||
152 | struct device_driver *get_driver(struct device_driver *drv) | ||
153 | { | ||
154 | if (drv) { | ||
155 | struct driver_private *priv; | ||
156 | struct kobject *kobj; | ||
134 | 157 | ||
158 | kobj = kobject_get(&drv->p->kobj); | ||
159 | priv = to_driver(kobj); | ||
160 | return priv->driver; | ||
161 | } | ||
162 | return NULL; | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(get_driver); | ||
135 | 165 | ||
136 | /** | 166 | /** |
137 | * put_driver - decrement driver's refcount. | 167 | * put_driver - decrement driver's refcount. |
138 | * @drv: driver. | 168 | * @drv: driver. |
139 | */ | 169 | */ |
140 | void put_driver(struct device_driver * drv) | 170 | void put_driver(struct device_driver *drv) |
171 | { | ||
172 | kobject_put(&drv->p->kobj); | ||
173 | } | ||
174 | EXPORT_SYMBOL_GPL(put_driver); | ||
175 | |||
176 | static int driver_add_groups(struct device_driver *drv, | ||
177 | struct attribute_group **groups) | ||
141 | { | 178 | { |
142 | kobject_put(&drv->kobj); | 179 | int error = 0; |
180 | int i; | ||
181 | |||
182 | if (groups) { | ||
183 | for (i = 0; groups[i]; i++) { | ||
184 | error = sysfs_create_group(&drv->p->kobj, groups[i]); | ||
185 | if (error) { | ||
186 | while (--i >= 0) | ||
187 | sysfs_remove_group(&drv->p->kobj, | ||
188 | groups[i]); | ||
189 | break; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | return error; | ||
194 | } | ||
195 | |||
196 | static void driver_remove_groups(struct device_driver *drv, | ||
197 | struct attribute_group **groups) | ||
198 | { | ||
199 | int i; | ||
200 | |||
201 | if (groups) | ||
202 | for (i = 0; groups[i]; i++) | ||
203 | sysfs_remove_group(&drv->p->kobj, groups[i]); | ||
143 | } | 204 | } |
144 | 205 | ||
145 | /** | 206 | /** |
146 | * driver_register - register driver with bus | 207 | * driver_register - register driver with bus |
147 | * @drv: driver to register | 208 | * @drv: driver to register |
148 | * | 209 | * |
149 | * We pass off most of the work to the bus_add_driver() call, | 210 | * We pass off most of the work to the bus_add_driver() call, |
150 | * since most of the things we have to do deal with the bus | 211 | * since most of the things we have to do deal with the bus |
151 | * structures. | 212 | * structures. |
152 | */ | 213 | */ |
153 | int driver_register(struct device_driver * drv) | 214 | int driver_register(struct device_driver *drv) |
154 | { | 215 | { |
216 | int ret; | ||
217 | |||
155 | if ((drv->bus->probe && drv->probe) || | 218 | if ((drv->bus->probe && drv->probe) || |
156 | (drv->bus->remove && drv->remove) || | 219 | (drv->bus->remove && drv->remove) || |
157 | (drv->bus->shutdown && drv->shutdown)) { | 220 | (drv->bus->shutdown && drv->shutdown)) |
158 | printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); | 221 | printk(KERN_WARNING "Driver '%s' needs updating - please use " |
159 | } | 222 | "bus_type methods\n", drv->name); |
160 | klist_init(&drv->klist_devices, NULL, NULL); | 223 | ret = bus_add_driver(drv); |
161 | return bus_add_driver(drv); | 224 | if (ret) |
225 | return ret; | ||
226 | ret = driver_add_groups(drv, drv->groups); | ||
227 | if (ret) | ||
228 | bus_remove_driver(drv); | ||
229 | return ret; | ||
162 | } | 230 | } |
231 | EXPORT_SYMBOL_GPL(driver_register); | ||
163 | 232 | ||
164 | /** | 233 | /** |
165 | * driver_unregister - remove driver from system. | 234 | * driver_unregister - remove driver from system. |
166 | * @drv: driver. | 235 | * @drv: driver. |
167 | * | 236 | * |
168 | * Again, we pass off most of the work to the bus-level call. | 237 | * Again, we pass off most of the work to the bus-level call. |
169 | */ | 238 | */ |
170 | 239 | void driver_unregister(struct device_driver *drv) | |
171 | void driver_unregister(struct device_driver * drv) | ||
172 | { | 240 | { |
241 | driver_remove_groups(drv, drv->groups); | ||
173 | bus_remove_driver(drv); | 242 | bus_remove_driver(drv); |
174 | } | 243 | } |
244 | EXPORT_SYMBOL_GPL(driver_unregister); | ||
175 | 245 | ||
176 | /** | 246 | /** |
177 | * driver_find - locate driver on a bus by its name. | 247 | * driver_find - locate driver on a bus by its name. |
178 | * @name: name of the driver. | 248 | * @name: name of the driver. |
179 | * @bus: bus to scan for the driver. | 249 | * @bus: bus to scan for the driver. |
180 | * | 250 | * |
181 | * Call kset_find_obj() to iterate over list of drivers on | 251 | * Call kset_find_obj() to iterate over list of drivers on |
182 | * a bus to find driver by name. Return driver if found. | 252 | * a bus to find driver by name. Return driver if found. |
183 | * | 253 | * |
184 | * Note that kset_find_obj increments driver's reference count. | 254 | * Note that kset_find_obj increments driver's reference count. |
185 | */ | 255 | */ |
186 | struct device_driver *driver_find(const char *name, struct bus_type *bus) | 256 | struct device_driver *driver_find(const char *name, struct bus_type *bus) |
187 | { | 257 | { |
188 | struct kobject *k = kset_find_obj(&bus->drivers, name); | 258 | struct kobject *k = kset_find_obj(bus->p->drivers_kset, name); |
189 | if (k) | 259 | struct driver_private *priv; |
190 | return to_drv(k); | 260 | |
261 | if (k) { | ||
262 | priv = to_driver(k); | ||
263 | return priv->driver; | ||
264 | } | ||
191 | return NULL; | 265 | return NULL; |
192 | } | 266 | } |
193 | |||
194 | EXPORT_SYMBOL_GPL(driver_register); | ||
195 | EXPORT_SYMBOL_GPL(driver_unregister); | ||
196 | EXPORT_SYMBOL_GPL(get_driver); | ||
197 | EXPORT_SYMBOL_GPL(put_driver); | ||
198 | EXPORT_SYMBOL_GPL(driver_find); | 267 | EXPORT_SYMBOL_GPL(driver_find); |
199 | |||
200 | EXPORT_SYMBOL_GPL(driver_create_file); | ||
201 | EXPORT_SYMBOL_GPL(driver_remove_file); | ||
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c index 90c862932169..113815556809 100644 --- a/drivers/base/firmware.c +++ b/drivers/base/firmware.c | |||
@@ -3,11 +3,11 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2002-3 Patrick Mochel | 4 | * Copyright (c) 2002-3 Patrick Mochel |
5 | * Copyright (c) 2002-3 Open Source Development Labs | 5 | * Copyright (c) 2002-3 Open Source Development Labs |
6 | * Copyright (c) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
7 | * Copyright (c) 2007 Novell Inc. | ||
6 | * | 8 | * |
7 | * This file is released under the GPLv2 | 9 | * This file is released under the GPLv2 |
8 | * | ||
9 | */ | 10 | */ |
10 | |||
11 | #include <linux/kobject.h> | 11 | #include <linux/kobject.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
@@ -15,23 +15,13 @@ | |||
15 | 15 | ||
16 | #include "base.h" | 16 | #include "base.h" |
17 | 17 | ||
18 | static decl_subsys(firmware, NULL, NULL); | 18 | struct kobject *firmware_kobj; |
19 | 19 | EXPORT_SYMBOL_GPL(firmware_kobj); | |
20 | int firmware_register(struct kset *s) | ||
21 | { | ||
22 | kobj_set_kset_s(s, firmware_subsys); | ||
23 | return subsystem_register(s); | ||
24 | } | ||
25 | |||
26 | void firmware_unregister(struct kset *s) | ||
27 | { | ||
28 | subsystem_unregister(s); | ||
29 | } | ||
30 | 20 | ||
31 | int __init firmware_init(void) | 21 | int __init firmware_init(void) |
32 | { | 22 | { |
33 | return subsystem_register(&firmware_subsys); | 23 | firmware_kobj = kobject_create_and_add("firmware", NULL); |
24 | if (!firmware_kobj) | ||
25 | return -ENOMEM; | ||
26 | return 0; | ||
34 | } | 27 | } |
35 | |||
36 | EXPORT_SYMBOL_GPL(firmware_register); | ||
37 | EXPORT_SYMBOL_GPL(firmware_unregister); | ||
diff --git a/drivers/base/hypervisor.c b/drivers/base/hypervisor.c index 7080b413ddc9..6428cba3aadd 100644 --- a/drivers/base/hypervisor.c +++ b/drivers/base/hypervisor.c | |||
@@ -2,19 +2,23 @@ | |||
2 | * hypervisor.c - /sys/hypervisor subsystem. | 2 | * hypervisor.c - /sys/hypervisor subsystem. |
3 | * | 3 | * |
4 | * Copyright (C) IBM Corp. 2006 | 4 | * Copyright (C) IBM Corp. 2006 |
5 | * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de> | ||
6 | * Copyright (C) 2007 Novell Inc. | ||
5 | * | 7 | * |
6 | * This file is released under the GPLv2 | 8 | * This file is released under the GPLv2 |
7 | */ | 9 | */ |
8 | 10 | ||
9 | #include <linux/kobject.h> | 11 | #include <linux/kobject.h> |
10 | #include <linux/device.h> | 12 | #include <linux/device.h> |
11 | |||
12 | #include "base.h" | 13 | #include "base.h" |
13 | 14 | ||
14 | decl_subsys(hypervisor, NULL, NULL); | 15 | struct kobject *hypervisor_kobj; |
15 | EXPORT_SYMBOL_GPL(hypervisor_subsys); | 16 | EXPORT_SYMBOL_GPL(hypervisor_kobj); |
16 | 17 | ||
17 | int __init hypervisor_init(void) | 18 | int __init hypervisor_init(void) |
18 | { | 19 | { |
19 | return subsystem_register(&hypervisor_subsys); | 20 | hypervisor_kobj = kobject_create_and_add("hypervisor", NULL); |
21 | if (!hypervisor_kobj) | ||
22 | return -ENOMEM; | ||
23 | return 0; | ||
20 | } | 24 | } |
diff --git a/drivers/base/init.c b/drivers/base/init.c index 37138154f9e8..7bd9b6a5b01f 100644 --- a/drivers/base/init.c +++ b/drivers/base/init.c | |||
@@ -1,10 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * | ||
3 | * Copyright (c) 2002-3 Patrick Mochel | 2 | * Copyright (c) 2002-3 Patrick Mochel |
4 | * Copyright (c) 2002-3 Open Source Development Labs | 3 | * Copyright (c) 2002-3 Open Source Development Labs |
5 | * | 4 | * |
6 | * This file is released under the GPLv2 | 5 | * This file is released under the GPLv2 |
7 | * | ||
8 | */ | 6 | */ |
9 | 7 | ||
10 | #include <linux/device.h> | 8 | #include <linux/device.h> |
@@ -14,12 +12,11 @@ | |||
14 | #include "base.h" | 12 | #include "base.h" |
15 | 13 | ||
16 | /** | 14 | /** |
17 | * driver_init - initialize driver model. | 15 | * driver_init - initialize driver model. |
18 | * | 16 | * |
19 | * Call the driver model init functions to initialize their | 17 | * Call the driver model init functions to initialize their |
20 | * subsystems. Called early from init/main.c. | 18 | * subsystems. Called early from init/main.c. |
21 | */ | 19 | */ |
22 | |||
23 | void __init driver_init(void) | 20 | void __init driver_init(void) |
24 | { | 21 | { |
25 | /* These are the core pieces */ | 22 | /* These are the core pieces */ |
@@ -36,5 +33,4 @@ void __init driver_init(void) | |||
36 | system_bus_init(); | 33 | system_bus_init(); |
37 | cpu_dev_init(); | 34 | cpu_dev_init(); |
38 | memory_dev_init(); | 35 | memory_dev_init(); |
39 | attribute_container_init(); | ||
40 | } | 36 | } |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 7868707c7eda..7ae413fdd5fc 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #define MEMORY_CLASS_NAME "memory" | 26 | #define MEMORY_CLASS_NAME "memory" |
27 | 27 | ||
28 | static struct sysdev_class memory_sysdev_class = { | 28 | static struct sysdev_class memory_sysdev_class = { |
29 | set_kset_name(MEMORY_CLASS_NAME), | 29 | .name = MEMORY_CLASS_NAME, |
30 | }; | 30 | }; |
31 | 31 | ||
32 | static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) | 32 | static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) |
diff --git a/drivers/base/module.c b/drivers/base/module.c new file mode 100644 index 000000000000..103be9cacb05 --- /dev/null +++ b/drivers/base/module.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * module.c - module sysfs fun for drivers | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/device.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/string.h> | ||
11 | #include "base.h" | ||
12 | |||
13 | static char *make_driver_name(struct device_driver *drv) | ||
14 | { | ||
15 | char *driver_name; | ||
16 | |||
17 | driver_name = kmalloc(strlen(drv->name) + strlen(drv->bus->name) + 2, | ||
18 | GFP_KERNEL); | ||
19 | if (!driver_name) | ||
20 | return NULL; | ||
21 | |||
22 | sprintf(driver_name, "%s:%s", drv->bus->name, drv->name); | ||
23 | return driver_name; | ||
24 | } | ||
25 | |||
26 | static void module_create_drivers_dir(struct module_kobject *mk) | ||
27 | { | ||
28 | if (!mk || mk->drivers_dir) | ||
29 | return; | ||
30 | |||
31 | mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj); | ||
32 | } | ||
33 | |||
34 | void module_add_driver(struct module *mod, struct device_driver *drv) | ||
35 | { | ||
36 | char *driver_name; | ||
37 | int no_warn; | ||
38 | struct module_kobject *mk = NULL; | ||
39 | |||
40 | if (!drv) | ||
41 | return; | ||
42 | |||
43 | if (mod) | ||
44 | mk = &mod->mkobj; | ||
45 | else if (drv->mod_name) { | ||
46 | struct kobject *mkobj; | ||
47 | |||
48 | /* Lookup built-in module entry in /sys/modules */ | ||
49 | mkobj = kset_find_obj(module_kset, drv->mod_name); | ||
50 | if (mkobj) { | ||
51 | mk = container_of(mkobj, struct module_kobject, kobj); | ||
52 | /* remember our module structure */ | ||
53 | drv->p->mkobj = mk; | ||
54 | /* kset_find_obj took a reference */ | ||
55 | kobject_put(mkobj); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (!mk) | ||
60 | return; | ||
61 | |||
62 | /* Don't check return codes; these calls are idempotent */ | ||
63 | no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module"); | ||
64 | driver_name = make_driver_name(drv); | ||
65 | if (driver_name) { | ||
66 | module_create_drivers_dir(mk); | ||
67 | no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, | ||
68 | driver_name); | ||
69 | kfree(driver_name); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | void module_remove_driver(struct device_driver *drv) | ||
74 | { | ||
75 | struct module_kobject *mk = NULL; | ||
76 | char *driver_name; | ||
77 | |||
78 | if (!drv) | ||
79 | return; | ||
80 | |||
81 | sysfs_remove_link(&drv->p->kobj, "module"); | ||
82 | |||
83 | if (drv->owner) | ||
84 | mk = &drv->owner->mkobj; | ||
85 | else if (drv->p->mkobj) | ||
86 | mk = drv->p->mkobj; | ||
87 | if (mk && mk->drivers_dir) { | ||
88 | driver_name = make_driver_name(drv); | ||
89 | if (driver_name) { | ||
90 | sysfs_remove_link(mk->drivers_dir, driver_name); | ||
91 | kfree(driver_name); | ||
92 | } | ||
93 | } | ||
94 | } | ||
diff --git a/drivers/base/node.c b/drivers/base/node.c index 88eeed72b5d6..e59861f18ce5 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | 16 | ||
17 | static struct sysdev_class node_class = { | 17 | static struct sysdev_class node_class = { |
18 | set_kset_name("node"), | 18 | .name = "node", |
19 | }; | 19 | }; |
20 | 20 | ||
21 | 21 | ||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index fb5609241482..efaf282c438c 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -20,7 +20,8 @@ | |||
20 | 20 | ||
21 | #include "base.h" | 21 | #include "base.h" |
22 | 22 | ||
23 | #define to_platform_driver(drv) (container_of((drv), struct platform_driver, driver)) | 23 | #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ |
24 | driver)) | ||
24 | 25 | ||
25 | struct device platform_bus = { | 26 | struct device platform_bus = { |
26 | .bus_id = "platform", | 27 | .bus_id = "platform", |
@@ -28,14 +29,13 @@ struct device platform_bus = { | |||
28 | EXPORT_SYMBOL_GPL(platform_bus); | 29 | EXPORT_SYMBOL_GPL(platform_bus); |
29 | 30 | ||
30 | /** | 31 | /** |
31 | * platform_get_resource - get a resource for a device | 32 | * platform_get_resource - get a resource for a device |
32 | * @dev: platform device | 33 | * @dev: platform device |
33 | * @type: resource type | 34 | * @type: resource type |
34 | * @num: resource index | 35 | * @num: resource index |
35 | */ | 36 | */ |
36 | struct resource * | 37 | struct resource *platform_get_resource(struct platform_device *dev, |
37 | platform_get_resource(struct platform_device *dev, unsigned int type, | 38 | unsigned int type, unsigned int num) |
38 | unsigned int num) | ||
39 | { | 39 | { |
40 | int i; | 40 | int i; |
41 | 41 | ||
@@ -43,8 +43,7 @@ platform_get_resource(struct platform_device *dev, unsigned int type, | |||
43 | struct resource *r = &dev->resource[i]; | 43 | struct resource *r = &dev->resource[i]; |
44 | 44 | ||
45 | if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| | 45 | if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM| |
46 | IORESOURCE_IRQ|IORESOURCE_DMA)) | 46 | IORESOURCE_IRQ|IORESOURCE_DMA)) == type) |
47 | == type) | ||
48 | if (num-- == 0) | 47 | if (num-- == 0) |
49 | return r; | 48 | return r; |
50 | } | 49 | } |
@@ -53,9 +52,9 @@ platform_get_resource(struct platform_device *dev, unsigned int type, | |||
53 | EXPORT_SYMBOL_GPL(platform_get_resource); | 52 | EXPORT_SYMBOL_GPL(platform_get_resource); |
54 | 53 | ||
55 | /** | 54 | /** |
56 | * platform_get_irq - get an IRQ for a device | 55 | * platform_get_irq - get an IRQ for a device |
57 | * @dev: platform device | 56 | * @dev: platform device |
58 | * @num: IRQ number index | 57 | * @num: IRQ number index |
59 | */ | 58 | */ |
60 | int platform_get_irq(struct platform_device *dev, unsigned int num) | 59 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
61 | { | 60 | { |
@@ -66,14 +65,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) | |||
66 | EXPORT_SYMBOL_GPL(platform_get_irq); | 65 | EXPORT_SYMBOL_GPL(platform_get_irq); |
67 | 66 | ||
68 | /** | 67 | /** |
69 | * platform_get_resource_byname - get a resource for a device by name | 68 | * platform_get_resource_byname - get a resource for a device by name |
70 | * @dev: platform device | 69 | * @dev: platform device |
71 | * @type: resource type | 70 | * @type: resource type |
72 | * @name: resource name | 71 | * @name: resource name |
73 | */ | 72 | */ |
74 | struct resource * | 73 | struct resource *platform_get_resource_byname(struct platform_device *dev, |
75 | platform_get_resource_byname(struct platform_device *dev, unsigned int type, | 74 | unsigned int type, char *name) |
76 | char *name) | ||
77 | { | 75 | { |
78 | int i; | 76 | int i; |
79 | 77 | ||
@@ -90,22 +88,23 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type, | |||
90 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); | 88 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); |
91 | 89 | ||
92 | /** | 90 | /** |
93 | * platform_get_irq - get an IRQ for a device | 91 | * platform_get_irq - get an IRQ for a device |
94 | * @dev: platform device | 92 | * @dev: platform device |
95 | * @name: IRQ name | 93 | * @name: IRQ name |
96 | */ | 94 | */ |
97 | int platform_get_irq_byname(struct platform_device *dev, char *name) | 95 | int platform_get_irq_byname(struct platform_device *dev, char *name) |
98 | { | 96 | { |
99 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); | 97 | struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, |
98 | name); | ||
100 | 99 | ||
101 | return r ? r->start : -ENXIO; | 100 | return r ? r->start : -ENXIO; |
102 | } | 101 | } |
103 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); | 102 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
104 | 103 | ||
105 | /** | 104 | /** |
106 | * platform_add_devices - add a numbers of platform devices | 105 | * platform_add_devices - add a numbers of platform devices |
107 | * @devs: array of platform devices to add | 106 | * @devs: array of platform devices to add |
108 | * @num: number of platform devices in array | 107 | * @num: number of platform devices in array |
109 | */ | 108 | */ |
110 | int platform_add_devices(struct platform_device **devs, int num) | 109 | int platform_add_devices(struct platform_device **devs, int num) |
111 | { | 110 | { |
@@ -130,12 +129,11 @@ struct platform_object { | |||
130 | }; | 129 | }; |
131 | 130 | ||
132 | /** | 131 | /** |
133 | * platform_device_put | 132 | * platform_device_put |
134 | * @pdev: platform device to free | 133 | * @pdev: platform device to free |
135 | * | 134 | * |
136 | * Free all memory associated with a platform device. This function | 135 | * Free all memory associated with a platform device. This function must |
137 | * must _only_ be externally called in error cases. All other usage | 136 | * _only_ be externally called in error cases. All other usage is a bug. |
138 | * is a bug. | ||
139 | */ | 137 | */ |
140 | void platform_device_put(struct platform_device *pdev) | 138 | void platform_device_put(struct platform_device *pdev) |
141 | { | 139 | { |
@@ -146,7 +144,8 @@ EXPORT_SYMBOL_GPL(platform_device_put); | |||
146 | 144 | ||
147 | static void platform_device_release(struct device *dev) | 145 | static void platform_device_release(struct device *dev) |
148 | { | 146 | { |
149 | struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev); | 147 | struct platform_object *pa = container_of(dev, struct platform_object, |
148 | pdev.dev); | ||
150 | 149 | ||
151 | kfree(pa->pdev.dev.platform_data); | 150 | kfree(pa->pdev.dev.platform_data); |
152 | kfree(pa->pdev.resource); | 151 | kfree(pa->pdev.resource); |
@@ -154,12 +153,12 @@ static void platform_device_release(struct device *dev) | |||
154 | } | 153 | } |
155 | 154 | ||
156 | /** | 155 | /** |
157 | * platform_device_alloc | 156 | * platform_device_alloc |
158 | * @name: base name of the device we're adding | 157 | * @name: base name of the device we're adding |
159 | * @id: instance id | 158 | * @id: instance id |
160 | * | 159 | * |
161 | * Create a platform device object which can have other objects attached | 160 | * Create a platform device object which can have other objects attached |
162 | * to it, and which will have attached objects freed when it is released. | 161 | * to it, and which will have attached objects freed when it is released. |
163 | */ | 162 | */ |
164 | struct platform_device *platform_device_alloc(const char *name, int id) | 163 | struct platform_device *platform_device_alloc(const char *name, int id) |
165 | { | 164 | { |
@@ -179,16 +178,17 @@ struct platform_device *platform_device_alloc(const char *name, int id) | |||
179 | EXPORT_SYMBOL_GPL(platform_device_alloc); | 178 | EXPORT_SYMBOL_GPL(platform_device_alloc); |
180 | 179 | ||
181 | /** | 180 | /** |
182 | * platform_device_add_resources | 181 | * platform_device_add_resources |
183 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 182 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
184 | * @res: set of resources that needs to be allocated for the device | 183 | * @res: set of resources that needs to be allocated for the device |
185 | * @num: number of resources | 184 | * @num: number of resources |
186 | * | 185 | * |
187 | * Add a copy of the resources to the platform device. The memory | 186 | * Add a copy of the resources to the platform device. The memory |
188 | * associated with the resources will be freed when the platform | 187 | * associated with the resources will be freed when the platform device is |
189 | * device is released. | 188 | * released. |
190 | */ | 189 | */ |
191 | int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num) | 190 | int platform_device_add_resources(struct platform_device *pdev, |
191 | struct resource *res, unsigned int num) | ||
192 | { | 192 | { |
193 | struct resource *r; | 193 | struct resource *r; |
194 | 194 | ||
@@ -203,16 +203,17 @@ int platform_device_add_resources(struct platform_device *pdev, struct resource | |||
203 | EXPORT_SYMBOL_GPL(platform_device_add_resources); | 203 | EXPORT_SYMBOL_GPL(platform_device_add_resources); |
204 | 204 | ||
205 | /** | 205 | /** |
206 | * platform_device_add_data | 206 | * platform_device_add_data |
207 | * @pdev: platform device allocated by platform_device_alloc to add resources to | 207 | * @pdev: platform device allocated by platform_device_alloc to add resources to |
208 | * @data: platform specific data for this platform device | 208 | * @data: platform specific data for this platform device |
209 | * @size: size of platform specific data | 209 | * @size: size of platform specific data |
210 | * | 210 | * |
211 | * Add a copy of platform specific data to the platform device's platform_data | 211 | * Add a copy of platform specific data to the platform device's |
212 | * pointer. The memory associated with the platform data will be freed | 212 | * platform_data pointer. The memory associated with the platform data |
213 | * when the platform device is released. | 213 | * will be freed when the platform device is released. |
214 | */ | 214 | */ |
215 | int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size) | 215 | int platform_device_add_data(struct platform_device *pdev, const void *data, |
216 | size_t size) | ||
216 | { | 217 | { |
217 | void *d; | 218 | void *d; |
218 | 219 | ||
@@ -226,11 +227,11 @@ int platform_device_add_data(struct platform_device *pdev, const void *data, siz | |||
226 | EXPORT_SYMBOL_GPL(platform_device_add_data); | 227 | EXPORT_SYMBOL_GPL(platform_device_add_data); |
227 | 228 | ||
228 | /** | 229 | /** |
229 | * platform_device_add - add a platform device to device hierarchy | 230 | * platform_device_add - add a platform device to device hierarchy |
230 | * @pdev: platform device we're adding | 231 | * @pdev: platform device we're adding |
231 | * | 232 | * |
232 | * This is part 2 of platform_device_register(), though may be called | 233 | * This is part 2 of platform_device_register(), though may be called |
233 | * separately _iff_ pdev was allocated by platform_device_alloc(). | 234 | * separately _iff_ pdev was allocated by platform_device_alloc(). |
234 | */ | 235 | */ |
235 | int platform_device_add(struct platform_device *pdev) | 236 | int platform_device_add(struct platform_device *pdev) |
236 | { | 237 | { |
@@ -289,13 +290,12 @@ int platform_device_add(struct platform_device *pdev) | |||
289 | EXPORT_SYMBOL_GPL(platform_device_add); | 290 | EXPORT_SYMBOL_GPL(platform_device_add); |
290 | 291 | ||
291 | /** | 292 | /** |
292 | * platform_device_del - remove a platform-level device | 293 | * platform_device_del - remove a platform-level device |
293 | * @pdev: platform device we're removing | 294 | * @pdev: platform device we're removing |
294 | * | 295 | * |
295 | * Note that this function will also release all memory- and port-based | 296 | * Note that this function will also release all memory- and port-based |
296 | * resources owned by the device (@dev->resource). This function | 297 | * resources owned by the device (@dev->resource). This function must |
297 | * must _only_ be externally called in error cases. All other usage | 298 | * _only_ be externally called in error cases. All other usage is a bug. |
298 | * is a bug. | ||
299 | */ | 299 | */ |
300 | void platform_device_del(struct platform_device *pdev) | 300 | void platform_device_del(struct platform_device *pdev) |
301 | { | 301 | { |
@@ -314,11 +314,10 @@ void platform_device_del(struct platform_device *pdev) | |||
314 | EXPORT_SYMBOL_GPL(platform_device_del); | 314 | EXPORT_SYMBOL_GPL(platform_device_del); |
315 | 315 | ||
316 | /** | 316 | /** |
317 | * platform_device_register - add a platform-level device | 317 | * platform_device_register - add a platform-level device |
318 | * @pdev: platform device we're adding | 318 | * @pdev: platform device we're adding |
319 | * | ||
320 | */ | 319 | */ |
321 | int platform_device_register(struct platform_device * pdev) | 320 | int platform_device_register(struct platform_device *pdev) |
322 | { | 321 | { |
323 | device_initialize(&pdev->dev); | 322 | device_initialize(&pdev->dev); |
324 | return platform_device_add(pdev); | 323 | return platform_device_add(pdev); |
@@ -326,14 +325,14 @@ int platform_device_register(struct platform_device * pdev) | |||
326 | EXPORT_SYMBOL_GPL(platform_device_register); | 325 | EXPORT_SYMBOL_GPL(platform_device_register); |
327 | 326 | ||
328 | /** | 327 | /** |
329 | * platform_device_unregister - unregister a platform-level device | 328 | * platform_device_unregister - unregister a platform-level device |
330 | * @pdev: platform device we're unregistering | 329 | * @pdev: platform device we're unregistering |
331 | * | 330 | * |
332 | * Unregistration is done in 2 steps. First we release all resources | 331 | * Unregistration is done in 2 steps. First we release all resources |
333 | * and remove it from the subsystem, then we drop reference count by | 332 | * and remove it from the subsystem, then we drop reference count by |
334 | * calling platform_device_put(). | 333 | * calling platform_device_put(). |
335 | */ | 334 | */ |
336 | void platform_device_unregister(struct platform_device * pdev) | 335 | void platform_device_unregister(struct platform_device *pdev) |
337 | { | 336 | { |
338 | platform_device_del(pdev); | 337 | platform_device_del(pdev); |
339 | platform_device_put(pdev); | 338 | platform_device_put(pdev); |
@@ -341,27 +340,29 @@ void platform_device_unregister(struct platform_device * pdev) | |||
341 | EXPORT_SYMBOL_GPL(platform_device_unregister); | 340 | EXPORT_SYMBOL_GPL(platform_device_unregister); |
342 | 341 | ||
343 | /** | 342 | /** |
344 | * platform_device_register_simple | 343 | * platform_device_register_simple |
345 | * @name: base name of the device we're adding | 344 | * @name: base name of the device we're adding |
346 | * @id: instance id | 345 | * @id: instance id |
347 | * @res: set of resources that needs to be allocated for the device | 346 | * @res: set of resources that needs to be allocated for the device |
348 | * @num: number of resources | 347 | * @num: number of resources |
349 | * | 348 | * |
350 | * This function creates a simple platform device that requires minimal | 349 | * This function creates a simple platform device that requires minimal |
351 | * resource and memory management. Canned release function freeing | 350 | * resource and memory management. Canned release function freeing memory |
352 | * memory allocated for the device allows drivers using such devices | 351 | * allocated for the device allows drivers using such devices to be |
353 | * to be unloaded without waiting for the last reference to the device | 352 | * unloaded without waiting for the last reference to the device to be |
354 | * to be dropped. | 353 | * dropped. |
355 | * | 354 | * |
356 | * This interface is primarily intended for use with legacy drivers | 355 | * This interface is primarily intended for use with legacy drivers which |
357 | * which probe hardware directly. Because such drivers create sysfs | 356 | * probe hardware directly. Because such drivers create sysfs device nodes |
358 | * device nodes themselves, rather than letting system infrastructure | 357 | * themselves, rather than letting system infrastructure handle such device |
359 | * handle such device enumeration tasks, they don't fully conform to | 358 | * enumeration tasks, they don't fully conform to the Linux driver model. |
360 | * the Linux driver model. In particular, when such drivers are built | 359 | * In particular, when such drivers are built as modules, they can't be |
361 | * as modules, they can't be "hotplugged". | 360 | * "hotplugged". |
362 | */ | 361 | */ |
363 | struct platform_device *platform_device_register_simple(char *name, int id, | 362 | struct platform_device *platform_device_register_simple(const char *name, |
364 | struct resource *res, unsigned int num) | 363 | int id, |
364 | struct resource *res, | ||
365 | unsigned int num) | ||
365 | { | 366 | { |
366 | struct platform_device *pdev; | 367 | struct platform_device *pdev; |
367 | int retval; | 368 | int retval; |
@@ -436,8 +437,8 @@ static int platform_drv_resume(struct device *_dev) | |||
436 | } | 437 | } |
437 | 438 | ||
438 | /** | 439 | /** |
439 | * platform_driver_register | 440 | * platform_driver_register |
440 | * @drv: platform driver structure | 441 | * @drv: platform driver structure |
441 | */ | 442 | */ |
442 | int platform_driver_register(struct platform_driver *drv) | 443 | int platform_driver_register(struct platform_driver *drv) |
443 | { | 444 | { |
@@ -457,8 +458,8 @@ int platform_driver_register(struct platform_driver *drv) | |||
457 | EXPORT_SYMBOL_GPL(platform_driver_register); | 458 | EXPORT_SYMBOL_GPL(platform_driver_register); |
458 | 459 | ||
459 | /** | 460 | /** |
460 | * platform_driver_unregister | 461 | * platform_driver_unregister |
461 | * @drv: platform driver structure | 462 | * @drv: platform driver structure |
462 | */ | 463 | */ |
463 | void platform_driver_unregister(struct platform_driver *drv) | 464 | void platform_driver_unregister(struct platform_driver *drv) |
464 | { | 465 | { |
@@ -497,12 +498,12 @@ int __init_or_module platform_driver_probe(struct platform_driver *drv, | |||
497 | * if the probe was successful, and make sure any forced probes of | 498 | * if the probe was successful, and make sure any forced probes of |
498 | * new devices fail. | 499 | * new devices fail. |
499 | */ | 500 | */ |
500 | spin_lock(&platform_bus_type.klist_drivers.k_lock); | 501 | spin_lock(&platform_bus_type.p->klist_drivers.k_lock); |
501 | drv->probe = NULL; | 502 | drv->probe = NULL; |
502 | if (code == 0 && list_empty(&drv->driver.klist_devices.k_list)) | 503 | if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list)) |
503 | retval = -ENODEV; | 504 | retval = -ENODEV; |
504 | drv->driver.probe = platform_drv_probe_fail; | 505 | drv->driver.probe = platform_drv_probe_fail; |
505 | spin_unlock(&platform_bus_type.klist_drivers.k_lock); | 506 | spin_unlock(&platform_bus_type.p->klist_drivers.k_lock); |
506 | 507 | ||
507 | if (code != retval) | 508 | if (code != retval) |
508 | platform_driver_unregister(drv); | 509 | platform_driver_unregister(drv); |
@@ -516,8 +517,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe); | |||
516 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events | 517 | * (b) sysfs attribute lets new-style coldplug recover from hotplug events |
517 | * mishandled before system is fully running: "modprobe $(cat modalias)" | 518 | * mishandled before system is fully running: "modprobe $(cat modalias)" |
518 | */ | 519 | */ |
519 | static ssize_t | 520 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, |
520 | modalias_show(struct device *dev, struct device_attribute *a, char *buf) | 521 | char *buf) |
521 | { | 522 | { |
522 | struct platform_device *pdev = to_platform_device(dev); | 523 | struct platform_device *pdev = to_platform_device(dev); |
523 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); | 524 | int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name); |
@@ -538,26 +539,24 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
538 | return 0; | 539 | return 0; |
539 | } | 540 | } |
540 | 541 | ||
541 | |||
542 | /** | 542 | /** |
543 | * platform_match - bind platform device to platform driver. | 543 | * platform_match - bind platform device to platform driver. |
544 | * @dev: device. | 544 | * @dev: device. |
545 | * @drv: driver. | 545 | * @drv: driver. |
546 | * | 546 | * |
547 | * Platform device IDs are assumed to be encoded like this: | 547 | * Platform device IDs are assumed to be encoded like this: |
548 | * "<name><instance>", where <name> is a short description of the | 548 | * "<name><instance>", where <name> is a short description of the type of |
549 | * type of device, like "pci" or "floppy", and <instance> is the | 549 | * device, like "pci" or "floppy", and <instance> is the enumerated |
550 | * enumerated instance of the device, like '0' or '42'. | 550 | * instance of the device, like '0' or '42'. Driver IDs are simply |
551 | * Driver IDs are simply "<name>". | 551 | * "<name>". So, extract the <name> from the platform_device structure, |
552 | * So, extract the <name> from the platform_device structure, | 552 | * and compare it against the name of the driver. Return whether they match |
553 | * and compare it against the name of the driver. Return whether | 553 | * or not. |
554 | * they match or not. | ||
555 | */ | 554 | */ |
556 | 555 | static int platform_match(struct device *dev, struct device_driver *drv) | |
557 | static int platform_match(struct device * dev, struct device_driver * drv) | ||
558 | { | 556 | { |
559 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | 557 | struct platform_device *pdev; |
560 | 558 | ||
559 | pdev = container_of(dev, struct platform_device, dev); | ||
561 | return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); | 560 | return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); |
562 | } | 561 | } |
563 | 562 | ||
@@ -574,9 +573,10 @@ static int platform_suspend(struct device *dev, pm_message_t mesg) | |||
574 | static int platform_suspend_late(struct device *dev, pm_message_t mesg) | 573 | static int platform_suspend_late(struct device *dev, pm_message_t mesg) |
575 | { | 574 | { |
576 | struct platform_driver *drv = to_platform_driver(dev->driver); | 575 | struct platform_driver *drv = to_platform_driver(dev->driver); |
577 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | 576 | struct platform_device *pdev; |
578 | int ret = 0; | 577 | int ret = 0; |
579 | 578 | ||
579 | pdev = container_of(dev, struct platform_device, dev); | ||
580 | if (dev->driver && drv->suspend_late) | 580 | if (dev->driver && drv->suspend_late) |
581 | ret = drv->suspend_late(pdev, mesg); | 581 | ret = drv->suspend_late(pdev, mesg); |
582 | 582 | ||
@@ -586,16 +586,17 @@ static int platform_suspend_late(struct device *dev, pm_message_t mesg) | |||
586 | static int platform_resume_early(struct device *dev) | 586 | static int platform_resume_early(struct device *dev) |
587 | { | 587 | { |
588 | struct platform_driver *drv = to_platform_driver(dev->driver); | 588 | struct platform_driver *drv = to_platform_driver(dev->driver); |
589 | struct platform_device *pdev = container_of(dev, struct platform_device, dev); | 589 | struct platform_device *pdev; |
590 | int ret = 0; | 590 | int ret = 0; |
591 | 591 | ||
592 | pdev = container_of(dev, struct platform_device, dev); | ||
592 | if (dev->driver && drv->resume_early) | 593 | if (dev->driver && drv->resume_early) |
593 | ret = drv->resume_early(pdev); | 594 | ret = drv->resume_early(pdev); |
594 | 595 | ||
595 | return ret; | 596 | return ret; |
596 | } | 597 | } |
597 | 598 | ||
598 | static int platform_resume(struct device * dev) | 599 | static int platform_resume(struct device *dev) |
599 | { | 600 | { |
600 | int ret = 0; | 601 | int ret = 0; |
601 | 602 | ||
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 44504e6618fb..06a86fe6a78d 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-y := shutdown.o | ||
2 | obj-$(CONFIG_PM) += sysfs.o | 1 | obj-$(CONFIG_PM) += sysfs.o |
3 | obj-$(CONFIG_PM_SLEEP) += main.o | 2 | obj-$(CONFIG_PM_SLEEP) += main.o |
4 | obj-$(CONFIG_PM_TRACE) += trace.o | 3 | obj-$(CONFIG_PM_TRACE) += trace.o |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 691ffb64cc37..200ed5fafd50 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -24,20 +24,45 @@ | |||
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/pm.h> | 25 | #include <linux/pm.h> |
26 | #include <linux/resume-trace.h> | 26 | #include <linux/resume-trace.h> |
27 | #include <linux/rwsem.h> | ||
27 | 28 | ||
28 | #include "../base.h" | 29 | #include "../base.h" |
29 | #include "power.h" | 30 | #include "power.h" |
30 | 31 | ||
32 | /* | ||
33 | * The entries in the dpm_active list are in a depth first order, simply | ||
34 | * because children are guaranteed to be discovered after parents, and | ||
35 | * are inserted at the back of the list on discovery. | ||
36 | * | ||
37 | * All the other lists are kept in the same order, for consistency. | ||
38 | * However the lists aren't always traversed in the same order. | ||
39 | * Semaphores must be acquired from the top (i.e., front) down | ||
40 | * and released in the opposite order. Devices must be suspended | ||
41 | * from the bottom (i.e., end) up and resumed in the opposite order. | ||
42 | * That way no parent will be suspended while it still has an active | ||
43 | * child. | ||
44 | * | ||
45 | * Since device_pm_add() may be called with a device semaphore held, | ||
46 | * we must never try to acquire a device semaphore while holding | ||
47 | * dpm_list_mutex. | ||
48 | */ | ||
49 | |||
31 | LIST_HEAD(dpm_active); | 50 | LIST_HEAD(dpm_active); |
51 | static LIST_HEAD(dpm_locked); | ||
32 | static LIST_HEAD(dpm_off); | 52 | static LIST_HEAD(dpm_off); |
33 | static LIST_HEAD(dpm_off_irq); | 53 | static LIST_HEAD(dpm_off_irq); |
54 | static LIST_HEAD(dpm_destroy); | ||
34 | 55 | ||
35 | static DEFINE_MUTEX(dpm_mtx); | ||
36 | static DEFINE_MUTEX(dpm_list_mtx); | 56 | static DEFINE_MUTEX(dpm_list_mtx); |
37 | 57 | ||
38 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | 58 | static DECLARE_RWSEM(pm_sleep_rwsem); |
39 | 59 | ||
60 | int (*platform_enable_wakeup)(struct device *dev, int is_on); | ||
40 | 61 | ||
62 | /** | ||
63 | * device_pm_add - add a device to the list of active devices | ||
64 | * @dev: Device to be added to the list | ||
65 | */ | ||
41 | void device_pm_add(struct device *dev) | 66 | void device_pm_add(struct device *dev) |
42 | { | 67 | { |
43 | pr_debug("PM: Adding info for %s:%s\n", | 68 | pr_debug("PM: Adding info for %s:%s\n", |
@@ -48,8 +73,36 @@ void device_pm_add(struct device *dev) | |||
48 | mutex_unlock(&dpm_list_mtx); | 73 | mutex_unlock(&dpm_list_mtx); |
49 | } | 74 | } |
50 | 75 | ||
76 | /** | ||
77 | * device_pm_remove - remove a device from the list of active devices | ||
78 | * @dev: Device to be removed from the list | ||
79 | * | ||
80 | * This function also removes the device's PM-related sysfs attributes. | ||
81 | */ | ||
51 | void device_pm_remove(struct device *dev) | 82 | void device_pm_remove(struct device *dev) |
52 | { | 83 | { |
84 | /* | ||
85 | * If this function is called during a suspend, it will be blocked, | ||
86 | * because we're holding the device's semaphore at that time, which may | ||
87 | * lead to a deadlock. In that case we want to print a warning. | ||
88 | * However, it may also be called by unregister_dropped_devices() with | ||
89 | * the device's semaphore released, in which case the warning should | ||
90 | * not be printed. | ||
91 | */ | ||
92 | if (down_trylock(&dev->sem)) { | ||
93 | if (down_read_trylock(&pm_sleep_rwsem)) { | ||
94 | /* No suspend in progress, wait on dev->sem */ | ||
95 | down(&dev->sem); | ||
96 | up_read(&pm_sleep_rwsem); | ||
97 | } else { | ||
98 | /* Suspend in progress, we may deadlock */ | ||
99 | dev_warn(dev, "Suspicious %s during suspend\n", | ||
100 | __FUNCTION__); | ||
101 | dump_stack(); | ||
102 | /* The user has been warned ... */ | ||
103 | down(&dev->sem); | ||
104 | } | ||
105 | } | ||
53 | pr_debug("PM: Removing info for %s:%s\n", | 106 | pr_debug("PM: Removing info for %s:%s\n", |
54 | dev->bus ? dev->bus->name : "No Bus", | 107 | dev->bus ? dev->bus->name : "No Bus", |
55 | kobject_name(&dev->kobj)); | 108 | kobject_name(&dev->kobj)); |
@@ -57,25 +110,124 @@ void device_pm_remove(struct device *dev) | |||
57 | dpm_sysfs_remove(dev); | 110 | dpm_sysfs_remove(dev); |
58 | list_del_init(&dev->power.entry); | 111 | list_del_init(&dev->power.entry); |
59 | mutex_unlock(&dpm_list_mtx); | 112 | mutex_unlock(&dpm_list_mtx); |
113 | up(&dev->sem); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * device_pm_schedule_removal - schedule the removal of a suspended device | ||
118 | * @dev: Device to destroy | ||
119 | * | ||
120 | * Moves the device to the dpm_destroy list for further processing by | ||
121 | * unregister_dropped_devices(). | ||
122 | */ | ||
123 | void device_pm_schedule_removal(struct device *dev) | ||
124 | { | ||
125 | pr_debug("PM: Preparing for removal: %s:%s\n", | ||
126 | dev->bus ? dev->bus->name : "No Bus", | ||
127 | kobject_name(&dev->kobj)); | ||
128 | mutex_lock(&dpm_list_mtx); | ||
129 | list_move_tail(&dev->power.entry, &dpm_destroy); | ||
130 | mutex_unlock(&dpm_list_mtx); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * pm_sleep_lock - mutual exclusion for registration and suspend | ||
135 | * | ||
136 | * Returns 0 if no suspend is underway and device registration | ||
137 | * may proceed, otherwise -EBUSY. | ||
138 | */ | ||
139 | int pm_sleep_lock(void) | ||
140 | { | ||
141 | if (down_read_trylock(&pm_sleep_rwsem)) | ||
142 | return 0; | ||
143 | |||
144 | return -EBUSY; | ||
145 | } | ||
146 | |||
147 | /** | ||
148 | * pm_sleep_unlock - mutual exclusion for registration and suspend | ||
149 | * | ||
150 | * This routine undoes the effect of device_pm_add_lock | ||
151 | * when a device's registration is complete. | ||
152 | */ | ||
153 | void pm_sleep_unlock(void) | ||
154 | { | ||
155 | up_read(&pm_sleep_rwsem); | ||
60 | } | 156 | } |
61 | 157 | ||
62 | 158 | ||
63 | /*------------------------- Resume routines -------------------------*/ | 159 | /*------------------------- Resume routines -------------------------*/ |
64 | 160 | ||
65 | /** | 161 | /** |
66 | * resume_device - Restore state for one device. | 162 | * resume_device_early - Power on one device (early resume). |
67 | * @dev: Device. | 163 | * @dev: Device. |
68 | * | 164 | * |
165 | * Must be called with interrupts disabled. | ||
69 | */ | 166 | */ |
70 | 167 | static int resume_device_early(struct device *dev) | |
71 | static int resume_device(struct device * dev) | ||
72 | { | 168 | { |
73 | int error = 0; | 169 | int error = 0; |
74 | 170 | ||
75 | TRACE_DEVICE(dev); | 171 | TRACE_DEVICE(dev); |
76 | TRACE_RESUME(0); | 172 | TRACE_RESUME(0); |
77 | 173 | ||
78 | down(&dev->sem); | 174 | if (dev->bus && dev->bus->resume_early) { |
175 | dev_dbg(dev, "EARLY resume\n"); | ||
176 | error = dev->bus->resume_early(dev); | ||
177 | } | ||
178 | |||
179 | TRACE_RESUME(error); | ||
180 | return error; | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * dpm_power_up - Power on all regular (non-sysdev) devices. | ||
185 | * | ||
186 | * Walk the dpm_off_irq list and power each device up. This | ||
187 | * is used for devices that required they be powered down with | ||
188 | * interrupts disabled. As devices are powered on, they are moved | ||
189 | * to the dpm_off list. | ||
190 | * | ||
191 | * Must be called with interrupts disabled and only one CPU running. | ||
192 | */ | ||
193 | static void dpm_power_up(void) | ||
194 | { | ||
195 | |||
196 | while (!list_empty(&dpm_off_irq)) { | ||
197 | struct list_head *entry = dpm_off_irq.next; | ||
198 | struct device *dev = to_device(entry); | ||
199 | |||
200 | list_move_tail(entry, &dpm_off); | ||
201 | resume_device_early(dev); | ||
202 | } | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * device_power_up - Turn on all devices that need special attention. | ||
207 | * | ||
208 | * Power on system devices, then devices that required we shut them down | ||
209 | * with interrupts disabled. | ||
210 | * | ||
211 | * Must be called with interrupts disabled. | ||
212 | */ | ||
213 | void device_power_up(void) | ||
214 | { | ||
215 | sysdev_resume(); | ||
216 | dpm_power_up(); | ||
217 | } | ||
218 | EXPORT_SYMBOL_GPL(device_power_up); | ||
219 | |||
220 | /** | ||
221 | * resume_device - Restore state for one device. | ||
222 | * @dev: Device. | ||
223 | * | ||
224 | */ | ||
225 | static int resume_device(struct device *dev) | ||
226 | { | ||
227 | int error = 0; | ||
228 | |||
229 | TRACE_DEVICE(dev); | ||
230 | TRACE_RESUME(0); | ||
79 | 231 | ||
80 | if (dev->bus && dev->bus->resume) { | 232 | if (dev->bus && dev->bus->resume) { |
81 | dev_dbg(dev,"resuming\n"); | 233 | dev_dbg(dev,"resuming\n"); |
@@ -92,126 +244,94 @@ static int resume_device(struct device * dev) | |||
92 | error = dev->class->resume(dev); | 244 | error = dev->class->resume(dev); |
93 | } | 245 | } |
94 | 246 | ||
95 | up(&dev->sem); | ||
96 | |||
97 | TRACE_RESUME(error); | 247 | TRACE_RESUME(error); |
98 | return error; | 248 | return error; |
99 | } | 249 | } |
100 | 250 | ||
101 | 251 | /** | |
102 | static int resume_device_early(struct device * dev) | 252 | * dpm_resume - Resume every device. |
103 | { | 253 | * |
104 | int error = 0; | 254 | * Resume the devices that have either not gone through |
105 | 255 | * the late suspend, or that did go through it but also | |
106 | TRACE_DEVICE(dev); | 256 | * went through the early resume. |
107 | TRACE_RESUME(0); | 257 | * |
108 | if (dev->bus && dev->bus->resume_early) { | 258 | * Take devices from the dpm_off_list, resume them, |
109 | dev_dbg(dev,"EARLY resume\n"); | 259 | * and put them on the dpm_locked list. |
110 | error = dev->bus->resume_early(dev); | ||
111 | } | ||
112 | TRACE_RESUME(error); | ||
113 | return error; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Resume the devices that have either not gone through | ||
118 | * the late suspend, or that did go through it but also | ||
119 | * went through the early resume | ||
120 | */ | 260 | */ |
121 | static void dpm_resume(void) | 261 | static void dpm_resume(void) |
122 | { | 262 | { |
123 | mutex_lock(&dpm_list_mtx); | 263 | mutex_lock(&dpm_list_mtx); |
124 | while(!list_empty(&dpm_off)) { | 264 | while(!list_empty(&dpm_off)) { |
125 | struct list_head * entry = dpm_off.next; | 265 | struct list_head *entry = dpm_off.next; |
126 | struct device * dev = to_device(entry); | 266 | struct device *dev = to_device(entry); |
127 | |||
128 | get_device(dev); | ||
129 | list_move_tail(entry, &dpm_active); | ||
130 | 267 | ||
268 | list_move_tail(entry, &dpm_locked); | ||
131 | mutex_unlock(&dpm_list_mtx); | 269 | mutex_unlock(&dpm_list_mtx); |
132 | resume_device(dev); | 270 | resume_device(dev); |
133 | mutex_lock(&dpm_list_mtx); | 271 | mutex_lock(&dpm_list_mtx); |
134 | put_device(dev); | ||
135 | } | 272 | } |
136 | mutex_unlock(&dpm_list_mtx); | 273 | mutex_unlock(&dpm_list_mtx); |
137 | } | 274 | } |
138 | 275 | ||
139 | |||
140 | /** | 276 | /** |
141 | * device_resume - Restore state of each device in system. | 277 | * unlock_all_devices - Release each device's semaphore |
142 | * | 278 | * |
143 | * Walk the dpm_off list, remove each entry, resume the device, | 279 | * Go through the dpm_off list. Put each device on the dpm_active |
144 | * then add it to the dpm_active list. | 280 | * list and unlock it. |
145 | */ | 281 | */ |
146 | 282 | static void unlock_all_devices(void) | |
147 | void device_resume(void) | ||
148 | { | 283 | { |
149 | might_sleep(); | 284 | mutex_lock(&dpm_list_mtx); |
150 | mutex_lock(&dpm_mtx); | 285 | while (!list_empty(&dpm_locked)) { |
151 | dpm_resume(); | 286 | struct list_head *entry = dpm_locked.prev; |
152 | mutex_unlock(&dpm_mtx); | 287 | struct device *dev = to_device(entry); |
153 | } | ||
154 | |||
155 | EXPORT_SYMBOL_GPL(device_resume); | ||
156 | 288 | ||
289 | list_move(entry, &dpm_active); | ||
290 | up(&dev->sem); | ||
291 | } | ||
292 | mutex_unlock(&dpm_list_mtx); | ||
293 | } | ||
157 | 294 | ||
158 | /** | 295 | /** |
159 | * dpm_power_up - Power on some devices. | 296 | * unregister_dropped_devices - Unregister devices scheduled for removal |
160 | * | ||
161 | * Walk the dpm_off_irq list and power each device up. This | ||
162 | * is used for devices that required they be powered down with | ||
163 | * interrupts disabled. As devices are powered on, they are moved | ||
164 | * to the dpm_active list. | ||
165 | * | 297 | * |
166 | * Interrupts must be disabled when calling this. | 298 | * Unregister all devices on the dpm_destroy list. |
167 | */ | 299 | */ |
168 | 300 | static void unregister_dropped_devices(void) | |
169 | static void dpm_power_up(void) | ||
170 | { | 301 | { |
171 | while(!list_empty(&dpm_off_irq)) { | 302 | mutex_lock(&dpm_list_mtx); |
172 | struct list_head * entry = dpm_off_irq.next; | 303 | while (!list_empty(&dpm_destroy)) { |
173 | struct device * dev = to_device(entry); | 304 | struct list_head *entry = dpm_destroy.next; |
305 | struct device *dev = to_device(entry); | ||
174 | 306 | ||
175 | list_move_tail(entry, &dpm_off); | 307 | up(&dev->sem); |
176 | resume_device_early(dev); | 308 | mutex_unlock(&dpm_list_mtx); |
309 | /* This also removes the device from the list */ | ||
310 | device_unregister(dev); | ||
311 | mutex_lock(&dpm_list_mtx); | ||
177 | } | 312 | } |
313 | mutex_unlock(&dpm_list_mtx); | ||
178 | } | 314 | } |
179 | 315 | ||
180 | |||
181 | /** | 316 | /** |
182 | * device_power_up - Turn on all devices that need special attention. | 317 | * device_resume - Restore state of each device in system. |
183 | * | 318 | * |
184 | * Power on system devices then devices that required we shut them down | 319 | * Resume all the devices, unlock them all, and allow new |
185 | * with interrupts disabled. | 320 | * devices to be registered once again. |
186 | * Called with interrupts disabled. | ||
187 | */ | 321 | */ |
188 | 322 | void device_resume(void) | |
189 | void device_power_up(void) | ||
190 | { | 323 | { |
191 | sysdev_resume(); | 324 | might_sleep(); |
192 | dpm_power_up(); | 325 | dpm_resume(); |
326 | unlock_all_devices(); | ||
327 | unregister_dropped_devices(); | ||
328 | up_write(&pm_sleep_rwsem); | ||
193 | } | 329 | } |
194 | 330 | EXPORT_SYMBOL_GPL(device_resume); | |
195 | EXPORT_SYMBOL_GPL(device_power_up); | ||
196 | 331 | ||
197 | 332 | ||
198 | /*------------------------- Suspend routines -------------------------*/ | 333 | /*------------------------- Suspend routines -------------------------*/ |
199 | 334 | ||
200 | /* | ||
201 | * The entries in the dpm_active list are in a depth first order, simply | ||
202 | * because children are guaranteed to be discovered after parents, and | ||
203 | * are inserted at the back of the list on discovery. | ||
204 | * | ||
205 | * All list on the suspend path are done in reverse order, so we operate | ||
206 | * on the leaves of the device tree (or forests, depending on how you want | ||
207 | * to look at it ;) first. As nodes are removed from the back of the list, | ||
208 | * they are inserted into the front of their destintation lists. | ||
209 | * | ||
210 | * Things are the reverse on the resume path - iterations are done in | ||
211 | * forward order, and nodes are inserted at the back of their destination | ||
212 | * lists. This way, the ancestors will be accessed before their descendents. | ||
213 | */ | ||
214 | |||
215 | static inline char *suspend_verb(u32 event) | 335 | static inline char *suspend_verb(u32 event) |
216 | { | 336 | { |
217 | switch (event) { | 337 | switch (event) { |
@@ -222,7 +342,6 @@ static inline char *suspend_verb(u32 event) | |||
222 | } | 342 | } |
223 | } | 343 | } |
224 | 344 | ||
225 | |||
226 | static void | 345 | static void |
227 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | 346 | suspend_device_dbg(struct device *dev, pm_message_t state, char *info) |
228 | { | 347 | { |
@@ -232,16 +351,73 @@ suspend_device_dbg(struct device *dev, pm_message_t state, char *info) | |||
232 | } | 351 | } |
233 | 352 | ||
234 | /** | 353 | /** |
235 | * suspend_device - Save state of one device. | 354 | * suspend_device_late - Shut down one device (late suspend). |
236 | * @dev: Device. | 355 | * @dev: Device. |
237 | * @state: Power state device is entering. | 356 | * @state: Power state device is entering. |
357 | * | ||
358 | * This is called with interrupts off and only a single CPU running. | ||
238 | */ | 359 | */ |
360 | static int suspend_device_late(struct device *dev, pm_message_t state) | ||
361 | { | ||
362 | int error = 0; | ||
239 | 363 | ||
240 | static int suspend_device(struct device * dev, pm_message_t state) | 364 | if (dev->bus && dev->bus->suspend_late) { |
365 | suspend_device_dbg(dev, state, "LATE "); | ||
366 | error = dev->bus->suspend_late(dev, state); | ||
367 | suspend_report_result(dev->bus->suspend_late, error); | ||
368 | } | ||
369 | return error; | ||
370 | } | ||
371 | |||
372 | /** | ||
373 | * device_power_down - Shut down special devices. | ||
374 | * @state: Power state to enter. | ||
375 | * | ||
376 | * Power down devices that require interrupts to be disabled | ||
377 | * and move them from the dpm_off list to the dpm_off_irq list. | ||
378 | * Then power down system devices. | ||
379 | * | ||
380 | * Must be called with interrupts disabled and only one CPU running. | ||
381 | */ | ||
382 | int device_power_down(pm_message_t state) | ||
383 | { | ||
384 | int error = 0; | ||
385 | |||
386 | while (!list_empty(&dpm_off)) { | ||
387 | struct list_head *entry = dpm_off.prev; | ||
388 | struct device *dev = to_device(entry); | ||
389 | |||
390 | list_del_init(&dev->power.entry); | ||
391 | error = suspend_device_late(dev, state); | ||
392 | if (error) { | ||
393 | printk(KERN_ERR "Could not power down device %s: " | ||
394 | "error %d\n", | ||
395 | kobject_name(&dev->kobj), error); | ||
396 | if (list_empty(&dev->power.entry)) | ||
397 | list_add(&dev->power.entry, &dpm_off); | ||
398 | break; | ||
399 | } | ||
400 | if (list_empty(&dev->power.entry)) | ||
401 | list_add(&dev->power.entry, &dpm_off_irq); | ||
402 | } | ||
403 | |||
404 | if (!error) | ||
405 | error = sysdev_suspend(state); | ||
406 | if (error) | ||
407 | dpm_power_up(); | ||
408 | return error; | ||
409 | } | ||
410 | EXPORT_SYMBOL_GPL(device_power_down); | ||
411 | |||
412 | /** | ||
413 | * suspend_device - Save state of one device. | ||
414 | * @dev: Device. | ||
415 | * @state: Power state device is entering. | ||
416 | */ | ||
417 | int suspend_device(struct device *dev, pm_message_t state) | ||
241 | { | 418 | { |
242 | int error = 0; | 419 | int error = 0; |
243 | 420 | ||
244 | down(&dev->sem); | ||
245 | if (dev->power.power_state.event) { | 421 | if (dev->power.power_state.event) { |
246 | dev_dbg(dev, "PM: suspend %d-->%d\n", | 422 | dev_dbg(dev, "PM: suspend %d-->%d\n", |
247 | dev->power.power_state.event, state.event); | 423 | dev->power.power_state.event, state.event); |
@@ -264,123 +440,105 @@ static int suspend_device(struct device * dev, pm_message_t state) | |||
264 | error = dev->bus->suspend(dev, state); | 440 | error = dev->bus->suspend(dev, state); |
265 | suspend_report_result(dev->bus->suspend, error); | 441 | suspend_report_result(dev->bus->suspend, error); |
266 | } | 442 | } |
267 | up(&dev->sem); | ||
268 | return error; | ||
269 | } | ||
270 | |||
271 | |||
272 | /* | ||
273 | * This is called with interrupts off, only a single CPU | ||
274 | * running. We can't acquire a mutex or semaphore (and we don't | ||
275 | * need the protection) | ||
276 | */ | ||
277 | static int suspend_device_late(struct device *dev, pm_message_t state) | ||
278 | { | ||
279 | int error = 0; | ||
280 | |||
281 | if (dev->bus && dev->bus->suspend_late) { | ||
282 | suspend_device_dbg(dev, state, "LATE "); | ||
283 | error = dev->bus->suspend_late(dev, state); | ||
284 | suspend_report_result(dev->bus->suspend_late, error); | ||
285 | } | ||
286 | return error; | 443 | return error; |
287 | } | 444 | } |
288 | 445 | ||
289 | /** | 446 | /** |
290 | * device_suspend - Save state and stop all devices in system. | 447 | * dpm_suspend - Suspend every device. |
291 | * @state: Power state to put each device in. | 448 | * @state: Power state to put each device in. |
292 | * | 449 | * |
293 | * Walk the dpm_active list, call ->suspend() for each device, and move | 450 | * Walk the dpm_locked list. Suspend each device and move it |
294 | * it to the dpm_off list. | 451 | * to the dpm_off list. |
295 | * | 452 | * |
296 | * (For historical reasons, if it returns -EAGAIN, that used to mean | 453 | * (For historical reasons, if it returns -EAGAIN, that used to mean |
297 | * that the device would be called again with interrupts disabled. | 454 | * that the device would be called again with interrupts disabled. |
298 | * These days, we use the "suspend_late()" callback for that, so we | 455 | * These days, we use the "suspend_late()" callback for that, so we |
299 | * print a warning and consider it an error). | 456 | * print a warning and consider it an error). |
300 | * | ||
301 | * If we get a different error, try and back out. | ||
302 | * | ||
303 | * If we hit a failure with any of the devices, call device_resume() | ||
304 | * above to bring the suspended devices back to life. | ||
305 | * | ||
306 | */ | 457 | */ |
307 | 458 | static int dpm_suspend(pm_message_t state) | |
308 | int device_suspend(pm_message_t state) | ||
309 | { | 459 | { |
310 | int error = 0; | 460 | int error = 0; |
311 | 461 | ||
312 | might_sleep(); | ||
313 | mutex_lock(&dpm_mtx); | ||
314 | mutex_lock(&dpm_list_mtx); | 462 | mutex_lock(&dpm_list_mtx); |
315 | while (!list_empty(&dpm_active) && error == 0) { | 463 | while (!list_empty(&dpm_locked)) { |
316 | struct list_head * entry = dpm_active.prev; | 464 | struct list_head *entry = dpm_locked.prev; |
317 | struct device * dev = to_device(entry); | 465 | struct device *dev = to_device(entry); |
318 | 466 | ||
319 | get_device(dev); | 467 | list_del_init(&dev->power.entry); |
320 | mutex_unlock(&dpm_list_mtx); | 468 | mutex_unlock(&dpm_list_mtx); |
321 | |||
322 | error = suspend_device(dev, state); | 469 | error = suspend_device(dev, state); |
323 | 470 | if (error) { | |
324 | mutex_lock(&dpm_list_mtx); | ||
325 | |||
326 | /* Check if the device got removed */ | ||
327 | if (!list_empty(&dev->power.entry)) { | ||
328 | /* Move it to the dpm_off list */ | ||
329 | if (!error) | ||
330 | list_move(&dev->power.entry, &dpm_off); | ||
331 | } | ||
332 | if (error) | ||
333 | printk(KERN_ERR "Could not suspend device %s: " | 471 | printk(KERN_ERR "Could not suspend device %s: " |
334 | "error %d%s\n", | 472 | "error %d%s\n", |
335 | kobject_name(&dev->kobj), error, | 473 | kobject_name(&dev->kobj), |
336 | error == -EAGAIN ? " (please convert to suspend_late)" : ""); | 474 | error, |
337 | put_device(dev); | 475 | (error == -EAGAIN ? |
476 | " (please convert to suspend_late)" : | ||
477 | "")); | ||
478 | mutex_lock(&dpm_list_mtx); | ||
479 | if (list_empty(&dev->power.entry)) | ||
480 | list_add(&dev->power.entry, &dpm_locked); | ||
481 | mutex_unlock(&dpm_list_mtx); | ||
482 | break; | ||
483 | } | ||
484 | mutex_lock(&dpm_list_mtx); | ||
485 | if (list_empty(&dev->power.entry)) | ||
486 | list_add(&dev->power.entry, &dpm_off); | ||
338 | } | 487 | } |
339 | mutex_unlock(&dpm_list_mtx); | 488 | mutex_unlock(&dpm_list_mtx); |
340 | if (error) | ||
341 | dpm_resume(); | ||
342 | 489 | ||
343 | mutex_unlock(&dpm_mtx); | ||
344 | return error; | 490 | return error; |
345 | } | 491 | } |
346 | 492 | ||
347 | EXPORT_SYMBOL_GPL(device_suspend); | ||
348 | |||
349 | /** | 493 | /** |
350 | * device_power_down - Shut down special devices. | 494 | * lock_all_devices - Acquire every device's semaphore |
351 | * @state: Power state to enter. | ||
352 | * | 495 | * |
353 | * Walk the dpm_off_irq list, calling ->power_down() for each device that | 496 | * Go through the dpm_active list. Carefully lock each device's |
354 | * couldn't power down the device with interrupts enabled. When we're | 497 | * semaphore and put it in on the dpm_locked list. |
355 | * done, power down system devices. | ||
356 | */ | 498 | */ |
357 | 499 | static void lock_all_devices(void) | |
358 | int device_power_down(pm_message_t state) | ||
359 | { | 500 | { |
360 | int error = 0; | 501 | mutex_lock(&dpm_list_mtx); |
361 | struct device * dev; | 502 | while (!list_empty(&dpm_active)) { |
503 | struct list_head *entry = dpm_active.next; | ||
504 | struct device *dev = to_device(entry); | ||
362 | 505 | ||
363 | while (!list_empty(&dpm_off)) { | 506 | /* Required locking order is dev->sem first, |
364 | struct list_head * entry = dpm_off.prev; | 507 | * then dpm_list_mutex. Hence this awkward code. |
508 | */ | ||
509 | get_device(dev); | ||
510 | mutex_unlock(&dpm_list_mtx); | ||
511 | down(&dev->sem); | ||
512 | mutex_lock(&dpm_list_mtx); | ||
365 | 513 | ||
366 | dev = to_device(entry); | 514 | if (list_empty(entry)) |
367 | error = suspend_device_late(dev, state); | 515 | up(&dev->sem); /* Device was removed */ |
368 | if (error) | 516 | else |
369 | goto Error; | 517 | list_move_tail(entry, &dpm_locked); |
370 | list_move(&dev->power.entry, &dpm_off_irq); | 518 | put_device(dev); |
371 | } | 519 | } |
520 | mutex_unlock(&dpm_list_mtx); | ||
521 | } | ||
522 | |||
523 | /** | ||
524 | * device_suspend - Save state and stop all devices in system. | ||
525 | * | ||
526 | * Prevent new devices from being registered, then lock all devices | ||
527 | * and suspend them. | ||
528 | */ | ||
529 | int device_suspend(pm_message_t state) | ||
530 | { | ||
531 | int error; | ||
372 | 532 | ||
373 | error = sysdev_suspend(state); | 533 | might_sleep(); |
374 | Done: | 534 | down_write(&pm_sleep_rwsem); |
535 | lock_all_devices(); | ||
536 | error = dpm_suspend(state); | ||
537 | if (error) | ||
538 | device_resume(); | ||
375 | return error; | 539 | return error; |
376 | Error: | ||
377 | printk(KERN_ERR "Could not power down device %s: " | ||
378 | "error %d\n", kobject_name(&dev->kobj), error); | ||
379 | dpm_power_up(); | ||
380 | goto Done; | ||
381 | } | 540 | } |
382 | 541 | EXPORT_SYMBOL_GPL(device_suspend); | |
383 | EXPORT_SYMBOL_GPL(device_power_down); | ||
384 | 542 | ||
385 | void __suspend_report_result(const char *function, void *fn, int ret) | 543 | void __suspend_report_result(const char *function, void *fn, int ret) |
386 | { | 544 | { |
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 379da4e958e0..6f0dfca8ebdd 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -1,10 +1,3 @@ | |||
1 | /* | ||
2 | * shutdown.c | ||
3 | */ | ||
4 | |||
5 | extern void device_shutdown(void); | ||
6 | |||
7 | |||
8 | #ifdef CONFIG_PM_SLEEP | 1 | #ifdef CONFIG_PM_SLEEP |
9 | 2 | ||
10 | /* | 3 | /* |
@@ -20,6 +13,9 @@ static inline struct device *to_device(struct list_head *entry) | |||
20 | 13 | ||
21 | extern void device_pm_add(struct device *); | 14 | extern void device_pm_add(struct device *); |
22 | extern void device_pm_remove(struct device *); | 15 | extern void device_pm_remove(struct device *); |
16 | extern void device_pm_schedule_removal(struct device *); | ||
17 | extern int pm_sleep_lock(void); | ||
18 | extern void pm_sleep_unlock(void); | ||
23 | 19 | ||
24 | #else /* CONFIG_PM_SLEEP */ | 20 | #else /* CONFIG_PM_SLEEP */ |
25 | 21 | ||
@@ -32,6 +28,15 @@ static inline void device_pm_remove(struct device *dev) | |||
32 | { | 28 | { |
33 | } | 29 | } |
34 | 30 | ||
31 | static inline int pm_sleep_lock(void) | ||
32 | { | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static inline void pm_sleep_unlock(void) | ||
37 | { | ||
38 | } | ||
39 | |||
35 | #endif | 40 | #endif |
36 | 41 | ||
37 | #ifdef CONFIG_PM | 42 | #ifdef CONFIG_PM |
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c deleted file mode 100644 index 56e8eaaac012..000000000000 --- a/drivers/base/power/shutdown.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * shutdown.c - power management functions for the device tree. | ||
3 | * | ||
4 | * Copyright (c) 2002-3 Patrick Mochel | ||
5 | * 2002-3 Open Source Development Lab | ||
6 | * | ||
7 | * This file is released under the GPLv2 | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/device.h> | ||
12 | #include <asm/semaphore.h> | ||
13 | |||
14 | #include "../base.h" | ||
15 | #include "power.h" | ||
16 | |||
17 | #define to_dev(node) container_of(node, struct device, kobj.entry) | ||
18 | |||
19 | |||
20 | /** | ||
21 | * We handle system devices differently - we suspend and shut them | ||
22 | * down last and resume them first. That way, we don't do anything stupid like | ||
23 | * shutting down the interrupt controller before any devices.. | ||
24 | * | ||
25 | * Note that there are not different stages for power management calls - | ||
26 | * they only get one called once when interrupts are disabled. | ||
27 | */ | ||
28 | |||
29 | |||
30 | /** | ||
31 | * device_shutdown - call ->shutdown() on each device to shutdown. | ||
32 | */ | ||
33 | void device_shutdown(void) | ||
34 | { | ||
35 | struct device * dev, *devn; | ||
36 | |||
37 | list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.list, | ||
38 | kobj.entry) { | ||
39 | if (dev->bus && dev->bus->shutdown) { | ||
40 | dev_dbg(dev, "shutdown\n"); | ||
41 | dev->bus->shutdown(dev); | ||
42 | } else if (dev->driver && dev->driver->shutdown) { | ||
43 | dev_dbg(dev, "shutdown\n"); | ||
44 | dev->driver->shutdown(dev); | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index ac7ff6d0c6e5..2f79c55acdcc 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
@@ -25,8 +25,6 @@ | |||
25 | 25 | ||
26 | #include "base.h" | 26 | #include "base.h" |
27 | 27 | ||
28 | extern struct kset devices_subsys; | ||
29 | |||
30 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | 28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) |
31 | #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) | 29 | #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) |
32 | 30 | ||
@@ -128,18 +126,17 @@ void sysdev_class_remove_file(struct sysdev_class *c, | |||
128 | } | 126 | } |
129 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); | 127 | EXPORT_SYMBOL_GPL(sysdev_class_remove_file); |
130 | 128 | ||
131 | /* | 129 | static struct kset *system_kset; |
132 | * declare system_subsys | ||
133 | */ | ||
134 | static decl_subsys(system, &ktype_sysdev_class, NULL); | ||
135 | 130 | ||
136 | int sysdev_class_register(struct sysdev_class * cls) | 131 | int sysdev_class_register(struct sysdev_class * cls) |
137 | { | 132 | { |
138 | pr_debug("Registering sysdev class '%s'\n", | 133 | pr_debug("Registering sysdev class '%s'\n", |
139 | kobject_name(&cls->kset.kobj)); | 134 | kobject_name(&cls->kset.kobj)); |
140 | INIT_LIST_HEAD(&cls->drivers); | 135 | INIT_LIST_HEAD(&cls->drivers); |
141 | cls->kset.kobj.parent = &system_subsys.kobj; | 136 | cls->kset.kobj.parent = &system_kset->kobj; |
142 | cls->kset.kobj.kset = &system_subsys; | 137 | cls->kset.kobj.ktype = &ktype_sysdev_class; |
138 | cls->kset.kobj.kset = system_kset; | ||
139 | kobject_set_name(&cls->kset.kobj, cls->name); | ||
143 | return kset_register(&cls->kset); | 140 | return kset_register(&cls->kset); |
144 | } | 141 | } |
145 | 142 | ||
@@ -228,20 +225,15 @@ int sysdev_register(struct sys_device * sysdev) | |||
228 | if (!cls) | 225 | if (!cls) |
229 | return -EINVAL; | 226 | return -EINVAL; |
230 | 227 | ||
228 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | ||
229 | |||
231 | /* Make sure the kset is set */ | 230 | /* Make sure the kset is set */ |
232 | sysdev->kobj.kset = &cls->kset; | 231 | sysdev->kobj.kset = &cls->kset; |
233 | 232 | ||
234 | /* But make sure we point to the right type for sysfs translation */ | ||
235 | sysdev->kobj.ktype = &ktype_sysdev; | ||
236 | error = kobject_set_name(&sysdev->kobj, "%s%d", | ||
237 | kobject_name(&cls->kset.kobj), sysdev->id); | ||
238 | if (error) | ||
239 | return error; | ||
240 | |||
241 | pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj)); | ||
242 | |||
243 | /* Register the object */ | 233 | /* Register the object */ |
244 | error = kobject_register(&sysdev->kobj); | 234 | error = kobject_init_and_add(&sysdev->kobj, &ktype_sysdev, NULL, |
235 | "%s%d", kobject_name(&cls->kset.kobj), | ||
236 | sysdev->id); | ||
245 | 237 | ||
246 | if (!error) { | 238 | if (!error) { |
247 | struct sysdev_driver * drv; | 239 | struct sysdev_driver * drv; |
@@ -258,6 +250,7 @@ int sysdev_register(struct sys_device * sysdev) | |||
258 | } | 250 | } |
259 | mutex_unlock(&sysdev_drivers_lock); | 251 | mutex_unlock(&sysdev_drivers_lock); |
260 | } | 252 | } |
253 | kobject_uevent(&sysdev->kobj, KOBJ_ADD); | ||
261 | return error; | 254 | return error; |
262 | } | 255 | } |
263 | 256 | ||
@@ -272,7 +265,7 @@ void sysdev_unregister(struct sys_device * sysdev) | |||
272 | } | 265 | } |
273 | mutex_unlock(&sysdev_drivers_lock); | 266 | mutex_unlock(&sysdev_drivers_lock); |
274 | 267 | ||
275 | kobject_unregister(&sysdev->kobj); | 268 | kobject_put(&sysdev->kobj); |
276 | } | 269 | } |
277 | 270 | ||
278 | 271 | ||
@@ -298,8 +291,7 @@ void sysdev_shutdown(void) | |||
298 | pr_debug("Shutting Down System Devices\n"); | 291 | pr_debug("Shutting Down System Devices\n"); |
299 | 292 | ||
300 | mutex_lock(&sysdev_drivers_lock); | 293 | mutex_lock(&sysdev_drivers_lock); |
301 | list_for_each_entry_reverse(cls, &system_subsys.list, | 294 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
302 | kset.kobj.entry) { | ||
303 | struct sys_device * sysdev; | 295 | struct sys_device * sysdev; |
304 | 296 | ||
305 | pr_debug("Shutting down type '%s':\n", | 297 | pr_debug("Shutting down type '%s':\n", |
@@ -361,9 +353,7 @@ int sysdev_suspend(pm_message_t state) | |||
361 | 353 | ||
362 | pr_debug("Suspending System Devices\n"); | 354 | pr_debug("Suspending System Devices\n"); |
363 | 355 | ||
364 | list_for_each_entry_reverse(cls, &system_subsys.list, | 356 | list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) { |
365 | kset.kobj.entry) { | ||
366 | |||
367 | pr_debug("Suspending type '%s':\n", | 357 | pr_debug("Suspending type '%s':\n", |
368 | kobject_name(&cls->kset.kobj)); | 358 | kobject_name(&cls->kset.kobj)); |
369 | 359 | ||
@@ -414,8 +404,7 @@ aux_driver: | |||
414 | } | 404 | } |
415 | 405 | ||
416 | /* resume other classes */ | 406 | /* resume other classes */ |
417 | list_for_each_entry_continue(cls, &system_subsys.list, | 407 | list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) { |
418 | kset.kobj.entry) { | ||
419 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { | 408 | list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { |
420 | pr_debug(" %s\n", kobject_name(&err_dev->kobj)); | 409 | pr_debug(" %s\n", kobject_name(&err_dev->kobj)); |
421 | __sysdev_resume(err_dev); | 410 | __sysdev_resume(err_dev); |
@@ -440,7 +429,7 @@ int sysdev_resume(void) | |||
440 | 429 | ||
441 | pr_debug("Resuming System Devices\n"); | 430 | pr_debug("Resuming System Devices\n"); |
442 | 431 | ||
443 | list_for_each_entry(cls, &system_subsys.list, kset.kobj.entry) { | 432 | list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) { |
444 | struct sys_device * sysdev; | 433 | struct sys_device * sysdev; |
445 | 434 | ||
446 | pr_debug("Resuming type '%s':\n", | 435 | pr_debug("Resuming type '%s':\n", |
@@ -458,8 +447,10 @@ int sysdev_resume(void) | |||
458 | 447 | ||
459 | int __init system_bus_init(void) | 448 | int __init system_bus_init(void) |
460 | { | 449 | { |
461 | system_subsys.kobj.parent = &devices_subsys.kobj; | 450 | system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj); |
462 | return subsystem_register(&system_subsys); | 451 | if (!system_kset) |
452 | return -ENOMEM; | ||
453 | return 0; | ||
463 | } | 454 | } |
464 | 455 | ||
465 | EXPORT_SYMBOL_GPL(sysdev_register); | 456 | EXPORT_SYMBOL_GPL(sysdev_register); |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index ad00b3d94711..826d12381e21 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -15,8 +15,10 @@ | |||
15 | 15 | ||
16 | static struct kmem_cache *buf_pool_cache; | 16 | static struct kmem_cache *buf_pool_cache; |
17 | 17 | ||
18 | static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) | 18 | static ssize_t aoedisk_show_state(struct device *dev, |
19 | struct device_attribute *attr, char *page) | ||
19 | { | 20 | { |
21 | struct gendisk *disk = dev_to_disk(dev); | ||
20 | struct aoedev *d = disk->private_data; | 22 | struct aoedev *d = disk->private_data; |
21 | 23 | ||
22 | return snprintf(page, PAGE_SIZE, | 24 | return snprintf(page, PAGE_SIZE, |
@@ -26,50 +28,47 @@ static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) | |||
26 | (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : ""); | 28 | (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : ""); |
27 | /* I'd rather see nopen exported so we can ditch closewait */ | 29 | /* I'd rather see nopen exported so we can ditch closewait */ |
28 | } | 30 | } |
29 | static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page) | 31 | static ssize_t aoedisk_show_mac(struct device *dev, |
32 | struct device_attribute *attr, char *page) | ||
30 | { | 33 | { |
34 | struct gendisk *disk = dev_to_disk(dev); | ||
31 | struct aoedev *d = disk->private_data; | 35 | struct aoedev *d = disk->private_data; |
32 | 36 | ||
33 | return snprintf(page, PAGE_SIZE, "%012llx\n", | 37 | return snprintf(page, PAGE_SIZE, "%012llx\n", |
34 | (unsigned long long)mac_addr(d->addr)); | 38 | (unsigned long long)mac_addr(d->addr)); |
35 | } | 39 | } |
36 | static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page) | 40 | static ssize_t aoedisk_show_netif(struct device *dev, |
41 | struct device_attribute *attr, char *page) | ||
37 | { | 42 | { |
43 | struct gendisk *disk = dev_to_disk(dev); | ||
38 | struct aoedev *d = disk->private_data; | 44 | struct aoedev *d = disk->private_data; |
39 | 45 | ||
40 | return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name); | 46 | return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name); |
41 | } | 47 | } |
42 | /* firmware version */ | 48 | /* firmware version */ |
43 | static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page) | 49 | static ssize_t aoedisk_show_fwver(struct device *dev, |
50 | struct device_attribute *attr, char *page) | ||
44 | { | 51 | { |
52 | struct gendisk *disk = dev_to_disk(dev); | ||
45 | struct aoedev *d = disk->private_data; | 53 | struct aoedev *d = disk->private_data; |
46 | 54 | ||
47 | return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver); | 55 | return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver); |
48 | } | 56 | } |
49 | 57 | ||
50 | static struct disk_attribute disk_attr_state = { | 58 | static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL); |
51 | .attr = {.name = "state", .mode = S_IRUGO }, | 59 | static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL); |
52 | .show = aoedisk_show_state | 60 | static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL); |
53 | }; | 61 | static struct device_attribute dev_attr_firmware_version = { |
54 | static struct disk_attribute disk_attr_mac = { | 62 | .attr = { .name = "firmware-version", .mode = S_IRUGO, .owner = THIS_MODULE }, |
55 | .attr = {.name = "mac", .mode = S_IRUGO }, | 63 | .show = aoedisk_show_fwver, |
56 | .show = aoedisk_show_mac | ||
57 | }; | ||
58 | static struct disk_attribute disk_attr_netif = { | ||
59 | .attr = {.name = "netif", .mode = S_IRUGO }, | ||
60 | .show = aoedisk_show_netif | ||
61 | }; | ||
62 | static struct disk_attribute disk_attr_fwver = { | ||
63 | .attr = {.name = "firmware-version", .mode = S_IRUGO }, | ||
64 | .show = aoedisk_show_fwver | ||
65 | }; | 64 | }; |
66 | 65 | ||
67 | static struct attribute *aoe_attrs[] = { | 66 | static struct attribute *aoe_attrs[] = { |
68 | &disk_attr_state.attr, | 67 | &dev_attr_state.attr, |
69 | &disk_attr_mac.attr, | 68 | &dev_attr_mac.attr, |
70 | &disk_attr_netif.attr, | 69 | &dev_attr_netif.attr, |
71 | &disk_attr_fwver.attr, | 70 | &dev_attr_firmware_version.attr, |
72 | NULL | 71 | NULL, |
73 | }; | 72 | }; |
74 | 73 | ||
75 | static const struct attribute_group attr_group = { | 74 | static const struct attribute_group attr_group = { |
@@ -79,12 +78,12 @@ static const struct attribute_group attr_group = { | |||
79 | static int | 78 | static int |
80 | aoedisk_add_sysfs(struct aoedev *d) | 79 | aoedisk_add_sysfs(struct aoedev *d) |
81 | { | 80 | { |
82 | return sysfs_create_group(&d->gd->kobj, &attr_group); | 81 | return sysfs_create_group(&d->gd->dev.kobj, &attr_group); |
83 | } | 82 | } |
84 | void | 83 | void |
85 | aoedisk_rm_sysfs(struct aoedev *d) | 84 | aoedisk_rm_sysfs(struct aoedev *d) |
86 | { | 85 | { |
87 | sysfs_remove_group(&d->gd->kobj, &attr_group); | 86 | sysfs_remove_group(&d->gd->dev.kobj, &attr_group); |
88 | } | 87 | } |
89 | 88 | ||
90 | static int | 89 | static int |
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 39e563ea0878..d5480e34cb22 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -259,9 +259,8 @@ aoechr_init(void) | |||
259 | return PTR_ERR(aoe_class); | 259 | return PTR_ERR(aoe_class); |
260 | } | 260 | } |
261 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) | 261 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) |
262 | class_device_create(aoe_class, NULL, | 262 | device_create(aoe_class, NULL, |
263 | MKDEV(AOE_MAJOR, chardevs[i].minor), | 263 | MKDEV(AOE_MAJOR, chardevs[i].minor), chardevs[i].name); |
264 | NULL, chardevs[i].name); | ||
265 | 264 | ||
266 | return 0; | 265 | return 0; |
267 | } | 266 | } |
@@ -272,7 +271,7 @@ aoechr_exit(void) | |||
272 | int i; | 271 | int i; |
273 | 272 | ||
274 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) | 273 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) |
275 | class_device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor)); | 274 | device_destroy(aoe_class, MKDEV(AOE_MAJOR, chardevs[i].minor)); |
276 | class_destroy(aoe_class); | 275 | class_destroy(aoe_class); |
277 | unregister_chrdev(AOE_MAJOR, "aoechr"); | 276 | unregister_chrdev(AOE_MAJOR, "aoechr"); |
278 | } | 277 | } |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index b4c0888aedc3..ba9b17e507e0 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -375,14 +375,17 @@ harderror: | |||
375 | return NULL; | 375 | return NULL; |
376 | } | 376 | } |
377 | 377 | ||
378 | static ssize_t pid_show(struct gendisk *disk, char *page) | 378 | static ssize_t pid_show(struct device *dev, |
379 | struct device_attribute *attr, char *buf) | ||
379 | { | 380 | { |
380 | return sprintf(page, "%ld\n", | 381 | struct gendisk *disk = dev_to_disk(dev); |
382 | |||
383 | return sprintf(buf, "%ld\n", | ||
381 | (long) ((struct nbd_device *)disk->private_data)->pid); | 384 | (long) ((struct nbd_device *)disk->private_data)->pid); |
382 | } | 385 | } |
383 | 386 | ||
384 | static struct disk_attribute pid_attr = { | 387 | static struct device_attribute pid_attr = { |
385 | .attr = { .name = "pid", .mode = S_IRUGO }, | 388 | .attr = { .name = "pid", .mode = S_IRUGO, .owner = THIS_MODULE }, |
386 | .show = pid_show, | 389 | .show = pid_show, |
387 | }; | 390 | }; |
388 | 391 | ||
@@ -394,7 +397,7 @@ static int nbd_do_it(struct nbd_device *lo) | |||
394 | BUG_ON(lo->magic != LO_MAGIC); | 397 | BUG_ON(lo->magic != LO_MAGIC); |
395 | 398 | ||
396 | lo->pid = current->pid; | 399 | lo->pid = current->pid; |
397 | ret = sysfs_create_file(&lo->disk->kobj, &pid_attr.attr); | 400 | ret = sysfs_create_file(&lo->disk->dev.kobj, &pid_attr.attr); |
398 | if (ret) { | 401 | if (ret) { |
399 | printk(KERN_ERR "nbd: sysfs_create_file failed!"); | 402 | printk(KERN_ERR "nbd: sysfs_create_file failed!"); |
400 | return ret; | 403 | return ret; |
@@ -403,7 +406,7 @@ static int nbd_do_it(struct nbd_device *lo) | |||
403 | while ((req = nbd_read_stat(lo)) != NULL) | 406 | while ((req = nbd_read_stat(lo)) != NULL) |
404 | nbd_end_request(req); | 407 | nbd_end_request(req); |
405 | 408 | ||
406 | sysfs_remove_file(&lo->disk->kobj, &pid_attr.attr); | 409 | sysfs_remove_file(&lo->disk->dev.kobj, &pid_attr.attr); |
407 | return 0; | 410 | return 0; |
408 | } | 411 | } |
409 | 412 | ||
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index d89e7d32a3b6..ab86e23ddc69 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c | |||
@@ -676,8 +676,8 @@ static int __init pg_init(void) | |||
676 | for (unit = 0; unit < PG_UNITS; unit++) { | 676 | for (unit = 0; unit < PG_UNITS; unit++) { |
677 | struct pg *dev = &devices[unit]; | 677 | struct pg *dev = &devices[unit]; |
678 | if (dev->present) | 678 | if (dev->present) |
679 | class_device_create(pg_class, NULL, MKDEV(major, unit), | 679 | device_create(pg_class, NULL, MKDEV(major, unit), |
680 | NULL, "pg%u", unit); | 680 | "pg%u", unit); |
681 | } | 681 | } |
682 | err = 0; | 682 | err = 0; |
683 | goto out; | 683 | goto out; |
@@ -695,7 +695,7 @@ static void __exit pg_exit(void) | |||
695 | for (unit = 0; unit < PG_UNITS; unit++) { | 695 | for (unit = 0; unit < PG_UNITS; unit++) { |
696 | struct pg *dev = &devices[unit]; | 696 | struct pg *dev = &devices[unit]; |
697 | if (dev->present) | 697 | if (dev->present) |
698 | class_device_destroy(pg_class, MKDEV(major, unit)); | 698 | device_destroy(pg_class, MKDEV(major, unit)); |
699 | } | 699 | } |
700 | class_destroy(pg_class); | 700 | class_destroy(pg_class); |
701 | unregister_chrdev(major, name); | 701 | unregister_chrdev(major, name); |
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index b91accf12656..76096cad798f 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c | |||
@@ -972,10 +972,10 @@ static int __init pt_init(void) | |||
972 | 972 | ||
973 | for (unit = 0; unit < PT_UNITS; unit++) | 973 | for (unit = 0; unit < PT_UNITS; unit++) |
974 | if (pt[unit].present) { | 974 | if (pt[unit].present) { |
975 | class_device_create(pt_class, NULL, MKDEV(major, unit), | 975 | device_create(pt_class, NULL, MKDEV(major, unit), |
976 | NULL, "pt%d", unit); | 976 | "pt%d", unit); |
977 | class_device_create(pt_class, NULL, MKDEV(major, unit + 128), | 977 | device_create(pt_class, NULL, MKDEV(major, unit + 128), |
978 | NULL, "pt%dn", unit); | 978 | "pt%dn", unit); |
979 | } | 979 | } |
980 | goto out; | 980 | goto out; |
981 | 981 | ||
@@ -990,8 +990,8 @@ static void __exit pt_exit(void) | |||
990 | int unit; | 990 | int unit; |
991 | for (unit = 0; unit < PT_UNITS; unit++) | 991 | for (unit = 0; unit < PT_UNITS; unit++) |
992 | if (pt[unit].present) { | 992 | if (pt[unit].present) { |
993 | class_device_destroy(pt_class, MKDEV(major, unit)); | 993 | device_destroy(pt_class, MKDEV(major, unit)); |
994 | class_device_destroy(pt_class, MKDEV(major, unit + 128)); | 994 | device_destroy(pt_class, MKDEV(major, unit + 128)); |
995 | } | 995 | } |
996 | class_destroy(pt_class); | 996 | class_destroy(pt_class); |
997 | unregister_chrdev(major, name); | 997 | unregister_chrdev(major, name); |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3535ef896677..e9de1712e5a0 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -110,17 +110,18 @@ static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd, | |||
110 | struct kobj_type* ktype) | 110 | struct kobj_type* ktype) |
111 | { | 111 | { |
112 | struct pktcdvd_kobj *p; | 112 | struct pktcdvd_kobj *p; |
113 | int error; | ||
114 | |||
113 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 115 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
114 | if (!p) | 116 | if (!p) |
115 | return NULL; | 117 | return NULL; |
116 | kobject_set_name(&p->kobj, "%s", name); | ||
117 | p->kobj.parent = parent; | ||
118 | p->kobj.ktype = ktype; | ||
119 | p->pd = pd; | 118 | p->pd = pd; |
120 | if (kobject_register(&p->kobj) != 0) { | 119 | error = kobject_init_and_add(&p->kobj, ktype, parent, "%s", name); |
120 | if (error) { | ||
121 | kobject_put(&p->kobj); | 121 | kobject_put(&p->kobj); |
122 | return NULL; | 122 | return NULL; |
123 | } | 123 | } |
124 | kobject_uevent(&p->kobj, KOBJ_ADD); | ||
124 | return p; | 125 | return p; |
125 | } | 126 | } |
126 | /* | 127 | /* |
@@ -129,7 +130,7 @@ static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd, | |||
129 | static void pkt_kobj_remove(struct pktcdvd_kobj *p) | 130 | static void pkt_kobj_remove(struct pktcdvd_kobj *p) |
130 | { | 131 | { |
131 | if (p) | 132 | if (p) |
132 | kobject_unregister(&p->kobj); | 133 | kobject_put(&p->kobj); |
133 | } | 134 | } |
134 | /* | 135 | /* |
135 | * default release function for pktcdvd kernel objects. | 136 | * default release function for pktcdvd kernel objects. |
@@ -301,18 +302,16 @@ static struct kobj_type kobj_pkt_type_wqueue = { | |||
301 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) | 302 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) |
302 | { | 303 | { |
303 | if (class_pktcdvd) { | 304 | if (class_pktcdvd) { |
304 | pd->clsdev = class_device_create(class_pktcdvd, | 305 | pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, "%s", pd->name); |
305 | NULL, pd->pkt_dev, | 306 | if (IS_ERR(pd->dev)) |
306 | NULL, "%s", pd->name); | 307 | pd->dev = NULL; |
307 | if (IS_ERR(pd->clsdev)) | ||
308 | pd->clsdev = NULL; | ||
309 | } | 308 | } |
310 | if (pd->clsdev) { | 309 | if (pd->dev) { |
311 | pd->kobj_stat = pkt_kobj_create(pd, "stat", | 310 | pd->kobj_stat = pkt_kobj_create(pd, "stat", |
312 | &pd->clsdev->kobj, | 311 | &pd->dev->kobj, |
313 | &kobj_pkt_type_stat); | 312 | &kobj_pkt_type_stat); |
314 | pd->kobj_wqueue = pkt_kobj_create(pd, "write_queue", | 313 | pd->kobj_wqueue = pkt_kobj_create(pd, "write_queue", |
315 | &pd->clsdev->kobj, | 314 | &pd->dev->kobj, |
316 | &kobj_pkt_type_wqueue); | 315 | &kobj_pkt_type_wqueue); |
317 | } | 316 | } |
318 | } | 317 | } |
@@ -322,7 +321,7 @@ static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd) | |||
322 | pkt_kobj_remove(pd->kobj_stat); | 321 | pkt_kobj_remove(pd->kobj_stat); |
323 | pkt_kobj_remove(pd->kobj_wqueue); | 322 | pkt_kobj_remove(pd->kobj_wqueue); |
324 | if (class_pktcdvd) | 323 | if (class_pktcdvd) |
325 | class_device_destroy(class_pktcdvd, pd->pkt_dev); | 324 | device_destroy(class_pktcdvd, pd->pkt_dev); |
326 | } | 325 | } |
327 | 326 | ||
328 | 327 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 2e3a0d4bc4c2..466629594776 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -373,6 +373,16 @@ config ISTALLION | |||
373 | To compile this driver as a module, choose M here: the | 373 | To compile this driver as a module, choose M here: the |
374 | module will be called istallion. | 374 | module will be called istallion. |
375 | 375 | ||
376 | config NOZOMI | ||
377 | tristate "HSDPA Broadband Wireless Data Card - Globe Trotter" | ||
378 | depends on PCI && EXPERIMENTAL | ||
379 | help | ||
380 | If you have a HSDPA driver Broadband Wireless Data Card - | ||
381 | Globe Trotter PCMCIA card, say Y here. | ||
382 | |||
383 | To compile this driver as a module, choose M here, the module | ||
384 | will be called nozomi. | ||
385 | |||
376 | config A2232 | 386 | config A2232 |
377 | tristate "Commodore A2232 serial support (EXPERIMENTAL)" | 387 | tristate "Commodore A2232 serial support (EXPERIMENTAL)" |
378 | depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP | 388 | depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 07304d50e0cb..96fc01eddefe 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -26,6 +26,7 @@ obj-$(CONFIG_SERIAL167) += serial167.o | |||
26 | obj-$(CONFIG_CYCLADES) += cyclades.o | 26 | obj-$(CONFIG_CYCLADES) += cyclades.o |
27 | obj-$(CONFIG_STALLION) += stallion.o | 27 | obj-$(CONFIG_STALLION) += stallion.o |
28 | obj-$(CONFIG_ISTALLION) += istallion.o | 28 | obj-$(CONFIG_ISTALLION) += istallion.o |
29 | obj-$(CONFIG_NOZOMI) += nozomi.o | ||
29 | obj-$(CONFIG_DIGIEPCA) += epca.o | 30 | obj-$(CONFIG_DIGIEPCA) += epca.o |
30 | obj-$(CONFIG_SPECIALIX) += specialix.o | 31 | obj-$(CONFIG_SPECIALIX) += specialix.o |
31 | obj-$(CONFIG_MOXA_INTELLIO) += moxa.o | 32 | obj-$(CONFIG_MOXA_INTELLIO) += moxa.o |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 8252f8668538..480fae29c9b2 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/kbd_kern.h> | 28 | #include <linux/kbd_kern.h> |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/kobject.h> | 30 | #include <linux/kref.h> |
31 | #include <linux/kthread.h> | 31 | #include <linux/kthread.h> |
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
@@ -89,7 +89,7 @@ struct hvc_struct { | |||
89 | int irq_requested; | 89 | int irq_requested; |
90 | int irq; | 90 | int irq; |
91 | struct list_head next; | 91 | struct list_head next; |
92 | struct kobject kobj; /* ref count & hvc_struct lifetime */ | 92 | struct kref kref; /* ref count & hvc_struct lifetime */ |
93 | }; | 93 | }; |
94 | 94 | ||
95 | /* dynamic list of hvc_struct instances */ | 95 | /* dynamic list of hvc_struct instances */ |
@@ -110,7 +110,7 @@ static int last_hvc = -1; | |||
110 | 110 | ||
111 | /* | 111 | /* |
112 | * Do not call this function with either the hvc_structs_lock or the hvc_struct | 112 | * Do not call this function with either the hvc_structs_lock or the hvc_struct |
113 | * lock held. If successful, this function increments the kobject reference | 113 | * lock held. If successful, this function increments the kref reference |
114 | * count against the target hvc_struct so it should be released when finished. | 114 | * count against the target hvc_struct so it should be released when finished. |
115 | */ | 115 | */ |
116 | static struct hvc_struct *hvc_get_by_index(int index) | 116 | static struct hvc_struct *hvc_get_by_index(int index) |
@@ -123,7 +123,7 @@ static struct hvc_struct *hvc_get_by_index(int index) | |||
123 | list_for_each_entry(hp, &hvc_structs, next) { | 123 | list_for_each_entry(hp, &hvc_structs, next) { |
124 | spin_lock_irqsave(&hp->lock, flags); | 124 | spin_lock_irqsave(&hp->lock, flags); |
125 | if (hp->index == index) { | 125 | if (hp->index == index) { |
126 | kobject_get(&hp->kobj); | 126 | kref_get(&hp->kref); |
127 | spin_unlock_irqrestore(&hp->lock, flags); | 127 | spin_unlock_irqrestore(&hp->lock, flags); |
128 | spin_unlock(&hvc_structs_lock); | 128 | spin_unlock(&hvc_structs_lock); |
129 | return hp; | 129 | return hp; |
@@ -242,6 +242,23 @@ static int __init hvc_console_init(void) | |||
242 | } | 242 | } |
243 | console_initcall(hvc_console_init); | 243 | console_initcall(hvc_console_init); |
244 | 244 | ||
245 | /* callback when the kboject ref count reaches zero. */ | ||
246 | static void destroy_hvc_struct(struct kref *kref) | ||
247 | { | ||
248 | struct hvc_struct *hp = container_of(kref, struct hvc_struct, kref); | ||
249 | unsigned long flags; | ||
250 | |||
251 | spin_lock(&hvc_structs_lock); | ||
252 | |||
253 | spin_lock_irqsave(&hp->lock, flags); | ||
254 | list_del(&(hp->next)); | ||
255 | spin_unlock_irqrestore(&hp->lock, flags); | ||
256 | |||
257 | spin_unlock(&hvc_structs_lock); | ||
258 | |||
259 | kfree(hp); | ||
260 | } | ||
261 | |||
245 | /* | 262 | /* |
246 | * hvc_instantiate() is an early console discovery method which locates | 263 | * hvc_instantiate() is an early console discovery method which locates |
247 | * consoles * prior to the vio subsystem discovering them. Hotplugged | 264 | * consoles * prior to the vio subsystem discovering them. Hotplugged |
@@ -261,7 +278,7 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops) | |||
261 | /* make sure no no tty has been registered in this index */ | 278 | /* make sure no no tty has been registered in this index */ |
262 | hp = hvc_get_by_index(index); | 279 | hp = hvc_get_by_index(index); |
263 | if (hp) { | 280 | if (hp) { |
264 | kobject_put(&hp->kobj); | 281 | kref_put(&hp->kref, destroy_hvc_struct); |
265 | return -1; | 282 | return -1; |
266 | } | 283 | } |
267 | 284 | ||
@@ -318,9 +335,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
318 | unsigned long flags; | 335 | unsigned long flags; |
319 | int irq = 0; | 336 | int irq = 0; |
320 | int rc = 0; | 337 | int rc = 0; |
321 | struct kobject *kobjp; | ||
322 | 338 | ||
323 | /* Auto increments kobject reference if found. */ | 339 | /* Auto increments kref reference if found. */ |
324 | if (!(hp = hvc_get_by_index(tty->index))) | 340 | if (!(hp = hvc_get_by_index(tty->index))) |
325 | return -ENODEV; | 341 | return -ENODEV; |
326 | 342 | ||
@@ -341,8 +357,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
341 | if (irq) | 357 | if (irq) |
342 | hp->irq_requested = 1; | 358 | hp->irq_requested = 1; |
343 | 359 | ||
344 | kobjp = &hp->kobj; | ||
345 | |||
346 | spin_unlock_irqrestore(&hp->lock, flags); | 360 | spin_unlock_irqrestore(&hp->lock, flags); |
347 | /* check error, fallback to non-irq */ | 361 | /* check error, fallback to non-irq */ |
348 | if (irq) | 362 | if (irq) |
@@ -352,7 +366,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
352 | * If the request_irq() fails and we return an error. The tty layer | 366 | * If the request_irq() fails and we return an error. The tty layer |
353 | * will call hvc_close() after a failed open but we don't want to clean | 367 | * will call hvc_close() after a failed open but we don't want to clean |
354 | * up there so we'll clean up here and clear out the previously set | 368 | * up there so we'll clean up here and clear out the previously set |
355 | * tty fields and return the kobject reference. | 369 | * tty fields and return the kref reference. |
356 | */ | 370 | */ |
357 | if (rc) { | 371 | if (rc) { |
358 | spin_lock_irqsave(&hp->lock, flags); | 372 | spin_lock_irqsave(&hp->lock, flags); |
@@ -360,7 +374,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
360 | hp->irq_requested = 0; | 374 | hp->irq_requested = 0; |
361 | spin_unlock_irqrestore(&hp->lock, flags); | 375 | spin_unlock_irqrestore(&hp->lock, flags); |
362 | tty->driver_data = NULL; | 376 | tty->driver_data = NULL; |
363 | kobject_put(kobjp); | 377 | kref_put(&hp->kref, destroy_hvc_struct); |
364 | printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); | 378 | printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); |
365 | } | 379 | } |
366 | /* Force wakeup of the polling thread */ | 380 | /* Force wakeup of the polling thread */ |
@@ -372,7 +386,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
372 | static void hvc_close(struct tty_struct *tty, struct file * filp) | 386 | static void hvc_close(struct tty_struct *tty, struct file * filp) |
373 | { | 387 | { |
374 | struct hvc_struct *hp; | 388 | struct hvc_struct *hp; |
375 | struct kobject *kobjp; | ||
376 | int irq = 0; | 389 | int irq = 0; |
377 | unsigned long flags; | 390 | unsigned long flags; |
378 | 391 | ||
@@ -382,7 +395,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
382 | /* | 395 | /* |
383 | * No driver_data means that this close was issued after a failed | 396 | * No driver_data means that this close was issued after a failed |
384 | * hvc_open by the tty layer's release_dev() function and we can just | 397 | * hvc_open by the tty layer's release_dev() function and we can just |
385 | * exit cleanly because the kobject reference wasn't made. | 398 | * exit cleanly because the kref reference wasn't made. |
386 | */ | 399 | */ |
387 | if (!tty->driver_data) | 400 | if (!tty->driver_data) |
388 | return; | 401 | return; |
@@ -390,7 +403,6 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
390 | hp = tty->driver_data; | 403 | hp = tty->driver_data; |
391 | spin_lock_irqsave(&hp->lock, flags); | 404 | spin_lock_irqsave(&hp->lock, flags); |
392 | 405 | ||
393 | kobjp = &hp->kobj; | ||
394 | if (--hp->count == 0) { | 406 | if (--hp->count == 0) { |
395 | if (hp->irq_requested) | 407 | if (hp->irq_requested) |
396 | irq = hp->irq; | 408 | irq = hp->irq; |
@@ -417,7 +429,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
417 | spin_unlock_irqrestore(&hp->lock, flags); | 429 | spin_unlock_irqrestore(&hp->lock, flags); |
418 | } | 430 | } |
419 | 431 | ||
420 | kobject_put(kobjp); | 432 | kref_put(&hp->kref, destroy_hvc_struct); |
421 | } | 433 | } |
422 | 434 | ||
423 | static void hvc_hangup(struct tty_struct *tty) | 435 | static void hvc_hangup(struct tty_struct *tty) |
@@ -426,7 +438,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
426 | unsigned long flags; | 438 | unsigned long flags; |
427 | int irq = 0; | 439 | int irq = 0; |
428 | int temp_open_count; | 440 | int temp_open_count; |
429 | struct kobject *kobjp; | ||
430 | 441 | ||
431 | if (!hp) | 442 | if (!hp) |
432 | return; | 443 | return; |
@@ -443,7 +454,6 @@ static void hvc_hangup(struct tty_struct *tty) | |||
443 | return; | 454 | return; |
444 | } | 455 | } |
445 | 456 | ||
446 | kobjp = &hp->kobj; | ||
447 | temp_open_count = hp->count; | 457 | temp_open_count = hp->count; |
448 | hp->count = 0; | 458 | hp->count = 0; |
449 | hp->n_outbuf = 0; | 459 | hp->n_outbuf = 0; |
@@ -457,7 +467,7 @@ static void hvc_hangup(struct tty_struct *tty) | |||
457 | free_irq(irq, hp); | 467 | free_irq(irq, hp); |
458 | while(temp_open_count) { | 468 | while(temp_open_count) { |
459 | --temp_open_count; | 469 | --temp_open_count; |
460 | kobject_put(kobjp); | 470 | kref_put(&hp->kref, destroy_hvc_struct); |
461 | } | 471 | } |
462 | } | 472 | } |
463 | 473 | ||
@@ -729,27 +739,6 @@ static const struct tty_operations hvc_ops = { | |||
729 | .chars_in_buffer = hvc_chars_in_buffer, | 739 | .chars_in_buffer = hvc_chars_in_buffer, |
730 | }; | 740 | }; |
731 | 741 | ||
732 | /* callback when the kboject ref count reaches zero. */ | ||
733 | static void destroy_hvc_struct(struct kobject *kobj) | ||
734 | { | ||
735 | struct hvc_struct *hp = container_of(kobj, struct hvc_struct, kobj); | ||
736 | unsigned long flags; | ||
737 | |||
738 | spin_lock(&hvc_structs_lock); | ||
739 | |||
740 | spin_lock_irqsave(&hp->lock, flags); | ||
741 | list_del(&(hp->next)); | ||
742 | spin_unlock_irqrestore(&hp->lock, flags); | ||
743 | |||
744 | spin_unlock(&hvc_structs_lock); | ||
745 | |||
746 | kfree(hp); | ||
747 | } | ||
748 | |||
749 | static struct kobj_type hvc_kobj_type = { | ||
750 | .release = destroy_hvc_struct, | ||
751 | }; | ||
752 | |||
753 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | 742 | struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, |
754 | struct hv_ops *ops, int outbuf_size) | 743 | struct hv_ops *ops, int outbuf_size) |
755 | { | 744 | { |
@@ -776,8 +765,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | |||
776 | hp->outbuf_size = outbuf_size; | 765 | hp->outbuf_size = outbuf_size; |
777 | hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))]; | 766 | hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))]; |
778 | 767 | ||
779 | kobject_init(&hp->kobj); | 768 | kref_init(&hp->kref); |
780 | hp->kobj.ktype = &hvc_kobj_type; | ||
781 | 769 | ||
782 | spin_lock_init(&hp->lock); | 770 | spin_lock_init(&hp->lock); |
783 | spin_lock(&hvc_structs_lock); | 771 | spin_lock(&hvc_structs_lock); |
@@ -806,12 +794,10 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | |||
806 | int __devexit hvc_remove(struct hvc_struct *hp) | 794 | int __devexit hvc_remove(struct hvc_struct *hp) |
807 | { | 795 | { |
808 | unsigned long flags; | 796 | unsigned long flags; |
809 | struct kobject *kobjp; | ||
810 | struct tty_struct *tty; | 797 | struct tty_struct *tty; |
811 | 798 | ||
812 | spin_lock_irqsave(&hp->lock, flags); | 799 | spin_lock_irqsave(&hp->lock, flags); |
813 | tty = hp->tty; | 800 | tty = hp->tty; |
814 | kobjp = &hp->kobj; | ||
815 | 801 | ||
816 | if (hp->index < MAX_NR_HVC_CONSOLES) | 802 | if (hp->index < MAX_NR_HVC_CONSOLES) |
817 | vtermnos[hp->index] = -1; | 803 | vtermnos[hp->index] = -1; |
@@ -821,12 +807,12 @@ int __devexit hvc_remove(struct hvc_struct *hp) | |||
821 | spin_unlock_irqrestore(&hp->lock, flags); | 807 | spin_unlock_irqrestore(&hp->lock, flags); |
822 | 808 | ||
823 | /* | 809 | /* |
824 | * We 'put' the instance that was grabbed when the kobject instance | 810 | * We 'put' the instance that was grabbed when the kref instance |
825 | * was initialized using kobject_init(). Let the last holder of this | 811 | * was initialized using kref_init(). Let the last holder of this |
826 | * kobject cause it to be removed, which will probably be the tty_hangup | 812 | * kref cause it to be removed, which will probably be the tty_hangup |
827 | * below. | 813 | * below. |
828 | */ | 814 | */ |
829 | kobject_put(kobjp); | 815 | kref_put(&hp->kref, destroy_hvc_struct); |
830 | 816 | ||
831 | /* | 817 | /* |
832 | * This function call will auto chain call hvc_hangup. The tty should | 818 | * This function call will auto chain call hvc_hangup. The tty should |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 69d8866de783..fd7559084b82 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -57,11 +57,7 @@ | |||
57 | * rescanning partner information upon a user's request. | 57 | * rescanning partner information upon a user's request. |
58 | * | 58 | * |
59 | * Each vty-server, prior to being exposed to this driver is reference counted | 59 | * Each vty-server, prior to being exposed to this driver is reference counted |
60 | * using the 2.6 Linux kernel kobject construct. This kobject is also used by | 60 | * using the 2.6 Linux kernel kref construct. |
61 | * the vio bus to provide a vio device sysfs entry that this driver attaches | ||
62 | * device specific attributes to, including partner information. The vio bus | ||
63 | * framework also provides a sysfs entry for each vio driver. The hvcs driver | ||
64 | * provides driver attributes in this entry. | ||
65 | * | 61 | * |
66 | * For direction on installation and usage of this driver please reference | 62 | * For direction on installation and usage of this driver please reference |
67 | * Documentation/powerpc/hvcs.txt. | 63 | * Documentation/powerpc/hvcs.txt. |
@@ -71,7 +67,7 @@ | |||
71 | #include <linux/init.h> | 67 | #include <linux/init.h> |
72 | #include <linux/interrupt.h> | 68 | #include <linux/interrupt.h> |
73 | #include <linux/kernel.h> | 69 | #include <linux/kernel.h> |
74 | #include <linux/kobject.h> | 70 | #include <linux/kref.h> |
75 | #include <linux/kthread.h> | 71 | #include <linux/kthread.h> |
76 | #include <linux/list.h> | 72 | #include <linux/list.h> |
77 | #include <linux/major.h> | 73 | #include <linux/major.h> |
@@ -293,12 +289,12 @@ struct hvcs_struct { | |||
293 | int chars_in_buffer; | 289 | int chars_in_buffer; |
294 | 290 | ||
295 | /* | 291 | /* |
296 | * Any variable below the kobject is valid before a tty is connected and | 292 | * Any variable below the kref is valid before a tty is connected and |
297 | * stays valid after the tty is disconnected. These shouldn't be | 293 | * stays valid after the tty is disconnected. These shouldn't be |
298 | * whacked until the koject refcount reaches zero though some entries | 294 | * whacked until the koject refcount reaches zero though some entries |
299 | * may be changed via sysfs initiatives. | 295 | * may be changed via sysfs initiatives. |
300 | */ | 296 | */ |
301 | struct kobject kobj; /* ref count & hvcs_struct lifetime */ | 297 | struct kref kref; /* ref count & hvcs_struct lifetime */ |
302 | int connected; /* is the vty-server currently connected to a vty? */ | 298 | int connected; /* is the vty-server currently connected to a vty? */ |
303 | uint32_t p_unit_address; /* partner unit address */ | 299 | uint32_t p_unit_address; /* partner unit address */ |
304 | uint32_t p_partition_ID; /* partner partition ID */ | 300 | uint32_t p_partition_ID; /* partner partition ID */ |
@@ -307,8 +303,8 @@ struct hvcs_struct { | |||
307 | struct vio_dev *vdev; | 303 | struct vio_dev *vdev; |
308 | }; | 304 | }; |
309 | 305 | ||
310 | /* Required to back map a kobject to its containing object */ | 306 | /* Required to back map a kref to its containing object */ |
311 | #define from_kobj(kobj) container_of(kobj, struct hvcs_struct, kobj) | 307 | #define from_kref(k) container_of(k, struct hvcs_struct, kref) |
312 | 308 | ||
313 | static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs); | 309 | static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs); |
314 | static DEFINE_SPINLOCK(hvcs_structs_lock); | 310 | static DEFINE_SPINLOCK(hvcs_structs_lock); |
@@ -334,7 +330,6 @@ static void hvcs_partner_free(struct hvcs_struct *hvcsd); | |||
334 | static int hvcs_enable_device(struct hvcs_struct *hvcsd, | 330 | static int hvcs_enable_device(struct hvcs_struct *hvcsd, |
335 | uint32_t unit_address, unsigned int irq, struct vio_dev *dev); | 331 | uint32_t unit_address, unsigned int irq, struct vio_dev *dev); |
336 | 332 | ||
337 | static void destroy_hvcs_struct(struct kobject *kobj); | ||
338 | static int hvcs_open(struct tty_struct *tty, struct file *filp); | 333 | static int hvcs_open(struct tty_struct *tty, struct file *filp); |
339 | static void hvcs_close(struct tty_struct *tty, struct file *filp); | 334 | static void hvcs_close(struct tty_struct *tty, struct file *filp); |
340 | static void hvcs_hangup(struct tty_struct * tty); | 335 | static void hvcs_hangup(struct tty_struct * tty); |
@@ -703,10 +698,10 @@ static void hvcs_return_index(int index) | |||
703 | hvcs_index_list[index] = -1; | 698 | hvcs_index_list[index] = -1; |
704 | } | 699 | } |
705 | 700 | ||
706 | /* callback when the kboject ref count reaches zero */ | 701 | /* callback when the kref ref count reaches zero */ |
707 | static void destroy_hvcs_struct(struct kobject *kobj) | 702 | static void destroy_hvcs_struct(struct kref *kref) |
708 | { | 703 | { |
709 | struct hvcs_struct *hvcsd = from_kobj(kobj); | 704 | struct hvcs_struct *hvcsd = from_kref(kref); |
710 | struct vio_dev *vdev; | 705 | struct vio_dev *vdev; |
711 | unsigned long flags; | 706 | unsigned long flags; |
712 | 707 | ||
@@ -743,10 +738,6 @@ static void destroy_hvcs_struct(struct kobject *kobj) | |||
743 | kfree(hvcsd); | 738 | kfree(hvcsd); |
744 | } | 739 | } |
745 | 740 | ||
746 | static struct kobj_type hvcs_kobj_type = { | ||
747 | .release = destroy_hvcs_struct, | ||
748 | }; | ||
749 | |||
750 | static int hvcs_get_index(void) | 741 | static int hvcs_get_index(void) |
751 | { | 742 | { |
752 | int i; | 743 | int i; |
@@ -791,9 +782,7 @@ static int __devinit hvcs_probe( | |||
791 | 782 | ||
792 | spin_lock_init(&hvcsd->lock); | 783 | spin_lock_init(&hvcsd->lock); |
793 | /* Automatically incs the refcount the first time */ | 784 | /* Automatically incs the refcount the first time */ |
794 | kobject_init(&hvcsd->kobj); | 785 | kref_init(&hvcsd->kref); |
795 | /* Set up the callback for terminating the hvcs_struct's life */ | ||
796 | hvcsd->kobj.ktype = &hvcs_kobj_type; | ||
797 | 786 | ||
798 | hvcsd->vdev = dev; | 787 | hvcsd->vdev = dev; |
799 | dev->dev.driver_data = hvcsd; | 788 | dev->dev.driver_data = hvcsd; |
@@ -844,7 +833,6 @@ static int __devexit hvcs_remove(struct vio_dev *dev) | |||
844 | { | 833 | { |
845 | struct hvcs_struct *hvcsd = dev->dev.driver_data; | 834 | struct hvcs_struct *hvcsd = dev->dev.driver_data; |
846 | unsigned long flags; | 835 | unsigned long flags; |
847 | struct kobject *kobjp; | ||
848 | struct tty_struct *tty; | 836 | struct tty_struct *tty; |
849 | 837 | ||
850 | if (!hvcsd) | 838 | if (!hvcsd) |
@@ -856,15 +844,13 @@ static int __devexit hvcs_remove(struct vio_dev *dev) | |||
856 | 844 | ||
857 | tty = hvcsd->tty; | 845 | tty = hvcsd->tty; |
858 | 846 | ||
859 | kobjp = &hvcsd->kobj; | ||
860 | |||
861 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 847 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
862 | 848 | ||
863 | /* | 849 | /* |
864 | * Let the last holder of this object cause it to be removed, which | 850 | * Let the last holder of this object cause it to be removed, which |
865 | * would probably be tty_hangup below. | 851 | * would probably be tty_hangup below. |
866 | */ | 852 | */ |
867 | kobject_put (kobjp); | 853 | kref_put(&hvcsd->kref, destroy_hvcs_struct); |
868 | 854 | ||
869 | /* | 855 | /* |
870 | * The hangup is a scheduled function which will auto chain call | 856 | * The hangup is a scheduled function which will auto chain call |
@@ -1086,7 +1072,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, | |||
1086 | } | 1072 | } |
1087 | 1073 | ||
1088 | /* | 1074 | /* |
1089 | * This always increments the kobject ref count if the call is successful. | 1075 | * This always increments the kref ref count if the call is successful. |
1090 | * Please remember to dec when you are done with the instance. | 1076 | * Please remember to dec when you are done with the instance. |
1091 | * | 1077 | * |
1092 | * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when | 1078 | * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when |
@@ -1103,7 +1089,7 @@ static struct hvcs_struct *hvcs_get_by_index(int index) | |||
1103 | list_for_each_entry(hvcsd, &hvcs_structs, next) { | 1089 | list_for_each_entry(hvcsd, &hvcs_structs, next) { |
1104 | spin_lock_irqsave(&hvcsd->lock, flags); | 1090 | spin_lock_irqsave(&hvcsd->lock, flags); |
1105 | if (hvcsd->index == index) { | 1091 | if (hvcsd->index == index) { |
1106 | kobject_get(&hvcsd->kobj); | 1092 | kref_get(&hvcsd->kref); |
1107 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1093 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
1108 | spin_unlock(&hvcs_structs_lock); | 1094 | spin_unlock(&hvcs_structs_lock); |
1109 | return hvcsd; | 1095 | return hvcsd; |
@@ -1129,14 +1115,13 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) | |||
1129 | unsigned int irq; | 1115 | unsigned int irq; |
1130 | struct vio_dev *vdev; | 1116 | struct vio_dev *vdev; |
1131 | unsigned long unit_address; | 1117 | unsigned long unit_address; |
1132 | struct kobject *kobjp; | ||
1133 | 1118 | ||
1134 | if (tty->driver_data) | 1119 | if (tty->driver_data) |
1135 | goto fast_open; | 1120 | goto fast_open; |
1136 | 1121 | ||
1137 | /* | 1122 | /* |
1138 | * Is there a vty-server that shares the same index? | 1123 | * Is there a vty-server that shares the same index? |
1139 | * This function increments the kobject index. | 1124 | * This function increments the kref index. |
1140 | */ | 1125 | */ |
1141 | if (!(hvcsd = hvcs_get_by_index(tty->index))) { | 1126 | if (!(hvcsd = hvcs_get_by_index(tty->index))) { |
1142 | printk(KERN_WARNING "HVCS: open failed, no device associated" | 1127 | printk(KERN_WARNING "HVCS: open failed, no device associated" |
@@ -1181,7 +1166,7 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) | |||
1181 | * and will grab the spinlock and free the connection if it fails. | 1166 | * and will grab the spinlock and free the connection if it fails. |
1182 | */ | 1167 | */ |
1183 | if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) { | 1168 | if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) { |
1184 | kobject_put(&hvcsd->kobj); | 1169 | kref_put(&hvcsd->kref, destroy_hvcs_struct); |
1185 | printk(KERN_WARNING "HVCS: enable device failed.\n"); | 1170 | printk(KERN_WARNING "HVCS: enable device failed.\n"); |
1186 | return rc; | 1171 | return rc; |
1187 | } | 1172 | } |
@@ -1192,17 +1177,11 @@ fast_open: | |||
1192 | hvcsd = tty->driver_data; | 1177 | hvcsd = tty->driver_data; |
1193 | 1178 | ||
1194 | spin_lock_irqsave(&hvcsd->lock, flags); | 1179 | spin_lock_irqsave(&hvcsd->lock, flags); |
1195 | if (!kobject_get(&hvcsd->kobj)) { | 1180 | kref_get(&hvcsd->kref); |
1196 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1197 | printk(KERN_ERR "HVCS: Kobject of open" | ||
1198 | " hvcs doesn't exist.\n"); | ||
1199 | return -EFAULT; /* Is this the right return value? */ | ||
1200 | } | ||
1201 | |||
1202 | hvcsd->open_count++; | 1181 | hvcsd->open_count++; |
1203 | |||
1204 | hvcsd->todo_mask |= HVCS_SCHED_READ; | 1182 | hvcsd->todo_mask |= HVCS_SCHED_READ; |
1205 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1183 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
1184 | |||
1206 | open_success: | 1185 | open_success: |
1207 | hvcs_kick(); | 1186 | hvcs_kick(); |
1208 | 1187 | ||
@@ -1212,9 +1191,8 @@ open_success: | |||
1212 | return 0; | 1191 | return 0; |
1213 | 1192 | ||
1214 | error_release: | 1193 | error_release: |
1215 | kobjp = &hvcsd->kobj; | ||
1216 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1194 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
1217 | kobject_put(&hvcsd->kobj); | 1195 | kref_put(&hvcsd->kref, destroy_hvcs_struct); |
1218 | 1196 | ||
1219 | printk(KERN_WARNING "HVCS: partner connect failed.\n"); | 1197 | printk(KERN_WARNING "HVCS: partner connect failed.\n"); |
1220 | return retval; | 1198 | return retval; |
@@ -1224,7 +1202,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
1224 | { | 1202 | { |
1225 | struct hvcs_struct *hvcsd; | 1203 | struct hvcs_struct *hvcsd; |
1226 | unsigned long flags; | 1204 | unsigned long flags; |
1227 | struct kobject *kobjp; | ||
1228 | int irq = NO_IRQ; | 1205 | int irq = NO_IRQ; |
1229 | 1206 | ||
1230 | /* | 1207 | /* |
@@ -1245,7 +1222,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
1245 | hvcsd = tty->driver_data; | 1222 | hvcsd = tty->driver_data; |
1246 | 1223 | ||
1247 | spin_lock_irqsave(&hvcsd->lock, flags); | 1224 | spin_lock_irqsave(&hvcsd->lock, flags); |
1248 | kobjp = &hvcsd->kobj; | ||
1249 | if (--hvcsd->open_count == 0) { | 1225 | if (--hvcsd->open_count == 0) { |
1250 | 1226 | ||
1251 | vio_disable_interrupts(hvcsd->vdev); | 1227 | vio_disable_interrupts(hvcsd->vdev); |
@@ -1270,7 +1246,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
1270 | tty->driver_data = NULL; | 1246 | tty->driver_data = NULL; |
1271 | 1247 | ||
1272 | free_irq(irq, hvcsd); | 1248 | free_irq(irq, hvcsd); |
1273 | kobject_put(kobjp); | 1249 | kref_put(&hvcsd->kref, destroy_hvcs_struct); |
1274 | return; | 1250 | return; |
1275 | } else if (hvcsd->open_count < 0) { | 1251 | } else if (hvcsd->open_count < 0) { |
1276 | printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" | 1252 | printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" |
@@ -1279,7 +1255,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
1279 | } | 1255 | } |
1280 | 1256 | ||
1281 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1257 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
1282 | kobject_put(kobjp); | 1258 | kref_put(&hvcsd->kref, destroy_hvcs_struct); |
1283 | } | 1259 | } |
1284 | 1260 | ||
1285 | static void hvcs_hangup(struct tty_struct * tty) | 1261 | static void hvcs_hangup(struct tty_struct * tty) |
@@ -1287,21 +1263,17 @@ static void hvcs_hangup(struct tty_struct * tty) | |||
1287 | struct hvcs_struct *hvcsd = tty->driver_data; | 1263 | struct hvcs_struct *hvcsd = tty->driver_data; |
1288 | unsigned long flags; | 1264 | unsigned long flags; |
1289 | int temp_open_count; | 1265 | int temp_open_count; |
1290 | struct kobject *kobjp; | ||
1291 | int irq = NO_IRQ; | 1266 | int irq = NO_IRQ; |
1292 | 1267 | ||
1293 | spin_lock_irqsave(&hvcsd->lock, flags); | 1268 | spin_lock_irqsave(&hvcsd->lock, flags); |
1294 | /* Preserve this so that we know how many kobject refs to put */ | 1269 | /* Preserve this so that we know how many kref refs to put */ |
1295 | temp_open_count = hvcsd->open_count; | 1270 | temp_open_count = hvcsd->open_count; |
1296 | 1271 | ||
1297 | /* | 1272 | /* |
1298 | * Don't kobject put inside the spinlock because the destruction | 1273 | * Don't kref put inside the spinlock because the destruction |
1299 | * callback may use the spinlock and it may get called before the | 1274 | * callback may use the spinlock and it may get called before the |
1300 | * spinlock has been released. Get a pointer to the kobject and | 1275 | * spinlock has been released. |
1301 | * kobject_put on that after releasing the spinlock. | ||
1302 | */ | 1276 | */ |
1303 | kobjp = &hvcsd->kobj; | ||
1304 | |||
1305 | vio_disable_interrupts(hvcsd->vdev); | 1277 | vio_disable_interrupts(hvcsd->vdev); |
1306 | 1278 | ||
1307 | hvcsd->todo_mask = 0; | 1279 | hvcsd->todo_mask = 0; |
@@ -1324,7 +1296,7 @@ static void hvcs_hangup(struct tty_struct * tty) | |||
1324 | free_irq(irq, hvcsd); | 1296 | free_irq(irq, hvcsd); |
1325 | 1297 | ||
1326 | /* | 1298 | /* |
1327 | * We need to kobject_put() for every open_count we have since the | 1299 | * We need to kref_put() for every open_count we have since the |
1328 | * tty_hangup() function doesn't invoke a close per open connection on a | 1300 | * tty_hangup() function doesn't invoke a close per open connection on a |
1329 | * non-console device. | 1301 | * non-console device. |
1330 | */ | 1302 | */ |
@@ -1335,7 +1307,7 @@ static void hvcs_hangup(struct tty_struct * tty) | |||
1335 | * NOTE: If this hangup was signaled from user space then the | 1307 | * NOTE: If this hangup was signaled from user space then the |
1336 | * final put will never happen. | 1308 | * final put will never happen. |
1337 | */ | 1309 | */ |
1338 | kobject_put(kobjp); | 1310 | kref_put(&hvcsd->kref, destroy_hvcs_struct); |
1339 | } | 1311 | } |
1340 | } | 1312 | } |
1341 | 1313 | ||
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c new file mode 100644 index 000000000000..6076e662886a --- /dev/null +++ b/drivers/char/nozomi.c | |||
@@ -0,0 +1,1993 @@ | |||
1 | /* | ||
2 | * nozomi.c -- HSDPA driver Broadband Wireless Data Card - Globe Trotter | ||
3 | * | ||
4 | * Written by: Ulf Jakobsson, | ||
5 | * Jan �erfeldt, | ||
6 | * Stefan Thomasson, | ||
7 | * | ||
8 | * Maintained by: Paul Hardwick (p.hardwick@option.com) | ||
9 | * | ||
10 | * Patches: | ||
11 | * Locking code changes for Vodafone by Sphere Systems Ltd, | ||
12 | * Andrew Bird (ajb@spheresystems.co.uk ) | ||
13 | * & Phil Sanderson | ||
14 | * | ||
15 | * Source has been ported from an implementation made by Filip Aben @ Option | ||
16 | * | ||
17 | * -------------------------------------------------------------------------- | ||
18 | * | ||
19 | * Copyright (c) 2005,2006 Option Wireless Sweden AB | ||
20 | * Copyright (c) 2006 Sphere Systems Ltd | ||
21 | * Copyright (c) 2006 Option Wireless n/v | ||
22 | * All rights Reserved. | ||
23 | * | ||
24 | * This program is free software; you can redistribute it and/or modify | ||
25 | * it under the terms of the GNU General Public License as published by | ||
26 | * the Free Software Foundation; either version 2 of the License, or | ||
27 | * (at your option) any later version. | ||
28 | * | ||
29 | * This program is distributed in the hope that it will be useful, | ||
30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
32 | * GNU General Public License for more details. | ||
33 | * | ||
34 | * You should have received a copy of the GNU General Public License | ||
35 | * along with this program; if not, write to the Free Software | ||
36 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
37 | * | ||
38 | * -------------------------------------------------------------------------- | ||
39 | */ | ||
40 | |||
41 | /* | ||
42 | * CHANGELOG | ||
43 | * Version 2.1d | ||
44 | * 11-November-2007 Jiri Slaby, Frank Seidel | ||
45 | * - Big rework of multicard support by Jiri | ||
46 | * - Major cleanups (semaphore to mutex, endianess, no major reservation) | ||
47 | * - Optimizations | ||
48 | * | ||
49 | * Version 2.1c | ||
50 | * 30-October-2007 Frank Seidel | ||
51 | * - Completed multicard support | ||
52 | * - Minor cleanups | ||
53 | * | ||
54 | * Version 2.1b | ||
55 | * 07-August-2007 Frank Seidel | ||
56 | * - Minor cleanups | ||
57 | * - theoretical multicard support | ||
58 | * | ||
59 | * Version 2.1 | ||
60 | * 03-July-2006 Paul Hardwick | ||
61 | * | ||
62 | * - Stability Improvements. Incorporated spinlock wraps patch. | ||
63 | * - Updated for newer 2.6.14+ kernels (tty_buffer_request_room) | ||
64 | * - using __devexit macro for tty | ||
65 | * | ||
66 | * | ||
67 | * Version 2.0 | ||
68 | * 08-feb-2006 15:34:10:Ulf | ||
69 | * | ||
70 | * -Fixed issue when not waking up line disipine layer, could probably result | ||
71 | * in better uplink performance for 2.4. | ||
72 | * | ||
73 | * -Fixed issue with big endian during initalization, now proper toggle flags | ||
74 | * are handled between preloader and maincode. | ||
75 | * | ||
76 | * -Fixed flow control issue. | ||
77 | * | ||
78 | * -Added support for setting DTR. | ||
79 | * | ||
80 | * -For 2.4 kernels, removing temporary buffer that's not needed. | ||
81 | * | ||
82 | * -Reading CTS only for modem port (only port that supports it). | ||
83 | * | ||
84 | * -Return 0 in write_room instead of netative value, it's not handled in | ||
85 | * upper layer. | ||
86 | * | ||
87 | * -------------------------------------------------------------------------- | ||
88 | * Version 1.0 | ||
89 | * | ||
90 | * First version of driver, only tested with card of type F32_2. | ||
91 | * Works fine with 2.4 and 2.6 kernels. | ||
92 | * Driver also support big endian architecture. | ||
93 | */ | ||
94 | |||
95 | /* Enable this to have a lot of debug printouts */ | ||
96 | #define DEBUG | ||
97 | |||
98 | #include <linux/kernel.h> | ||
99 | #include <linux/module.h> | ||
100 | #include <linux/pci.h> | ||
101 | #include <linux/ioport.h> | ||
102 | #include <linux/tty.h> | ||
103 | #include <linux/tty_driver.h> | ||
104 | #include <linux/tty_flip.h> | ||
105 | #include <linux/serial.h> | ||
106 | #include <linux/interrupt.h> | ||
107 | #include <linux/kmod.h> | ||
108 | #include <linux/init.h> | ||
109 | #include <linux/kfifo.h> | ||
110 | #include <linux/uaccess.h> | ||
111 | #include <asm/byteorder.h> | ||
112 | |||
113 | #include <linux/delay.h> | ||
114 | |||
115 | |||
116 | #define VERSION_STRING DRIVER_DESC " 2.1d (build date: " \ | ||
117 | __DATE__ " " __TIME__ ")" | ||
118 | |||
119 | /* Macros definitions */ | ||
120 | |||
121 | /* Default debug printout level */ | ||
122 | #define NOZOMI_DEBUG_LEVEL 0x00 | ||
123 | |||
124 | #define P_BUF_SIZE 128 | ||
125 | #define NFO(_err_flag_, args...) \ | ||
126 | do { \ | ||
127 | char tmp[P_BUF_SIZE]; \ | ||
128 | snprintf(tmp, sizeof(tmp), ##args); \ | ||
129 | printk(_err_flag_ "[%d] %s(): %s\n", __LINE__, \ | ||
130 | __FUNCTION__, tmp); \ | ||
131 | } while (0) | ||
132 | |||
133 | #define DBG1(args...) D_(0x01, ##args) | ||
134 | #define DBG2(args...) D_(0x02, ##args) | ||
135 | #define DBG3(args...) D_(0x04, ##args) | ||
136 | #define DBG4(args...) D_(0x08, ##args) | ||
137 | #define DBG5(args...) D_(0x10, ##args) | ||
138 | #define DBG6(args...) D_(0x20, ##args) | ||
139 | #define DBG7(args...) D_(0x40, ##args) | ||
140 | #define DBG8(args...) D_(0x80, ##args) | ||
141 | |||
142 | #ifdef DEBUG | ||
143 | /* Do we need this settable at runtime? */ | ||
144 | static int debug = NOZOMI_DEBUG_LEVEL; | ||
145 | |||
146 | #define D(lvl, args...) do {if (lvl & debug) NFO(KERN_DEBUG, ##args); } \ | ||
147 | while (0) | ||
148 | #define D_(lvl, args...) D(lvl, ##args) | ||
149 | |||
150 | /* These printouts are always printed */ | ||
151 | |||
152 | #else | ||
153 | static int debug; | ||
154 | #define D_(lvl, args...) | ||
155 | #endif | ||
156 | |||
157 | /* TODO: rewrite to optimize macros... */ | ||
158 | |||
159 | #define TMP_BUF_MAX 256 | ||
160 | |||
161 | #define DUMP(buf__,len__) \ | ||
162 | do { \ | ||
163 | char tbuf[TMP_BUF_MAX] = {0};\ | ||
164 | if (len__ > 1) {\ | ||
165 | snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\ | ||
166 | if (tbuf[len__-2] == '\r') {\ | ||
167 | tbuf[len__-2] = 'r';\ | ||
168 | } \ | ||
169 | DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\ | ||
170 | } else {\ | ||
171 | DBG1("SENDING: '%s' (%d)", tbuf, len__);\ | ||
172 | } \ | ||
173 | } while (0) | ||
174 | |||
175 | /* Defines */ | ||
176 | #define NOZOMI_NAME "nozomi" | ||
177 | #define NOZOMI_NAME_TTY "nozomi_tty" | ||
178 | #define DRIVER_DESC "Nozomi driver" | ||
179 | |||
180 | #define NTTY_TTY_MAXMINORS 256 | ||
181 | #define NTTY_FIFO_BUFFER_SIZE 8192 | ||
182 | |||
183 | /* Must be power of 2 */ | ||
184 | #define FIFO_BUFFER_SIZE_UL 8192 | ||
185 | |||
186 | /* Size of tmp send buffer to card */ | ||
187 | #define SEND_BUF_MAX 1024 | ||
188 | #define RECEIVE_BUF_MAX 4 | ||
189 | |||
190 | |||
191 | /* Define all types of vendors and devices to support */ | ||
192 | #define VENDOR1 0x1931 /* Vendor Option */ | ||
193 | #define DEVICE1 0x000c /* HSDPA card */ | ||
194 | |||
195 | #define R_IIR 0x0000 /* Interrupt Identity Register */ | ||
196 | #define R_FCR 0x0000 /* Flow Control Register */ | ||
197 | #define R_IER 0x0004 /* Interrupt Enable Register */ | ||
198 | |||
199 | #define CONFIG_MAGIC 0xEFEFFEFE | ||
200 | #define TOGGLE_VALID 0x0000 | ||
201 | |||
202 | /* Definition of interrupt tokens */ | ||
203 | #define MDM_DL1 0x0001 | ||
204 | #define MDM_UL1 0x0002 | ||
205 | #define MDM_DL2 0x0004 | ||
206 | #define MDM_UL2 0x0008 | ||
207 | #define DIAG_DL1 0x0010 | ||
208 | #define DIAG_DL2 0x0020 | ||
209 | #define DIAG_UL 0x0040 | ||
210 | #define APP1_DL 0x0080 | ||
211 | #define APP1_UL 0x0100 | ||
212 | #define APP2_DL 0x0200 | ||
213 | #define APP2_UL 0x0400 | ||
214 | #define CTRL_DL 0x0800 | ||
215 | #define CTRL_UL 0x1000 | ||
216 | #define RESET 0x8000 | ||
217 | |||
218 | #define MDM_DL (MDM_DL1 | MDM_DL2) | ||
219 | #define MDM_UL (MDM_UL1 | MDM_UL2) | ||
220 | #define DIAG_DL (DIAG_DL1 | DIAG_DL2) | ||
221 | |||
222 | /* modem signal definition */ | ||
223 | #define CTRL_DSR 0x0001 | ||
224 | #define CTRL_DCD 0x0002 | ||
225 | #define CTRL_RI 0x0004 | ||
226 | #define CTRL_CTS 0x0008 | ||
227 | |||
228 | #define CTRL_DTR 0x0001 | ||
229 | #define CTRL_RTS 0x0002 | ||
230 | |||
231 | #define MAX_PORT 4 | ||
232 | #define NOZOMI_MAX_PORTS 5 | ||
233 | #define NOZOMI_MAX_CARDS (NTTY_TTY_MAXMINORS / MAX_PORT) | ||
234 | |||
235 | /* Type definitions */ | ||
236 | |||
237 | /* | ||
238 | * There are two types of nozomi cards, | ||
239 | * one with 2048 memory and with 8192 memory | ||
240 | */ | ||
241 | enum card_type { | ||
242 | F32_2 = 2048, /* 512 bytes downlink + uplink * 2 -> 2048 */ | ||
243 | F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ | ||
244 | }; | ||
245 | |||
246 | /* Two different toggle channels exist */ | ||
247 | enum channel_type { | ||
248 | CH_A = 0, | ||
249 | CH_B = 1, | ||
250 | }; | ||
251 | |||
252 | /* Port definition for the card regarding flow control */ | ||
253 | enum ctrl_port_type { | ||
254 | CTRL_CMD = 0, | ||
255 | CTRL_MDM = 1, | ||
256 | CTRL_DIAG = 2, | ||
257 | CTRL_APP1 = 3, | ||
258 | CTRL_APP2 = 4, | ||
259 | CTRL_ERROR = -1, | ||
260 | }; | ||
261 | |||
262 | /* Ports that the nozomi has */ | ||
263 | enum port_type { | ||
264 | PORT_MDM = 0, | ||
265 | PORT_DIAG = 1, | ||
266 | PORT_APP1 = 2, | ||
267 | PORT_APP2 = 3, | ||
268 | PORT_CTRL = 4, | ||
269 | PORT_ERROR = -1, | ||
270 | }; | ||
271 | |||
272 | #ifdef __BIG_ENDIAN | ||
273 | /* Big endian */ | ||
274 | |||
275 | struct toggles { | ||
276 | unsigned enabled:5; /* | ||
277 | * Toggle fields are valid if enabled is 0, | ||
278 | * else A-channels must always be used. | ||
279 | */ | ||
280 | unsigned diag_dl:1; | ||
281 | unsigned mdm_dl:1; | ||
282 | unsigned mdm_ul:1; | ||
283 | } __attribute__ ((packed)); | ||
284 | |||
285 | /* Configuration table to read at startup of card */ | ||
286 | /* Is for now only needed during initialization phase */ | ||
287 | struct config_table { | ||
288 | u32 signature; | ||
289 | u16 product_information; | ||
290 | u16 version; | ||
291 | u8 pad3[3]; | ||
292 | struct toggles toggle; | ||
293 | u8 pad1[4]; | ||
294 | u16 dl_mdm_len1; /* | ||
295 | * If this is 64, it can hold | ||
296 | * 60 bytes + 4 that is length field | ||
297 | */ | ||
298 | u16 dl_start; | ||
299 | |||
300 | u16 dl_diag_len1; | ||
301 | u16 dl_mdm_len2; /* | ||
302 | * If this is 64, it can hold | ||
303 | * 60 bytes + 4 that is length field | ||
304 | */ | ||
305 | u16 dl_app1_len; | ||
306 | |||
307 | u16 dl_diag_len2; | ||
308 | u16 dl_ctrl_len; | ||
309 | u16 dl_app2_len; | ||
310 | u8 pad2[16]; | ||
311 | u16 ul_mdm_len1; | ||
312 | u16 ul_start; | ||
313 | u16 ul_diag_len; | ||
314 | u16 ul_mdm_len2; | ||
315 | u16 ul_app1_len; | ||
316 | u16 ul_app2_len; | ||
317 | u16 ul_ctrl_len; | ||
318 | } __attribute__ ((packed)); | ||
319 | |||
320 | /* This stores all control downlink flags */ | ||
321 | struct ctrl_dl { | ||
322 | u8 port; | ||
323 | unsigned reserved:4; | ||
324 | unsigned CTS:1; | ||
325 | unsigned RI:1; | ||
326 | unsigned DCD:1; | ||
327 | unsigned DSR:1; | ||
328 | } __attribute__ ((packed)); | ||
329 | |||
330 | /* This stores all control uplink flags */ | ||
331 | struct ctrl_ul { | ||
332 | u8 port; | ||
333 | unsigned reserved:6; | ||
334 | unsigned RTS:1; | ||
335 | unsigned DTR:1; | ||
336 | } __attribute__ ((packed)); | ||
337 | |||
338 | #else | ||
339 | /* Little endian */ | ||
340 | |||
341 | /* This represents the toggle information */ | ||
342 | struct toggles { | ||
343 | unsigned mdm_ul:1; | ||
344 | unsigned mdm_dl:1; | ||
345 | unsigned diag_dl:1; | ||
346 | unsigned enabled:5; /* | ||
347 | * Toggle fields are valid if enabled is 0, | ||
348 | * else A-channels must always be used. | ||
349 | */ | ||
350 | } __attribute__ ((packed)); | ||
351 | |||
352 | /* Configuration table to read at startup of card */ | ||
353 | struct config_table { | ||
354 | u32 signature; | ||
355 | u16 version; | ||
356 | u16 product_information; | ||
357 | struct toggles toggle; | ||
358 | u8 pad1[7]; | ||
359 | u16 dl_start; | ||
360 | u16 dl_mdm_len1; /* | ||
361 | * If this is 64, it can hold | ||
362 | * 60 bytes + 4 that is length field | ||
363 | */ | ||
364 | u16 dl_mdm_len2; | ||
365 | u16 dl_diag_len1; | ||
366 | u16 dl_diag_len2; | ||
367 | u16 dl_app1_len; | ||
368 | u16 dl_app2_len; | ||
369 | u16 dl_ctrl_len; | ||
370 | u8 pad2[16]; | ||
371 | u16 ul_start; | ||
372 | u16 ul_mdm_len2; | ||
373 | u16 ul_mdm_len1; | ||
374 | u16 ul_diag_len; | ||
375 | u16 ul_app1_len; | ||
376 | u16 ul_app2_len; | ||
377 | u16 ul_ctrl_len; | ||
378 | } __attribute__ ((packed)); | ||
379 | |||
380 | /* This stores all control downlink flags */ | ||
381 | struct ctrl_dl { | ||
382 | unsigned DSR:1; | ||
383 | unsigned DCD:1; | ||
384 | unsigned RI:1; | ||
385 | unsigned CTS:1; | ||
386 | unsigned reserverd:4; | ||
387 | u8 port; | ||
388 | } __attribute__ ((packed)); | ||
389 | |||
390 | /* This stores all control uplink flags */ | ||
391 | struct ctrl_ul { | ||
392 | unsigned DTR:1; | ||
393 | unsigned RTS:1; | ||
394 | unsigned reserved:6; | ||
395 | u8 port; | ||
396 | } __attribute__ ((packed)); | ||
397 | #endif | ||
398 | |||
399 | /* This holds all information that is needed regarding a port */ | ||
400 | struct port { | ||
401 | u8 update_flow_control; | ||
402 | struct ctrl_ul ctrl_ul; | ||
403 | struct ctrl_dl ctrl_dl; | ||
404 | struct kfifo *fifo_ul; | ||
405 | void __iomem *dl_addr[2]; | ||
406 | u32 dl_size[2]; | ||
407 | u8 toggle_dl; | ||
408 | void __iomem *ul_addr[2]; | ||
409 | u32 ul_size[2]; | ||
410 | u8 toggle_ul; | ||
411 | u16 token_dl; | ||
412 | |||
413 | struct tty_struct *tty; | ||
414 | int tty_open_count; | ||
415 | /* mutex to ensure one access patch to this port */ | ||
416 | struct mutex tty_sem; | ||
417 | wait_queue_head_t tty_wait; | ||
418 | struct async_icount tty_icount; | ||
419 | }; | ||
420 | |||
421 | /* Private data one for each card in the system */ | ||
422 | struct nozomi { | ||
423 | void __iomem *base_addr; | ||
424 | unsigned long flip; | ||
425 | |||
426 | /* Pointers to registers */ | ||
427 | void __iomem *reg_iir; | ||
428 | void __iomem *reg_fcr; | ||
429 | void __iomem *reg_ier; | ||
430 | |||
431 | u16 last_ier; | ||
432 | enum card_type card_type; | ||
433 | struct config_table config_table; /* Configuration table */ | ||
434 | struct pci_dev *pdev; | ||
435 | struct port port[NOZOMI_MAX_PORTS]; | ||
436 | u8 *send_buf; | ||
437 | |||
438 | spinlock_t spin_mutex; /* secures access to registers and tty */ | ||
439 | |||
440 | unsigned int index_start; | ||
441 | u32 open_ttys; | ||
442 | }; | ||
443 | |||
444 | /* This is a data packet that is read or written to/from card */ | ||
445 | struct buffer { | ||
446 | u32 size; /* size is the length of the data buffer */ | ||
447 | u8 *data; | ||
448 | } __attribute__ ((packed)); | ||
449 | |||
450 | /* Global variables */ | ||
451 | static struct pci_device_id nozomi_pci_tbl[] = { | ||
452 | {PCI_DEVICE(VENDOR1, DEVICE1)}, | ||
453 | {}, | ||
454 | }; | ||
455 | |||
456 | MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl); | ||
457 | |||
458 | static struct nozomi *ndevs[NOZOMI_MAX_CARDS]; | ||
459 | static struct tty_driver *ntty_driver; | ||
460 | |||
461 | /* | ||
462 | * find card by tty_index | ||
463 | */ | ||
464 | static inline struct nozomi *get_dc_by_tty(const struct tty_struct *tty) | ||
465 | { | ||
466 | return tty ? ndevs[tty->index / MAX_PORT] : NULL; | ||
467 | } | ||
468 | |||
469 | static inline struct port *get_port_by_tty(const struct tty_struct *tty) | ||
470 | { | ||
471 | struct nozomi *ndev = get_dc_by_tty(tty); | ||
472 | return ndev ? &ndev->port[tty->index % MAX_PORT] : NULL; | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * TODO: | ||
477 | * -Optimize | ||
478 | * -Rewrite cleaner | ||
479 | */ | ||
480 | |||
481 | static void read_mem32(u32 *buf, const void __iomem *mem_addr_start, | ||
482 | u32 size_bytes) | ||
483 | { | ||
484 | u32 i = 0; | ||
485 | const u32 *ptr = (__force u32 *) mem_addr_start; | ||
486 | u16 *buf16; | ||
487 | |||
488 | if (unlikely(!ptr || !buf)) | ||
489 | goto out; | ||
490 | |||
491 | /* shortcut for extremely often used cases */ | ||
492 | switch (size_bytes) { | ||
493 | case 2: /* 2 bytes */ | ||
494 | buf16 = (u16 *) buf; | ||
495 | *buf16 = __le16_to_cpu(readw((void __iomem *)ptr)); | ||
496 | goto out; | ||
497 | break; | ||
498 | case 4: /* 4 bytes */ | ||
499 | *(buf) = __le32_to_cpu(readl((void __iomem *)ptr)); | ||
500 | goto out; | ||
501 | break; | ||
502 | } | ||
503 | |||
504 | while (i < size_bytes) { | ||
505 | if (size_bytes - i == 2) { | ||
506 | /* Handle 2 bytes in the end */ | ||
507 | buf16 = (u16 *) buf; | ||
508 | *(buf16) = __le16_to_cpu(readw((void __iomem *)ptr)); | ||
509 | i += 2; | ||
510 | } else { | ||
511 | /* Read 4 bytes */ | ||
512 | *(buf) = __le32_to_cpu(readl((void __iomem *)ptr)); | ||
513 | i += 4; | ||
514 | } | ||
515 | buf++; | ||
516 | ptr++; | ||
517 | } | ||
518 | out: | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | /* | ||
523 | * TODO: | ||
524 | * -Optimize | ||
525 | * -Rewrite cleaner | ||
526 | */ | ||
527 | static u32 write_mem32(void __iomem *mem_addr_start, u32 *buf, | ||
528 | u32 size_bytes) | ||
529 | { | ||
530 | u32 i = 0; | ||
531 | u32 *ptr = (__force u32 *) mem_addr_start; | ||
532 | u16 *buf16; | ||
533 | |||
534 | if (unlikely(!ptr || !buf)) | ||
535 | return 0; | ||
536 | |||
537 | /* shortcut for extremely often used cases */ | ||
538 | switch (size_bytes) { | ||
539 | case 2: /* 2 bytes */ | ||
540 | buf16 = (u16 *) buf; | ||
541 | writew(__cpu_to_le16(*buf16), (void __iomem *)ptr); | ||
542 | return 2; | ||
543 | break; | ||
544 | case 1: /* | ||
545 | * also needs to write 4 bytes in this case | ||
546 | * so falling through.. | ||
547 | */ | ||
548 | case 4: /* 4 bytes */ | ||
549 | writel(__cpu_to_le32(*buf), (void __iomem *)ptr); | ||
550 | return 4; | ||
551 | break; | ||
552 | } | ||
553 | |||
554 | while (i < size_bytes) { | ||
555 | if (size_bytes - i == 2) { | ||
556 | /* 2 bytes */ | ||
557 | buf16 = (u16 *) buf; | ||
558 | writew(__cpu_to_le16(*buf16), (void __iomem *)ptr); | ||
559 | i += 2; | ||
560 | } else { | ||
561 | /* 4 bytes */ | ||
562 | writel(__cpu_to_le32(*buf), (void __iomem *)ptr); | ||
563 | i += 4; | ||
564 | } | ||
565 | buf++; | ||
566 | ptr++; | ||
567 | } | ||
568 | return i; | ||
569 | } | ||
570 | |||
571 | /* Setup pointers to different channels and also setup buffer sizes. */ | ||
572 | static void setup_memory(struct nozomi *dc) | ||
573 | { | ||
574 | void __iomem *offset = dc->base_addr + dc->config_table.dl_start; | ||
575 | /* The length reported is including the length field of 4 bytes, | ||
576 | * hence subtract with 4. | ||
577 | */ | ||
578 | const u16 buff_offset = 4; | ||
579 | |||
580 | /* Modem port dl configuration */ | ||
581 | dc->port[PORT_MDM].dl_addr[CH_A] = offset; | ||
582 | dc->port[PORT_MDM].dl_addr[CH_B] = | ||
583 | (offset += dc->config_table.dl_mdm_len1); | ||
584 | dc->port[PORT_MDM].dl_size[CH_A] = | ||
585 | dc->config_table.dl_mdm_len1 - buff_offset; | ||
586 | dc->port[PORT_MDM].dl_size[CH_B] = | ||
587 | dc->config_table.dl_mdm_len2 - buff_offset; | ||
588 | |||
589 | /* Diag port dl configuration */ | ||
590 | dc->port[PORT_DIAG].dl_addr[CH_A] = | ||
591 | (offset += dc->config_table.dl_mdm_len2); | ||
592 | dc->port[PORT_DIAG].dl_size[CH_A] = | ||
593 | dc->config_table.dl_diag_len1 - buff_offset; | ||
594 | dc->port[PORT_DIAG].dl_addr[CH_B] = | ||
595 | (offset += dc->config_table.dl_diag_len1); | ||
596 | dc->port[PORT_DIAG].dl_size[CH_B] = | ||
597 | dc->config_table.dl_diag_len2 - buff_offset; | ||
598 | |||
599 | /* App1 port dl configuration */ | ||
600 | dc->port[PORT_APP1].dl_addr[CH_A] = | ||
601 | (offset += dc->config_table.dl_diag_len2); | ||
602 | dc->port[PORT_APP1].dl_size[CH_A] = | ||
603 | dc->config_table.dl_app1_len - buff_offset; | ||
604 | |||
605 | /* App2 port dl configuration */ | ||
606 | dc->port[PORT_APP2].dl_addr[CH_A] = | ||
607 | (offset += dc->config_table.dl_app1_len); | ||
608 | dc->port[PORT_APP2].dl_size[CH_A] = | ||
609 | dc->config_table.dl_app2_len - buff_offset; | ||
610 | |||
611 | /* Ctrl dl configuration */ | ||
612 | dc->port[PORT_CTRL].dl_addr[CH_A] = | ||
613 | (offset += dc->config_table.dl_app2_len); | ||
614 | dc->port[PORT_CTRL].dl_size[CH_A] = | ||
615 | dc->config_table.dl_ctrl_len - buff_offset; | ||
616 | |||
617 | offset = dc->base_addr + dc->config_table.ul_start; | ||
618 | |||
619 | /* Modem Port ul configuration */ | ||
620 | dc->port[PORT_MDM].ul_addr[CH_A] = offset; | ||
621 | dc->port[PORT_MDM].ul_size[CH_A] = | ||
622 | dc->config_table.ul_mdm_len1 - buff_offset; | ||
623 | dc->port[PORT_MDM].ul_addr[CH_B] = | ||
624 | (offset += dc->config_table.ul_mdm_len1); | ||
625 | dc->port[PORT_MDM].ul_size[CH_B] = | ||
626 | dc->config_table.ul_mdm_len2 - buff_offset; | ||
627 | |||
628 | /* Diag port ul configuration */ | ||
629 | dc->port[PORT_DIAG].ul_addr[CH_A] = | ||
630 | (offset += dc->config_table.ul_mdm_len2); | ||
631 | dc->port[PORT_DIAG].ul_size[CH_A] = | ||
632 | dc->config_table.ul_diag_len - buff_offset; | ||
633 | |||
634 | /* App1 port ul configuration */ | ||
635 | dc->port[PORT_APP1].ul_addr[CH_A] = | ||
636 | (offset += dc->config_table.ul_diag_len); | ||
637 | dc->port[PORT_APP1].ul_size[CH_A] = | ||
638 | dc->config_table.ul_app1_len - buff_offset; | ||
639 | |||
640 | /* App2 port ul configuration */ | ||
641 | dc->port[PORT_APP2].ul_addr[CH_A] = | ||
642 | (offset += dc->config_table.ul_app1_len); | ||
643 | dc->port[PORT_APP2].ul_size[CH_A] = | ||
644 | dc->config_table.ul_app2_len - buff_offset; | ||
645 | |||
646 | /* Ctrl ul configuration */ | ||
647 | dc->port[PORT_CTRL].ul_addr[CH_A] = | ||
648 | (offset += dc->config_table.ul_app2_len); | ||
649 | dc->port[PORT_CTRL].ul_size[CH_A] = | ||
650 | dc->config_table.ul_ctrl_len - buff_offset; | ||
651 | } | ||
652 | |||
653 | /* Dump config table under initalization phase */ | ||
654 | #ifdef DEBUG | ||
655 | static void dump_table(const struct nozomi *dc) | ||
656 | { | ||
657 | DBG3("signature: 0x%08X", dc->config_table.signature); | ||
658 | DBG3("version: 0x%04X", dc->config_table.version); | ||
659 | DBG3("product_information: 0x%04X", \ | ||
660 | dc->config_table.product_information); | ||
661 | DBG3("toggle enabled: %d", dc->config_table.toggle.enabled); | ||
662 | DBG3("toggle up_mdm: %d", dc->config_table.toggle.mdm_ul); | ||
663 | DBG3("toggle dl_mdm: %d", dc->config_table.toggle.mdm_dl); | ||
664 | DBG3("toggle dl_dbg: %d", dc->config_table.toggle.diag_dl); | ||
665 | |||
666 | DBG3("dl_start: 0x%04X", dc->config_table.dl_start); | ||
667 | DBG3("dl_mdm_len0: 0x%04X, %d", dc->config_table.dl_mdm_len1, | ||
668 | dc->config_table.dl_mdm_len1); | ||
669 | DBG3("dl_mdm_len1: 0x%04X, %d", dc->config_table.dl_mdm_len2, | ||
670 | dc->config_table.dl_mdm_len2); | ||
671 | DBG3("dl_diag_len0: 0x%04X, %d", dc->config_table.dl_diag_len1, | ||
672 | dc->config_table.dl_diag_len1); | ||
673 | DBG3("dl_diag_len1: 0x%04X, %d", dc->config_table.dl_diag_len2, | ||
674 | dc->config_table.dl_diag_len2); | ||
675 | DBG3("dl_app1_len: 0x%04X, %d", dc->config_table.dl_app1_len, | ||
676 | dc->config_table.dl_app1_len); | ||
677 | DBG3("dl_app2_len: 0x%04X, %d", dc->config_table.dl_app2_len, | ||
678 | dc->config_table.dl_app2_len); | ||
679 | DBG3("dl_ctrl_len: 0x%04X, %d", dc->config_table.dl_ctrl_len, | ||
680 | dc->config_table.dl_ctrl_len); | ||
681 | DBG3("ul_start: 0x%04X, %d", dc->config_table.ul_start, | ||
682 | dc->config_table.ul_start); | ||
683 | DBG3("ul_mdm_len[0]: 0x%04X, %d", dc->config_table.ul_mdm_len1, | ||
684 | dc->config_table.ul_mdm_len1); | ||
685 | DBG3("ul_mdm_len[1]: 0x%04X, %d", dc->config_table.ul_mdm_len2, | ||
686 | dc->config_table.ul_mdm_len2); | ||
687 | DBG3("ul_diag_len: 0x%04X, %d", dc->config_table.ul_diag_len, | ||
688 | dc->config_table.ul_diag_len); | ||
689 | DBG3("ul_app1_len: 0x%04X, %d", dc->config_table.ul_app1_len, | ||
690 | dc->config_table.ul_app1_len); | ||
691 | DBG3("ul_app2_len: 0x%04X, %d", dc->config_table.ul_app2_len, | ||
692 | dc->config_table.ul_app2_len); | ||
693 | DBG3("ul_ctrl_len: 0x%04X, %d", dc->config_table.ul_ctrl_len, | ||
694 | dc->config_table.ul_ctrl_len); | ||
695 | } | ||
696 | #else | ||
697 | static __inline__ void dump_table(const struct nozomi *dc) { } | ||
698 | #endif | ||
699 | |||
700 | /* | ||
701 | * Read configuration table from card under intalization phase | ||
702 | * Returns 1 if ok, else 0 | ||
703 | */ | ||
704 | static int nozomi_read_config_table(struct nozomi *dc) | ||
705 | { | ||
706 | read_mem32((u32 *) &dc->config_table, dc->base_addr + 0, | ||
707 | sizeof(struct config_table)); | ||
708 | |||
709 | if (dc->config_table.signature != CONFIG_MAGIC) { | ||
710 | dev_err(&dc->pdev->dev, "ConfigTable Bad! 0x%08X != 0x%08X\n", | ||
711 | dc->config_table.signature, CONFIG_MAGIC); | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | if ((dc->config_table.version == 0) | ||
716 | || (dc->config_table.toggle.enabled == TOGGLE_VALID)) { | ||
717 | int i; | ||
718 | DBG1("Second phase, configuring card"); | ||
719 | |||
720 | setup_memory(dc); | ||
721 | |||
722 | dc->port[PORT_MDM].toggle_ul = dc->config_table.toggle.mdm_ul; | ||
723 | dc->port[PORT_MDM].toggle_dl = dc->config_table.toggle.mdm_dl; | ||
724 | dc->port[PORT_DIAG].toggle_dl = dc->config_table.toggle.diag_dl; | ||
725 | DBG1("toggle ports: MDM UL:%d MDM DL:%d, DIAG DL:%d", | ||
726 | dc->port[PORT_MDM].toggle_ul, | ||
727 | dc->port[PORT_MDM].toggle_dl, dc->port[PORT_DIAG].toggle_dl); | ||
728 | |||
729 | dump_table(dc); | ||
730 | |||
731 | for (i = PORT_MDM; i < MAX_PORT; i++) { | ||
732 | dc->port[i].fifo_ul = | ||
733 | kfifo_alloc(FIFO_BUFFER_SIZE_UL, GFP_ATOMIC, NULL); | ||
734 | memset(&dc->port[i].ctrl_dl, 0, sizeof(struct ctrl_dl)); | ||
735 | memset(&dc->port[i].ctrl_ul, 0, sizeof(struct ctrl_ul)); | ||
736 | } | ||
737 | |||
738 | /* Enable control channel */ | ||
739 | dc->last_ier = dc->last_ier | CTRL_DL; | ||
740 | writew(dc->last_ier, dc->reg_ier); | ||
741 | |||
742 | dev_info(&dc->pdev->dev, "Initialization OK!\n"); | ||
743 | return 1; | ||
744 | } | ||
745 | |||
746 | if ((dc->config_table.version > 0) | ||
747 | && (dc->config_table.toggle.enabled != TOGGLE_VALID)) { | ||
748 | u32 offset = 0; | ||
749 | DBG1("First phase: pushing upload buffers, clearing download"); | ||
750 | |||
751 | dev_info(&dc->pdev->dev, "Version of card: %d\n", | ||
752 | dc->config_table.version); | ||
753 | |||
754 | /* Here we should disable all I/O over F32. */ | ||
755 | setup_memory(dc); | ||
756 | |||
757 | /* | ||
758 | * We should send ALL channel pair tokens back along | ||
759 | * with reset token | ||
760 | */ | ||
761 | |||
762 | /* push upload modem buffers */ | ||
763 | write_mem32(dc->port[PORT_MDM].ul_addr[CH_A], | ||
764 | (u32 *) &offset, 4); | ||
765 | write_mem32(dc->port[PORT_MDM].ul_addr[CH_B], | ||
766 | (u32 *) &offset, 4); | ||
767 | |||
768 | writew(MDM_UL | DIAG_DL | MDM_DL, dc->reg_fcr); | ||
769 | |||
770 | DBG1("First phase done"); | ||
771 | } | ||
772 | |||
773 | return 1; | ||
774 | } | ||
775 | |||
776 | /* Enable uplink interrupts */ | ||
777 | static void enable_transmit_ul(enum port_type port, struct nozomi *dc) | ||
778 | { | ||
779 | u16 mask[NOZOMI_MAX_PORTS] = \ | ||
780 | {MDM_UL, DIAG_UL, APP1_UL, APP2_UL, CTRL_UL}; | ||
781 | |||
782 | if (port < NOZOMI_MAX_PORTS) { | ||
783 | dc->last_ier |= mask[port]; | ||
784 | writew(dc->last_ier, dc->reg_ier); | ||
785 | } else { | ||
786 | dev_err(&dc->pdev->dev, "Called with wrong port?\n"); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | /* Disable uplink interrupts */ | ||
791 | static void disable_transmit_ul(enum port_type port, struct nozomi *dc) | ||
792 | { | ||
793 | u16 mask[NOZOMI_MAX_PORTS] = \ | ||
794 | {~MDM_UL, ~DIAG_UL, ~APP1_UL, ~APP2_UL, ~CTRL_UL}; | ||
795 | |||
796 | if (port < NOZOMI_MAX_PORTS) { | ||
797 | dc->last_ier &= mask[port]; | ||
798 | writew(dc->last_ier, dc->reg_ier); | ||
799 | } else { | ||
800 | dev_err(&dc->pdev->dev, "Called with wrong port?\n"); | ||
801 | } | ||
802 | } | ||
803 | |||
804 | /* Enable downlink interrupts */ | ||
805 | static void enable_transmit_dl(enum port_type port, struct nozomi *dc) | ||
806 | { | ||
807 | u16 mask[NOZOMI_MAX_PORTS] = \ | ||
808 | {MDM_DL, DIAG_DL, APP1_DL, APP2_DL, CTRL_DL}; | ||
809 | |||
810 | if (port < NOZOMI_MAX_PORTS) { | ||
811 | dc->last_ier |= mask[port]; | ||
812 | writew(dc->last_ier, dc->reg_ier); | ||
813 | } else { | ||
814 | dev_err(&dc->pdev->dev, "Called with wrong port?\n"); | ||
815 | } | ||
816 | } | ||
817 | |||
818 | /* Disable downlink interrupts */ | ||
819 | static void disable_transmit_dl(enum port_type port, struct nozomi *dc) | ||
820 | { | ||
821 | u16 mask[NOZOMI_MAX_PORTS] = \ | ||
822 | {~MDM_DL, ~DIAG_DL, ~APP1_DL, ~APP2_DL, ~CTRL_DL}; | ||
823 | |||
824 | if (port < NOZOMI_MAX_PORTS) { | ||
825 | dc->last_ier &= mask[port]; | ||
826 | writew(dc->last_ier, dc->reg_ier); | ||
827 | } else { | ||
828 | dev_err(&dc->pdev->dev, "Called with wrong port?\n"); | ||
829 | } | ||
830 | } | ||
831 | |||
832 | /* | ||
833 | * Return 1 - send buffer to card and ack. | ||
834 | * Return 0 - don't ack, don't send buffer to card. | ||
835 | */ | ||
836 | static int send_data(enum port_type index, struct nozomi *dc) | ||
837 | { | ||
838 | u32 size = 0; | ||
839 | struct port *port = &dc->port[index]; | ||
840 | u8 toggle = port->toggle_ul; | ||
841 | void __iomem *addr = port->ul_addr[toggle]; | ||
842 | u32 ul_size = port->ul_size[toggle]; | ||
843 | struct tty_struct *tty = port->tty; | ||
844 | |||
845 | /* Get data from tty and place in buf for now */ | ||
846 | size = __kfifo_get(port->fifo_ul, dc->send_buf, | ||
847 | ul_size < SEND_BUF_MAX ? ul_size : SEND_BUF_MAX); | ||
848 | |||
849 | if (size == 0) { | ||
850 | DBG4("No more data to send, disable link:"); | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | /* DUMP(buf, size); */ | ||
855 | |||
856 | /* Write length + data */ | ||
857 | write_mem32(addr, (u32 *) &size, 4); | ||
858 | write_mem32(addr + 4, (u32 *) dc->send_buf, size); | ||
859 | |||
860 | if (tty) | ||
861 | tty_wakeup(tty); | ||
862 | |||
863 | return 1; | ||
864 | } | ||
865 | |||
866 | /* If all data has been read, return 1, else 0 */ | ||
867 | static int receive_data(enum port_type index, struct nozomi *dc) | ||
868 | { | ||
869 | u8 buf[RECEIVE_BUF_MAX] = { 0 }; | ||
870 | int size; | ||
871 | u32 offset = 4; | ||
872 | struct port *port = &dc->port[index]; | ||
873 | void __iomem *addr = port->dl_addr[port->toggle_dl]; | ||
874 | struct tty_struct *tty = port->tty; | ||
875 | int i; | ||
876 | |||
877 | if (unlikely(!tty)) { | ||
878 | DBG1("tty not open for port: %d?", index); | ||
879 | return 1; | ||
880 | } | ||
881 | |||
882 | read_mem32((u32 *) &size, addr, 4); | ||
883 | /* DBG1( "%d bytes port: %d", size, index); */ | ||
884 | |||
885 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | ||
886 | DBG1("No room in tty, don't read data, don't ack interrupt, " | ||
887 | "disable interrupt"); | ||
888 | |||
889 | /* disable interrupt in downlink... */ | ||
890 | disable_transmit_dl(index, dc); | ||
891 | return 0; | ||
892 | } | ||
893 | |||
894 | if (unlikely(size == 0)) { | ||
895 | dev_err(&dc->pdev->dev, "size == 0?\n"); | ||
896 | return 1; | ||
897 | } | ||
898 | |||
899 | tty_buffer_request_room(tty, size); | ||
900 | |||
901 | while (size > 0) { | ||
902 | read_mem32((u32 *) buf, addr + offset, RECEIVE_BUF_MAX); | ||
903 | |||
904 | if (size == 1) { | ||
905 | tty_insert_flip_char(tty, buf[0], TTY_NORMAL); | ||
906 | size = 0; | ||
907 | } else if (size < RECEIVE_BUF_MAX) { | ||
908 | size -= tty_insert_flip_string(tty, (char *) buf, size); | ||
909 | } else { | ||
910 | i = tty_insert_flip_string(tty, \ | ||
911 | (char *) buf, RECEIVE_BUF_MAX); | ||
912 | size -= i; | ||
913 | offset += i; | ||
914 | } | ||
915 | } | ||
916 | |||
917 | set_bit(index, &dc->flip); | ||
918 | |||
919 | return 1; | ||
920 | } | ||
921 | |||
922 | /* Debug for interrupts */ | ||
923 | #ifdef DEBUG | ||
924 | static char *interrupt2str(u16 interrupt) | ||
925 | { | ||
926 | static char buf[TMP_BUF_MAX]; | ||
927 | char *p = buf; | ||
928 | |||
929 | interrupt & MDM_DL1 ? p += snprintf(p, TMP_BUF_MAX, "MDM_DL1 ") : NULL; | ||
930 | interrupt & MDM_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
931 | "MDM_DL2 ") : NULL; | ||
932 | |||
933 | interrupt & MDM_UL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
934 | "MDM_UL1 ") : NULL; | ||
935 | interrupt & MDM_UL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
936 | "MDM_UL2 ") : NULL; | ||
937 | |||
938 | interrupt & DIAG_DL1 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
939 | "DIAG_DL1 ") : NULL; | ||
940 | interrupt & DIAG_DL2 ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
941 | "DIAG_DL2 ") : NULL; | ||
942 | |||
943 | interrupt & DIAG_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
944 | "DIAG_UL ") : NULL; | ||
945 | |||
946 | interrupt & APP1_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
947 | "APP1_DL ") : NULL; | ||
948 | interrupt & APP2_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
949 | "APP2_DL ") : NULL; | ||
950 | |||
951 | interrupt & APP1_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
952 | "APP1_UL ") : NULL; | ||
953 | interrupt & APP2_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
954 | "APP2_UL ") : NULL; | ||
955 | |||
956 | interrupt & CTRL_DL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
957 | "CTRL_DL ") : NULL; | ||
958 | interrupt & CTRL_UL ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
959 | "CTRL_UL ") : NULL; | ||
960 | |||
961 | interrupt & RESET ? p += snprintf(p, TMP_BUF_MAX - (p - buf), | ||
962 | "RESET ") : NULL; | ||
963 | |||
964 | return buf; | ||
965 | } | ||
966 | #endif | ||
967 | |||
968 | /* | ||
969 | * Receive flow control | ||
970 | * Return 1 - If ok, else 0 | ||
971 | */ | ||
972 | static int receive_flow_control(struct nozomi *dc) | ||
973 | { | ||
974 | enum port_type port = PORT_MDM; | ||
975 | struct ctrl_dl ctrl_dl; | ||
976 | struct ctrl_dl old_ctrl; | ||
977 | u16 enable_ier = 0; | ||
978 | |||
979 | read_mem32((u32 *) &ctrl_dl, dc->port[PORT_CTRL].dl_addr[CH_A], 2); | ||
980 | |||
981 | switch (ctrl_dl.port) { | ||
982 | case CTRL_CMD: | ||
983 | DBG1("The Base Band sends this value as a response to a " | ||
984 | "request for IMSI detach sent over the control " | ||
985 | "channel uplink (see section 7.6.1)."); | ||
986 | break; | ||
987 | case CTRL_MDM: | ||
988 | port = PORT_MDM; | ||
989 | enable_ier = MDM_DL; | ||
990 | break; | ||
991 | case CTRL_DIAG: | ||
992 | port = PORT_DIAG; | ||
993 | enable_ier = DIAG_DL; | ||
994 | break; | ||
995 | case CTRL_APP1: | ||
996 | port = PORT_APP1; | ||
997 | enable_ier = APP1_DL; | ||
998 | break; | ||
999 | case CTRL_APP2: | ||
1000 | port = PORT_APP2; | ||
1001 | enable_ier = APP2_DL; | ||
1002 | break; | ||
1003 | default: | ||
1004 | dev_err(&dc->pdev->dev, | ||
1005 | "ERROR: flow control received for non-existing port\n"); | ||
1006 | return 0; | ||
1007 | }; | ||
1008 | |||
1009 | DBG1("0x%04X->0x%04X", *((u16 *)&dc->port[port].ctrl_dl), | ||
1010 | *((u16 *)&ctrl_dl)); | ||
1011 | |||
1012 | old_ctrl = dc->port[port].ctrl_dl; | ||
1013 | dc->port[port].ctrl_dl = ctrl_dl; | ||
1014 | |||
1015 | if (old_ctrl.CTS == 1 && ctrl_dl.CTS == 0) { | ||
1016 | DBG1("Disable interrupt (0x%04X) on port: %d", | ||
1017 | enable_ier, port); | ||
1018 | disable_transmit_ul(port, dc); | ||
1019 | |||
1020 | } else if (old_ctrl.CTS == 0 && ctrl_dl.CTS == 1) { | ||
1021 | |||
1022 | if (__kfifo_len(dc->port[port].fifo_ul)) { | ||
1023 | DBG1("Enable interrupt (0x%04X) on port: %d", | ||
1024 | enable_ier, port); | ||
1025 | DBG1("Data in buffer [%d], enable transmit! ", | ||
1026 | __kfifo_len(dc->port[port].fifo_ul)); | ||
1027 | enable_transmit_ul(port, dc); | ||
1028 | } else { | ||
1029 | DBG1("No data in buffer..."); | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | if (*(u16 *)&old_ctrl == *(u16 *)&ctrl_dl) { | ||
1034 | DBG1(" No change in mctrl"); | ||
1035 | return 1; | ||
1036 | } | ||
1037 | /* Update statistics */ | ||
1038 | if (old_ctrl.CTS != ctrl_dl.CTS) | ||
1039 | dc->port[port].tty_icount.cts++; | ||
1040 | if (old_ctrl.DSR != ctrl_dl.DSR) | ||
1041 | dc->port[port].tty_icount.dsr++; | ||
1042 | if (old_ctrl.RI != ctrl_dl.RI) | ||
1043 | dc->port[port].tty_icount.rng++; | ||
1044 | if (old_ctrl.DCD != ctrl_dl.DCD) | ||
1045 | dc->port[port].tty_icount.dcd++; | ||
1046 | |||
1047 | wake_up_interruptible(&dc->port[port].tty_wait); | ||
1048 | |||
1049 | DBG1("port: %d DCD(%d), CTS(%d), RI(%d), DSR(%d)", | ||
1050 | port, | ||
1051 | dc->port[port].tty_icount.dcd, dc->port[port].tty_icount.cts, | ||
1052 | dc->port[port].tty_icount.rng, dc->port[port].tty_icount.dsr); | ||
1053 | |||
1054 | return 1; | ||
1055 | } | ||
1056 | |||
1057 | static enum ctrl_port_type port2ctrl(enum port_type port, | ||
1058 | const struct nozomi *dc) | ||
1059 | { | ||
1060 | switch (port) { | ||
1061 | case PORT_MDM: | ||
1062 | return CTRL_MDM; | ||
1063 | case PORT_DIAG: | ||
1064 | return CTRL_DIAG; | ||
1065 | case PORT_APP1: | ||
1066 | return CTRL_APP1; | ||
1067 | case PORT_APP2: | ||
1068 | return CTRL_APP2; | ||
1069 | default: | ||
1070 | dev_err(&dc->pdev->dev, | ||
1071 | "ERROR: send flow control " \ | ||
1072 | "received for non-existing port\n"); | ||
1073 | }; | ||
1074 | return CTRL_ERROR; | ||
1075 | } | ||
1076 | |||
1077 | /* | ||
1078 | * Send flow control, can only update one channel at a time | ||
1079 | * Return 0 - If we have updated all flow control | ||
1080 | * Return 1 - If we need to update more flow control, ack current enable more | ||
1081 | */ | ||
1082 | static int send_flow_control(struct nozomi *dc) | ||
1083 | { | ||
1084 | u32 i, more_flow_control_to_be_updated = 0; | ||
1085 | u16 *ctrl; | ||
1086 | |||
1087 | for (i = PORT_MDM; i < MAX_PORT; i++) { | ||
1088 | if (dc->port[i].update_flow_control) { | ||
1089 | if (more_flow_control_to_be_updated) { | ||
1090 | /* We have more flow control to be updated */ | ||
1091 | return 1; | ||
1092 | } | ||
1093 | dc->port[i].ctrl_ul.port = port2ctrl(i, dc); | ||
1094 | ctrl = (u16 *)&dc->port[i].ctrl_ul; | ||
1095 | write_mem32(dc->port[PORT_CTRL].ul_addr[0], \ | ||
1096 | (u32 *) ctrl, 2); | ||
1097 | dc->port[i].update_flow_control = 0; | ||
1098 | more_flow_control_to_be_updated = 1; | ||
1099 | } | ||
1100 | } | ||
1101 | return 0; | ||
1102 | } | ||
1103 | |||
1104 | /* | ||
1105 | * Handle donlink data, ports that are handled are modem and diagnostics | ||
1106 | * Return 1 - ok | ||
1107 | * Return 0 - toggle fields are out of sync | ||
1108 | */ | ||
1109 | static int handle_data_dl(struct nozomi *dc, enum port_type port, u8 *toggle, | ||
1110 | u16 read_iir, u16 mask1, u16 mask2) | ||
1111 | { | ||
1112 | if (*toggle == 0 && read_iir & mask1) { | ||
1113 | if (receive_data(port, dc)) { | ||
1114 | writew(mask1, dc->reg_fcr); | ||
1115 | *toggle = !(*toggle); | ||
1116 | } | ||
1117 | |||
1118 | if (read_iir & mask2) { | ||
1119 | if (receive_data(port, dc)) { | ||
1120 | writew(mask2, dc->reg_fcr); | ||
1121 | *toggle = !(*toggle); | ||
1122 | } | ||
1123 | } | ||
1124 | } else if (*toggle == 1 && read_iir & mask2) { | ||
1125 | if (receive_data(port, dc)) { | ||
1126 | writew(mask2, dc->reg_fcr); | ||
1127 | *toggle = !(*toggle); | ||
1128 | } | ||
1129 | |||
1130 | if (read_iir & mask1) { | ||
1131 | if (receive_data(port, dc)) { | ||
1132 | writew(mask1, dc->reg_fcr); | ||
1133 | *toggle = !(*toggle); | ||
1134 | } | ||
1135 | } | ||
1136 | } else { | ||
1137 | dev_err(&dc->pdev->dev, "port out of sync!, toggle:%d\n", | ||
1138 | *toggle); | ||
1139 | return 0; | ||
1140 | } | ||
1141 | return 1; | ||
1142 | } | ||
1143 | |||
1144 | /* | ||
1145 | * Handle uplink data, this is currently for the modem port | ||
1146 | * Return 1 - ok | ||
1147 | * Return 0 - toggle field are out of sync | ||
1148 | */ | ||
1149 | static int handle_data_ul(struct nozomi *dc, enum port_type port, u16 read_iir) | ||
1150 | { | ||
1151 | u8 *toggle = &(dc->port[port].toggle_ul); | ||
1152 | |||
1153 | if (*toggle == 0 && read_iir & MDM_UL1) { | ||
1154 | dc->last_ier &= ~MDM_UL; | ||
1155 | writew(dc->last_ier, dc->reg_ier); | ||
1156 | if (send_data(port, dc)) { | ||
1157 | writew(MDM_UL1, dc->reg_fcr); | ||
1158 | dc->last_ier = dc->last_ier | MDM_UL; | ||
1159 | writew(dc->last_ier, dc->reg_ier); | ||
1160 | *toggle = !*toggle; | ||
1161 | } | ||
1162 | |||
1163 | if (read_iir & MDM_UL2) { | ||
1164 | dc->last_ier &= ~MDM_UL; | ||
1165 | writew(dc->last_ier, dc->reg_ier); | ||
1166 | if (send_data(port, dc)) { | ||
1167 | writew(MDM_UL2, dc->reg_fcr); | ||
1168 | dc->last_ier = dc->last_ier | MDM_UL; | ||
1169 | writew(dc->last_ier, dc->reg_ier); | ||
1170 | *toggle = !*toggle; | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | } else if (*toggle == 1 && read_iir & MDM_UL2) { | ||
1175 | dc->last_ier &= ~MDM_UL; | ||
1176 | writew(dc->last_ier, dc->reg_ier); | ||
1177 | if (send_data(port, dc)) { | ||
1178 | writew(MDM_UL2, dc->reg_fcr); | ||
1179 | dc->last_ier = dc->last_ier | MDM_UL; | ||
1180 | writew(dc->last_ier, dc->reg_ier); | ||
1181 | *toggle = !*toggle; | ||
1182 | } | ||
1183 | |||
1184 | if (read_iir & MDM_UL1) { | ||
1185 | dc->last_ier &= ~MDM_UL; | ||
1186 | writew(dc->last_ier, dc->reg_ier); | ||
1187 | if (send_data(port, dc)) { | ||
1188 | writew(MDM_UL1, dc->reg_fcr); | ||
1189 | dc->last_ier = dc->last_ier | MDM_UL; | ||
1190 | writew(dc->last_ier, dc->reg_ier); | ||
1191 | *toggle = !*toggle; | ||
1192 | } | ||
1193 | } | ||
1194 | } else { | ||
1195 | writew(read_iir & MDM_UL, dc->reg_fcr); | ||
1196 | dev_err(&dc->pdev->dev, "port out of sync!\n"); | ||
1197 | return 0; | ||
1198 | } | ||
1199 | return 1; | ||
1200 | } | ||
1201 | |||
1202 | static irqreturn_t interrupt_handler(int irq, void *dev_id) | ||
1203 | { | ||
1204 | struct nozomi *dc = dev_id; | ||
1205 | unsigned int a; | ||
1206 | u16 read_iir; | ||
1207 | |||
1208 | if (!dc) | ||
1209 | return IRQ_NONE; | ||
1210 | |||
1211 | spin_lock(&dc->spin_mutex); | ||
1212 | read_iir = readw(dc->reg_iir); | ||
1213 | |||
1214 | /* Card removed */ | ||
1215 | if (read_iir == (u16)-1) | ||
1216 | goto none; | ||
1217 | /* | ||
1218 | * Just handle interrupt enabled in IER | ||
1219 | * (by masking with dc->last_ier) | ||
1220 | */ | ||
1221 | read_iir &= dc->last_ier; | ||
1222 | |||
1223 | if (read_iir == 0) | ||
1224 | goto none; | ||
1225 | |||
1226 | |||
1227 | DBG4("%s irq:0x%04X, prev:0x%04X", interrupt2str(read_iir), read_iir, | ||
1228 | dc->last_ier); | ||
1229 | |||
1230 | if (read_iir & RESET) { | ||
1231 | if (unlikely(!nozomi_read_config_table(dc))) { | ||
1232 | dc->last_ier = 0x0; | ||
1233 | writew(dc->last_ier, dc->reg_ier); | ||
1234 | dev_err(&dc->pdev->dev, "Could not read status from " | ||
1235 | "card, we should disable interface\n"); | ||
1236 | } else { | ||
1237 | writew(RESET, dc->reg_fcr); | ||
1238 | } | ||
1239 | /* No more useful info if this was the reset interrupt. */ | ||
1240 | goto exit_handler; | ||
1241 | } | ||
1242 | if (read_iir & CTRL_UL) { | ||
1243 | DBG1("CTRL_UL"); | ||
1244 | dc->last_ier &= ~CTRL_UL; | ||
1245 | writew(dc->last_ier, dc->reg_ier); | ||
1246 | if (send_flow_control(dc)) { | ||
1247 | writew(CTRL_UL, dc->reg_fcr); | ||
1248 | dc->last_ier = dc->last_ier | CTRL_UL; | ||
1249 | writew(dc->last_ier, dc->reg_ier); | ||
1250 | } | ||
1251 | } | ||
1252 | if (read_iir & CTRL_DL) { | ||
1253 | receive_flow_control(dc); | ||
1254 | writew(CTRL_DL, dc->reg_fcr); | ||
1255 | } | ||
1256 | if (read_iir & MDM_DL) { | ||
1257 | if (!handle_data_dl(dc, PORT_MDM, | ||
1258 | &(dc->port[PORT_MDM].toggle_dl), read_iir, | ||
1259 | MDM_DL1, MDM_DL2)) { | ||
1260 | dev_err(&dc->pdev->dev, "MDM_DL out of sync!\n"); | ||
1261 | goto exit_handler; | ||
1262 | } | ||
1263 | } | ||
1264 | if (read_iir & MDM_UL) { | ||
1265 | if (!handle_data_ul(dc, PORT_MDM, read_iir)) { | ||
1266 | dev_err(&dc->pdev->dev, "MDM_UL out of sync!\n"); | ||
1267 | goto exit_handler; | ||
1268 | } | ||
1269 | } | ||
1270 | if (read_iir & DIAG_DL) { | ||
1271 | if (!handle_data_dl(dc, PORT_DIAG, | ||
1272 | &(dc->port[PORT_DIAG].toggle_dl), read_iir, | ||
1273 | DIAG_DL1, DIAG_DL2)) { | ||
1274 | dev_err(&dc->pdev->dev, "DIAG_DL out of sync!\n"); | ||
1275 | goto exit_handler; | ||
1276 | } | ||
1277 | } | ||
1278 | if (read_iir & DIAG_UL) { | ||
1279 | dc->last_ier &= ~DIAG_UL; | ||
1280 | writew(dc->last_ier, dc->reg_ier); | ||
1281 | if (send_data(PORT_DIAG, dc)) { | ||
1282 | writew(DIAG_UL, dc->reg_fcr); | ||
1283 | dc->last_ier = dc->last_ier | DIAG_UL; | ||
1284 | writew(dc->last_ier, dc->reg_ier); | ||
1285 | } | ||
1286 | } | ||
1287 | if (read_iir & APP1_DL) { | ||
1288 | if (receive_data(PORT_APP1, dc)) | ||
1289 | writew(APP1_DL, dc->reg_fcr); | ||
1290 | } | ||
1291 | if (read_iir & APP1_UL) { | ||
1292 | dc->last_ier &= ~APP1_UL; | ||
1293 | writew(dc->last_ier, dc->reg_ier); | ||
1294 | if (send_data(PORT_APP1, dc)) { | ||
1295 | writew(APP1_UL, dc->reg_fcr); | ||
1296 | dc->last_ier = dc->last_ier | APP1_UL; | ||
1297 | writew(dc->last_ier, dc->reg_ier); | ||
1298 | } | ||
1299 | } | ||
1300 | if (read_iir & APP2_DL) { | ||
1301 | if (receive_data(PORT_APP2, dc)) | ||
1302 | writew(APP2_DL, dc->reg_fcr); | ||
1303 | } | ||
1304 | if (read_iir & APP2_UL) { | ||
1305 | dc->last_ier &= ~APP2_UL; | ||
1306 | writew(dc->last_ier, dc->reg_ier); | ||
1307 | if (send_data(PORT_APP2, dc)) { | ||
1308 | writew(APP2_UL, dc->reg_fcr); | ||
1309 | dc->last_ier = dc->last_ier | APP2_UL; | ||
1310 | writew(dc->last_ier, dc->reg_ier); | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | exit_handler: | ||
1315 | spin_unlock(&dc->spin_mutex); | ||
1316 | for (a = 0; a < NOZOMI_MAX_PORTS; a++) | ||
1317 | if (test_and_clear_bit(a, &dc->flip)) | ||
1318 | tty_flip_buffer_push(dc->port[a].tty); | ||
1319 | return IRQ_HANDLED; | ||
1320 | none: | ||
1321 | spin_unlock(&dc->spin_mutex); | ||
1322 | return IRQ_NONE; | ||
1323 | } | ||
1324 | |||
1325 | static void nozomi_get_card_type(struct nozomi *dc) | ||
1326 | { | ||
1327 | int i; | ||
1328 | u32 size = 0; | ||
1329 | |||
1330 | for (i = 0; i < 6; i++) | ||
1331 | size += pci_resource_len(dc->pdev, i); | ||
1332 | |||
1333 | /* Assume card type F32_8 if no match */ | ||
1334 | dc->card_type = size == 2048 ? F32_2 : F32_8; | ||
1335 | |||
1336 | dev_info(&dc->pdev->dev, "Card type is: %d\n", dc->card_type); | ||
1337 | } | ||
1338 | |||
1339 | static void nozomi_setup_private_data(struct nozomi *dc) | ||
1340 | { | ||
1341 | void __iomem *offset = dc->base_addr + dc->card_type / 2; | ||
1342 | unsigned int i; | ||
1343 | |||
1344 | dc->reg_fcr = (void __iomem *)(offset + R_FCR); | ||
1345 | dc->reg_iir = (void __iomem *)(offset + R_IIR); | ||
1346 | dc->reg_ier = (void __iomem *)(offset + R_IER); | ||
1347 | dc->last_ier = 0; | ||
1348 | dc->flip = 0; | ||
1349 | |||
1350 | dc->port[PORT_MDM].token_dl = MDM_DL; | ||
1351 | dc->port[PORT_DIAG].token_dl = DIAG_DL; | ||
1352 | dc->port[PORT_APP1].token_dl = APP1_DL; | ||
1353 | dc->port[PORT_APP2].token_dl = APP2_DL; | ||
1354 | |||
1355 | for (i = 0; i < MAX_PORT; i++) | ||
1356 | init_waitqueue_head(&dc->port[i].tty_wait); | ||
1357 | } | ||
1358 | |||
1359 | static ssize_t card_type_show(struct device *dev, struct device_attribute *attr, | ||
1360 | char *buf) | ||
1361 | { | ||
1362 | struct nozomi *dc = pci_get_drvdata(to_pci_dev(dev)); | ||
1363 | |||
1364 | return sprintf(buf, "%d\n", dc->card_type); | ||
1365 | } | ||
1366 | static DEVICE_ATTR(card_type, 0444, card_type_show, NULL); | ||
1367 | |||
1368 | static ssize_t open_ttys_show(struct device *dev, struct device_attribute *attr, | ||
1369 | char *buf) | ||
1370 | { | ||
1371 | struct nozomi *dc = pci_get_drvdata(to_pci_dev(dev)); | ||
1372 | |||
1373 | return sprintf(buf, "%u\n", dc->open_ttys); | ||
1374 | } | ||
1375 | static DEVICE_ATTR(open_ttys, 0444, open_ttys_show, NULL); | ||
1376 | |||
1377 | static void make_sysfs_files(struct nozomi *dc) | ||
1378 | { | ||
1379 | if (device_create_file(&dc->pdev->dev, &dev_attr_card_type)) | ||
1380 | dev_err(&dc->pdev->dev, | ||
1381 | "Could not create sysfs file for card_type\n"); | ||
1382 | if (device_create_file(&dc->pdev->dev, &dev_attr_open_ttys)) | ||
1383 | dev_err(&dc->pdev->dev, | ||
1384 | "Could not create sysfs file for open_ttys\n"); | ||
1385 | } | ||
1386 | |||
1387 | static void remove_sysfs_files(struct nozomi *dc) | ||
1388 | { | ||
1389 | device_remove_file(&dc->pdev->dev, &dev_attr_card_type); | ||
1390 | device_remove_file(&dc->pdev->dev, &dev_attr_open_ttys); | ||
1391 | } | ||
1392 | |||
1393 | /* Allocate memory for one device */ | ||
1394 | static int __devinit nozomi_card_init(struct pci_dev *pdev, | ||
1395 | const struct pci_device_id *ent) | ||
1396 | { | ||
1397 | resource_size_t start; | ||
1398 | int ret; | ||
1399 | struct nozomi *dc = NULL; | ||
1400 | int ndev_idx; | ||
1401 | int i; | ||
1402 | |||
1403 | dev_dbg(&pdev->dev, "Init, new card found\n"); | ||
1404 | |||
1405 | for (ndev_idx = 0; ndev_idx < ARRAY_SIZE(ndevs); ndev_idx++) | ||
1406 | if (!ndevs[ndev_idx]) | ||
1407 | break; | ||
1408 | |||
1409 | if (ndev_idx >= ARRAY_SIZE(ndevs)) { | ||
1410 | dev_err(&pdev->dev, "no free tty range for this card left\n"); | ||
1411 | ret = -EIO; | ||
1412 | goto err; | ||
1413 | } | ||
1414 | |||
1415 | dc = kzalloc(sizeof(struct nozomi), GFP_KERNEL); | ||
1416 | if (unlikely(!dc)) { | ||
1417 | dev_err(&pdev->dev, "Could not allocate memory\n"); | ||
1418 | ret = -ENOMEM; | ||
1419 | goto err_free; | ||
1420 | } | ||
1421 | |||
1422 | dc->pdev = pdev; | ||
1423 | |||
1424 | /* Find out what card type it is */ | ||
1425 | nozomi_get_card_type(dc); | ||
1426 | |||
1427 | ret = pci_enable_device(dc->pdev); | ||
1428 | if (ret) { | ||
1429 | dev_err(&pdev->dev, "Failed to enable PCI Device\n"); | ||
1430 | goto err_free; | ||
1431 | } | ||
1432 | |||
1433 | start = pci_resource_start(dc->pdev, 0); | ||
1434 | if (start == 0) { | ||
1435 | dev_err(&pdev->dev, "No I/O address for card detected\n"); | ||
1436 | ret = -ENODEV; | ||
1437 | goto err_disable_device; | ||
1438 | } | ||
1439 | |||
1440 | ret = pci_request_regions(dc->pdev, NOZOMI_NAME); | ||
1441 | if (ret) { | ||
1442 | dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", | ||
1443 | (int) /* nozomi_private.io_addr */ 0); | ||
1444 | goto err_disable_device; | ||
1445 | } | ||
1446 | |||
1447 | dc->base_addr = ioremap(start, dc->card_type); | ||
1448 | if (!dc->base_addr) { | ||
1449 | dev_err(&pdev->dev, "Unable to map card MMIO\n"); | ||
1450 | ret = -ENODEV; | ||
1451 | goto err_rel_regs; | ||
1452 | } | ||
1453 | |||
1454 | dc->send_buf = kmalloc(SEND_BUF_MAX, GFP_KERNEL); | ||
1455 | if (!dc->send_buf) { | ||
1456 | dev_err(&pdev->dev, "Could not allocate send buffer?\n"); | ||
1457 | ret = -ENOMEM; | ||
1458 | goto err_free_sbuf; | ||
1459 | } | ||
1460 | |||
1461 | spin_lock_init(&dc->spin_mutex); | ||
1462 | |||
1463 | nozomi_setup_private_data(dc); | ||
1464 | |||
1465 | /* Disable all interrupts */ | ||
1466 | dc->last_ier = 0; | ||
1467 | writew(dc->last_ier, dc->reg_ier); | ||
1468 | |||
1469 | ret = request_irq(pdev->irq, &interrupt_handler, IRQF_SHARED, | ||
1470 | NOZOMI_NAME, dc); | ||
1471 | if (unlikely(ret)) { | ||
1472 | dev_err(&pdev->dev, "can't request irq %d\n", pdev->irq); | ||
1473 | goto err_free_sbuf; | ||
1474 | } | ||
1475 | |||
1476 | DBG1("base_addr: %p", dc->base_addr); | ||
1477 | |||
1478 | make_sysfs_files(dc); | ||
1479 | |||
1480 | dc->index_start = ndev_idx * MAX_PORT; | ||
1481 | ndevs[ndev_idx] = dc; | ||
1482 | |||
1483 | for (i = 0; i < MAX_PORT; i++) { | ||
1484 | mutex_init(&dc->port[i].tty_sem); | ||
1485 | dc->port[i].tty_open_count = 0; | ||
1486 | dc->port[i].tty = NULL; | ||
1487 | tty_register_device(ntty_driver, dc->index_start + i, | ||
1488 | &pdev->dev); | ||
1489 | } | ||
1490 | |||
1491 | /* Enable RESET interrupt. */ | ||
1492 | dc->last_ier = RESET; | ||
1493 | writew(dc->last_ier, dc->reg_ier); | ||
1494 | |||
1495 | pci_set_drvdata(pdev, dc); | ||
1496 | |||
1497 | return 0; | ||
1498 | |||
1499 | err_free_sbuf: | ||
1500 | kfree(dc->send_buf); | ||
1501 | iounmap(dc->base_addr); | ||
1502 | err_rel_regs: | ||
1503 | pci_release_regions(pdev); | ||
1504 | err_disable_device: | ||
1505 | pci_disable_device(pdev); | ||
1506 | err_free: | ||
1507 | kfree(dc); | ||
1508 | err: | ||
1509 | return ret; | ||
1510 | } | ||
1511 | |||
1512 | static void __devexit tty_exit(struct nozomi *dc) | ||
1513 | { | ||
1514 | unsigned int i; | ||
1515 | |||
1516 | DBG1(" "); | ||
1517 | |||
1518 | flush_scheduled_work(); | ||
1519 | |||
1520 | for (i = 0; i < MAX_PORT; ++i) | ||
1521 | if (dc->port[i].tty && \ | ||
1522 | list_empty(&dc->port[i].tty->hangup_work.entry)) | ||
1523 | tty_hangup(dc->port[i].tty); | ||
1524 | |||
1525 | while (dc->open_ttys) | ||
1526 | msleep(1); | ||
1527 | |||
1528 | for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) | ||
1529 | tty_unregister_device(ntty_driver, i); | ||
1530 | } | ||
1531 | |||
1532 | /* Deallocate memory for one device */ | ||
1533 | static void __devexit nozomi_card_exit(struct pci_dev *pdev) | ||
1534 | { | ||
1535 | int i; | ||
1536 | struct ctrl_ul ctrl; | ||
1537 | struct nozomi *dc = pci_get_drvdata(pdev); | ||
1538 | |||
1539 | /* Disable all interrupts */ | ||
1540 | dc->last_ier = 0; | ||
1541 | writew(dc->last_ier, dc->reg_ier); | ||
1542 | |||
1543 | tty_exit(dc); | ||
1544 | |||
1545 | /* Send 0x0001, command card to resend the reset token. */ | ||
1546 | /* This is to get the reset when the module is reloaded. */ | ||
1547 | ctrl.port = 0x00; | ||
1548 | ctrl.reserved = 0; | ||
1549 | ctrl.RTS = 0; | ||
1550 | ctrl.DTR = 1; | ||
1551 | DBG1("sending flow control 0x%04X", *((u16 *)&ctrl)); | ||
1552 | |||
1553 | /* Setup dc->reg addresses to we can use defines here */ | ||
1554 | write_mem32(dc->port[PORT_CTRL].ul_addr[0], (u32 *)&ctrl, 2); | ||
1555 | writew(CTRL_UL, dc->reg_fcr); /* push the token to the card. */ | ||
1556 | |||
1557 | remove_sysfs_files(dc); | ||
1558 | |||
1559 | free_irq(pdev->irq, dc); | ||
1560 | |||
1561 | for (i = 0; i < MAX_PORT; i++) | ||
1562 | if (dc->port[i].fifo_ul) | ||
1563 | kfifo_free(dc->port[i].fifo_ul); | ||
1564 | |||
1565 | kfree(dc->send_buf); | ||
1566 | |||
1567 | iounmap(dc->base_addr); | ||
1568 | |||
1569 | pci_release_regions(pdev); | ||
1570 | |||
1571 | pci_disable_device(pdev); | ||
1572 | |||
1573 | ndevs[dc->index_start / MAX_PORT] = NULL; | ||
1574 | |||
1575 | kfree(dc); | ||
1576 | } | ||
1577 | |||
1578 | static void set_rts(const struct tty_struct *tty, int rts) | ||
1579 | { | ||
1580 | struct port *port = get_port_by_tty(tty); | ||
1581 | |||
1582 | port->ctrl_ul.RTS = rts; | ||
1583 | port->update_flow_control = 1; | ||
1584 | enable_transmit_ul(PORT_CTRL, get_dc_by_tty(tty)); | ||
1585 | } | ||
1586 | |||
1587 | static void set_dtr(const struct tty_struct *tty, int dtr) | ||
1588 | { | ||
1589 | struct port *port = get_port_by_tty(tty); | ||
1590 | |||
1591 | DBG1("SETTING DTR index: %d, dtr: %d", tty->index, dtr); | ||
1592 | |||
1593 | port->ctrl_ul.DTR = dtr; | ||
1594 | port->update_flow_control = 1; | ||
1595 | enable_transmit_ul(PORT_CTRL, get_dc_by_tty(tty)); | ||
1596 | } | ||
1597 | |||
1598 | /* | ||
1599 | * ---------------------------------------------------------------------------- | ||
1600 | * TTY code | ||
1601 | * ---------------------------------------------------------------------------- | ||
1602 | */ | ||
1603 | |||
1604 | /* Called when the userspace process opens the tty, /dev/noz*. */ | ||
1605 | static int ntty_open(struct tty_struct *tty, struct file *file) | ||
1606 | { | ||
1607 | struct port *port = get_port_by_tty(tty); | ||
1608 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1609 | unsigned long flags; | ||
1610 | |||
1611 | if (!port || !dc) | ||
1612 | return -ENODEV; | ||
1613 | |||
1614 | if (mutex_lock_interruptible(&port->tty_sem)) | ||
1615 | return -ERESTARTSYS; | ||
1616 | |||
1617 | port->tty_open_count++; | ||
1618 | dc->open_ttys++; | ||
1619 | |||
1620 | /* Enable interrupt downlink for channel */ | ||
1621 | if (port->tty_open_count == 1) { | ||
1622 | tty->low_latency = 1; | ||
1623 | tty->driver_data = port; | ||
1624 | port->tty = tty; | ||
1625 | DBG1("open: %d", port->token_dl); | ||
1626 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1627 | dc->last_ier = dc->last_ier | port->token_dl; | ||
1628 | writew(dc->last_ier, dc->reg_ier); | ||
1629 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1630 | } | ||
1631 | |||
1632 | mutex_unlock(&port->tty_sem); | ||
1633 | |||
1634 | return 0; | ||
1635 | } | ||
1636 | |||
1637 | /* Called when the userspace process close the tty, /dev/noz*. */ | ||
1638 | static void ntty_close(struct tty_struct *tty, struct file *file) | ||
1639 | { | ||
1640 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1641 | struct port *port = tty->driver_data; | ||
1642 | unsigned long flags; | ||
1643 | |||
1644 | if (!dc || !port) | ||
1645 | return; | ||
1646 | |||
1647 | if (mutex_lock_interruptible(&port->tty_sem)) | ||
1648 | return; | ||
1649 | |||
1650 | if (!port->tty_open_count) | ||
1651 | goto exit; | ||
1652 | |||
1653 | dc->open_ttys--; | ||
1654 | port->tty_open_count--; | ||
1655 | |||
1656 | if (port->tty_open_count == 0) { | ||
1657 | DBG1("close: %d", port->token_dl); | ||
1658 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1659 | dc->last_ier &= ~(port->token_dl); | ||
1660 | writew(dc->last_ier, dc->reg_ier); | ||
1661 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1662 | } | ||
1663 | |||
1664 | exit: | ||
1665 | mutex_unlock(&port->tty_sem); | ||
1666 | } | ||
1667 | |||
1668 | /* | ||
1669 | * called when the userspace process writes to the tty (/dev/noz*). | ||
1670 | * Data is inserted into a fifo, which is then read and transfered to the modem. | ||
1671 | */ | ||
1672 | static int ntty_write(struct tty_struct *tty, const unsigned char *buffer, | ||
1673 | int count) | ||
1674 | { | ||
1675 | int rval = -EINVAL; | ||
1676 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1677 | struct port *port = tty->driver_data; | ||
1678 | unsigned long flags; | ||
1679 | |||
1680 | /* DBG1( "WRITEx: %d, index = %d", count, index); */ | ||
1681 | |||
1682 | if (!dc || !port) | ||
1683 | return -ENODEV; | ||
1684 | |||
1685 | if (unlikely(!mutex_trylock(&port->tty_sem))) { | ||
1686 | /* | ||
1687 | * must test lock as tty layer wraps calls | ||
1688 | * to this function with BKL | ||
1689 | */ | ||
1690 | dev_err(&dc->pdev->dev, "Would have deadlocked - " | ||
1691 | "return EAGAIN\n"); | ||
1692 | return -EAGAIN; | ||
1693 | } | ||
1694 | |||
1695 | if (unlikely(!port->tty_open_count)) { | ||
1696 | DBG1(" "); | ||
1697 | goto exit; | ||
1698 | } | ||
1699 | |||
1700 | rval = __kfifo_put(port->fifo_ul, (unsigned char *)buffer, count); | ||
1701 | |||
1702 | /* notify card */ | ||
1703 | if (unlikely(dc == NULL)) { | ||
1704 | DBG1("No device context?"); | ||
1705 | goto exit; | ||
1706 | } | ||
1707 | |||
1708 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1709 | /* CTS is only valid on the modem channel */ | ||
1710 | if (port == &(dc->port[PORT_MDM])) { | ||
1711 | if (port->ctrl_dl.CTS) { | ||
1712 | DBG4("Enable interrupt"); | ||
1713 | enable_transmit_ul(tty->index % MAX_PORT, dc); | ||
1714 | } else { | ||
1715 | dev_err(&dc->pdev->dev, | ||
1716 | "CTS not active on modem port?\n"); | ||
1717 | } | ||
1718 | } else { | ||
1719 | enable_transmit_ul(tty->index % MAX_PORT, dc); | ||
1720 | } | ||
1721 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1722 | |||
1723 | exit: | ||
1724 | mutex_unlock(&port->tty_sem); | ||
1725 | return rval; | ||
1726 | } | ||
1727 | |||
1728 | /* | ||
1729 | * Calculate how much is left in device | ||
1730 | * This method is called by the upper tty layer. | ||
1731 | * #according to sources N_TTY.c it expects a value >= 0 and | ||
1732 | * does not check for negative values. | ||
1733 | */ | ||
1734 | static int ntty_write_room(struct tty_struct *tty) | ||
1735 | { | ||
1736 | struct port *port = tty->driver_data; | ||
1737 | int room = 0; | ||
1738 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1739 | |||
1740 | if (!dc || !port) | ||
1741 | return 0; | ||
1742 | if (!mutex_trylock(&port->tty_sem)) | ||
1743 | return 0; | ||
1744 | |||
1745 | if (!port->tty_open_count) | ||
1746 | goto exit; | ||
1747 | |||
1748 | room = port->fifo_ul->size - __kfifo_len(port->fifo_ul); | ||
1749 | |||
1750 | exit: | ||
1751 | mutex_unlock(&port->tty_sem); | ||
1752 | return room; | ||
1753 | } | ||
1754 | |||
1755 | /* Gets io control parameters */ | ||
1756 | static int ntty_tiocmget(struct tty_struct *tty, struct file *file) | ||
1757 | { | ||
1758 | struct port *port = tty->driver_data; | ||
1759 | struct ctrl_dl *ctrl_dl = &port->ctrl_dl; | ||
1760 | struct ctrl_ul *ctrl_ul = &port->ctrl_ul; | ||
1761 | |||
1762 | return (ctrl_ul->RTS ? TIOCM_RTS : 0) | | ||
1763 | (ctrl_ul->DTR ? TIOCM_DTR : 0) | | ||
1764 | (ctrl_dl->DCD ? TIOCM_CAR : 0) | | ||
1765 | (ctrl_dl->RI ? TIOCM_RNG : 0) | | ||
1766 | (ctrl_dl->DSR ? TIOCM_DSR : 0) | | ||
1767 | (ctrl_dl->CTS ? TIOCM_CTS : 0); | ||
1768 | } | ||
1769 | |||
1770 | /* Sets io controls parameters */ | ||
1771 | static int ntty_tiocmset(struct tty_struct *tty, struct file *file, | ||
1772 | unsigned int set, unsigned int clear) | ||
1773 | { | ||
1774 | if (set & TIOCM_RTS) | ||
1775 | set_rts(tty, 1); | ||
1776 | else if (clear & TIOCM_RTS) | ||
1777 | set_rts(tty, 0); | ||
1778 | |||
1779 | if (set & TIOCM_DTR) | ||
1780 | set_dtr(tty, 1); | ||
1781 | else if (clear & TIOCM_DTR) | ||
1782 | set_dtr(tty, 0); | ||
1783 | |||
1784 | return 0; | ||
1785 | } | ||
1786 | |||
1787 | static int ntty_cflags_changed(struct port *port, unsigned long flags, | ||
1788 | struct async_icount *cprev) | ||
1789 | { | ||
1790 | struct async_icount cnow = port->tty_icount; | ||
1791 | int ret; | ||
1792 | |||
1793 | ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) || | ||
1794 | ((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) || | ||
1795 | ((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd)) || | ||
1796 | ((flags & TIOCM_CTS) && (cnow.cts != cprev->cts)); | ||
1797 | |||
1798 | *cprev = cnow; | ||
1799 | |||
1800 | return ret; | ||
1801 | } | ||
1802 | |||
1803 | static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) | ||
1804 | { | ||
1805 | struct async_icount cnow = port->tty_icount; | ||
1806 | struct serial_icounter_struct icount; | ||
1807 | |||
1808 | icount.cts = cnow.cts; | ||
1809 | icount.dsr = cnow.dsr; | ||
1810 | icount.rng = cnow.rng; | ||
1811 | icount.dcd = cnow.dcd; | ||
1812 | icount.rx = cnow.rx; | ||
1813 | icount.tx = cnow.tx; | ||
1814 | icount.frame = cnow.frame; | ||
1815 | icount.overrun = cnow.overrun; | ||
1816 | icount.parity = cnow.parity; | ||
1817 | icount.brk = cnow.brk; | ||
1818 | icount.buf_overrun = cnow.buf_overrun; | ||
1819 | |||
1820 | return copy_to_user(argp, &icount, sizeof(icount)); | ||
1821 | } | ||
1822 | |||
1823 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, | ||
1824 | unsigned int cmd, unsigned long arg) | ||
1825 | { | ||
1826 | struct port *port = tty->driver_data; | ||
1827 | void __user *argp = (void __user *)arg; | ||
1828 | int rval = -ENOIOCTLCMD; | ||
1829 | |||
1830 | DBG1("******** IOCTL, cmd: %d", cmd); | ||
1831 | |||
1832 | switch (cmd) { | ||
1833 | case TIOCMIWAIT: { | ||
1834 | struct async_icount cprev = port->tty_icount; | ||
1835 | |||
1836 | rval = wait_event_interruptible(port->tty_wait, | ||
1837 | ntty_cflags_changed(port, arg, &cprev)); | ||
1838 | break; | ||
1839 | } case TIOCGICOUNT: | ||
1840 | rval = ntty_ioctl_tiocgicount(port, argp); | ||
1841 | break; | ||
1842 | default: | ||
1843 | DBG1("ERR: 0x%08X, %d", cmd, cmd); | ||
1844 | break; | ||
1845 | }; | ||
1846 | |||
1847 | return rval; | ||
1848 | } | ||
1849 | |||
1850 | /* | ||
1851 | * Called by the upper tty layer when tty buffers are ready | ||
1852 | * to receive data again after a call to throttle. | ||
1853 | */ | ||
1854 | static void ntty_unthrottle(struct tty_struct *tty) | ||
1855 | { | ||
1856 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1857 | unsigned long flags; | ||
1858 | |||
1859 | DBG1("UNTHROTTLE"); | ||
1860 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1861 | enable_transmit_dl(tty->index % MAX_PORT, dc); | ||
1862 | set_rts(tty, 1); | ||
1863 | |||
1864 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1865 | } | ||
1866 | |||
1867 | /* | ||
1868 | * Called by the upper tty layer when the tty buffers are almost full. | ||
1869 | * The driver should stop send more data. | ||
1870 | */ | ||
1871 | static void ntty_throttle(struct tty_struct *tty) | ||
1872 | { | ||
1873 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1874 | unsigned long flags; | ||
1875 | |||
1876 | DBG1("THROTTLE"); | ||
1877 | spin_lock_irqsave(&dc->spin_mutex, flags); | ||
1878 | set_rts(tty, 0); | ||
1879 | spin_unlock_irqrestore(&dc->spin_mutex, flags); | ||
1880 | } | ||
1881 | |||
1882 | /* just to discard single character writes */ | ||
1883 | static void ntty_put_char(struct tty_struct *tty, unsigned char c) | ||
1884 | { | ||
1885 | /* FIXME !!! */ | ||
1886 | DBG2("PUT CHAR Function: %c", c); | ||
1887 | } | ||
1888 | |||
1889 | /* Returns number of chars in buffer, called by tty layer */ | ||
1890 | static s32 ntty_chars_in_buffer(struct tty_struct *tty) | ||
1891 | { | ||
1892 | struct port *port = tty->driver_data; | ||
1893 | struct nozomi *dc = get_dc_by_tty(tty); | ||
1894 | s32 rval; | ||
1895 | |||
1896 | if (unlikely(!dc || !port)) { | ||
1897 | rval = -ENODEV; | ||
1898 | goto exit_in_buffer; | ||
1899 | } | ||
1900 | |||
1901 | if (unlikely(!port->tty_open_count)) { | ||
1902 | dev_err(&dc->pdev->dev, "No tty open?\n"); | ||
1903 | rval = -ENODEV; | ||
1904 | goto exit_in_buffer; | ||
1905 | } | ||
1906 | |||
1907 | rval = __kfifo_len(port->fifo_ul); | ||
1908 | |||
1909 | exit_in_buffer: | ||
1910 | return rval; | ||
1911 | } | ||
1912 | |||
1913 | static struct tty_operations tty_ops = { | ||
1914 | .ioctl = ntty_ioctl, | ||
1915 | .open = ntty_open, | ||
1916 | .close = ntty_close, | ||
1917 | .write = ntty_write, | ||
1918 | .write_room = ntty_write_room, | ||
1919 | .unthrottle = ntty_unthrottle, | ||
1920 | .throttle = ntty_throttle, | ||
1921 | .chars_in_buffer = ntty_chars_in_buffer, | ||
1922 | .put_char = ntty_put_char, | ||
1923 | .tiocmget = ntty_tiocmget, | ||
1924 | .tiocmset = ntty_tiocmset, | ||
1925 | }; | ||
1926 | |||
1927 | /* Module initialization */ | ||
1928 | static struct pci_driver nozomi_driver = { | ||
1929 | .name = NOZOMI_NAME, | ||
1930 | .id_table = nozomi_pci_tbl, | ||
1931 | .probe = nozomi_card_init, | ||
1932 | .remove = __devexit_p(nozomi_card_exit), | ||
1933 | }; | ||
1934 | |||
1935 | static __init int nozomi_init(void) | ||
1936 | { | ||
1937 | int ret; | ||
1938 | |||
1939 | printk(KERN_INFO "Initializing %s\n", VERSION_STRING); | ||
1940 | |||
1941 | ntty_driver = alloc_tty_driver(NTTY_TTY_MAXMINORS); | ||
1942 | if (!ntty_driver) | ||
1943 | return -ENOMEM; | ||
1944 | |||
1945 | ntty_driver->owner = THIS_MODULE; | ||
1946 | ntty_driver->driver_name = NOZOMI_NAME_TTY; | ||
1947 | ntty_driver->name = "noz"; | ||
1948 | ntty_driver->major = 0; | ||
1949 | ntty_driver->type = TTY_DRIVER_TYPE_SERIAL; | ||
1950 | ntty_driver->subtype = SERIAL_TYPE_NORMAL; | ||
1951 | ntty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
1952 | ntty_driver->init_termios = tty_std_termios; | ||
1953 | ntty_driver->init_termios.c_cflag = B115200 | CS8 | CREAD | \ | ||
1954 | HUPCL | CLOCAL; | ||
1955 | ntty_driver->init_termios.c_ispeed = 115200; | ||
1956 | ntty_driver->init_termios.c_ospeed = 115200; | ||
1957 | tty_set_operations(ntty_driver, &tty_ops); | ||
1958 | |||
1959 | ret = tty_register_driver(ntty_driver); | ||
1960 | if (ret) { | ||
1961 | printk(KERN_ERR "Nozomi: failed to register ntty driver\n"); | ||
1962 | goto free_tty; | ||
1963 | } | ||
1964 | |||
1965 | ret = pci_register_driver(&nozomi_driver); | ||
1966 | if (ret) { | ||
1967 | printk(KERN_ERR "Nozomi: can't register pci driver\n"); | ||
1968 | goto unr_tty; | ||
1969 | } | ||
1970 | |||
1971 | return 0; | ||
1972 | unr_tty: | ||
1973 | tty_unregister_driver(ntty_driver); | ||
1974 | free_tty: | ||
1975 | put_tty_driver(ntty_driver); | ||
1976 | return ret; | ||
1977 | } | ||
1978 | |||
1979 | static __exit void nozomi_exit(void) | ||
1980 | { | ||
1981 | printk(KERN_INFO "Unloading %s\n", DRIVER_DESC); | ||
1982 | pci_unregister_driver(&nozomi_driver); | ||
1983 | tty_unregister_driver(ntty_driver); | ||
1984 | put_tty_driver(ntty_driver); | ||
1985 | } | ||
1986 | |||
1987 | module_init(nozomi_init); | ||
1988 | module_exit(nozomi_exit); | ||
1989 | |||
1990 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
1991 | |||
1992 | MODULE_LICENSE("Dual BSD/GPL"); | ||
1993 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 79581fab82d6..5efd5550f4ca 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -828,11 +828,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
828 | memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); | 828 | memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); |
829 | 829 | ||
830 | /* prepare interface data */ | 830 | /* prepare interface data */ |
831 | policy->kobj.parent = &sys_dev->kobj; | 831 | ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &sys_dev->kobj, |
832 | policy->kobj.ktype = &ktype_cpufreq; | 832 | "cpufreq"); |
833 | kobject_set_name(&policy->kobj, "cpufreq"); | ||
834 | |||
835 | ret = kobject_register(&policy->kobj); | ||
836 | if (ret) { | 833 | if (ret) { |
837 | unlock_policy_rwsem_write(cpu); | 834 | unlock_policy_rwsem_write(cpu); |
838 | goto err_out_driver_exit; | 835 | goto err_out_driver_exit; |
@@ -902,6 +899,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
902 | goto err_out_unregister; | 899 | goto err_out_unregister; |
903 | } | 900 | } |
904 | 901 | ||
902 | kobject_uevent(&policy->kobj, KOBJ_ADD); | ||
905 | module_put(cpufreq_driver->owner); | 903 | module_put(cpufreq_driver->owner); |
906 | dprintk("initialization complete\n"); | 904 | dprintk("initialization complete\n"); |
907 | cpufreq_debug_enable_ratelimit(); | 905 | cpufreq_debug_enable_ratelimit(); |
@@ -915,7 +913,7 @@ err_out_unregister: | |||
915 | cpufreq_cpu_data[j] = NULL; | 913 | cpufreq_cpu_data[j] = NULL; |
916 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); | 914 | spin_unlock_irqrestore(&cpufreq_driver_lock, flags); |
917 | 915 | ||
918 | kobject_unregister(&policy->kobj); | 916 | kobject_put(&policy->kobj); |
919 | wait_for_completion(&policy->kobj_unregister); | 917 | wait_for_completion(&policy->kobj_unregister); |
920 | 918 | ||
921 | err_out_driver_exit: | 919 | err_out_driver_exit: |
@@ -1032,8 +1030,6 @@ static int __cpufreq_remove_dev (struct sys_device * sys_dev) | |||
1032 | 1030 | ||
1033 | unlock_policy_rwsem_write(cpu); | 1031 | unlock_policy_rwsem_write(cpu); |
1034 | 1032 | ||
1035 | kobject_unregister(&data->kobj); | ||
1036 | |||
1037 | kobject_put(&data->kobj); | 1033 | kobject_put(&data->kobj); |
1038 | 1034 | ||
1039 | /* we need to make sure that the underlying kobj is actually | 1035 | /* we need to make sure that the underlying kobj is actually |
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 0f3515e77d4b..088ea74edd34 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c | |||
@@ -277,7 +277,7 @@ static struct kobj_type ktype_state_cpuidle = { | |||
277 | 277 | ||
278 | static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i) | 278 | static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i) |
279 | { | 279 | { |
280 | kobject_unregister(&device->kobjs[i]->kobj); | 280 | kobject_put(&device->kobjs[i]->kobj); |
281 | wait_for_completion(&device->kobjs[i]->kobj_unregister); | 281 | wait_for_completion(&device->kobjs[i]->kobj_unregister); |
282 | kfree(device->kobjs[i]); | 282 | kfree(device->kobjs[i]); |
283 | device->kobjs[i] = NULL; | 283 | device->kobjs[i] = NULL; |
@@ -300,14 +300,13 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device) | |||
300 | kobj->state = &device->states[i]; | 300 | kobj->state = &device->states[i]; |
301 | init_completion(&kobj->kobj_unregister); | 301 | init_completion(&kobj->kobj_unregister); |
302 | 302 | ||
303 | kobj->kobj.parent = &device->kobj; | 303 | ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &device->kobj, |
304 | kobj->kobj.ktype = &ktype_state_cpuidle; | 304 | "state%d", i); |
305 | kobject_set_name(&kobj->kobj, "state%d", i); | ||
306 | ret = kobject_register(&kobj->kobj); | ||
307 | if (ret) { | 305 | if (ret) { |
308 | kfree(kobj); | 306 | kfree(kobj); |
309 | goto error_state; | 307 | goto error_state; |
310 | } | 308 | } |
309 | kobject_uevent(&kobj->kobj, KOBJ_ADD); | ||
311 | device->kobjs[i] = kobj; | 310 | device->kobjs[i] = kobj; |
312 | } | 311 | } |
313 | 312 | ||
@@ -339,12 +338,14 @@ int cpuidle_add_sysfs(struct sys_device *sysdev) | |||
339 | { | 338 | { |
340 | int cpu = sysdev->id; | 339 | int cpu = sysdev->id; |
341 | struct cpuidle_device *dev; | 340 | struct cpuidle_device *dev; |
341 | int error; | ||
342 | 342 | ||
343 | dev = per_cpu(cpuidle_devices, cpu); | 343 | dev = per_cpu(cpuidle_devices, cpu); |
344 | dev->kobj.parent = &sysdev->kobj; | 344 | error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &sysdev->kobj, |
345 | dev->kobj.ktype = &ktype_cpuidle; | 345 | "cpuidle"); |
346 | kobject_set_name(&dev->kobj, "%s", "cpuidle"); | 346 | if (!error) |
347 | return kobject_register(&dev->kobj); | 347 | kobject_uevent(&dev->kobj, KOBJ_ADD); |
348 | return error; | ||
348 | } | 349 | } |
349 | 350 | ||
350 | /** | 351 | /** |
@@ -357,5 +358,5 @@ void cpuidle_remove_sysfs(struct sys_device *sysdev) | |||
357 | struct cpuidle_device *dev; | 358 | struct cpuidle_device *dev; |
358 | 359 | ||
359 | dev = per_cpu(cpuidle_devices, cpu); | 360 | dev = per_cpu(cpuidle_devices, cpu); |
360 | kobject_unregister(&dev->kobj); | 361 | kobject_put(&dev->kobj); |
361 | } | 362 | } |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index d59b2f417306..bcf52df30339 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -41,12 +41,12 @@ | |||
41 | * the definition of dma_event_callback in dmaengine.h. | 41 | * the definition of dma_event_callback in dmaengine.h. |
42 | * | 42 | * |
43 | * Each device has a kref, which is initialized to 1 when the device is | 43 | * Each device has a kref, which is initialized to 1 when the device is |
44 | * registered. A kref_get is done for each class_device registered. When the | 44 | * registered. A kref_get is done for each device registered. When the |
45 | * class_device is released, the coresponding kref_put is done in the release | 45 | * device is released, the coresponding kref_put is done in the release |
46 | * method. Every time one of the device's channels is allocated to a client, | 46 | * method. Every time one of the device's channels is allocated to a client, |
47 | * a kref_get occurs. When the channel is freed, the coresponding kref_put | 47 | * a kref_get occurs. When the channel is freed, the coresponding kref_put |
48 | * happens. The device's release function does a completion, so | 48 | * happens. The device's release function does a completion, so |
49 | * unregister_device does a remove event, class_device_unregister, a kref_put | 49 | * unregister_device does a remove event, device_unregister, a kref_put |
50 | * for the first reference, then waits on the completion for all other | 50 | * for the first reference, then waits on the completion for all other |
51 | * references to finish. | 51 | * references to finish. |
52 | * | 52 | * |
@@ -77,9 +77,9 @@ static LIST_HEAD(dma_client_list); | |||
77 | 77 | ||
78 | /* --- sysfs implementation --- */ | 78 | /* --- sysfs implementation --- */ |
79 | 79 | ||
80 | static ssize_t show_memcpy_count(struct class_device *cd, char *buf) | 80 | static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *attr, char *buf) |
81 | { | 81 | { |
82 | struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); | 82 | struct dma_chan *chan = to_dma_chan(dev); |
83 | unsigned long count = 0; | 83 | unsigned long count = 0; |
84 | int i; | 84 | int i; |
85 | 85 | ||
@@ -89,9 +89,10 @@ static ssize_t show_memcpy_count(struct class_device *cd, char *buf) | |||
89 | return sprintf(buf, "%lu\n", count); | 89 | return sprintf(buf, "%lu\n", count); |
90 | } | 90 | } |
91 | 91 | ||
92 | static ssize_t show_bytes_transferred(struct class_device *cd, char *buf) | 92 | static ssize_t show_bytes_transferred(struct device *dev, struct device_attribute *attr, |
93 | char *buf) | ||
93 | { | 94 | { |
94 | struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); | 95 | struct dma_chan *chan = to_dma_chan(dev); |
95 | unsigned long count = 0; | 96 | unsigned long count = 0; |
96 | int i; | 97 | int i; |
97 | 98 | ||
@@ -101,9 +102,9 @@ static ssize_t show_bytes_transferred(struct class_device *cd, char *buf) | |||
101 | return sprintf(buf, "%lu\n", count); | 102 | return sprintf(buf, "%lu\n", count); |
102 | } | 103 | } |
103 | 104 | ||
104 | static ssize_t show_in_use(struct class_device *cd, char *buf) | 105 | static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, char *buf) |
105 | { | 106 | { |
106 | struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); | 107 | struct dma_chan *chan = to_dma_chan(dev); |
107 | int in_use = 0; | 108 | int in_use = 0; |
108 | 109 | ||
109 | if (unlikely(chan->slow_ref) && | 110 | if (unlikely(chan->slow_ref) && |
@@ -119,7 +120,7 @@ static ssize_t show_in_use(struct class_device *cd, char *buf) | |||
119 | return sprintf(buf, "%d\n", in_use); | 120 | return sprintf(buf, "%d\n", in_use); |
120 | } | 121 | } |
121 | 122 | ||
122 | static struct class_device_attribute dma_class_attrs[] = { | 123 | static struct device_attribute dma_attrs[] = { |
123 | __ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL), | 124 | __ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL), |
124 | __ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL), | 125 | __ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL), |
125 | __ATTR(in_use, S_IRUGO, show_in_use, NULL), | 126 | __ATTR(in_use, S_IRUGO, show_in_use, NULL), |
@@ -128,16 +129,16 @@ static struct class_device_attribute dma_class_attrs[] = { | |||
128 | 129 | ||
129 | static void dma_async_device_cleanup(struct kref *kref); | 130 | static void dma_async_device_cleanup(struct kref *kref); |
130 | 131 | ||
131 | static void dma_class_dev_release(struct class_device *cd) | 132 | static void dma_dev_release(struct device *dev) |
132 | { | 133 | { |
133 | struct dma_chan *chan = container_of(cd, struct dma_chan, class_dev); | 134 | struct dma_chan *chan = to_dma_chan(dev); |
134 | kref_put(&chan->device->refcount, dma_async_device_cleanup); | 135 | kref_put(&chan->device->refcount, dma_async_device_cleanup); |
135 | } | 136 | } |
136 | 137 | ||
137 | static struct class dma_devclass = { | 138 | static struct class dma_devclass = { |
138 | .name = "dma", | 139 | .name = "dma", |
139 | .class_dev_attrs = dma_class_attrs, | 140 | .dev_attrs = dma_attrs, |
140 | .release = dma_class_dev_release, | 141 | .dev_release = dma_dev_release, |
141 | }; | 142 | }; |
142 | 143 | ||
143 | /* --- client and device registration --- */ | 144 | /* --- client and device registration --- */ |
@@ -377,12 +378,12 @@ int dma_async_device_register(struct dma_device *device) | |||
377 | continue; | 378 | continue; |
378 | 379 | ||
379 | chan->chan_id = chancnt++; | 380 | chan->chan_id = chancnt++; |
380 | chan->class_dev.class = &dma_devclass; | 381 | chan->dev.class = &dma_devclass; |
381 | chan->class_dev.dev = NULL; | 382 | chan->dev.parent = NULL; |
382 | snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d", | 383 | snprintf(chan->dev.bus_id, BUS_ID_SIZE, "dma%dchan%d", |
383 | device->dev_id, chan->chan_id); | 384 | device->dev_id, chan->chan_id); |
384 | 385 | ||
385 | rc = class_device_register(&chan->class_dev); | 386 | rc = device_register(&chan->dev); |
386 | if (rc) { | 387 | if (rc) { |
387 | chancnt--; | 388 | chancnt--; |
388 | free_percpu(chan->local); | 389 | free_percpu(chan->local); |
@@ -411,7 +412,7 @@ err_out: | |||
411 | if (chan->local == NULL) | 412 | if (chan->local == NULL) |
412 | continue; | 413 | continue; |
413 | kref_put(&device->refcount, dma_async_device_cleanup); | 414 | kref_put(&device->refcount, dma_async_device_cleanup); |
414 | class_device_unregister(&chan->class_dev); | 415 | device_unregister(&chan->dev); |
415 | chancnt--; | 416 | chancnt--; |
416 | free_percpu(chan->local); | 417 | free_percpu(chan->local); |
417 | } | 418 | } |
@@ -445,7 +446,7 @@ void dma_async_device_unregister(struct dma_device *device) | |||
445 | 446 | ||
446 | list_for_each_entry(chan, &device->channels, device_node) { | 447 | list_for_each_entry(chan, &device->channels, device_node) { |
447 | dma_clients_notify_removed(chan); | 448 | dma_clients_notify_removed(chan); |
448 | class_device_unregister(&chan->class_dev); | 449 | device_unregister(&chan->dev); |
449 | dma_chan_release(chan); | 450 | dma_chan_release(chan); |
450 | } | 451 | } |
451 | 452 | ||
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c index 70b837f23c43..53764577035f 100644 --- a/drivers/edac/edac_device_sysfs.c +++ b/drivers/edac/edac_device_sysfs.c | |||
@@ -246,16 +246,6 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev) | |||
246 | 246 | ||
247 | /* Init the devices's kobject */ | 247 | /* Init the devices's kobject */ |
248 | memset(&edac_dev->kobj, 0, sizeof(struct kobject)); | 248 | memset(&edac_dev->kobj, 0, sizeof(struct kobject)); |
249 | edac_dev->kobj.ktype = &ktype_device_ctrl; | ||
250 | |||
251 | /* set this new device under the edac_class kobject */ | ||
252 | edac_dev->kobj.parent = &edac_class->kset.kobj; | ||
253 | |||
254 | /* generate sysfs "..../edac/<name>" */ | ||
255 | debugf4("%s() set name of kobject to: %s\n", __func__, edac_dev->name); | ||
256 | err = kobject_set_name(&edac_dev->kobj, "%s", edac_dev->name); | ||
257 | if (err) | ||
258 | goto err_out; | ||
259 | 249 | ||
260 | /* Record which module 'owns' this control structure | 250 | /* Record which module 'owns' this control structure |
261 | * and bump the ref count of the module | 251 | * and bump the ref count of the module |
@@ -268,12 +258,15 @@ int edac_device_register_sysfs_main_kobj(struct edac_device_ctl_info *edac_dev) | |||
268 | } | 258 | } |
269 | 259 | ||
270 | /* register */ | 260 | /* register */ |
271 | err = kobject_register(&edac_dev->kobj); | 261 | err = kobject_init_and_add(&edac_dev->kobj, &ktype_device_ctrl, |
262 | &edac_class->kset.kobj, | ||
263 | "%s", edac_dev->name); | ||
272 | if (err) { | 264 | if (err) { |
273 | debugf1("%s()Failed to register '.../edac/%s'\n", | 265 | debugf1("%s()Failed to register '.../edac/%s'\n", |
274 | __func__, edac_dev->name); | 266 | __func__, edac_dev->name); |
275 | goto err_kobj_reg; | 267 | goto err_kobj_reg; |
276 | } | 268 | } |
269 | kobject_uevent(&edac_dev->kobj, KOBJ_ADD); | ||
277 | 270 | ||
278 | /* At this point, to 'free' the control struct, | 271 | /* At this point, to 'free' the control struct, |
279 | * edac_device_unregister_sysfs_main_kobj() must be used | 272 | * edac_device_unregister_sysfs_main_kobj() must be used |
@@ -310,7 +303,7 @@ void edac_device_unregister_sysfs_main_kobj( | |||
310 | * a) module_put() this module | 303 | * a) module_put() this module |
311 | * b) 'kfree' the memory | 304 | * b) 'kfree' the memory |
312 | */ | 305 | */ |
313 | kobject_unregister(&edac_dev->kobj); | 306 | kobject_put(&edac_dev->kobj); |
314 | } | 307 | } |
315 | 308 | ||
316 | /* edac_dev -> instance information */ | 309 | /* edac_dev -> instance information */ |
@@ -533,12 +526,6 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev, | |||
533 | 526 | ||
534 | /* init this block's kobject */ | 527 | /* init this block's kobject */ |
535 | memset(&block->kobj, 0, sizeof(struct kobject)); | 528 | memset(&block->kobj, 0, sizeof(struct kobject)); |
536 | block->kobj.parent = &instance->kobj; | ||
537 | block->kobj.ktype = &ktype_block_ctrl; | ||
538 | |||
539 | err = kobject_set_name(&block->kobj, "%s", block->name); | ||
540 | if (err) | ||
541 | return err; | ||
542 | 529 | ||
543 | /* bump the main kobject's reference count for this controller | 530 | /* bump the main kobject's reference count for this controller |
544 | * and this instance is dependant on the main | 531 | * and this instance is dependant on the main |
@@ -550,7 +537,9 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev, | |||
550 | } | 537 | } |
551 | 538 | ||
552 | /* Add this block's kobject */ | 539 | /* Add this block's kobject */ |
553 | err = kobject_register(&block->kobj); | 540 | err = kobject_init_and_add(&block->kobj, &ktype_block_ctrl, |
541 | &instance->kobj, | ||
542 | "%s", block->name); | ||
554 | if (err) { | 543 | if (err) { |
555 | debugf1("%s() Failed to register instance '%s'\n", | 544 | debugf1("%s() Failed to register instance '%s'\n", |
556 | __func__, block->name); | 545 | __func__, block->name); |
@@ -579,12 +568,13 @@ static int edac_device_create_block(struct edac_device_ctl_info *edac_dev, | |||
579 | goto err_on_attrib; | 568 | goto err_on_attrib; |
580 | } | 569 | } |
581 | } | 570 | } |
571 | kobject_uevent(&block->kobj, KOBJ_ADD); | ||
582 | 572 | ||
583 | return 0; | 573 | return 0; |
584 | 574 | ||
585 | /* Error unwind stack */ | 575 | /* Error unwind stack */ |
586 | err_on_attrib: | 576 | err_on_attrib: |
587 | kobject_unregister(&block->kobj); | 577 | kobject_put(&block->kobj); |
588 | 578 | ||
589 | err_out: | 579 | err_out: |
590 | return err; | 580 | return err; |
@@ -615,7 +605,7 @@ static void edac_device_delete_block(struct edac_device_ctl_info *edac_dev, | |||
615 | /* unregister this block's kobject, SEE: | 605 | /* unregister this block's kobject, SEE: |
616 | * edac_device_ctrl_block_release() callback operation | 606 | * edac_device_ctrl_block_release() callback operation |
617 | */ | 607 | */ |
618 | kobject_unregister(&block->kobj); | 608 | kobject_put(&block->kobj); |
619 | } | 609 | } |
620 | 610 | ||
621 | /* instance ctor/dtor code */ | 611 | /* instance ctor/dtor code */ |
@@ -637,15 +627,8 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev, | |||
637 | /* Init the instance's kobject */ | 627 | /* Init the instance's kobject */ |
638 | memset(&instance->kobj, 0, sizeof(struct kobject)); | 628 | memset(&instance->kobj, 0, sizeof(struct kobject)); |
639 | 629 | ||
640 | /* set this new device under the edac_device main kobject */ | ||
641 | instance->kobj.parent = &edac_dev->kobj; | ||
642 | instance->kobj.ktype = &ktype_instance_ctrl; | ||
643 | instance->ctl = edac_dev; | 630 | instance->ctl = edac_dev; |
644 | 631 | ||
645 | err = kobject_set_name(&instance->kobj, "%s", instance->name); | ||
646 | if (err) | ||
647 | goto err_out; | ||
648 | |||
649 | /* bump the main kobject's reference count for this controller | 632 | /* bump the main kobject's reference count for this controller |
650 | * and this instance is dependant on the main | 633 | * and this instance is dependant on the main |
651 | */ | 634 | */ |
@@ -655,8 +638,9 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev, | |||
655 | goto err_out; | 638 | goto err_out; |
656 | } | 639 | } |
657 | 640 | ||
658 | /* Formally register this instance's kobject */ | 641 | /* Formally register this instance's kobject under the edac_device */ |
659 | err = kobject_register(&instance->kobj); | 642 | err = kobject_init_and_add(&instance->kobj, &ktype_instance_ctrl, |
643 | &edac_dev->kobj, "%s", instance->name); | ||
660 | if (err != 0) { | 644 | if (err != 0) { |
661 | debugf2("%s() Failed to register instance '%s'\n", | 645 | debugf2("%s() Failed to register instance '%s'\n", |
662 | __func__, instance->name); | 646 | __func__, instance->name); |
@@ -679,6 +663,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev, | |||
679 | goto err_release_instance_kobj; | 663 | goto err_release_instance_kobj; |
680 | } | 664 | } |
681 | } | 665 | } |
666 | kobject_uevent(&instance->kobj, KOBJ_ADD); | ||
682 | 667 | ||
683 | debugf4("%s() Registered instance %d '%s' kobject\n", | 668 | debugf4("%s() Registered instance %d '%s' kobject\n", |
684 | __func__, idx, instance->name); | 669 | __func__, idx, instance->name); |
@@ -687,7 +672,7 @@ static int edac_device_create_instance(struct edac_device_ctl_info *edac_dev, | |||
687 | 672 | ||
688 | /* error unwind stack */ | 673 | /* error unwind stack */ |
689 | err_release_instance_kobj: | 674 | err_release_instance_kobj: |
690 | kobject_unregister(&instance->kobj); | 675 | kobject_put(&instance->kobj); |
691 | 676 | ||
692 | err_out: | 677 | err_out: |
693 | return err; | 678 | return err; |
@@ -712,7 +697,7 @@ static void edac_device_delete_instance(struct edac_device_ctl_info *edac_dev, | |||
712 | /* unregister this instance's kobject, SEE: | 697 | /* unregister this instance's kobject, SEE: |
713 | * edac_device_ctrl_instance_release() for callback operation | 698 | * edac_device_ctrl_instance_release() for callback operation |
714 | */ | 699 | */ |
715 | kobject_unregister(&instance->kobj); | 700 | kobject_put(&instance->kobj); |
716 | } | 701 | } |
717 | 702 | ||
718 | /* | 703 | /* |
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 3706b2bc0987..9aac88027fb3 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -380,13 +380,6 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, | |||
380 | /* generate ..../edac/mc/mc<id>/csrow<index> */ | 380 | /* generate ..../edac/mc/mc<id>/csrow<index> */ |
381 | memset(&csrow->kobj, 0, sizeof(csrow->kobj)); | 381 | memset(&csrow->kobj, 0, sizeof(csrow->kobj)); |
382 | csrow->mci = mci; /* include container up link */ | 382 | csrow->mci = mci; /* include container up link */ |
383 | csrow->kobj.parent = kobj_mci; | ||
384 | csrow->kobj.ktype = &ktype_csrow; | ||
385 | |||
386 | /* name this instance of csrow<id> */ | ||
387 | err = kobject_set_name(&csrow->kobj, "csrow%d", index); | ||
388 | if (err) | ||
389 | goto err_out; | ||
390 | 383 | ||
391 | /* bump the mci instance's kobject's ref count */ | 384 | /* bump the mci instance's kobject's ref count */ |
392 | kobj = kobject_get(&mci->edac_mci_kobj); | 385 | kobj = kobject_get(&mci->edac_mci_kobj); |
@@ -396,12 +389,13 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, | |||
396 | } | 389 | } |
397 | 390 | ||
398 | /* Instanstiate the csrow object */ | 391 | /* Instanstiate the csrow object */ |
399 | err = kobject_register(&csrow->kobj); | 392 | err = kobject_init_and_add(&csrow->kobj, &ktype_csrow, kobj_mci, |
393 | "csrow%d", index); | ||
400 | if (err) | 394 | if (err) |
401 | goto err_release_top_kobj; | 395 | goto err_release_top_kobj; |
402 | 396 | ||
403 | /* At this point, to release a csrow kobj, one must | 397 | /* At this point, to release a csrow kobj, one must |
404 | * call the kobject_unregister and allow that tear down | 398 | * call the kobject_put and allow that tear down |
405 | * to work the releasing | 399 | * to work the releasing |
406 | */ | 400 | */ |
407 | 401 | ||
@@ -412,11 +406,11 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, | |||
412 | err = edac_create_channel_files(&csrow->kobj, chan); | 406 | err = edac_create_channel_files(&csrow->kobj, chan); |
413 | if (err) { | 407 | if (err) { |
414 | /* special case the unregister here */ | 408 | /* special case the unregister here */ |
415 | kobject_unregister(&csrow->kobj); | 409 | kobject_put(&csrow->kobj); |
416 | goto err_out; | 410 | goto err_out; |
417 | } | 411 | } |
418 | } | 412 | } |
419 | 413 | kobject_uevent(&csrow->kobj, KOBJ_ADD); | |
420 | return 0; | 414 | return 0; |
421 | 415 | ||
422 | /* error unwind stack */ | 416 | /* error unwind stack */ |
@@ -744,7 +738,6 @@ static struct kobj_type ktype_mc_set_attribs = { | |||
744 | */ | 738 | */ |
745 | static struct kset mc_kset = { | 739 | static struct kset mc_kset = { |
746 | .kobj = {.ktype = &ktype_mc_set_attribs }, | 740 | .kobj = {.ktype = &ktype_mc_set_attribs }, |
747 | .ktype = &ktype_mci, | ||
748 | }; | 741 | }; |
749 | 742 | ||
750 | 743 | ||
@@ -765,14 +758,6 @@ int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci) | |||
765 | /* Init the mci's kobject */ | 758 | /* Init the mci's kobject */ |
766 | memset(kobj_mci, 0, sizeof(*kobj_mci)); | 759 | memset(kobj_mci, 0, sizeof(*kobj_mci)); |
767 | 760 | ||
768 | /* this instance become part of the mc_kset */ | ||
769 | kobj_mci->kset = &mc_kset; | ||
770 | |||
771 | /* set the name of the mc<id> object */ | ||
772 | err = kobject_set_name(kobj_mci, "mc%d", mci->mc_idx); | ||
773 | if (err) | ||
774 | goto fail_out; | ||
775 | |||
776 | /* Record which module 'owns' this control structure | 761 | /* Record which module 'owns' this control structure |
777 | * and bump the ref count of the module | 762 | * and bump the ref count of the module |
778 | */ | 763 | */ |
@@ -784,13 +769,18 @@ int edac_mc_register_sysfs_main_kobj(struct mem_ctl_info *mci) | |||
784 | goto fail_out; | 769 | goto fail_out; |
785 | } | 770 | } |
786 | 771 | ||
772 | /* this instance become part of the mc_kset */ | ||
773 | kobj_mci->kset = &mc_kset; | ||
774 | |||
787 | /* register the mc<id> kobject to the mc_kset */ | 775 | /* register the mc<id> kobject to the mc_kset */ |
788 | err = kobject_register(kobj_mci); | 776 | err = kobject_init_and_add(kobj_mci, &ktype_mci, NULL, |
777 | "mc%d", mci->mc_idx); | ||
789 | if (err) { | 778 | if (err) { |
790 | debugf1("%s()Failed to register '.../edac/mc%d'\n", | 779 | debugf1("%s()Failed to register '.../edac/mc%d'\n", |
791 | __func__, mci->mc_idx); | 780 | __func__, mci->mc_idx); |
792 | goto kobj_reg_fail; | 781 | goto kobj_reg_fail; |
793 | } | 782 | } |
783 | kobject_uevent(kobj_mci, KOBJ_ADD); | ||
794 | 784 | ||
795 | /* At this point, to 'free' the control struct, | 785 | /* At this point, to 'free' the control struct, |
796 | * edac_mc_unregister_sysfs_main_kobj() must be used | 786 | * edac_mc_unregister_sysfs_main_kobj() must be used |
@@ -818,7 +808,7 @@ fail_out: | |||
818 | void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) | 808 | void edac_mc_unregister_sysfs_main_kobj(struct mem_ctl_info *mci) |
819 | { | 809 | { |
820 | /* delete the kobj from the mc_kset */ | 810 | /* delete the kobj from the mc_kset */ |
821 | kobject_unregister(&mci->edac_mci_kobj); | 811 | kobject_put(&mci->edac_mci_kobj); |
822 | } | 812 | } |
823 | 813 | ||
824 | #define EDAC_DEVICE_SYMLINK "device" | 814 | #define EDAC_DEVICE_SYMLINK "device" |
@@ -933,7 +923,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
933 | fail1: | 923 | fail1: |
934 | for (i--; i >= 0; i--) { | 924 | for (i--; i >= 0; i--) { |
935 | if (csrow->nr_pages > 0) { | 925 | if (csrow->nr_pages > 0) { |
936 | kobject_unregister(&mci->csrows[i].kobj); | 926 | kobject_put(&mci->csrows[i].kobj); |
937 | } | 927 | } |
938 | } | 928 | } |
939 | 929 | ||
@@ -960,7 +950,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
960 | for (i = 0; i < mci->nr_csrows; i++) { | 950 | for (i = 0; i < mci->nr_csrows; i++) { |
961 | if (mci->csrows[i].nr_pages > 0) { | 951 | if (mci->csrows[i].nr_pages > 0) { |
962 | debugf0("%s() unreg csrow-%d\n", __func__, i); | 952 | debugf0("%s() unreg csrow-%d\n", __func__, i); |
963 | kobject_unregister(&mci->csrows[i].kobj); | 953 | kobject_put(&mci->csrows[i].kobj); |
964 | } | 954 | } |
965 | } | 955 | } |
966 | 956 | ||
@@ -977,7 +967,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | |||
977 | debugf0("%s() unregister this mci kobj\n", __func__); | 967 | debugf0("%s() unregister this mci kobj\n", __func__); |
978 | 968 | ||
979 | /* unregister this instance's kobject */ | 969 | /* unregister this instance's kobject */ |
980 | kobject_unregister(&mci->edac_mci_kobj); | 970 | kobject_put(&mci->edac_mci_kobj); |
981 | } | 971 | } |
982 | 972 | ||
983 | 973 | ||
diff --git a/drivers/edac/edac_module.c b/drivers/edac/edac_module.c index e0c4a4086055..7e1374afd967 100644 --- a/drivers/edac/edac_module.c +++ b/drivers/edac/edac_module.c | |||
@@ -31,7 +31,7 @@ struct workqueue_struct *edac_workqueue; | |||
31 | * need to export to other files in this modules | 31 | * need to export to other files in this modules |
32 | */ | 32 | */ |
33 | static struct sysdev_class edac_class = { | 33 | static struct sysdev_class edac_class = { |
34 | set_kset_name("edac"), | 34 | .name = "edac", |
35 | }; | 35 | }; |
36 | static int edac_class_valid; | 36 | static int edac_class_valid; |
37 | 37 | ||
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 69f5dddabddf..5b075da99145 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c | |||
@@ -162,14 +162,6 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) | |||
162 | 162 | ||
163 | debugf0("%s()\n", __func__); | 163 | debugf0("%s()\n", __func__); |
164 | 164 | ||
165 | /* Set the parent and the instance's ktype */ | ||
166 | pci->kobj.parent = &edac_pci_top_main_kobj; | ||
167 | pci->kobj.ktype = &ktype_pci_instance; | ||
168 | |||
169 | err = kobject_set_name(&pci->kobj, "pci%d", idx); | ||
170 | if (err) | ||
171 | return err; | ||
172 | |||
173 | /* First bump the ref count on the top main kobj, which will | 165 | /* First bump the ref count on the top main kobj, which will |
174 | * track the number of PCI instances we have, and thus nest | 166 | * track the number of PCI instances we have, and thus nest |
175 | * properly on keeping the module loaded | 167 | * properly on keeping the module loaded |
@@ -181,7 +173,8 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) | |||
181 | } | 173 | } |
182 | 174 | ||
183 | /* And now register this new kobject under the main kobj */ | 175 | /* And now register this new kobject under the main kobj */ |
184 | err = kobject_register(&pci->kobj); | 176 | err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance, |
177 | &edac_pci_top_main_kobj, "pci%d", idx); | ||
185 | if (err != 0) { | 178 | if (err != 0) { |
186 | debugf2("%s() failed to register instance pci%d\n", | 179 | debugf2("%s() failed to register instance pci%d\n", |
187 | __func__, idx); | 180 | __func__, idx); |
@@ -189,6 +182,7 @@ static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx) | |||
189 | goto error_out; | 182 | goto error_out; |
190 | } | 183 | } |
191 | 184 | ||
185 | kobject_uevent(&pci->kobj, KOBJ_ADD); | ||
192 | debugf1("%s() Register instance 'pci%d' kobject\n", __func__, idx); | 186 | debugf1("%s() Register instance 'pci%d' kobject\n", __func__, idx); |
193 | 187 | ||
194 | return 0; | 188 | return 0; |
@@ -211,7 +205,7 @@ void edac_pci_unregister_sysfs_instance_kobj(struct edac_pci_ctl_info *pci) | |||
211 | * function release the main reference count and then | 205 | * function release the main reference count and then |
212 | * kfree the memory | 206 | * kfree the memory |
213 | */ | 207 | */ |
214 | kobject_unregister(&pci->kobj); | 208 | kobject_put(&pci->kobj); |
215 | } | 209 | } |
216 | 210 | ||
217 | /***************************** EDAC PCI sysfs root **********************/ | 211 | /***************************** EDAC PCI sysfs root **********************/ |
@@ -364,14 +358,6 @@ int edac_pci_main_kobj_setup(void) | |||
364 | goto decrement_count_fail; | 358 | goto decrement_count_fail; |
365 | } | 359 | } |
366 | 360 | ||
367 | /* Need the kobject hook ups, and name setting */ | ||
368 | edac_pci_top_main_kobj.ktype = &ktype_edac_pci_main_kobj; | ||
369 | edac_pci_top_main_kobj.parent = &edac_class->kset.kobj; | ||
370 | |||
371 | err = kobject_set_name(&edac_pci_top_main_kobj, "pci"); | ||
372 | if (err) | ||
373 | goto decrement_count_fail; | ||
374 | |||
375 | /* Bump the reference count on this module to ensure the | 361 | /* Bump the reference count on this module to ensure the |
376 | * modules isn't unloaded until we deconstruct the top | 362 | * modules isn't unloaded until we deconstruct the top |
377 | * level main kobj for EDAC PCI | 363 | * level main kobj for EDAC PCI |
@@ -383,23 +369,24 @@ int edac_pci_main_kobj_setup(void) | |||
383 | } | 369 | } |
384 | 370 | ||
385 | /* Instanstiate the pci object */ | 371 | /* Instanstiate the pci object */ |
386 | /* FIXME: maybe new sysdev_create_subdir() */ | 372 | err = kobject_init_and_add(&edac_pci_top_main_kobj, &ktype_edac_pci_main_kobj, |
387 | err = kobject_register(&edac_pci_top_main_kobj); | 373 | &edac_class->kset.kobj, "pci"); |
388 | if (err) { | 374 | if (err) { |
389 | debugf1("Failed to register '.../edac/pci'\n"); | 375 | debugf1("Failed to register '.../edac/pci'\n"); |
390 | goto kobject_register_fail; | 376 | goto kobject_init_and_add_fail; |
391 | } | 377 | } |
392 | 378 | ||
393 | /* At this point, to 'release' the top level kobject | 379 | /* At this point, to 'release' the top level kobject |
394 | * for EDAC PCI, then edac_pci_main_kobj_teardown() | 380 | * for EDAC PCI, then edac_pci_main_kobj_teardown() |
395 | * must be used, for resources to be cleaned up properly | 381 | * must be used, for resources to be cleaned up properly |
396 | */ | 382 | */ |
383 | kobject_uevent(&edac_pci_top_main_kobj, KOBJ_ADD); | ||
397 | debugf1("Registered '.../edac/pci' kobject\n"); | 384 | debugf1("Registered '.../edac/pci' kobject\n"); |
398 | 385 | ||
399 | return 0; | 386 | return 0; |
400 | 387 | ||
401 | /* Error unwind statck */ | 388 | /* Error unwind statck */ |
402 | kobject_register_fail: | 389 | kobject_init_and_add_fail: |
403 | module_put(THIS_MODULE); | 390 | module_put(THIS_MODULE); |
404 | 391 | ||
405 | decrement_count_fail: | 392 | decrement_count_fail: |
@@ -424,9 +411,9 @@ static void edac_pci_main_kobj_teardown(void) | |||
424 | * main kobj | 411 | * main kobj |
425 | */ | 412 | */ |
426 | if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { | 413 | if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) { |
427 | debugf0("%s() called kobject_unregister on main kobj\n", | 414 | debugf0("%s() called kobject_put on main kobj\n", |
428 | __func__); | 415 | __func__); |
429 | kobject_unregister(&edac_pci_top_main_kobj); | 416 | kobject_put(&edac_pci_top_main_kobj); |
430 | } | 417 | } |
431 | } | 418 | } |
432 | 419 | ||
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 6942e065e609..d168223db159 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c | |||
@@ -631,7 +631,7 @@ static struct kobj_type edd_ktype = { | |||
631 | .default_attrs = def_attrs, | 631 | .default_attrs = def_attrs, |
632 | }; | 632 | }; |
633 | 633 | ||
634 | static decl_subsys(edd, &edd_ktype, NULL); | 634 | static struct kset *edd_kset; |
635 | 635 | ||
636 | 636 | ||
637 | /** | 637 | /** |
@@ -693,7 +693,7 @@ edd_create_symlink_to_pcidev(struct edd_device *edev) | |||
693 | static inline void | 693 | static inline void |
694 | edd_device_unregister(struct edd_device *edev) | 694 | edd_device_unregister(struct edd_device *edev) |
695 | { | 695 | { |
696 | kobject_unregister(&edev->kobj); | 696 | kobject_put(&edev->kobj); |
697 | } | 697 | } |
698 | 698 | ||
699 | static void edd_populate_dir(struct edd_device * edev) | 699 | static void edd_populate_dir(struct edd_device * edev) |
@@ -721,12 +721,13 @@ edd_device_register(struct edd_device *edev, int i) | |||
721 | if (!edev) | 721 | if (!edev) |
722 | return 1; | 722 | return 1; |
723 | edd_dev_set_info(edev, i); | 723 | edd_dev_set_info(edev, i); |
724 | kobject_set_name(&edev->kobj, "int13_dev%02x", | 724 | edev->kobj.kset = edd_kset; |
725 | 0x80 + i); | 725 | error = kobject_init_and_add(&edev->kobj, &edd_ktype, NULL, |
726 | kobj_set_kset_s(edev,edd_subsys); | 726 | "int13_dev%02x", 0x80 + i); |
727 | error = kobject_register(&edev->kobj); | 727 | if (!error) { |
728 | if (!error) | ||
729 | edd_populate_dir(edev); | 728 | edd_populate_dir(edev); |
729 | kobject_uevent(&edev->kobj, KOBJ_ADD); | ||
730 | } | ||
730 | return error; | 731 | return error; |
731 | } | 732 | } |
732 | 733 | ||
@@ -755,9 +756,9 @@ edd_init(void) | |||
755 | return 1; | 756 | return 1; |
756 | } | 757 | } |
757 | 758 | ||
758 | rc = firmware_register(&edd_subsys); | 759 | edd_kset = kset_create_and_add("edd", NULL, firmware_kobj); |
759 | if (rc) | 760 | if (!edd_kset) |
760 | return rc; | 761 | return -ENOMEM; |
761 | 762 | ||
762 | for (i = 0; i < edd_num_devices() && !rc; i++) { | 763 | for (i = 0; i < edd_num_devices() && !rc; i++) { |
763 | edev = kzalloc(sizeof (*edev), GFP_KERNEL); | 764 | edev = kzalloc(sizeof (*edev), GFP_KERNEL); |
@@ -773,7 +774,7 @@ edd_init(void) | |||
773 | } | 774 | } |
774 | 775 | ||
775 | if (rc) | 776 | if (rc) |
776 | firmware_unregister(&edd_subsys); | 777 | kset_unregister(edd_kset); |
777 | return rc; | 778 | return rc; |
778 | } | 779 | } |
779 | 780 | ||
@@ -787,7 +788,7 @@ edd_exit(void) | |||
787 | if ((edev = edd_devices[i])) | 788 | if ((edev = edd_devices[i])) |
788 | edd_device_unregister(edev); | 789 | edd_device_unregister(edev); |
789 | } | 790 | } |
790 | firmware_unregister(&edd_subsys); | 791 | kset_unregister(edd_kset); |
791 | } | 792 | } |
792 | 793 | ||
793 | late_initcall(edd_init); | 794 | late_initcall(edd_init); |
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 858a7b95933b..f4f709d1370b 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -129,13 +129,6 @@ struct efivar_attribute { | |||
129 | }; | 129 | }; |
130 | 130 | ||
131 | 131 | ||
132 | #define EFI_ATTR(_name, _mode, _show, _store) \ | ||
133 | struct subsys_attribute efi_attr_##_name = { \ | ||
134 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | ||
135 | .show = _show, \ | ||
136 | .store = _store, \ | ||
137 | }; | ||
138 | |||
139 | #define EFIVAR_ATTR(_name, _mode, _show, _store) \ | 132 | #define EFIVAR_ATTR(_name, _mode, _show, _store) \ |
140 | struct efivar_attribute efivar_attr_##_name = { \ | 133 | struct efivar_attribute efivar_attr_##_name = { \ |
141 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | 134 | .attr = {.name = __stringify(_name), .mode = _mode}, \ |
@@ -143,13 +136,6 @@ struct efivar_attribute efivar_attr_##_name = { \ | |||
143 | .store = _store, \ | 136 | .store = _store, \ |
144 | }; | 137 | }; |
145 | 138 | ||
146 | #define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \ | ||
147 | struct subsys_attribute var_subsys_attr_##_name = { \ | ||
148 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | ||
149 | .show = _show, \ | ||
150 | .store = _store, \ | ||
151 | }; | ||
152 | |||
153 | #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr) | 139 | #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr) |
154 | #define to_efivar_entry(obj) container_of(obj, struct efivar_entry, kobj) | 140 | #define to_efivar_entry(obj) container_of(obj, struct efivar_entry, kobj) |
155 | 141 | ||
@@ -408,21 +394,16 @@ static struct kobj_type efivar_ktype = { | |||
408 | .default_attrs = def_attrs, | 394 | .default_attrs = def_attrs, |
409 | }; | 395 | }; |
410 | 396 | ||
411 | static ssize_t | ||
412 | dummy(struct kset *kset, char *buf) | ||
413 | { | ||
414 | return -ENODEV; | ||
415 | } | ||
416 | |||
417 | static inline void | 397 | static inline void |
418 | efivar_unregister(struct efivar_entry *var) | 398 | efivar_unregister(struct efivar_entry *var) |
419 | { | 399 | { |
420 | kobject_unregister(&var->kobj); | 400 | kobject_put(&var->kobj); |
421 | } | 401 | } |
422 | 402 | ||
423 | 403 | ||
424 | static ssize_t | 404 | static ssize_t efivar_create(struct kobject *kobj, |
425 | efivar_create(struct kset *kset, const char *buf, size_t count) | 405 | struct bin_attribute *bin_attr, |
406 | char *buf, loff_t pos, size_t count) | ||
426 | { | 407 | { |
427 | struct efi_variable *new_var = (struct efi_variable *)buf; | 408 | struct efi_variable *new_var = (struct efi_variable *)buf; |
428 | struct efivar_entry *search_efivar, *n; | 409 | struct efivar_entry *search_efivar, *n; |
@@ -479,8 +460,9 @@ efivar_create(struct kset *kset, const char *buf, size_t count) | |||
479 | return count; | 460 | return count; |
480 | } | 461 | } |
481 | 462 | ||
482 | static ssize_t | 463 | static ssize_t efivar_delete(struct kobject *kobj, |
483 | efivar_delete(struct kset *kset, const char *buf, size_t count) | 464 | struct bin_attribute *bin_attr, |
465 | char *buf, loff_t pos, size_t count) | ||
484 | { | 466 | { |
485 | struct efi_variable *del_var = (struct efi_variable *)buf; | 467 | struct efi_variable *del_var = (struct efi_variable *)buf; |
486 | struct efivar_entry *search_efivar, *n; | 468 | struct efivar_entry *search_efivar, *n; |
@@ -537,25 +519,26 @@ efivar_delete(struct kset *kset, const char *buf, size_t count) | |||
537 | return count; | 519 | return count; |
538 | } | 520 | } |
539 | 521 | ||
540 | static VAR_SUBSYS_ATTR(new_var, 0200, dummy, efivar_create); | 522 | static struct bin_attribute var_subsys_attr_new_var = { |
541 | static VAR_SUBSYS_ATTR(del_var, 0200, dummy, efivar_delete); | 523 | .attr = {.name = "new_var", .mode = 0200}, |
524 | .write = efivar_create, | ||
525 | }; | ||
542 | 526 | ||
543 | static struct subsys_attribute *var_subsys_attrs[] = { | 527 | static struct bin_attribute var_subsys_attr_del_var = { |
544 | &var_subsys_attr_new_var, | 528 | .attr = {.name = "del_var", .mode = 0200}, |
545 | &var_subsys_attr_del_var, | 529 | .write = efivar_delete, |
546 | NULL, | ||
547 | }; | 530 | }; |
548 | 531 | ||
549 | /* | 532 | /* |
550 | * Let's not leave out systab information that snuck into | 533 | * Let's not leave out systab information that snuck into |
551 | * the efivars driver | 534 | * the efivars driver |
552 | */ | 535 | */ |
553 | static ssize_t | 536 | static ssize_t systab_show(struct kobject *kobj, |
554 | systab_read(struct kset *kset, char *buf) | 537 | struct kobj_attribute *attr, char *buf) |
555 | { | 538 | { |
556 | char *str = buf; | 539 | char *str = buf; |
557 | 540 | ||
558 | if (!kset || !buf) | 541 | if (!kobj || !buf) |
559 | return -EINVAL; | 542 | return -EINVAL; |
560 | 543 | ||
561 | if (efi.mps != EFI_INVALID_TABLE_ADDR) | 544 | if (efi.mps != EFI_INVALID_TABLE_ADDR) |
@@ -576,15 +559,21 @@ systab_read(struct kset *kset, char *buf) | |||
576 | return str - buf; | 559 | return str - buf; |
577 | } | 560 | } |
578 | 561 | ||
579 | static EFI_ATTR(systab, 0400, systab_read, NULL); | 562 | static struct kobj_attribute efi_attr_systab = |
563 | __ATTR(systab, 0400, systab_show, NULL); | ||
580 | 564 | ||
581 | static struct subsys_attribute *efi_subsys_attrs[] = { | 565 | static struct attribute *efi_subsys_attrs[] = { |
582 | &efi_attr_systab, | 566 | &efi_attr_systab.attr, |
583 | NULL, /* maybe more in the future? */ | 567 | NULL, /* maybe more in the future? */ |
584 | }; | 568 | }; |
585 | 569 | ||
586 | static decl_subsys(vars, &efivar_ktype, NULL); | 570 | static struct attribute_group efi_subsys_attr_group = { |
587 | static decl_subsys(efi, NULL, NULL); | 571 | .attrs = efi_subsys_attrs, |
572 | }; | ||
573 | |||
574 | |||
575 | static struct kset *vars_kset; | ||
576 | static struct kobject *efi_kobj; | ||
588 | 577 | ||
589 | /* | 578 | /* |
590 | * efivar_create_sysfs_entry() | 579 | * efivar_create_sysfs_entry() |
@@ -628,15 +617,16 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, | |||
628 | *(short_name + strlen(short_name)) = '-'; | 617 | *(short_name + strlen(short_name)) = '-'; |
629 | efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); | 618 | efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); |
630 | 619 | ||
631 | kobject_set_name(&new_efivar->kobj, "%s", short_name); | 620 | new_efivar->kobj.kset = vars_kset; |
632 | kobj_set_kset_s(new_efivar, vars_subsys); | 621 | i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL, |
633 | i = kobject_register(&new_efivar->kobj); | 622 | "%s", short_name); |
634 | if (i) { | 623 | if (i) { |
635 | kfree(short_name); | 624 | kfree(short_name); |
636 | kfree(new_efivar); | 625 | kfree(new_efivar); |
637 | return 1; | 626 | return 1; |
638 | } | 627 | } |
639 | 628 | ||
629 | kobject_uevent(&new_efivar->kobj, KOBJ_ADD); | ||
640 | kfree(short_name); | 630 | kfree(short_name); |
641 | short_name = NULL; | 631 | short_name = NULL; |
642 | 632 | ||
@@ -660,9 +650,8 @@ efivars_init(void) | |||
660 | efi_status_t status = EFI_NOT_FOUND; | 650 | efi_status_t status = EFI_NOT_FOUND; |
661 | efi_guid_t vendor_guid; | 651 | efi_guid_t vendor_guid; |
662 | efi_char16_t *variable_name; | 652 | efi_char16_t *variable_name; |
663 | struct subsys_attribute *attr; | ||
664 | unsigned long variable_name_size = 1024; | 653 | unsigned long variable_name_size = 1024; |
665 | int i, error = 0; | 654 | int error = 0; |
666 | 655 | ||
667 | if (!efi_enabled) | 656 | if (!efi_enabled) |
668 | return -ENODEV; | 657 | return -ENODEV; |
@@ -676,23 +665,18 @@ efivars_init(void) | |||
676 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, | 665 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, |
677 | EFIVARS_DATE); | 666 | EFIVARS_DATE); |
678 | 667 | ||
679 | /* | 668 | /* For now we'll register the efi directory at /sys/firmware/efi */ |
680 | * For now we'll register the efi subsys within this driver | 669 | efi_kobj = kobject_create_and_add("efi", firmware_kobj); |
681 | */ | 670 | if (!efi_kobj) { |
682 | 671 | printk(KERN_ERR "efivars: Firmware registration failed.\n"); | |
683 | error = firmware_register(&efi_subsys); | 672 | error = -ENOMEM; |
684 | |||
685 | if (error) { | ||
686 | printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error); | ||
687 | goto out_free; | 673 | goto out_free; |
688 | } | 674 | } |
689 | 675 | ||
690 | kobj_set_kset_s(&vars_subsys, efi_subsys); | 676 | vars_kset = kset_create_and_add("vars", NULL, efi_kobj); |
691 | 677 | if (!vars_kset) { | |
692 | error = subsystem_register(&vars_subsys); | 678 | printk(KERN_ERR "efivars: Subsystem registration failed.\n"); |
693 | 679 | error = -ENOMEM; | |
694 | if (error) { | ||
695 | printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error); | ||
696 | goto out_firmware_unregister; | 680 | goto out_firmware_unregister; |
697 | } | 681 | } |
698 | 682 | ||
@@ -727,28 +711,28 @@ efivars_init(void) | |||
727 | * Now add attributes to allow creation of new vars | 711 | * Now add attributes to allow creation of new vars |
728 | * and deletion of existing ones... | 712 | * and deletion of existing ones... |
729 | */ | 713 | */ |
730 | 714 | error = sysfs_create_bin_file(&vars_kset->kobj, | |
731 | for (i = 0; (attr = var_subsys_attrs[i]) && !error; i++) { | 715 | &var_subsys_attr_new_var); |
732 | if (attr->show && attr->store) | 716 | if (error) |
733 | error = subsys_create_file(&vars_subsys, attr); | 717 | printk(KERN_ERR "efivars: unable to create new_var sysfs file" |
734 | } | 718 | " due to error %d\n", error); |
719 | error = sysfs_create_bin_file(&vars_kset->kobj, | ||
720 | &var_subsys_attr_del_var); | ||
721 | if (error) | ||
722 | printk(KERN_ERR "efivars: unable to create del_var sysfs file" | ||
723 | " due to error %d\n", error); | ||
735 | 724 | ||
736 | /* Don't forget the systab entry */ | 725 | /* Don't forget the systab entry */ |
737 | 726 | error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); | |
738 | for (i = 0; (attr = efi_subsys_attrs[i]) && !error; i++) { | ||
739 | if (attr->show) | ||
740 | error = subsys_create_file(&efi_subsys, attr); | ||
741 | } | ||
742 | |||
743 | if (error) | 727 | if (error) |
744 | printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); | 728 | printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); |
745 | else | 729 | else |
746 | goto out_free; | 730 | goto out_free; |
747 | 731 | ||
748 | subsystem_unregister(&vars_subsys); | 732 | kset_unregister(vars_kset); |
749 | 733 | ||
750 | out_firmware_unregister: | 734 | out_firmware_unregister: |
751 | firmware_unregister(&efi_subsys); | 735 | kobject_put(efi_kobj); |
752 | 736 | ||
753 | out_free: | 737 | out_free: |
754 | kfree(variable_name); | 738 | kfree(variable_name); |
@@ -768,8 +752,8 @@ efivars_exit(void) | |||
768 | efivar_unregister(entry); | 752 | efivar_unregister(entry); |
769 | } | 753 | } |
770 | 754 | ||
771 | subsystem_unregister(&vars_subsys); | 755 | kset_unregister(vars_kset); |
772 | firmware_unregister(&efi_subsys); | 756 | kobject_put(efi_kobj); |
773 | } | 757 | } |
774 | 758 | ||
775 | module_init(efivars_init); | 759 | module_init(efivars_init); |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index b767603a07ba..ebfbb2947ae6 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
@@ -259,12 +259,6 @@ static inline const char *state_name(struct isp1301 *isp) | |||
259 | return state_string(isp->otg.state); | 259 | return state_string(isp->otg.state); |
260 | } | 260 | } |
261 | 261 | ||
262 | #ifdef VERBOSE | ||
263 | #define dev_vdbg dev_dbg | ||
264 | #else | ||
265 | #define dev_vdbg(dev, fmt, arg...) do{}while(0) | ||
266 | #endif | ||
267 | |||
268 | /*-------------------------------------------------------------------------*/ | 262 | /*-------------------------------------------------------------------------*/ |
269 | 263 | ||
270 | /* NOTE: some of this ISP1301 setup is specific to H2 boards; | 264 | /* NOTE: some of this ISP1301 setup is specific to H2 boards; |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 2994523be7bf..0cb3d2bb3ab9 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -1173,7 +1173,7 @@ static struct kobject *exact_match(dev_t dev, int *part, void *data) | |||
1173 | { | 1173 | { |
1174 | struct gendisk *p = data; | 1174 | struct gendisk *p = data; |
1175 | *part &= (1 << PARTN_BITS) - 1; | 1175 | *part &= (1 << PARTN_BITS) - 1; |
1176 | return &p->kobj; | 1176 | return &p->dev.kobj; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static int exact_lock(dev_t dev, void *data) | 1179 | static int exact_lock(dev_t dev, void *data) |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7b9181b5469d..1495792d7917 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -4724,10 +4724,8 @@ static void ide_tape_release(struct kref *kref) | |||
4724 | 4724 | ||
4725 | drive->dsc_overlap = 0; | 4725 | drive->dsc_overlap = 0; |
4726 | drive->driver_data = NULL; | 4726 | drive->driver_data = NULL; |
4727 | class_device_destroy(idetape_sysfs_class, | 4727 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); |
4728 | MKDEV(IDETAPE_MAJOR, tape->minor)); | 4728 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor + 128)); |
4729 | class_device_destroy(idetape_sysfs_class, | ||
4730 | MKDEV(IDETAPE_MAJOR, tape->minor + 128)); | ||
4731 | idetape_devs[tape->minor] = NULL; | 4729 | idetape_devs[tape->minor] = NULL; |
4732 | g->private_data = NULL; | 4730 | g->private_data = NULL; |
4733 | put_disk(g); | 4731 | put_disk(g); |
@@ -4884,10 +4882,10 @@ static int ide_tape_probe(ide_drive_t *drive) | |||
4884 | 4882 | ||
4885 | idetape_setup(drive, tape, minor); | 4883 | idetape_setup(drive, tape, minor); |
4886 | 4884 | ||
4887 | class_device_create(idetape_sysfs_class, NULL, | 4885 | device_create(idetape_sysfs_class, &drive->gendev, |
4888 | MKDEV(IDETAPE_MAJOR, minor), &drive->gendev, "%s", tape->name); | 4886 | MKDEV(IDETAPE_MAJOR, minor), "%s", tape->name); |
4889 | class_device_create(idetape_sysfs_class, NULL, | 4887 | device_create(idetape_sysfs_class, &drive->gendev, |
4890 | MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name); | 4888 | MKDEV(IDETAPE_MAJOR, minor + 128), "n%s", tape->name); |
4891 | 4889 | ||
4892 | g->fops = &idetape_block_ops; | 4890 | g->fops = &idetape_block_ops; |
4893 | ide_register_region(g); | 4891 | ide_register_region(g); |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 90dc75be3418..511e4321c6b6 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -727,33 +727,31 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv) | |||
727 | 727 | ||
728 | static DEFINE_MUTEX(nodemgr_serialize_remove_uds); | 728 | static DEFINE_MUTEX(nodemgr_serialize_remove_uds); |
729 | 729 | ||
730 | static int __match_ne(struct device *dev, void *data) | ||
731 | { | ||
732 | struct unit_directory *ud; | ||
733 | struct node_entry *ne = (struct node_entry *)data; | ||
734 | |||
735 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
736 | return ud->ne == ne; | ||
737 | } | ||
738 | |||
730 | static void nodemgr_remove_uds(struct node_entry *ne) | 739 | static void nodemgr_remove_uds(struct node_entry *ne) |
731 | { | 740 | { |
732 | struct device *dev; | 741 | struct device *dev; |
733 | struct unit_directory *tmp, *ud; | 742 | struct unit_directory *ud; |
734 | 743 | ||
735 | /* Iteration over nodemgr_ud_class.devices has to be protected by | 744 | /* Use class_find device to iterate the devices. Since this code |
736 | * nodemgr_ud_class.sem, but device_unregister() will eventually | 745 | * may be called from other contexts besides the knodemgrds, |
737 | * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, | 746 | * protect it by nodemgr_serialize_remove_uds. |
738 | * release the semaphore, and then unregister the ud. Since this code | ||
739 | * may be called from other contexts besides the knodemgrds, protect the | ||
740 | * gap after release of the semaphore by nodemgr_serialize_remove_uds. | ||
741 | */ | 747 | */ |
742 | mutex_lock(&nodemgr_serialize_remove_uds); | 748 | mutex_lock(&nodemgr_serialize_remove_uds); |
743 | for (;;) { | 749 | for (;;) { |
744 | ud = NULL; | 750 | dev = class_find_device(&nodemgr_ud_class, ne, __match_ne); |
745 | down(&nodemgr_ud_class.sem); | 751 | if (!dev) |
746 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { | ||
747 | tmp = container_of(dev, struct unit_directory, | ||
748 | unit_dev); | ||
749 | if (tmp->ne == ne) { | ||
750 | ud = tmp; | ||
751 | break; | ||
752 | } | ||
753 | } | ||
754 | up(&nodemgr_ud_class.sem); | ||
755 | if (ud == NULL) | ||
756 | break; | 752 | break; |
753 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
754 | put_device(dev); | ||
757 | device_unregister(&ud->unit_dev); | 755 | device_unregister(&ud->unit_dev); |
758 | device_unregister(&ud->device); | 756 | device_unregister(&ud->device); |
759 | } | 757 | } |
@@ -882,45 +880,66 @@ fail_alloc: | |||
882 | return NULL; | 880 | return NULL; |
883 | } | 881 | } |
884 | 882 | ||
883 | static int __match_ne_guid(struct device *dev, void *data) | ||
884 | { | ||
885 | struct node_entry *ne; | ||
886 | u64 *guid = (u64 *)data; | ||
887 | |||
888 | ne = container_of(dev, struct node_entry, node_dev); | ||
889 | return ne->guid == *guid; | ||
890 | } | ||
885 | 891 | ||
886 | static struct node_entry *find_entry_by_guid(u64 guid) | 892 | static struct node_entry *find_entry_by_guid(u64 guid) |
887 | { | 893 | { |
888 | struct device *dev; | 894 | struct device *dev; |
889 | struct node_entry *ne, *ret_ne = NULL; | 895 | struct node_entry *ne; |
890 | |||
891 | down(&nodemgr_ne_class.sem); | ||
892 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { | ||
893 | ne = container_of(dev, struct node_entry, node_dev); | ||
894 | 896 | ||
895 | if (ne->guid == guid) { | 897 | dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid); |
896 | ret_ne = ne; | 898 | if (!dev) |
897 | break; | 899 | return NULL; |
898 | } | 900 | ne = container_of(dev, struct node_entry, node_dev); |
899 | } | 901 | put_device(dev); |
900 | up(&nodemgr_ne_class.sem); | ||
901 | 902 | ||
902 | return ret_ne; | 903 | return ne; |
903 | } | 904 | } |
904 | 905 | ||
906 | struct match_nodeid_param { | ||
907 | struct hpsb_host *host; | ||
908 | nodeid_t nodeid; | ||
909 | }; | ||
910 | |||
911 | static int __match_ne_nodeid(struct device *dev, void *data) | ||
912 | { | ||
913 | int found = 0; | ||
914 | struct node_entry *ne; | ||
915 | struct match_nodeid_param *param = (struct match_nodeid_param *)data; | ||
916 | |||
917 | if (!dev) | ||
918 | goto ret; | ||
919 | ne = container_of(dev, struct node_entry, node_dev); | ||
920 | if (ne->host == param->host && ne->nodeid == param->nodeid) | ||
921 | found = 1; | ||
922 | ret: | ||
923 | return found; | ||
924 | } | ||
905 | 925 | ||
906 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, | 926 | static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, |
907 | nodeid_t nodeid) | 927 | nodeid_t nodeid) |
908 | { | 928 | { |
909 | struct device *dev; | 929 | struct device *dev; |
910 | struct node_entry *ne, *ret_ne = NULL; | 930 | struct node_entry *ne; |
931 | struct match_nodeid_param param; | ||
911 | 932 | ||
912 | down(&nodemgr_ne_class.sem); | 933 | param.host = host; |
913 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { | 934 | param.nodeid = nodeid; |
914 | ne = container_of(dev, struct node_entry, node_dev); | ||
915 | 935 | ||
916 | if (ne->host == host && ne->nodeid == nodeid) { | 936 | dev = class_find_device(&nodemgr_ne_class, ¶m, __match_ne_nodeid); |
917 | ret_ne = ne; | 937 | if (!dev) |
918 | break; | 938 | return NULL; |
919 | } | 939 | ne = container_of(dev, struct node_entry, node_dev); |
920 | } | 940 | put_device(dev); |
921 | up(&nodemgr_ne_class.sem); | ||
922 | 941 | ||
923 | return ret_ne; | 942 | return ne; |
924 | } | 943 | } |
925 | 944 | ||
926 | 945 | ||
@@ -1370,107 +1389,109 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) | |||
1370 | } | 1389 | } |
1371 | } | 1390 | } |
1372 | 1391 | ||
1373 | 1392 | static int __nodemgr_driver_suspend(struct device *dev, void *data) | |
1374 | static void nodemgr_suspend_ne(struct node_entry *ne) | ||
1375 | { | 1393 | { |
1376 | struct device *dev; | ||
1377 | struct unit_directory *ud; | 1394 | struct unit_directory *ud; |
1378 | struct device_driver *drv; | 1395 | struct device_driver *drv; |
1396 | struct node_entry *ne = (struct node_entry *)data; | ||
1379 | int error; | 1397 | int error; |
1380 | 1398 | ||
1381 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1399 | ud = container_of(dev, struct unit_directory, unit_dev); |
1382 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 1400 | if (ud->ne == ne) { |
1401 | drv = get_driver(ud->device.driver); | ||
1402 | if (drv) { | ||
1403 | error = 1; /* release if suspend is not implemented */ | ||
1404 | if (drv->suspend) { | ||
1405 | down(&ud->device.sem); | ||
1406 | error = drv->suspend(&ud->device, PMSG_SUSPEND); | ||
1407 | up(&ud->device.sem); | ||
1408 | } | ||
1409 | if (error) | ||
1410 | device_release_driver(&ud->device); | ||
1411 | put_driver(drv); | ||
1412 | } | ||
1413 | } | ||
1383 | 1414 | ||
1384 | ne->in_limbo = 1; | 1415 | return 0; |
1385 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); | 1416 | } |
1386 | 1417 | ||
1387 | down(&nodemgr_ud_class.sem); | 1418 | static int __nodemgr_driver_resume(struct device *dev, void *data) |
1388 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { | 1419 | { |
1389 | ud = container_of(dev, struct unit_directory, unit_dev); | 1420 | struct unit_directory *ud; |
1390 | if (ud->ne != ne) | 1421 | struct device_driver *drv; |
1391 | continue; | 1422 | struct node_entry *ne = (struct node_entry *)data; |
1392 | 1423 | ||
1424 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1425 | if (ud->ne == ne) { | ||
1393 | drv = get_driver(ud->device.driver); | 1426 | drv = get_driver(ud->device.driver); |
1394 | if (!drv) | 1427 | if (drv) { |
1395 | continue; | 1428 | if (drv->resume) { |
1396 | 1429 | down(&ud->device.sem); | |
1397 | error = 1; /* release if suspend is not implemented */ | 1430 | drv->resume(&ud->device); |
1398 | if (drv->suspend) { | 1431 | up(&ud->device.sem); |
1399 | down(&ud->device.sem); | 1432 | } |
1400 | error = drv->suspend(&ud->device, PMSG_SUSPEND); | 1433 | put_driver(drv); |
1401 | up(&ud->device.sem); | ||
1402 | } | 1434 | } |
1403 | if (error) | ||
1404 | device_release_driver(&ud->device); | ||
1405 | put_driver(drv); | ||
1406 | } | 1435 | } |
1407 | up(&nodemgr_ud_class.sem); | ||
1408 | } | ||
1409 | 1436 | ||
1437 | return 0; | ||
1438 | } | ||
1410 | 1439 | ||
1411 | static void nodemgr_resume_ne(struct node_entry *ne) | 1440 | static void nodemgr_suspend_ne(struct node_entry *ne) |
1412 | { | 1441 | { |
1413 | struct device *dev; | 1442 | HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1414 | struct unit_directory *ud; | 1443 | NODE_BUS_ARGS(ne->host, ne->nodeid), |
1415 | struct device_driver *drv; | 1444 | (unsigned long long)ne->guid); |
1416 | 1445 | ||
1417 | ne->in_limbo = 0; | 1446 | ne->in_limbo = 1; |
1418 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); | 1447 | WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); |
1419 | 1448 | ||
1420 | down(&nodemgr_ud_class.sem); | 1449 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend); |
1421 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { | 1450 | } |
1422 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1423 | if (ud->ne != ne) | ||
1424 | continue; | ||
1425 | 1451 | ||
1426 | drv = get_driver(ud->device.driver); | ||
1427 | if (!drv) | ||
1428 | continue; | ||
1429 | 1452 | ||
1430 | if (drv->resume) { | 1453 | static void nodemgr_resume_ne(struct node_entry *ne) |
1431 | down(&ud->device.sem); | 1454 | { |
1432 | drv->resume(&ud->device); | 1455 | ne->in_limbo = 0; |
1433 | up(&ud->device.sem); | 1456 | device_remove_file(&ne->device, &dev_attr_ne_in_limbo); |
1434 | } | ||
1435 | put_driver(drv); | ||
1436 | } | ||
1437 | up(&nodemgr_ud_class.sem); | ||
1438 | 1457 | ||
1458 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume); | ||
1439 | HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", | 1459 | HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", |
1440 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); | 1460 | NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); |
1441 | } | 1461 | } |
1442 | 1462 | ||
1443 | 1463 | static int __nodemgr_update_pdrv(struct device *dev, void *data) | |
1444 | static void nodemgr_update_pdrv(struct node_entry *ne) | ||
1445 | { | 1464 | { |
1446 | struct device *dev; | ||
1447 | struct unit_directory *ud; | 1465 | struct unit_directory *ud; |
1448 | struct device_driver *drv; | 1466 | struct device_driver *drv; |
1449 | struct hpsb_protocol_driver *pdrv; | 1467 | struct hpsb_protocol_driver *pdrv; |
1468 | struct node_entry *ne = (struct node_entry *)data; | ||
1450 | int error; | 1469 | int error; |
1451 | 1470 | ||
1452 | down(&nodemgr_ud_class.sem); | 1471 | ud = container_of(dev, struct unit_directory, unit_dev); |
1453 | list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { | 1472 | if (ud->ne == ne) { |
1454 | ud = container_of(dev, struct unit_directory, unit_dev); | ||
1455 | if (ud->ne != ne) | ||
1456 | continue; | ||
1457 | |||
1458 | drv = get_driver(ud->device.driver); | 1473 | drv = get_driver(ud->device.driver); |
1459 | if (!drv) | 1474 | if (drv) { |
1460 | continue; | 1475 | error = 0; |
1461 | 1476 | pdrv = container_of(drv, struct hpsb_protocol_driver, | |
1462 | error = 0; | 1477 | driver); |
1463 | pdrv = container_of(drv, struct hpsb_protocol_driver, driver); | 1478 | if (pdrv->update) { |
1464 | if (pdrv->update) { | 1479 | down(&ud->device.sem); |
1465 | down(&ud->device.sem); | 1480 | error = pdrv->update(ud); |
1466 | error = pdrv->update(ud); | 1481 | up(&ud->device.sem); |
1467 | up(&ud->device.sem); | 1482 | } |
1483 | if (error) | ||
1484 | device_release_driver(&ud->device); | ||
1485 | put_driver(drv); | ||
1468 | } | 1486 | } |
1469 | if (error) | ||
1470 | device_release_driver(&ud->device); | ||
1471 | put_driver(drv); | ||
1472 | } | 1487 | } |
1473 | up(&nodemgr_ud_class.sem); | 1488 | |
1489 | return 0; | ||
1490 | } | ||
1491 | |||
1492 | static void nodemgr_update_pdrv(struct node_entry *ne) | ||
1493 | { | ||
1494 | class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv); | ||
1474 | } | 1495 | } |
1475 | 1496 | ||
1476 | 1497 | ||
@@ -1529,13 +1550,31 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge | |||
1529 | put_device(dev); | 1550 | put_device(dev); |
1530 | } | 1551 | } |
1531 | 1552 | ||
1553 | struct probe_param { | ||
1554 | struct host_info *hi; | ||
1555 | int generation; | ||
1556 | }; | ||
1557 | |||
1558 | static int __nodemgr_node_probe(struct device *dev, void *data) | ||
1559 | { | ||
1560 | struct probe_param *param = (struct probe_param *)data; | ||
1561 | struct node_entry *ne; | ||
1562 | |||
1563 | ne = container_of(dev, struct node_entry, node_dev); | ||
1564 | if (!ne->needs_probe) | ||
1565 | nodemgr_probe_ne(param->hi, ne, param->generation); | ||
1566 | if (ne->needs_probe) | ||
1567 | nodemgr_probe_ne(param->hi, ne, param->generation); | ||
1568 | return 0; | ||
1569 | } | ||
1532 | 1570 | ||
1533 | static void nodemgr_node_probe(struct host_info *hi, int generation) | 1571 | static void nodemgr_node_probe(struct host_info *hi, int generation) |
1534 | { | 1572 | { |
1535 | struct hpsb_host *host = hi->host; | 1573 | struct hpsb_host *host = hi->host; |
1536 | struct device *dev; | 1574 | struct probe_param param; |
1537 | struct node_entry *ne; | ||
1538 | 1575 | ||
1576 | param.hi = hi; | ||
1577 | param.generation = generation; | ||
1539 | /* Do some processing of the nodes we've probed. This pulls them | 1578 | /* Do some processing of the nodes we've probed. This pulls them |
1540 | * into the sysfs layer if needed, and can result in processing of | 1579 | * into the sysfs layer if needed, and can result in processing of |
1541 | * unit-directories, or just updating the node and it's | 1580 | * unit-directories, or just updating the node and it's |
@@ -1545,19 +1584,7 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) | |||
1545 | * while probes are time-consuming. (Well, those probes need some | 1584 | * while probes are time-consuming. (Well, those probes need some |
1546 | * improvement...) */ | 1585 | * improvement...) */ |
1547 | 1586 | ||
1548 | down(&nodemgr_ne_class.sem); | 1587 | class_for_each_device(&nodemgr_ne_class, ¶m, __nodemgr_node_probe); |
1549 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { | ||
1550 | ne = container_of(dev, struct node_entry, node_dev); | ||
1551 | if (!ne->needs_probe) | ||
1552 | nodemgr_probe_ne(hi, ne, generation); | ||
1553 | } | ||
1554 | list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { | ||
1555 | ne = container_of(dev, struct node_entry, node_dev); | ||
1556 | if (ne->needs_probe) | ||
1557 | nodemgr_probe_ne(hi, ne, generation); | ||
1558 | } | ||
1559 | up(&nodemgr_ne_class.sem); | ||
1560 | |||
1561 | 1588 | ||
1562 | /* If we had a bus reset while we were scanning the bus, it is | 1589 | /* If we had a bus reset while we were scanning the bus, it is |
1563 | * possible that we did not probe all nodes. In that case, we | 1590 | * possible that we did not probe all nodes. In that case, we |
@@ -1757,6 +1784,22 @@ exit: | |||
1757 | return 0; | 1784 | return 0; |
1758 | } | 1785 | } |
1759 | 1786 | ||
1787 | struct host_iter_param { | ||
1788 | void *data; | ||
1789 | int (*cb)(struct hpsb_host *, void *); | ||
1790 | }; | ||
1791 | |||
1792 | static int __nodemgr_for_each_host(struct device *dev, void *data) | ||
1793 | { | ||
1794 | struct hpsb_host *host; | ||
1795 | struct host_iter_param *hip = (struct host_iter_param *)data; | ||
1796 | int error = 0; | ||
1797 | |||
1798 | host = container_of(dev, struct hpsb_host, host_dev); | ||
1799 | error = hip->cb(host, hip->data); | ||
1800 | |||
1801 | return error; | ||
1802 | } | ||
1760 | /** | 1803 | /** |
1761 | * nodemgr_for_each_host - call a function for each IEEE 1394 host | 1804 | * nodemgr_for_each_host - call a function for each IEEE 1394 host |
1762 | * @data: an address to supply to the callback | 1805 | * @data: an address to supply to the callback |
@@ -1771,18 +1814,13 @@ exit: | |||
1771 | */ | 1814 | */ |
1772 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) | 1815 | int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) |
1773 | { | 1816 | { |
1774 | struct device *dev; | 1817 | struct host_iter_param hip; |
1775 | struct hpsb_host *host; | 1818 | int error; |
1776 | int error = 0; | ||
1777 | |||
1778 | down(&hpsb_host_class.sem); | ||
1779 | list_for_each_entry(dev, &hpsb_host_class.devices, node) { | ||
1780 | host = container_of(dev, struct hpsb_host, host_dev); | ||
1781 | 1819 | ||
1782 | if ((error = cb(host, data))) | 1820 | hip.cb = cb; |
1783 | break; | 1821 | hip.data = data; |
1784 | } | 1822 | error = class_for_each_device(&hpsb_host_class, &hip, |
1785 | up(&hpsb_host_class.sem); | 1823 | __nodemgr_for_each_host); |
1786 | 1824 | ||
1787 | return error; | 1825 | return error; |
1788 | } | 1826 | } |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 3d4050681325..c864ef70fdf9 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -508,19 +508,10 @@ static int add_port(struct ib_device *device, int port_num) | |||
508 | 508 | ||
509 | p->ibdev = device; | 509 | p->ibdev = device; |
510 | p->port_num = port_num; | 510 | p->port_num = port_num; |
511 | p->kobj.ktype = &port_type; | ||
512 | 511 | ||
513 | p->kobj.parent = kobject_get(&device->ports_parent); | 512 | ret = kobject_init_and_add(&p->kobj, &port_type, |
514 | if (!p->kobj.parent) { | 513 | kobject_get(device->ports_parent), |
515 | ret = -EBUSY; | 514 | "%d", port_num); |
516 | goto err; | ||
517 | } | ||
518 | |||
519 | ret = kobject_set_name(&p->kobj, "%d", port_num); | ||
520 | if (ret) | ||
521 | goto err_put; | ||
522 | |||
523 | ret = kobject_register(&p->kobj); | ||
524 | if (ret) | 515 | if (ret) |
525 | goto err_put; | 516 | goto err_put; |
526 | 517 | ||
@@ -549,6 +540,7 @@ static int add_port(struct ib_device *device, int port_num) | |||
549 | 540 | ||
550 | list_add_tail(&p->kobj.entry, &device->port_list); | 541 | list_add_tail(&p->kobj.entry, &device->port_list); |
551 | 542 | ||
543 | kobject_uevent(&p->kobj, KOBJ_ADD); | ||
552 | return 0; | 544 | return 0; |
553 | 545 | ||
554 | err_free_pkey: | 546 | err_free_pkey: |
@@ -570,9 +562,7 @@ err_remove_pma: | |||
570 | sysfs_remove_group(&p->kobj, &pma_group); | 562 | sysfs_remove_group(&p->kobj, &pma_group); |
571 | 563 | ||
572 | err_put: | 564 | err_put: |
573 | kobject_put(&device->ports_parent); | 565 | kobject_put(device->ports_parent); |
574 | |||
575 | err: | ||
576 | kfree(p); | 566 | kfree(p); |
577 | return ret; | 567 | return ret; |
578 | } | 568 | } |
@@ -694,16 +684,9 @@ int ib_device_register_sysfs(struct ib_device *device) | |||
694 | goto err_unregister; | 684 | goto err_unregister; |
695 | } | 685 | } |
696 | 686 | ||
697 | device->ports_parent.parent = kobject_get(&class_dev->kobj); | 687 | device->ports_parent = kobject_create_and_add("ports", |
698 | if (!device->ports_parent.parent) { | 688 | kobject_get(&class_dev->kobj)); |
699 | ret = -EBUSY; | 689 | if (!device->ports_parent) |
700 | goto err_unregister; | ||
701 | } | ||
702 | ret = kobject_set_name(&device->ports_parent, "ports"); | ||
703 | if (ret) | ||
704 | goto err_put; | ||
705 | ret = kobject_register(&device->ports_parent); | ||
706 | if (ret) | ||
707 | goto err_put; | 690 | goto err_put; |
708 | 691 | ||
709 | if (device->node_type == RDMA_NODE_IB_SWITCH) { | 692 | if (device->node_type == RDMA_NODE_IB_SWITCH) { |
@@ -731,7 +714,7 @@ err_put: | |||
731 | sysfs_remove_group(p, &pma_group); | 714 | sysfs_remove_group(p, &pma_group); |
732 | sysfs_remove_group(p, &port->pkey_group); | 715 | sysfs_remove_group(p, &port->pkey_group); |
733 | sysfs_remove_group(p, &port->gid_group); | 716 | sysfs_remove_group(p, &port->gid_group); |
734 | kobject_unregister(p); | 717 | kobject_put(p); |
735 | } | 718 | } |
736 | } | 719 | } |
737 | 720 | ||
@@ -755,10 +738,10 @@ void ib_device_unregister_sysfs(struct ib_device *device) | |||
755 | sysfs_remove_group(p, &pma_group); | 738 | sysfs_remove_group(p, &pma_group); |
756 | sysfs_remove_group(p, &port->pkey_group); | 739 | sysfs_remove_group(p, &port->pkey_group); |
757 | sysfs_remove_group(p, &port->gid_group); | 740 | sysfs_remove_group(p, &port->gid_group); |
758 | kobject_unregister(p); | 741 | kobject_put(p); |
759 | } | 742 | } |
760 | 743 | ||
761 | kobject_unregister(&device->ports_parent); | 744 | kobject_put(device->ports_parent); |
762 | class_device_unregister(&device->class_dev); | 745 | class_device_unregister(&device->class_dev); |
763 | } | 746 | } |
764 | 747 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 6a56d86a2951..c9e32b46387f 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -590,6 +590,11 @@ static struct attribute_group ehca_drv_attr_grp = { | |||
590 | .attrs = ehca_drv_attrs | 590 | .attrs = ehca_drv_attrs |
591 | }; | 591 | }; |
592 | 592 | ||
593 | static struct attribute_group *ehca_drv_attr_groups[] = { | ||
594 | &ehca_drv_attr_grp, | ||
595 | NULL, | ||
596 | }; | ||
597 | |||
593 | #define EHCA_RESOURCE_ATTR(name) \ | 598 | #define EHCA_RESOURCE_ATTR(name) \ |
594 | static ssize_t ehca_show_##name(struct device *dev, \ | 599 | static ssize_t ehca_show_##name(struct device *dev, \ |
595 | struct device_attribute *attr, \ | 600 | struct device_attribute *attr, \ |
@@ -899,6 +904,9 @@ static struct of_platform_driver ehca_driver = { | |||
899 | .match_table = ehca_device_table, | 904 | .match_table = ehca_device_table, |
900 | .probe = ehca_probe, | 905 | .probe = ehca_probe, |
901 | .remove = ehca_remove, | 906 | .remove = ehca_remove, |
907 | .driver = { | ||
908 | .groups = ehca_drv_attr_groups, | ||
909 | }, | ||
902 | }; | 910 | }; |
903 | 911 | ||
904 | void ehca_poll_eqs(unsigned long data) | 912 | void ehca_poll_eqs(unsigned long data) |
@@ -957,10 +965,6 @@ int __init ehca_module_init(void) | |||
957 | goto module_init2; | 965 | goto module_init2; |
958 | } | 966 | } |
959 | 967 | ||
960 | ret = sysfs_create_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp); | ||
961 | if (ret) /* only complain; we can live without attributes */ | ||
962 | ehca_gen_err("Cannot create driver attributes ret=%d", ret); | ||
963 | |||
964 | if (ehca_poll_all_eqs != 1) { | 968 | if (ehca_poll_all_eqs != 1) { |
965 | ehca_gen_err("WARNING!!!"); | 969 | ehca_gen_err("WARNING!!!"); |
966 | ehca_gen_err("It is possible to lose interrupts."); | 970 | ehca_gen_err("It is possible to lose interrupts."); |
@@ -986,7 +990,6 @@ void __exit ehca_module_exit(void) | |||
986 | if (ehca_poll_all_eqs == 1) | 990 | if (ehca_poll_all_eqs == 1) |
987 | del_timer_sync(&poll_eqs_timer); | 991 | del_timer_sync(&poll_eqs_timer); |
988 | 992 | ||
989 | sysfs_remove_group(&ehca_driver.driver.kobj, &ehca_drv_attr_grp); | ||
990 | ibmebus_unregister_driver(&ehca_driver); | 993 | ibmebus_unregister_driver(&ehca_driver); |
991 | 994 | ||
992 | ehca_destroy_slab_caches(); | 995 | ehca_destroy_slab_caches(); |
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 1f152ded1e3c..fc355981bbab 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -121,6 +121,9 @@ static struct pci_driver ipath_driver = { | |||
121 | .probe = ipath_init_one, | 121 | .probe = ipath_init_one, |
122 | .remove = __devexit_p(ipath_remove_one), | 122 | .remove = __devexit_p(ipath_remove_one), |
123 | .id_table = ipath_pci_tbl, | 123 | .id_table = ipath_pci_tbl, |
124 | .driver = { | ||
125 | .groups = ipath_driver_attr_groups, | ||
126 | }, | ||
124 | }; | 127 | }; |
125 | 128 | ||
126 | static void ipath_check_status(struct work_struct *work) | 129 | static void ipath_check_status(struct work_struct *work) |
@@ -2217,25 +2220,15 @@ static int __init infinipath_init(void) | |||
2217 | goto bail_unit; | 2220 | goto bail_unit; |
2218 | } | 2221 | } |
2219 | 2222 | ||
2220 | ret = ipath_driver_create_group(&ipath_driver.driver); | ||
2221 | if (ret < 0) { | ||
2222 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create driver " | ||
2223 | "sysfs entries: error %d\n", -ret); | ||
2224 | goto bail_pci; | ||
2225 | } | ||
2226 | |||
2227 | ret = ipath_init_ipathfs(); | 2223 | ret = ipath_init_ipathfs(); |
2228 | if (ret < 0) { | 2224 | if (ret < 0) { |
2229 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create " | 2225 | printk(KERN_ERR IPATH_DRV_NAME ": Unable to create " |
2230 | "ipathfs: error %d\n", -ret); | 2226 | "ipathfs: error %d\n", -ret); |
2231 | goto bail_group; | 2227 | goto bail_pci; |
2232 | } | 2228 | } |
2233 | 2229 | ||
2234 | goto bail; | 2230 | goto bail; |
2235 | 2231 | ||
2236 | bail_group: | ||
2237 | ipath_driver_remove_group(&ipath_driver.driver); | ||
2238 | |||
2239 | bail_pci: | 2232 | bail_pci: |
2240 | pci_unregister_driver(&ipath_driver); | 2233 | pci_unregister_driver(&ipath_driver); |
2241 | 2234 | ||
@@ -2250,8 +2243,6 @@ static void __exit infinipath_cleanup(void) | |||
2250 | { | 2243 | { |
2251 | ipath_exit_ipathfs(); | 2244 | ipath_exit_ipathfs(); |
2252 | 2245 | ||
2253 | ipath_driver_remove_group(&ipath_driver.driver); | ||
2254 | |||
2255 | ipath_cdbg(VERBOSE, "Unregistering pci driver\n"); | 2246 | ipath_cdbg(VERBOSE, "Unregistering pci driver\n"); |
2256 | pci_unregister_driver(&ipath_driver); | 2247 | pci_unregister_driver(&ipath_driver); |
2257 | 2248 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 8786dd7922e4..bb1dc075f1d1 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -938,8 +938,7 @@ struct device_driver; | |||
938 | 938 | ||
939 | extern const char ib_ipath_version[]; | 939 | extern const char ib_ipath_version[]; |
940 | 940 | ||
941 | int ipath_driver_create_group(struct device_driver *); | 941 | extern struct attribute_group *ipath_driver_attr_groups[]; |
942 | void ipath_driver_remove_group(struct device_driver *); | ||
943 | 942 | ||
944 | int ipath_device_create_group(struct device *, struct ipath_devdata *); | 943 | int ipath_device_create_group(struct device *, struct ipath_devdata *); |
945 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); | 944 | void ipath_device_remove_group(struct device *, struct ipath_devdata *); |
diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index e1ad7cfc21fd..aa27ca9f03b1 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c | |||
@@ -683,6 +683,11 @@ static struct attribute_group driver_attr_group = { | |||
683 | .attrs = driver_attributes | 683 | .attrs = driver_attributes |
684 | }; | 684 | }; |
685 | 685 | ||
686 | struct attribute_group *ipath_driver_attr_groups[] = { | ||
687 | &driver_attr_group, | ||
688 | NULL, | ||
689 | }; | ||
690 | |||
686 | static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid); | 691 | static DEVICE_ATTR(guid, S_IWUSR | S_IRUGO, show_guid, store_guid); |
687 | static DEVICE_ATTR(lmc, S_IWUSR | S_IRUGO, show_lmc, store_lmc); | 692 | static DEVICE_ATTR(lmc, S_IWUSR | S_IRUGO, show_lmc, store_lmc); |
688 | static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid); | 693 | static DEVICE_ATTR(lid, S_IWUSR | S_IRUGO, show_lid, store_lid); |
@@ -753,24 +758,9 @@ int ipath_expose_reset(struct device *dev) | |||
753 | return ret; | 758 | return ret; |
754 | } | 759 | } |
755 | 760 | ||
756 | int ipath_driver_create_group(struct device_driver *drv) | ||
757 | { | ||
758 | int ret; | ||
759 | |||
760 | ret = sysfs_create_group(&drv->kobj, &driver_attr_group); | ||
761 | |||
762 | return ret; | ||
763 | } | ||
764 | |||
765 | void ipath_driver_remove_group(struct device_driver *drv) | ||
766 | { | ||
767 | sysfs_remove_group(&drv->kobj, &driver_attr_group); | ||
768 | } | ||
769 | |||
770 | int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd) | 761 | int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd) |
771 | { | 762 | { |
772 | int ret; | 763 | int ret; |
773 | char unit[5]; | ||
774 | 764 | ||
775 | ret = sysfs_create_group(&dev->kobj, &dev_attr_group); | 765 | ret = sysfs_create_group(&dev->kobj, &dev_attr_group); |
776 | if (ret) | 766 | if (ret) |
@@ -780,11 +770,6 @@ int ipath_device_create_group(struct device *dev, struct ipath_devdata *dd) | |||
780 | if (ret) | 770 | if (ret) |
781 | goto bail_attrs; | 771 | goto bail_attrs; |
782 | 772 | ||
783 | snprintf(unit, sizeof(unit), "%02d", dd->ipath_unit); | ||
784 | ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, unit); | ||
785 | if (ret == 0) | ||
786 | goto bail; | ||
787 | |||
788 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | 773 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); |
789 | bail_attrs: | 774 | bail_attrs: |
790 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | 775 | sysfs_remove_group(&dev->kobj, &dev_attr_group); |
@@ -794,11 +779,6 @@ bail: | |||
794 | 779 | ||
795 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) | 780 | void ipath_device_remove_group(struct device *dev, struct ipath_devdata *dd) |
796 | { | 781 | { |
797 | char unit[5]; | ||
798 | |||
799 | snprintf(unit, sizeof(unit), "%02d", dd->ipath_unit); | ||
800 | sysfs_remove_link(&dev->driver->kobj, unit); | ||
801 | |||
802 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); | 782 | sysfs_remove_group(&dev->kobj, &dev_counter_attr_group); |
803 | sysfs_remove_group(&dev->kobj, &dev_attr_group); | 783 | sysfs_remove_group(&dev->kobj, &dev_attr_group); |
804 | 784 | ||
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index f449daef3eed..23ae66c76d47 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -1544,11 +1544,11 @@ static int __init capi_init(void) | |||
1544 | return PTR_ERR(capi_class); | 1544 | return PTR_ERR(capi_class); |
1545 | } | 1545 | } |
1546 | 1546 | ||
1547 | class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); | 1547 | device_create(capi_class, NULL, MKDEV(capi_major, 0), "capi"); |
1548 | 1548 | ||
1549 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 1549 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
1550 | if (capinc_tty_init() < 0) { | 1550 | if (capinc_tty_init() < 0) { |
1551 | class_device_destroy(capi_class, MKDEV(capi_major, 0)); | 1551 | device_destroy(capi_class, MKDEV(capi_major, 0)); |
1552 | class_destroy(capi_class); | 1552 | class_destroy(capi_class); |
1553 | unregister_chrdev(capi_major, "capi20"); | 1553 | unregister_chrdev(capi_major, "capi20"); |
1554 | return -ENOMEM; | 1554 | return -ENOMEM; |
@@ -1576,7 +1576,7 @@ static void __exit capi_exit(void) | |||
1576 | { | 1576 | { |
1577 | proc_exit(); | 1577 | proc_exit(); |
1578 | 1578 | ||
1579 | class_device_destroy(capi_class, MKDEV(capi_major, 0)); | 1579 | device_destroy(capi_class, MKDEV(capi_major, 0)); |
1580 | class_destroy(capi_class); | 1580 | class_destroy(capi_class); |
1581 | unregister_chrdev(capi_major, "capi20"); | 1581 | unregister_chrdev(capi_major, "capi20"); |
1582 | 1582 | ||
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index a0317abaeb11..02bdaf22d7ea 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -106,12 +106,6 @@ enum debuglevel { | |||
106 | activated */ | 106 | activated */ |
107 | }; | 107 | }; |
108 | 108 | ||
109 | /* missing from linux/device.h ... */ | ||
110 | #ifndef dev_notice | ||
111 | #define dev_notice(dev, format, arg...) \ | ||
112 | dev_printk(KERN_NOTICE , dev , format , ## arg) | ||
113 | #endif | ||
114 | |||
115 | /* Kernel message macros for situations where dev_printk and friends cannot be | 109 | /* Kernel message macros for situations where dev_printk and friends cannot be |
116 | * used for lack of reliable access to a device structure. | 110 | * used for lack of reliable access to a device structure. |
117 | * linux/usb.h already contains these but in an obsolete form which clutters | 111 | * linux/usb.h already contains these but in an obsolete form which clutters |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 47c10b8f89b3..c0f372f1d761 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -3451,7 +3451,7 @@ static int kvm_resume(struct sys_device *dev) | |||
3451 | } | 3451 | } |
3452 | 3452 | ||
3453 | static struct sysdev_class kvm_sysdev_class = { | 3453 | static struct sysdev_class kvm_sysdev_class = { |
3454 | set_kset_name("kvm"), | 3454 | .name = "kvm", |
3455 | .suspend = kvm_suspend, | 3455 | .suspend = kvm_suspend, |
3456 | .resume = kvm_resume, | 3456 | .resume = kvm_resume, |
3457 | }; | 3457 | }; |
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 5c742a526082..b7adde4324e4 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c | |||
@@ -875,5 +875,5 @@ adbdev_init(void) | |||
875 | adb_dev_class = class_create(THIS_MODULE, "adb"); | 875 | adb_dev_class = class_create(THIS_MODULE, "adb"); |
876 | if (IS_ERR(adb_dev_class)) | 876 | if (IS_ERR(adb_dev_class)) |
877 | return; | 877 | return; |
878 | class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb"); | 878 | device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb"); |
879 | } | 879 | } |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 6123c70153d3..ac420b17e16f 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -2796,7 +2796,7 @@ static int pmu_sys_resume(struct sys_device *sysdev) | |||
2796 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ | 2796 | #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ |
2797 | 2797 | ||
2798 | static struct sysdev_class pmu_sysclass = { | 2798 | static struct sysdev_class pmu_sysclass = { |
2799 | set_kset_name("pmu"), | 2799 | .name = "pmu", |
2800 | }; | 2800 | }; |
2801 | 2801 | ||
2802 | static struct sys_device device_pmu = { | 2802 | static struct sys_device device_pmu = { |
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 88c0fd657825..f2d24eb3208c 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1109,7 +1109,7 @@ static void event_callback(void *context) | |||
1109 | list_splice_init(&md->uevent_list, &uevents); | 1109 | list_splice_init(&md->uevent_list, &uevents); |
1110 | spin_unlock_irqrestore(&md->uevent_lock, flags); | 1110 | spin_unlock_irqrestore(&md->uevent_lock, flags); |
1111 | 1111 | ||
1112 | dm_send_uevents(&uevents, &md->disk->kobj); | 1112 | dm_send_uevents(&uevents, &md->disk->dev.kobj); |
1113 | 1113 | ||
1114 | atomic_inc(&md->event_nr); | 1114 | atomic_inc(&md->event_nr); |
1115 | wake_up(&md->eventq); | 1115 | wake_up(&md->eventq); |
@@ -1530,7 +1530,7 @@ out: | |||
1530 | *---------------------------------------------------------------*/ | 1530 | *---------------------------------------------------------------*/ |
1531 | void dm_kobject_uevent(struct mapped_device *md) | 1531 | void dm_kobject_uevent(struct mapped_device *md) |
1532 | { | 1532 | { |
1533 | kobject_uevent(&md->disk->kobj, KOBJ_CHANGE); | 1533 | kobject_uevent(&md->disk->dev.kobj, KOBJ_CHANGE); |
1534 | } | 1534 | } |
1535 | 1535 | ||
1536 | uint32_t dm_next_uevent_seq(struct mapped_device *md) | 1536 | uint32_t dm_next_uevent_seq(struct mapped_device *md) |
diff --git a/drivers/md/md.c b/drivers/md/md.c index cef9ebd5a046..c28a120b4161 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -231,7 +231,7 @@ static void mddev_put(mddev_t *mddev) | |||
231 | list_del(&mddev->all_mddevs); | 231 | list_del(&mddev->all_mddevs); |
232 | spin_unlock(&all_mddevs_lock); | 232 | spin_unlock(&all_mddevs_lock); |
233 | blk_cleanup_queue(mddev->queue); | 233 | blk_cleanup_queue(mddev->queue); |
234 | kobject_unregister(&mddev->kobj); | 234 | kobject_put(&mddev->kobj); |
235 | } else | 235 | } else |
236 | spin_unlock(&all_mddevs_lock); | 236 | spin_unlock(&all_mddevs_lock); |
237 | } | 237 | } |
@@ -1383,22 +1383,19 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1383 | return -EBUSY; | 1383 | return -EBUSY; |
1384 | } | 1384 | } |
1385 | bdevname(rdev->bdev,b); | 1385 | bdevname(rdev->bdev,b); |
1386 | if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0) | 1386 | while ( (s=strchr(b, '/')) != NULL) |
1387 | return -ENOMEM; | ||
1388 | while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL) | ||
1389 | *s = '!'; | 1387 | *s = '!'; |
1390 | 1388 | ||
1391 | rdev->mddev = mddev; | 1389 | rdev->mddev = mddev; |
1392 | printk(KERN_INFO "md: bind<%s>\n", b); | 1390 | printk(KERN_INFO "md: bind<%s>\n", b); |
1393 | 1391 | ||
1394 | rdev->kobj.parent = &mddev->kobj; | 1392 | if ((err = kobject_add(&rdev->kobj, &mddev->kobj, "dev-%s", b))) |
1395 | if ((err = kobject_add(&rdev->kobj))) | ||
1396 | goto fail; | 1393 | goto fail; |
1397 | 1394 | ||
1398 | if (rdev->bdev->bd_part) | 1395 | if (rdev->bdev->bd_part) |
1399 | ko = &rdev->bdev->bd_part->kobj; | 1396 | ko = &rdev->bdev->bd_part->dev.kobj; |
1400 | else | 1397 | else |
1401 | ko = &rdev->bdev->bd_disk->kobj; | 1398 | ko = &rdev->bdev->bd_disk->dev.kobj; |
1402 | if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) { | 1399 | if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) { |
1403 | kobject_del(&rdev->kobj); | 1400 | kobject_del(&rdev->kobj); |
1404 | goto fail; | 1401 | goto fail; |
@@ -2036,9 +2033,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi | |||
2036 | if (err) | 2033 | if (err) |
2037 | goto abort_free; | 2034 | goto abort_free; |
2038 | 2035 | ||
2039 | rdev->kobj.parent = NULL; | 2036 | kobject_init(&rdev->kobj, &rdev_ktype); |
2040 | rdev->kobj.ktype = &rdev_ktype; | ||
2041 | kobject_init(&rdev->kobj); | ||
2042 | 2037 | ||
2043 | rdev->desc_nr = -1; | 2038 | rdev->desc_nr = -1; |
2044 | rdev->saved_raid_disk = -1; | 2039 | rdev->saved_raid_disk = -1; |
@@ -3054,6 +3049,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
3054 | int partitioned = (MAJOR(dev) != MD_MAJOR); | 3049 | int partitioned = (MAJOR(dev) != MD_MAJOR); |
3055 | int shift = partitioned ? MdpMinorShift : 0; | 3050 | int shift = partitioned ? MdpMinorShift : 0; |
3056 | int unit = MINOR(dev) >> shift; | 3051 | int unit = MINOR(dev) >> shift; |
3052 | int error; | ||
3057 | 3053 | ||
3058 | if (!mddev) | 3054 | if (!mddev) |
3059 | return NULL; | 3055 | return NULL; |
@@ -3082,12 +3078,13 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) | |||
3082 | add_disk(disk); | 3078 | add_disk(disk); |
3083 | mddev->gendisk = disk; | 3079 | mddev->gendisk = disk; |
3084 | mutex_unlock(&disks_mutex); | 3080 | mutex_unlock(&disks_mutex); |
3085 | mddev->kobj.parent = &disk->kobj; | 3081 | error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj, |
3086 | kobject_set_name(&mddev->kobj, "%s", "md"); | 3082 | "%s", "md"); |
3087 | mddev->kobj.ktype = &md_ktype; | 3083 | if (error) |
3088 | if (kobject_register(&mddev->kobj)) | ||
3089 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", | 3084 | printk(KERN_WARNING "md: cannot register %s/md - name in use\n", |
3090 | disk->disk_name); | 3085 | disk->disk_name); |
3086 | else | ||
3087 | kobject_uevent(&mddev->kobj, KOBJ_ADD); | ||
3091 | return NULL; | 3088 | return NULL; |
3092 | } | 3089 | } |
3093 | 3090 | ||
@@ -3359,7 +3356,7 @@ static int do_md_run(mddev_t * mddev) | |||
3359 | 3356 | ||
3360 | mddev->changed = 1; | 3357 | mddev->changed = 1; |
3361 | md_new_event(mddev); | 3358 | md_new_event(mddev); |
3362 | kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE); | 3359 | kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE); |
3363 | return 0; | 3360 | return 0; |
3364 | } | 3361 | } |
3365 | 3362 | ||
diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c index e325fa71f38b..b7c8e7813865 100644 --- a/drivers/mfd/ucb1x00-assabet.c +++ b/drivers/mfd/ucb1x00-assabet.c | |||
@@ -20,7 +20,8 @@ | |||
20 | #include "ucb1x00.h" | 20 | #include "ucb1x00.h" |
21 | 21 | ||
22 | #define UCB1X00_ATTR(name,input)\ | 22 | #define UCB1X00_ATTR(name,input)\ |
23 | static ssize_t name##_show(struct class_device *dev, char *buf) \ | 23 | static ssize_t name##_show(struct device *dev, struct device_attribute *attr, |
24 | char *buf) \ | ||
24 | { \ | 25 | { \ |
25 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ | 26 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ |
26 | int val; \ | 27 | int val; \ |
@@ -29,7 +30,7 @@ static ssize_t name##_show(struct class_device *dev, char *buf) \ | |||
29 | ucb1x00_adc_disable(ucb); \ | 30 | ucb1x00_adc_disable(ucb); \ |
30 | return sprintf(buf, "%d\n", val); \ | 31 | return sprintf(buf, "%d\n", val); \ |
31 | } \ | 32 | } \ |
32 | static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL) | 33 | static DEVICE_ATTR(name,0444,name##_show,NULL) |
33 | 34 | ||
34 | UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); | 35 | UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); |
35 | UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); | 36 | UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); |
@@ -37,17 +38,17 @@ UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); | |||
37 | 38 | ||
38 | static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) | 39 | static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) |
39 | { | 40 | { |
40 | class_device_create_file(&dev->ucb->cdev, &class_device_attr_vbatt); | 41 | device_create_file(&dev->ucb->dev, &device_attr_vbatt); |
41 | class_device_create_file(&dev->ucb->cdev, &class_device_attr_vcharger); | 42 | device_create_file(&dev->ucb->dev, &device_attr_vcharger); |
42 | class_device_create_file(&dev->ucb->cdev, &class_device_attr_batt_temp); | 43 | device_create_file(&dev->ucb->dev, &device_attr_batt_temp); |
43 | return 0; | 44 | return 0; |
44 | } | 45 | } |
45 | 46 | ||
46 | static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) | 47 | static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) |
47 | { | 48 | { |
48 | class_device_remove_file(&dev->ucb->cdev, &class_device_attr_batt_temp); | 49 | device_remove_file(&dev->ucb->cdev, &device_attr_batt_temp); |
49 | class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vcharger); | 50 | device_remove_file(&dev->ucb->cdev, &device_attr_vcharger); |
50 | class_device_remove_file(&dev->ucb->cdev, &class_device_attr_vbatt); | 51 | device_remove_file(&dev->ucb->cdev, &device_attr_vbatt); |
51 | } | 52 | } |
52 | 53 | ||
53 | static struct ucb1x00_driver ucb1x00_assabet_driver = { | 54 | static struct ucb1x00_driver ucb1x00_assabet_driver = { |
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index e03f1bcd4f9f..f6b10dda31fd 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
@@ -458,7 +458,7 @@ static int ucb1x00_detect_irq(struct ucb1x00 *ucb) | |||
458 | return probe_irq_off(mask); | 458 | return probe_irq_off(mask); |
459 | } | 459 | } |
460 | 460 | ||
461 | static void ucb1x00_release(struct class_device *dev) | 461 | static void ucb1x00_release(struct device *dev) |
462 | { | 462 | { |
463 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); | 463 | struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); |
464 | kfree(ucb); | 464 | kfree(ucb); |
@@ -466,7 +466,7 @@ static void ucb1x00_release(struct class_device *dev) | |||
466 | 466 | ||
467 | static struct class ucb1x00_class = { | 467 | static struct class ucb1x00_class = { |
468 | .name = "ucb1x00", | 468 | .name = "ucb1x00", |
469 | .release = ucb1x00_release, | 469 | .dev_release = ucb1x00_release, |
470 | }; | 470 | }; |
471 | 471 | ||
472 | static int ucb1x00_probe(struct mcp *mcp) | 472 | static int ucb1x00_probe(struct mcp *mcp) |
@@ -490,9 +490,9 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
490 | goto err_disable; | 490 | goto err_disable; |
491 | 491 | ||
492 | 492 | ||
493 | ucb->cdev.class = &ucb1x00_class; | 493 | ucb->dev.class = &ucb1x00_class; |
494 | ucb->cdev.dev = &mcp->attached_device; | 494 | ucb->dev.parent = &mcp->attached_device; |
495 | strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id)); | 495 | strlcpy(ucb->dev.bus_id, "ucb1x00", sizeof(ucb->dev.bus_id)); |
496 | 496 | ||
497 | spin_lock_init(&ucb->lock); | 497 | spin_lock_init(&ucb->lock); |
498 | spin_lock_init(&ucb->io_lock); | 498 | spin_lock_init(&ucb->io_lock); |
@@ -517,7 +517,7 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
517 | 517 | ||
518 | mcp_set_drvdata(mcp, ucb); | 518 | mcp_set_drvdata(mcp, ucb); |
519 | 519 | ||
520 | ret = class_device_register(&ucb->cdev); | 520 | ret = device_register(&ucb->dev); |
521 | if (ret) | 521 | if (ret) |
522 | goto err_irq; | 522 | goto err_irq; |
523 | 523 | ||
@@ -554,7 +554,7 @@ static void ucb1x00_remove(struct mcp *mcp) | |||
554 | mutex_unlock(&ucb1x00_mutex); | 554 | mutex_unlock(&ucb1x00_mutex); |
555 | 555 | ||
556 | free_irq(ucb->irq, ucb); | 556 | free_irq(ucb->irq, ucb); |
557 | class_device_unregister(&ucb->cdev); | 557 | device_unregister(&ucb->dev); |
558 | } | 558 | } |
559 | 559 | ||
560 | int ucb1x00_register_driver(struct ucb1x00_driver *drv) | 560 | int ucb1x00_register_driver(struct ucb1x00_driver *drv) |
diff --git a/drivers/mfd/ucb1x00.h b/drivers/mfd/ucb1x00.h index ca8df8072d43..a8ad8a0ed5db 100644 --- a/drivers/mfd/ucb1x00.h +++ b/drivers/mfd/ucb1x00.h | |||
@@ -120,7 +120,7 @@ struct ucb1x00 { | |||
120 | u16 irq_fal_enbl; | 120 | u16 irq_fal_enbl; |
121 | u16 irq_ris_enbl; | 121 | u16 irq_ris_enbl; |
122 | struct ucb1x00_irq irq_handler[16]; | 122 | struct ucb1x00_irq irq_handler[16]; |
123 | struct class_device cdev; | 123 | struct device dev; |
124 | struct list_head node; | 124 | struct list_head node; |
125 | struct list_head devs; | 125 | struct list_head devs; |
126 | }; | 126 | }; |
@@ -144,7 +144,7 @@ struct ucb1x00_driver { | |||
144 | int (*resume)(struct ucb1x00_dev *dev); | 144 | int (*resume)(struct ucb1x00_dev *dev); |
145 | }; | 145 | }; |
146 | 146 | ||
147 | #define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev) | 147 | #define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, dev) |
148 | 148 | ||
149 | int ucb1x00_register_driver(struct ucb1x00_driver *); | 149 | int ucb1x00_register_driver(struct ucb1x00_driver *); |
150 | void ucb1x00_unregister_driver(struct ucb1x00_driver *); | 150 | void ucb1x00_unregister_driver(struct ucb1x00_driver *); |
diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c index 6497872df524..1a0e7978226a 100644 --- a/drivers/misc/ibmasm/command.c +++ b/drivers/misc/ibmasm/command.c | |||
@@ -26,11 +26,6 @@ | |||
26 | #include "lowlevel.h" | 26 | #include "lowlevel.h" |
27 | 27 | ||
28 | static void exec_next_command(struct service_processor *sp); | 28 | static void exec_next_command(struct service_processor *sp); |
29 | static void free_command(struct kobject *kobj); | ||
30 | |||
31 | static struct kobj_type ibmasm_cmd_kobj_type = { | ||
32 | .release = free_command, | ||
33 | }; | ||
34 | 29 | ||
35 | static atomic_t command_count = ATOMIC_INIT(0); | 30 | static atomic_t command_count = ATOMIC_INIT(0); |
36 | 31 | ||
@@ -53,8 +48,7 @@ struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_s | |||
53 | } | 48 | } |
54 | cmd->buffer_size = buffer_size; | 49 | cmd->buffer_size = buffer_size; |
55 | 50 | ||
56 | kobject_init(&cmd->kobj); | 51 | kref_init(&cmd->kref); |
57 | cmd->kobj.ktype = &ibmasm_cmd_kobj_type; | ||
58 | cmd->lock = &sp->lock; | 52 | cmd->lock = &sp->lock; |
59 | 53 | ||
60 | cmd->status = IBMASM_CMD_PENDING; | 54 | cmd->status = IBMASM_CMD_PENDING; |
@@ -67,9 +61,9 @@ struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_s | |||
67 | return cmd; | 61 | return cmd; |
68 | } | 62 | } |
69 | 63 | ||
70 | static void free_command(struct kobject *kobj) | 64 | void ibmasm_free_command(struct kref *kref) |
71 | { | 65 | { |
72 | struct command *cmd = to_command(kobj); | 66 | struct command *cmd = to_command(kref); |
73 | 67 | ||
74 | list_del(&cmd->queue_node); | 68 | list_del(&cmd->queue_node); |
75 | atomic_dec(&command_count); | 69 | atomic_dec(&command_count); |
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h index de860bc6d3f5..4d8a4e248b34 100644 --- a/drivers/misc/ibmasm/ibmasm.h +++ b/drivers/misc/ibmasm/ibmasm.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/kref.h> | ||
34 | #include <linux/device.h> | 35 | #include <linux/device.h> |
35 | #include <linux/input.h> | 36 | #include <linux/input.h> |
36 | 37 | ||
@@ -92,24 +93,25 @@ struct command { | |||
92 | unsigned char *buffer; | 93 | unsigned char *buffer; |
93 | size_t buffer_size; | 94 | size_t buffer_size; |
94 | int status; | 95 | int status; |
95 | struct kobject kobj; | 96 | struct kref kref; |
96 | spinlock_t *lock; | 97 | spinlock_t *lock; |
97 | }; | 98 | }; |
98 | #define to_command(c) container_of(c, struct command, kobj) | 99 | #define to_command(c) container_of(c, struct command, kref) |
99 | 100 | ||
101 | void ibmasm_free_command(struct kref *kref); | ||
100 | static inline void command_put(struct command *cmd) | 102 | static inline void command_put(struct command *cmd) |
101 | { | 103 | { |
102 | unsigned long flags; | 104 | unsigned long flags; |
103 | spinlock_t *lock = cmd->lock; | 105 | spinlock_t *lock = cmd->lock; |
104 | 106 | ||
105 | spin_lock_irqsave(lock, flags); | 107 | spin_lock_irqsave(lock, flags); |
106 | kobject_put(&cmd->kobj); | 108 | kref_put(&cmd->kref, ibmasm_free_command); |
107 | spin_unlock_irqrestore(lock, flags); | 109 | spin_unlock_irqrestore(lock, flags); |
108 | } | 110 | } |
109 | 111 | ||
110 | static inline void command_get(struct command *cmd) | 112 | static inline void command_get(struct command *cmd) |
111 | { | 113 | { |
112 | kobject_get(&cmd->kobj); | 114 | kref_get(&cmd->kref); |
113 | } | 115 | } |
114 | 116 | ||
115 | 117 | ||
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 2d1b3df95c5b..54380da343a5 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -149,7 +149,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work) | |||
149 | socket_change_set = fm->socket_change_set; | 149 | socket_change_set = fm->socket_change_set; |
150 | fm->socket_change_set = 0; | 150 | fm->socket_change_set = 0; |
151 | 151 | ||
152 | dev_dbg(fm->cdev.dev, "checking media set %x\n", | 152 | dev_dbg(fm->dev.parent, "checking media set %x\n", |
153 | socket_change_set); | 153 | socket_change_set); |
154 | 154 | ||
155 | if (!socket_change_set) { | 155 | if (!socket_change_set) { |
@@ -164,7 +164,7 @@ static void tifm_7xx1_switch_media(struct work_struct *work) | |||
164 | if (sock) { | 164 | if (sock) { |
165 | printk(KERN_INFO | 165 | printk(KERN_INFO |
166 | "%s : demand removing card from socket %u:%u\n", | 166 | "%s : demand removing card from socket %u:%u\n", |
167 | fm->cdev.class_id, fm->id, cnt); | 167 | fm->dev.bus_id, fm->id, cnt); |
168 | fm->sockets[cnt] = NULL; | 168 | fm->sockets[cnt] = NULL; |
169 | sock_addr = sock->addr; | 169 | sock_addr = sock->addr; |
170 | spin_unlock_irqrestore(&fm->lock, flags); | 170 | spin_unlock_irqrestore(&fm->lock, flags); |
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 8f77949f93dd..97544052e768 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c | |||
@@ -160,16 +160,16 @@ static struct bus_type tifm_bus_type = { | |||
160 | .resume = tifm_device_resume | 160 | .resume = tifm_device_resume |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static void tifm_free(struct class_device *cdev) | 163 | static void tifm_free(struct device *dev) |
164 | { | 164 | { |
165 | struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev); | 165 | struct tifm_adapter *fm = container_of(dev, struct tifm_adapter, dev); |
166 | 166 | ||
167 | kfree(fm); | 167 | kfree(fm); |
168 | } | 168 | } |
169 | 169 | ||
170 | static struct class tifm_adapter_class = { | 170 | static struct class tifm_adapter_class = { |
171 | .name = "tifm_adapter", | 171 | .name = "tifm_adapter", |
172 | .release = tifm_free | 172 | .dev_release = tifm_free |
173 | }; | 173 | }; |
174 | 174 | ||
175 | struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, | 175 | struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, |
@@ -180,9 +180,9 @@ struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, | |||
180 | fm = kzalloc(sizeof(struct tifm_adapter) | 180 | fm = kzalloc(sizeof(struct tifm_adapter) |
181 | + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL); | 181 | + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL); |
182 | if (fm) { | 182 | if (fm) { |
183 | fm->cdev.class = &tifm_adapter_class; | 183 | fm->dev.class = &tifm_adapter_class; |
184 | fm->cdev.dev = dev; | 184 | fm->dev.parent = dev; |
185 | class_device_initialize(&fm->cdev); | 185 | device_initialize(&fm->dev); |
186 | spin_lock_init(&fm->lock); | 186 | spin_lock_init(&fm->lock); |
187 | fm->num_sockets = num_sockets; | 187 | fm->num_sockets = num_sockets; |
188 | } | 188 | } |
@@ -203,8 +203,8 @@ int tifm_add_adapter(struct tifm_adapter *fm) | |||
203 | if (rc) | 203 | if (rc) |
204 | return rc; | 204 | return rc; |
205 | 205 | ||
206 | snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); | 206 | snprintf(fm->dev.bus_id, BUS_ID_SIZE, "tifm%u", fm->id); |
207 | rc = class_device_add(&fm->cdev); | 207 | rc = device_add(&fm->dev); |
208 | if (rc) { | 208 | if (rc) { |
209 | spin_lock(&tifm_adapter_lock); | 209 | spin_lock(&tifm_adapter_lock); |
210 | idr_remove(&tifm_adapter_idr, fm->id); | 210 | idr_remove(&tifm_adapter_idr, fm->id); |
@@ -228,13 +228,13 @@ void tifm_remove_adapter(struct tifm_adapter *fm) | |||
228 | spin_lock(&tifm_adapter_lock); | 228 | spin_lock(&tifm_adapter_lock); |
229 | idr_remove(&tifm_adapter_idr, fm->id); | 229 | idr_remove(&tifm_adapter_idr, fm->id); |
230 | spin_unlock(&tifm_adapter_lock); | 230 | spin_unlock(&tifm_adapter_lock); |
231 | class_device_del(&fm->cdev); | 231 | device_del(&fm->dev); |
232 | } | 232 | } |
233 | EXPORT_SYMBOL(tifm_remove_adapter); | 233 | EXPORT_SYMBOL(tifm_remove_adapter); |
234 | 234 | ||
235 | void tifm_free_adapter(struct tifm_adapter *fm) | 235 | void tifm_free_adapter(struct tifm_adapter *fm) |
236 | { | 236 | { |
237 | class_device_put(&fm->cdev); | 237 | put_device(&fm->dev); |
238 | } | 238 | } |
239 | EXPORT_SYMBOL(tifm_free_adapter); | 239 | EXPORT_SYMBOL(tifm_free_adapter); |
240 | 240 | ||
@@ -261,9 +261,9 @@ struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, | |||
261 | sock->card_event = tifm_dummy_event; | 261 | sock->card_event = tifm_dummy_event; |
262 | sock->data_event = tifm_dummy_event; | 262 | sock->data_event = tifm_dummy_event; |
263 | 263 | ||
264 | sock->dev.parent = fm->cdev.dev; | 264 | sock->dev.parent = fm->dev.parent; |
265 | sock->dev.bus = &tifm_bus_type; | 265 | sock->dev.bus = &tifm_bus_type; |
266 | sock->dev.dma_mask = fm->cdev.dev->dma_mask; | 266 | sock->dev.dma_mask = fm->dev.parent->dma_mask; |
267 | sock->dev.release = tifm_free_device; | 267 | sock->dev.release = tifm_free_device; |
268 | 268 | ||
269 | snprintf(sock->dev.bus_id, BUS_ID_SIZE, | 269 | snprintf(sock->dev.bus_id, BUS_ID_SIZE, |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 22ed96c4b7bd..a0cee86464ca 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -27,12 +27,10 @@ static void mtd_notify_add(struct mtd_info* mtd) | |||
27 | if (!mtd) | 27 | if (!mtd) |
28 | return; | 28 | return; |
29 | 29 | ||
30 | class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), | 30 | device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), "mtd%d", mtd->index); |
31 | NULL, "mtd%d", mtd->index); | ||
32 | 31 | ||
33 | class_device_create(mtd_class, NULL, | 32 | device_create(mtd_class, NULL, |
34 | MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), | 33 | MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), "mtd%dro", mtd->index); |
35 | NULL, "mtd%dro", mtd->index); | ||
36 | } | 34 | } |
37 | 35 | ||
38 | static void mtd_notify_remove(struct mtd_info* mtd) | 36 | static void mtd_notify_remove(struct mtd_info* mtd) |
@@ -40,8 +38,8 @@ static void mtd_notify_remove(struct mtd_info* mtd) | |||
40 | if (!mtd) | 38 | if (!mtd) |
41 | return; | 39 | return; |
42 | 40 | ||
43 | class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2)); | 41 | device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2)); |
44 | class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1)); | 42 | device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1)); |
45 | } | 43 | } |
46 | 44 | ||
47 | static struct mtd_notifier notifier = { | 45 | static struct mtd_notifier notifier = { |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 7d7758f3ad8c..57772bebff56 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -1179,13 +1179,15 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ | |||
1179 | 1179 | ||
1180 | for(i = 0; i<IbmVethNumBufferPools; i++) { | 1180 | for(i = 0; i<IbmVethNumBufferPools; i++) { |
1181 | struct kobject *kobj = &adapter->rx_buff_pool[i].kobj; | 1181 | struct kobject *kobj = &adapter->rx_buff_pool[i].kobj; |
1182 | int error; | ||
1183 | |||
1182 | ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i, | 1184 | ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i, |
1183 | pool_count[i], pool_size[i], | 1185 | pool_count[i], pool_size[i], |
1184 | pool_active[i]); | 1186 | pool_active[i]); |
1185 | kobj->parent = &dev->dev.kobj; | 1187 | error = kobject_init_and_add(kobj, &ktype_veth_pool, |
1186 | kobject_set_name(kobj, "pool%d", i); | 1188 | &dev->dev.kobj, "pool%d", i); |
1187 | kobj->ktype = &ktype_veth_pool; | 1189 | if (!error) |
1188 | kobject_register(kobj); | 1190 | kobject_uevent(kobj, KOBJ_ADD); |
1189 | } | 1191 | } |
1190 | 1192 | ||
1191 | ibmveth_debug_printk("adapter @ 0x%p\n", adapter); | 1193 | ibmveth_debug_printk("adapter @ 0x%p\n", adapter); |
@@ -1234,7 +1236,7 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) | |||
1234 | int i; | 1236 | int i; |
1235 | 1237 | ||
1236 | for(i = 0; i<IbmVethNumBufferPools; i++) | 1238 | for(i = 0; i<IbmVethNumBufferPools; i++) |
1237 | kobject_unregister(&adapter->rx_buff_pool[i].kobj); | 1239 | kobject_put(&adapter->rx_buff_pool[i].kobj); |
1238 | 1240 | ||
1239 | unregister_netdev(netdev); | 1241 | unregister_netdev(netdev); |
1240 | 1242 | ||
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 97bd9dc2e52e..419861cbc65e 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -815,7 +815,7 @@ static int veth_init_connection(u8 rlp) | |||
815 | { | 815 | { |
816 | struct veth_lpar_connection *cnx; | 816 | struct veth_lpar_connection *cnx; |
817 | struct veth_msg *msgs; | 817 | struct veth_msg *msgs; |
818 | int i, rc; | 818 | int i; |
819 | 819 | ||
820 | if ( (rlp == this_lp) | 820 | if ( (rlp == this_lp) |
821 | || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) ) | 821 | || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) ) |
@@ -844,11 +844,7 @@ static int veth_init_connection(u8 rlp) | |||
844 | 844 | ||
845 | /* This gets us 1 reference, which is held on behalf of the driver | 845 | /* This gets us 1 reference, which is held on behalf of the driver |
846 | * infrastructure. It's released at module unload. */ | 846 | * infrastructure. It's released at module unload. */ |
847 | kobject_init(&cnx->kobject); | 847 | kobject_init(&cnx->kobject, &veth_lpar_connection_ktype); |
848 | cnx->kobject.ktype = &veth_lpar_connection_ktype; | ||
849 | rc = kobject_set_name(&cnx->kobject, "cnx%.2d", rlp); | ||
850 | if (rc != 0) | ||
851 | return rc; | ||
852 | 848 | ||
853 | msgs = kcalloc(VETH_NUMBUFFERS, sizeof(struct veth_msg), GFP_KERNEL); | 849 | msgs = kcalloc(VETH_NUMBUFFERS, sizeof(struct veth_msg), GFP_KERNEL); |
854 | if (! msgs) { | 850 | if (! msgs) { |
@@ -1087,11 +1083,8 @@ static struct net_device * __init veth_probe_one(int vlan, | |||
1087 | return NULL; | 1083 | return NULL; |
1088 | } | 1084 | } |
1089 | 1085 | ||
1090 | kobject_init(&port->kobject); | 1086 | kobject_init(&port->kobject, &veth_port_ktype); |
1091 | port->kobject.parent = &dev->dev.kobj; | 1087 | if (0 != kobject_add(&port->kobject, &dev->dev.kobj, "veth_port")) |
1092 | port->kobject.ktype = &veth_port_ktype; | ||
1093 | kobject_set_name(&port->kobject, "veth_port"); | ||
1094 | if (0 != kobject_add(&port->kobject)) | ||
1095 | veth_error("Failed adding port for %s to sysfs.\n", dev->name); | 1088 | veth_error("Failed adding port for %s to sysfs.\n", dev->name); |
1096 | 1089 | ||
1097 | veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n", | 1090 | veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n", |
@@ -1711,9 +1704,9 @@ static int __init veth_module_init(void) | |||
1711 | continue; | 1704 | continue; |
1712 | 1705 | ||
1713 | kobj = &veth_cnx[i]->kobject; | 1706 | kobj = &veth_cnx[i]->kobject; |
1714 | kobj->parent = &veth_driver.driver.kobj; | ||
1715 | /* If the add failes, complain but otherwise continue */ | 1707 | /* If the add failes, complain but otherwise continue */ |
1716 | if (0 != kobject_add(kobj)) | 1708 | if (0 != driver_add_kobj(&veth_driver.driver, kobj, |
1709 | "cnx%.2d", veth_cnx[i]->remote_lp)) | ||
1717 | veth_error("cnx %d: Failed adding to sysfs.\n", i); | 1710 | veth_error("cnx %d: Failed adding to sysfs.\n", i); |
1718 | } | 1711 | } |
1719 | 1712 | ||
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index ff37bf437a99..1d706eae3052 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -395,8 +395,7 @@ static int __init cosa_init(void) | |||
395 | goto out_chrdev; | 395 | goto out_chrdev; |
396 | } | 396 | } |
397 | for (i=0; i<nr_cards; i++) { | 397 | for (i=0; i<nr_cards; i++) { |
398 | class_device_create(cosa_class, NULL, MKDEV(cosa_major, i), | 398 | device_create(cosa_class, NULL, MKDEV(cosa_major, i), "cosa%d", i); |
399 | NULL, "cosa%d", i); | ||
400 | } | 399 | } |
401 | err = 0; | 400 | err = 0; |
402 | goto out; | 401 | goto out; |
@@ -415,7 +414,7 @@ static void __exit cosa_exit(void) | |||
415 | printk(KERN_INFO "Unloading the cosa module\n"); | 414 | printk(KERN_INFO "Unloading the cosa module\n"); |
416 | 415 | ||
417 | for (i=0; i<nr_cards; i++) | 416 | for (i=0; i<nr_cards; i++) |
418 | class_device_destroy(cosa_class, MKDEV(cosa_major, i)); | 417 | device_destroy(cosa_class, MKDEV(cosa_major, i)); |
419 | class_destroy(cosa_class); | 418 | class_destroy(cosa_class); |
420 | for (cosa=cosa_cards; nr_cards--; cosa++) { | 419 | for (cosa=cosa_cards; nr_cards--; cosa++) { |
421 | /* Clean up the per-channel data */ | 420 | /* Clean up the per-channel data */ |
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index ebb09e98d215..de34aa9d3136 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -120,7 +120,7 @@ struct pdcspath_entry pdcspath_entry_##_name = { \ | |||
120 | }; | 120 | }; |
121 | 121 | ||
122 | #define PDCS_ATTR(_name, _mode, _show, _store) \ | 122 | #define PDCS_ATTR(_name, _mode, _show, _store) \ |
123 | struct subsys_attribute pdcs_attr_##_name = { \ | 123 | struct kobj_attribute pdcs_attr_##_name = { \ |
124 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | 124 | .attr = {.name = __stringify(_name), .mode = _mode}, \ |
125 | .show = _show, \ | 125 | .show = _show, \ |
126 | .store = _store, \ | 126 | .store = _store, \ |
@@ -523,15 +523,15 @@ static struct pdcspath_entry *pdcspath_entries[] = { | |||
523 | 523 | ||
524 | /** | 524 | /** |
525 | * pdcs_size_read - Stable Storage size output. | 525 | * pdcs_size_read - Stable Storage size output. |
526 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
527 | * @buf: The output buffer to write to. | 526 | * @buf: The output buffer to write to. |
528 | */ | 527 | */ |
529 | static ssize_t | 528 | static ssize_t pdcs_size_read(struct kobject *kobj, |
530 | pdcs_size_read(struct kset *kset, char *buf) | 529 | struct kobj_attribute *attr, |
530 | char *buf) | ||
531 | { | 531 | { |
532 | char *out = buf; | 532 | char *out = buf; |
533 | 533 | ||
534 | if (!kset || !buf) | 534 | if (!buf) |
535 | return -EINVAL; | 535 | return -EINVAL; |
536 | 536 | ||
537 | /* show the size of the stable storage */ | 537 | /* show the size of the stable storage */ |
@@ -542,17 +542,17 @@ pdcs_size_read(struct kset *kset, char *buf) | |||
542 | 542 | ||
543 | /** | 543 | /** |
544 | * pdcs_auto_read - Stable Storage autoboot/search flag output. | 544 | * pdcs_auto_read - Stable Storage autoboot/search flag output. |
545 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
546 | * @buf: The output buffer to write to. | 545 | * @buf: The output buffer to write to. |
547 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | 546 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag |
548 | */ | 547 | */ |
549 | static ssize_t | 548 | static ssize_t pdcs_auto_read(struct kobject *kobj, |
550 | pdcs_auto_read(struct kset *kset, char *buf, int knob) | 549 | struct kobj_attribute *attr, |
550 | char *buf, int knob) | ||
551 | { | 551 | { |
552 | char *out = buf; | 552 | char *out = buf; |
553 | struct pdcspath_entry *pathentry; | 553 | struct pdcspath_entry *pathentry; |
554 | 554 | ||
555 | if (!kset || !buf) | 555 | if (!buf) |
556 | return -EINVAL; | 556 | return -EINVAL; |
557 | 557 | ||
558 | /* Current flags are stored in primary boot path entry */ | 558 | /* Current flags are stored in primary boot path entry */ |
@@ -568,40 +568,37 @@ pdcs_auto_read(struct kset *kset, char *buf, int knob) | |||
568 | 568 | ||
569 | /** | 569 | /** |
570 | * pdcs_autoboot_read - Stable Storage autoboot flag output. | 570 | * pdcs_autoboot_read - Stable Storage autoboot flag output. |
571 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
572 | * @buf: The output buffer to write to. | 571 | * @buf: The output buffer to write to. |
573 | */ | 572 | */ |
574 | static inline ssize_t | 573 | static ssize_t pdcs_autoboot_read(struct kobject *kobj, |
575 | pdcs_autoboot_read(struct kset *kset, char *buf) | 574 | struct kobj_attribute *attr, char *buf) |
576 | { | 575 | { |
577 | return pdcs_auto_read(kset, buf, PF_AUTOBOOT); | 576 | return pdcs_auto_read(kobj, attr, buf, PF_AUTOBOOT); |
578 | } | 577 | } |
579 | 578 | ||
580 | /** | 579 | /** |
581 | * pdcs_autosearch_read - Stable Storage autoboot flag output. | 580 | * pdcs_autosearch_read - Stable Storage autoboot flag output. |
582 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
583 | * @buf: The output buffer to write to. | 581 | * @buf: The output buffer to write to. |
584 | */ | 582 | */ |
585 | static inline ssize_t | 583 | static ssize_t pdcs_autosearch_read(struct kobject *kobj, |
586 | pdcs_autosearch_read(struct kset *kset, char *buf) | 584 | struct kobj_attribute *attr, char *buf) |
587 | { | 585 | { |
588 | return pdcs_auto_read(kset, buf, PF_AUTOSEARCH); | 586 | return pdcs_auto_read(kobj, attr, buf, PF_AUTOSEARCH); |
589 | } | 587 | } |
590 | 588 | ||
591 | /** | 589 | /** |
592 | * pdcs_timer_read - Stable Storage timer count output (in seconds). | 590 | * pdcs_timer_read - Stable Storage timer count output (in seconds). |
593 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
594 | * @buf: The output buffer to write to. | 591 | * @buf: The output buffer to write to. |
595 | * | 592 | * |
596 | * The value of the timer field correponds to a number of seconds in powers of 2. | 593 | * The value of the timer field correponds to a number of seconds in powers of 2. |
597 | */ | 594 | */ |
598 | static ssize_t | 595 | static ssize_t pdcs_timer_read(struct kobject *kobj, |
599 | pdcs_timer_read(struct kset *kset, char *buf) | 596 | struct kobj_attribute *attr, char *buf) |
600 | { | 597 | { |
601 | char *out = buf; | 598 | char *out = buf; |
602 | struct pdcspath_entry *pathentry; | 599 | struct pdcspath_entry *pathentry; |
603 | 600 | ||
604 | if (!kset || !buf) | 601 | if (!buf) |
605 | return -EINVAL; | 602 | return -EINVAL; |
606 | 603 | ||
607 | /* Current flags are stored in primary boot path entry */ | 604 | /* Current flags are stored in primary boot path entry */ |
@@ -618,15 +615,14 @@ pdcs_timer_read(struct kset *kset, char *buf) | |||
618 | 615 | ||
619 | /** | 616 | /** |
620 | * pdcs_osid_read - Stable Storage OS ID register output. | 617 | * pdcs_osid_read - Stable Storage OS ID register output. |
621 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
622 | * @buf: The output buffer to write to. | 618 | * @buf: The output buffer to write to. |
623 | */ | 619 | */ |
624 | static ssize_t | 620 | static ssize_t pdcs_osid_read(struct kobject *kobj, |
625 | pdcs_osid_read(struct kset *kset, char *buf) | 621 | struct kobj_attribute *attr, char *buf) |
626 | { | 622 | { |
627 | char *out = buf; | 623 | char *out = buf; |
628 | 624 | ||
629 | if (!kset || !buf) | 625 | if (!buf) |
630 | return -EINVAL; | 626 | return -EINVAL; |
631 | 627 | ||
632 | out += sprintf(out, "%s dependent data (0x%.4x)\n", | 628 | out += sprintf(out, "%s dependent data (0x%.4x)\n", |
@@ -637,18 +633,17 @@ pdcs_osid_read(struct kset *kset, char *buf) | |||
637 | 633 | ||
638 | /** | 634 | /** |
639 | * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. | 635 | * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. |
640 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
641 | * @buf: The output buffer to write to. | 636 | * @buf: The output buffer to write to. |
642 | * | 637 | * |
643 | * This can hold 16 bytes of OS-Dependent data. | 638 | * This can hold 16 bytes of OS-Dependent data. |
644 | */ | 639 | */ |
645 | static ssize_t | 640 | static ssize_t pdcs_osdep1_read(struct kobject *kobj, |
646 | pdcs_osdep1_read(struct kset *kset, char *buf) | 641 | struct kobj_attribute *attr, char *buf) |
647 | { | 642 | { |
648 | char *out = buf; | 643 | char *out = buf; |
649 | u32 result[4]; | 644 | u32 result[4]; |
650 | 645 | ||
651 | if (!kset || !buf) | 646 | if (!buf) |
652 | return -EINVAL; | 647 | return -EINVAL; |
653 | 648 | ||
654 | if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) | 649 | if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) |
@@ -664,18 +659,17 @@ pdcs_osdep1_read(struct kset *kset, char *buf) | |||
664 | 659 | ||
665 | /** | 660 | /** |
666 | * pdcs_diagnostic_read - Stable Storage Diagnostic register output. | 661 | * pdcs_diagnostic_read - Stable Storage Diagnostic register output. |
667 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
668 | * @buf: The output buffer to write to. | 662 | * @buf: The output buffer to write to. |
669 | * | 663 | * |
670 | * I have NFC how to interpret the content of that register ;-). | 664 | * I have NFC how to interpret the content of that register ;-). |
671 | */ | 665 | */ |
672 | static ssize_t | 666 | static ssize_t pdcs_diagnostic_read(struct kobject *kobj, |
673 | pdcs_diagnostic_read(struct kset *kset, char *buf) | 667 | struct kobj_attribute *attr, char *buf) |
674 | { | 668 | { |
675 | char *out = buf; | 669 | char *out = buf; |
676 | u32 result; | 670 | u32 result; |
677 | 671 | ||
678 | if (!kset || !buf) | 672 | if (!buf) |
679 | return -EINVAL; | 673 | return -EINVAL; |
680 | 674 | ||
681 | /* get diagnostic */ | 675 | /* get diagnostic */ |
@@ -689,18 +683,17 @@ pdcs_diagnostic_read(struct kset *kset, char *buf) | |||
689 | 683 | ||
690 | /** | 684 | /** |
691 | * pdcs_fastsize_read - Stable Storage FastSize register output. | 685 | * pdcs_fastsize_read - Stable Storage FastSize register output. |
692 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
693 | * @buf: The output buffer to write to. | 686 | * @buf: The output buffer to write to. |
694 | * | 687 | * |
695 | * This register holds the amount of system RAM to be tested during boot sequence. | 688 | * This register holds the amount of system RAM to be tested during boot sequence. |
696 | */ | 689 | */ |
697 | static ssize_t | 690 | static ssize_t pdcs_fastsize_read(struct kobject *kobj, |
698 | pdcs_fastsize_read(struct kset *kset, char *buf) | 691 | struct kobj_attribute *attr, char *buf) |
699 | { | 692 | { |
700 | char *out = buf; | 693 | char *out = buf; |
701 | u32 result; | 694 | u32 result; |
702 | 695 | ||
703 | if (!kset || !buf) | 696 | if (!buf) |
704 | return -EINVAL; | 697 | return -EINVAL; |
705 | 698 | ||
706 | /* get fast-size */ | 699 | /* get fast-size */ |
@@ -718,13 +711,12 @@ pdcs_fastsize_read(struct kset *kset, char *buf) | |||
718 | 711 | ||
719 | /** | 712 | /** |
720 | * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. | 713 | * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. |
721 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
722 | * @buf: The output buffer to write to. | 714 | * @buf: The output buffer to write to. |
723 | * | 715 | * |
724 | * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. | 716 | * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. |
725 | */ | 717 | */ |
726 | static ssize_t | 718 | static ssize_t pdcs_osdep2_read(struct kobject *kobj, |
727 | pdcs_osdep2_read(struct kset *kset, char *buf) | 719 | struct kobj_attribute *attr, char *buf) |
728 | { | 720 | { |
729 | char *out = buf; | 721 | char *out = buf; |
730 | unsigned long size; | 722 | unsigned long size; |
@@ -736,7 +728,7 @@ pdcs_osdep2_read(struct kset *kset, char *buf) | |||
736 | 728 | ||
737 | size = pdcs_size - 224; | 729 | size = pdcs_size - 224; |
738 | 730 | ||
739 | if (!kset || !buf) | 731 | if (!buf) |
740 | return -EINVAL; | 732 | return -EINVAL; |
741 | 733 | ||
742 | for (i=0; i<size; i+=4) { | 734 | for (i=0; i<size; i+=4) { |
@@ -751,7 +743,6 @@ pdcs_osdep2_read(struct kset *kset, char *buf) | |||
751 | 743 | ||
752 | /** | 744 | /** |
753 | * pdcs_auto_write - This function handles autoboot/search flag modifying. | 745 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
754 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
755 | * @buf: The input buffer to read from. | 746 | * @buf: The input buffer to read from. |
756 | * @count: The number of bytes to be read. | 747 | * @count: The number of bytes to be read. |
757 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | 748 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag |
@@ -760,8 +751,9 @@ pdcs_osdep2_read(struct kset *kset, char *buf) | |||
760 | * We expect a precise syntax: | 751 | * We expect a precise syntax: |
761 | * \"n\" (n == 0 or 1) to toggle AutoBoot Off or On | 752 | * \"n\" (n == 0 or 1) to toggle AutoBoot Off or On |
762 | */ | 753 | */ |
763 | static ssize_t | 754 | static ssize_t pdcs_auto_write(struct kobject *kobj, |
764 | pdcs_auto_write(struct kset *kset, const char *buf, size_t count, int knob) | 755 | struct kobj_attribute *attr, const char *buf, |
756 | size_t count, int knob) | ||
765 | { | 757 | { |
766 | struct pdcspath_entry *pathentry; | 758 | struct pdcspath_entry *pathentry; |
767 | unsigned char flags; | 759 | unsigned char flags; |
@@ -771,7 +763,7 @@ pdcs_auto_write(struct kset *kset, const char *buf, size_t count, int knob) | |||
771 | if (!capable(CAP_SYS_ADMIN)) | 763 | if (!capable(CAP_SYS_ADMIN)) |
772 | return -EACCES; | 764 | return -EACCES; |
773 | 765 | ||
774 | if (!kset || !buf || !count) | 766 | if (!buf || !count) |
775 | return -EINVAL; | 767 | return -EINVAL; |
776 | 768 | ||
777 | /* We'll use a local copy of buf */ | 769 | /* We'll use a local copy of buf */ |
@@ -826,7 +818,6 @@ parse_error: | |||
826 | 818 | ||
827 | /** | 819 | /** |
828 | * pdcs_autoboot_write - This function handles autoboot flag modifying. | 820 | * pdcs_autoboot_write - This function handles autoboot flag modifying. |
829 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
830 | * @buf: The input buffer to read from. | 821 | * @buf: The input buffer to read from. |
831 | * @count: The number of bytes to be read. | 822 | * @count: The number of bytes to be read. |
832 | * | 823 | * |
@@ -834,15 +825,15 @@ parse_error: | |||
834 | * We expect a precise syntax: | 825 | * We expect a precise syntax: |
835 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | 826 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On |
836 | */ | 827 | */ |
837 | static inline ssize_t | 828 | static ssize_t pdcs_autoboot_write(struct kobject *kobj, |
838 | pdcs_autoboot_write(struct kset *kset, const char *buf, size_t count) | 829 | struct kobj_attribute *attr, |
830 | const char *buf, size_t count) | ||
839 | { | 831 | { |
840 | return pdcs_auto_write(kset, buf, count, PF_AUTOBOOT); | 832 | return pdcs_auto_write(kset, attr, buf, count, PF_AUTOBOOT); |
841 | } | 833 | } |
842 | 834 | ||
843 | /** | 835 | /** |
844 | * pdcs_autosearch_write - This function handles autosearch flag modifying. | 836 | * pdcs_autosearch_write - This function handles autosearch flag modifying. |
845 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
846 | * @buf: The input buffer to read from. | 837 | * @buf: The input buffer to read from. |
847 | * @count: The number of bytes to be read. | 838 | * @count: The number of bytes to be read. |
848 | * | 839 | * |
@@ -850,15 +841,15 @@ pdcs_autoboot_write(struct kset *kset, const char *buf, size_t count) | |||
850 | * We expect a precise syntax: | 841 | * We expect a precise syntax: |
851 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | 842 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On |
852 | */ | 843 | */ |
853 | static inline ssize_t | 844 | static ssize_t pdcs_autosearch_write(struct kobject *kobj, |
854 | pdcs_autosearch_write(struct kset *kset, const char *buf, size_t count) | 845 | struct kobj_attribute *attr, |
846 | const char *buf, size_t count) | ||
855 | { | 847 | { |
856 | return pdcs_auto_write(kset, buf, count, PF_AUTOSEARCH); | 848 | return pdcs_auto_write(kset, attr, buf, count, PF_AUTOSEARCH); |
857 | } | 849 | } |
858 | 850 | ||
859 | /** | 851 | /** |
860 | * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input. | 852 | * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input. |
861 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
862 | * @buf: The input buffer to read from. | 853 | * @buf: The input buffer to read from. |
863 | * @count: The number of bytes to be read. | 854 | * @count: The number of bytes to be read. |
864 | * | 855 | * |
@@ -866,15 +857,16 @@ pdcs_autosearch_write(struct kset *kset, const char *buf, size_t count) | |||
866 | * write approach. It's up to userspace to deal with it when constructing | 857 | * write approach. It's up to userspace to deal with it when constructing |
867 | * its input buffer. | 858 | * its input buffer. |
868 | */ | 859 | */ |
869 | static ssize_t | 860 | static ssize_t pdcs_osdep1_write(struct kobject *kobj, |
870 | pdcs_osdep1_write(struct kset *kset, const char *buf, size_t count) | 861 | struct kobj_attribute *attr, |
862 | const char *buf, size_t count) | ||
871 | { | 863 | { |
872 | u8 in[16]; | 864 | u8 in[16]; |
873 | 865 | ||
874 | if (!capable(CAP_SYS_ADMIN)) | 866 | if (!capable(CAP_SYS_ADMIN)) |
875 | return -EACCES; | 867 | return -EACCES; |
876 | 868 | ||
877 | if (!kset || !buf || !count) | 869 | if (!buf || !count) |
878 | return -EINVAL; | 870 | return -EINVAL; |
879 | 871 | ||
880 | if (unlikely(pdcs_osid != OS_ID_LINUX)) | 872 | if (unlikely(pdcs_osid != OS_ID_LINUX)) |
@@ -895,7 +887,6 @@ pdcs_osdep1_write(struct kset *kset, const char *buf, size_t count) | |||
895 | 887 | ||
896 | /** | 888 | /** |
897 | * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. | 889 | * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. |
898 | * @kset: An allocated and populated struct kset. We don't use it tho. | ||
899 | * @buf: The input buffer to read from. | 890 | * @buf: The input buffer to read from. |
900 | * @count: The number of bytes to be read. | 891 | * @count: The number of bytes to be read. |
901 | * | 892 | * |
@@ -903,8 +894,9 @@ pdcs_osdep1_write(struct kset *kset, const char *buf, size_t count) | |||
903 | * byte-by-byte write approach. It's up to userspace to deal with it when | 894 | * byte-by-byte write approach. It's up to userspace to deal with it when |
904 | * constructing its input buffer. | 895 | * constructing its input buffer. |
905 | */ | 896 | */ |
906 | static ssize_t | 897 | static ssize_t pdcs_osdep2_write(struct kobject *kobj, |
907 | pdcs_osdep2_write(struct kset *kset, const char *buf, size_t count) | 898 | struct kobj_attribute *attr, |
899 | const char *buf, size_t count) | ||
908 | { | 900 | { |
909 | unsigned long size; | 901 | unsigned long size; |
910 | unsigned short i; | 902 | unsigned short i; |
@@ -913,7 +905,7 @@ pdcs_osdep2_write(struct kset *kset, const char *buf, size_t count) | |||
913 | if (!capable(CAP_SYS_ADMIN)) | 905 | if (!capable(CAP_SYS_ADMIN)) |
914 | return -EACCES; | 906 | return -EACCES; |
915 | 907 | ||
916 | if (!kset || !buf || !count) | 908 | if (!buf || !count) |
917 | return -EINVAL; | 909 | return -EINVAL; |
918 | 910 | ||
919 | if (unlikely(pdcs_size <= 224)) | 911 | if (unlikely(pdcs_size <= 224)) |
@@ -951,21 +943,25 @@ static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL); | |||
951 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | 943 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); |
952 | static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write); | 944 | static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write); |
953 | 945 | ||
954 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 946 | static struct attribute *pdcs_subsys_attrs[] = { |
955 | &pdcs_attr_size, | 947 | &pdcs_attr_size.attr, |
956 | &pdcs_attr_autoboot, | 948 | &pdcs_attr_autoboot.attr, |
957 | &pdcs_attr_autosearch, | 949 | &pdcs_attr_autosearch.attr, |
958 | &pdcs_attr_timer, | 950 | &pdcs_attr_timer.attr, |
959 | &pdcs_attr_osid, | 951 | &pdcs_attr_osid.attr, |
960 | &pdcs_attr_osdep1, | 952 | &pdcs_attr_osdep1.attr, |
961 | &pdcs_attr_diagnostic, | 953 | &pdcs_attr_diagnostic.attr, |
962 | &pdcs_attr_fastsize, | 954 | &pdcs_attr_fastsize.attr, |
963 | &pdcs_attr_osdep2, | 955 | &pdcs_attr_osdep2.attr, |
964 | NULL, | 956 | NULL, |
965 | }; | 957 | }; |
966 | 958 | ||
967 | static decl_subsys(paths, &ktype_pdcspath, NULL); | 959 | static struct attribute_group pdcs_attr_group = { |
968 | static decl_subsys(stable, NULL, NULL); | 960 | .attrs = pdcs_subsys_attrs, |
961 | }; | ||
962 | |||
963 | static struct kobject *stable_kobj; | ||
964 | static struct kset *paths_kset; | ||
969 | 965 | ||
970 | /** | 966 | /** |
971 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. | 967 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. |
@@ -995,12 +991,12 @@ pdcs_register_pathentries(void) | |||
995 | if (err < 0) | 991 | if (err < 0) |
996 | continue; | 992 | continue; |
997 | 993 | ||
998 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) | 994 | entry->kobj.kset = paths_kset; |
999 | return err; | 995 | err = kobject_init_and_add(&entry->kobj, &ktype_pdcspath, NULL, |
1000 | kobj_set_kset_s(entry, paths_subsys); | 996 | "%s", entry->name); |
1001 | if ((err = kobject_register(&entry->kobj))) | 997 | if (err) |
1002 | return err; | 998 | return err; |
1003 | 999 | ||
1004 | /* kobject is now registered */ | 1000 | /* kobject is now registered */ |
1005 | write_lock(&entry->rw_lock); | 1001 | write_lock(&entry->rw_lock); |
1006 | entry->ready = 2; | 1002 | entry->ready = 2; |
@@ -1012,6 +1008,7 @@ pdcs_register_pathentries(void) | |||
1012 | } | 1008 | } |
1013 | 1009 | ||
1014 | write_unlock(&entry->rw_lock); | 1010 | write_unlock(&entry->rw_lock); |
1011 | kobject_uevent(&entry->kobj, KOBJ_ADD); | ||
1015 | } | 1012 | } |
1016 | 1013 | ||
1017 | return 0; | 1014 | return 0; |
@@ -1029,7 +1026,7 @@ pdcs_unregister_pathentries(void) | |||
1029 | for (i = 0; (entry = pdcspath_entries[i]); i++) { | 1026 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
1030 | read_lock(&entry->rw_lock); | 1027 | read_lock(&entry->rw_lock); |
1031 | if (entry->ready >= 2) | 1028 | if (entry->ready >= 2) |
1032 | kobject_unregister(&entry->kobj); | 1029 | kobject_put(&entry->kobj); |
1033 | read_unlock(&entry->rw_lock); | 1030 | read_unlock(&entry->rw_lock); |
1034 | } | 1031 | } |
1035 | } | 1032 | } |
@@ -1041,8 +1038,7 @@ pdcs_unregister_pathentries(void) | |||
1041 | static int __init | 1038 | static int __init |
1042 | pdc_stable_init(void) | 1039 | pdc_stable_init(void) |
1043 | { | 1040 | { |
1044 | struct subsys_attribute *attr; | 1041 | int rc = 0, error = 0; |
1045 | int i, rc = 0, error = 0; | ||
1046 | u32 result; | 1042 | u32 result; |
1047 | 1043 | ||
1048 | /* find the size of the stable storage */ | 1044 | /* find the size of the stable storage */ |
@@ -1062,21 +1058,24 @@ pdc_stable_init(void) | |||
1062 | /* the actual result is 16 bits away */ | 1058 | /* the actual result is 16 bits away */ |
1063 | pdcs_osid = (u16)(result >> 16); | 1059 | pdcs_osid = (u16)(result >> 16); |
1064 | 1060 | ||
1065 | /* For now we'll register the stable subsys within this driver */ | 1061 | /* For now we'll register the directory at /sys/firmware/stable */ |
1066 | if ((rc = firmware_register(&stable_subsys))) | 1062 | stable_kobj = kobject_create_and_add("stable", firmware_kobj); |
1063 | if (!stable_kobj) { | ||
1064 | rc = -ENOMEM; | ||
1067 | goto fail_firmreg; | 1065 | goto fail_firmreg; |
1066 | } | ||
1068 | 1067 | ||
1069 | /* Don't forget the root entries */ | 1068 | /* Don't forget the root entries */ |
1070 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) | 1069 | error = sysfs_create_group(stable_kobj, pdcs_attr_group); |
1071 | if (attr->show) | ||
1072 | error = subsys_create_file(&stable_subsys, attr); | ||
1073 | |||
1074 | /* register the paths subsys as a subsystem of stable subsys */ | ||
1075 | kobj_set_kset_s(&paths_subsys, stable_subsys); | ||
1076 | if ((rc = subsystem_register(&paths_subsys))) | ||
1077 | goto fail_subsysreg; | ||
1078 | 1070 | ||
1079 | /* now we create all "files" for the paths subsys */ | 1071 | /* register the paths kset as a child of the stable kset */ |
1072 | paths_kset = kset_create_and_add("paths", NULL, stable_kobj); | ||
1073 | if (!paths_kset) { | ||
1074 | rc = -ENOMEM; | ||
1075 | goto fail_ksetreg; | ||
1076 | } | ||
1077 | |||
1078 | /* now we create all "files" for the paths kset */ | ||
1080 | if ((rc = pdcs_register_pathentries())) | 1079 | if ((rc = pdcs_register_pathentries())) |
1081 | goto fail_pdcsreg; | 1080 | goto fail_pdcsreg; |
1082 | 1081 | ||
@@ -1084,10 +1083,10 @@ pdc_stable_init(void) | |||
1084 | 1083 | ||
1085 | fail_pdcsreg: | 1084 | fail_pdcsreg: |
1086 | pdcs_unregister_pathentries(); | 1085 | pdcs_unregister_pathentries(); |
1087 | subsystem_unregister(&paths_subsys); | 1086 | kset_unregister(paths_kset); |
1088 | 1087 | ||
1089 | fail_subsysreg: | 1088 | fail_ksetreg: |
1090 | firmware_unregister(&stable_subsys); | 1089 | kobject_put(stable_kobj); |
1091 | 1090 | ||
1092 | fail_firmreg: | 1091 | fail_firmreg: |
1093 | printk(KERN_INFO PDCS_PREFIX " bailing out\n"); | 1092 | printk(KERN_INFO PDCS_PREFIX " bailing out\n"); |
@@ -1098,9 +1097,8 @@ static void __exit | |||
1098 | pdc_stable_exit(void) | 1097 | pdc_stable_exit(void) |
1099 | { | 1098 | { |
1100 | pdcs_unregister_pathentries(); | 1099 | pdcs_unregister_pathentries(); |
1101 | subsystem_unregister(&paths_subsys); | 1100 | kset_unregister(paths_kset); |
1102 | 1101 | kobject_put(stable_kobj); | |
1103 | firmware_unregister(&stable_subsys); | ||
1104 | } | 1102 | } |
1105 | 1103 | ||
1106 | 1104 | ||
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 47d26b65e99a..750ebd7a4c10 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c | |||
@@ -429,7 +429,7 @@ static int __init ibm_acpiphp_init(void) | |||
429 | int retval = 0; | 429 | int retval = 0; |
430 | acpi_status status; | 430 | acpi_status status; |
431 | struct acpi_device *device; | 431 | struct acpi_device *device; |
432 | struct kobject *sysdir = &pci_hotplug_slots_subsys.kobj; | 432 | struct kobject *sysdir = &pci_hotplug_slots_kset->kobj; |
433 | 433 | ||
434 | dbg("%s\n", __FUNCTION__); | 434 | dbg("%s\n", __FUNCTION__); |
435 | 435 | ||
@@ -476,7 +476,7 @@ init_return: | |||
476 | static void __exit ibm_acpiphp_exit(void) | 476 | static void __exit ibm_acpiphp_exit(void) |
477 | { | 477 | { |
478 | acpi_status status; | 478 | acpi_status status; |
479 | struct kobject *sysdir = &pci_hotplug_slots_subsys.kobj; | 479 | struct kobject *sysdir = &pci_hotplug_slots_kset->kobj; |
480 | 480 | ||
481 | dbg("%s\n", __FUNCTION__); | 481 | dbg("%s\n", __FUNCTION__); |
482 | 482 | ||
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 01c351c176ac..47bb0e1ff3fa 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -61,7 +61,7 @@ static int debug; | |||
61 | 61 | ||
62 | static LIST_HEAD(pci_hotplug_slot_list); | 62 | static LIST_HEAD(pci_hotplug_slot_list); |
63 | 63 | ||
64 | struct kset pci_hotplug_slots_subsys; | 64 | struct kset *pci_hotplug_slots_kset; |
65 | 65 | ||
66 | static ssize_t hotplug_slot_attr_show(struct kobject *kobj, | 66 | static ssize_t hotplug_slot_attr_show(struct kobject *kobj, |
67 | struct attribute *attr, char *buf) | 67 | struct attribute *attr, char *buf) |
@@ -96,8 +96,6 @@ static struct kobj_type hotplug_slot_ktype = { | |||
96 | .release = &hotplug_slot_release, | 96 | .release = &hotplug_slot_release, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | decl_subsys_name(pci_hotplug_slots, slots, &hotplug_slot_ktype, NULL); | ||
100 | |||
101 | /* these strings match up with the values in pci_bus_speed */ | 99 | /* these strings match up with the values in pci_bus_speed */ |
102 | static char *pci_bus_speed_strings[] = { | 100 | static char *pci_bus_speed_strings[] = { |
103 | "33 MHz PCI", /* 0x00 */ | 101 | "33 MHz PCI", /* 0x00 */ |
@@ -632,18 +630,19 @@ int pci_hp_register (struct hotplug_slot *slot) | |||
632 | return -EINVAL; | 630 | return -EINVAL; |
633 | } | 631 | } |
634 | 632 | ||
635 | kobject_set_name(&slot->kobj, "%s", slot->name); | ||
636 | kobj_set_kset_s(slot, pci_hotplug_slots_subsys); | ||
637 | |||
638 | /* this can fail if we have already registered a slot with the same name */ | 633 | /* this can fail if we have already registered a slot with the same name */ |
639 | if (kobject_register(&slot->kobj)) { | 634 | slot->kobj.kset = pci_hotplug_slots_kset; |
640 | err("Unable to register kobject"); | 635 | result = kobject_init_and_add(&slot->kobj, &hotplug_slot_ktype, NULL, |
636 | "%s", slot->name); | ||
637 | if (result) { | ||
638 | err("Unable to register kobject '%s'", slot->name); | ||
641 | return -EINVAL; | 639 | return -EINVAL; |
642 | } | 640 | } |
643 | 641 | ||
644 | list_add (&slot->slot_list, &pci_hotplug_slot_list); | 642 | list_add (&slot->slot_list, &pci_hotplug_slot_list); |
645 | 643 | ||
646 | result = fs_add_slot (slot); | 644 | result = fs_add_slot (slot); |
645 | kobject_uevent(&slot->kobj, KOBJ_ADD); | ||
647 | dbg ("Added slot %s to the list\n", slot->name); | 646 | dbg ("Added slot %s to the list\n", slot->name); |
648 | return result; | 647 | return result; |
649 | } | 648 | } |
@@ -672,7 +671,7 @@ int pci_hp_deregister (struct hotplug_slot *slot) | |||
672 | 671 | ||
673 | fs_remove_slot (slot); | 672 | fs_remove_slot (slot); |
674 | dbg ("Removed slot %s from the list\n", slot->name); | 673 | dbg ("Removed slot %s from the list\n", slot->name); |
675 | kobject_unregister(&slot->kobj); | 674 | kobject_put(&slot->kobj); |
676 | return 0; | 675 | return 0; |
677 | } | 676 | } |
678 | 677 | ||
@@ -700,11 +699,15 @@ int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, | |||
700 | static int __init pci_hotplug_init (void) | 699 | static int __init pci_hotplug_init (void) |
701 | { | 700 | { |
702 | int result; | 701 | int result; |
702 | struct kset *pci_bus_kset; | ||
703 | 703 | ||
704 | kobj_set_kset_s(&pci_hotplug_slots_subsys, pci_bus_type.subsys); | 704 | pci_bus_kset = bus_get_kset(&pci_bus_type); |
705 | result = subsystem_register(&pci_hotplug_slots_subsys); | 705 | |
706 | if (result) { | 706 | pci_hotplug_slots_kset = kset_create_and_add("slots", NULL, |
707 | err("Register subsys with error %d\n", result); | 707 | &pci_bus_kset->kobj); |
708 | if (!pci_hotplug_slots_kset) { | ||
709 | result = -ENOMEM; | ||
710 | err("Register subsys error\n"); | ||
708 | goto exit; | 711 | goto exit; |
709 | } | 712 | } |
710 | result = cpci_hotplug_init(debug); | 713 | result = cpci_hotplug_init(debug); |
@@ -715,9 +718,9 @@ static int __init pci_hotplug_init (void) | |||
715 | 718 | ||
716 | info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); | 719 | info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); |
717 | goto exit; | 720 | goto exit; |
718 | 721 | ||
719 | err_subsys: | 722 | err_subsys: |
720 | subsystem_unregister(&pci_hotplug_slots_subsys); | 723 | kset_unregister(pci_hotplug_slots_kset); |
721 | exit: | 724 | exit: |
722 | return result; | 725 | return result; |
723 | } | 726 | } |
@@ -725,7 +728,7 @@ exit: | |||
725 | static void __exit pci_hotplug_exit (void) | 728 | static void __exit pci_hotplug_exit (void) |
726 | { | 729 | { |
727 | cpci_hotplug_exit(); | 730 | cpci_hotplug_exit(); |
728 | subsystem_unregister(&pci_hotplug_slots_subsys); | 731 | kset_unregister(pci_hotplug_slots_kset); |
729 | } | 732 | } |
730 | 733 | ||
731 | module_init(pci_hotplug_init); | 734 | module_init(pci_hotplug_init); |
@@ -737,7 +740,7 @@ MODULE_LICENSE("GPL"); | |||
737 | module_param(debug, bool, 0644); | 740 | module_param(debug, bool, 0644); |
738 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | 741 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); |
739 | 742 | ||
740 | EXPORT_SYMBOL_GPL(pci_hotplug_slots_subsys); | 743 | EXPORT_SYMBOL_GPL(pci_hotplug_slots_kset); |
741 | EXPORT_SYMBOL_GPL(pci_hp_register); | 744 | EXPORT_SYMBOL_GPL(pci_hp_register); |
742 | EXPORT_SYMBOL_GPL(pci_hp_deregister); | 745 | EXPORT_SYMBOL_GPL(pci_hp_deregister); |
743 | EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); | 746 | EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); |
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c index a080fedf0332..e32148a8fa12 100644 --- a/drivers/pci/hotplug/rpadlpar_sysfs.c +++ b/drivers/pci/hotplug/rpadlpar_sysfs.c | |||
@@ -23,44 +23,13 @@ | |||
23 | 23 | ||
24 | #define MAX_DRC_NAME_LEN 64 | 24 | #define MAX_DRC_NAME_LEN 64 |
25 | 25 | ||
26 | /* Store return code of dlpar operation in attribute struct */ | ||
27 | struct dlpar_io_attr { | ||
28 | int rc; | ||
29 | struct attribute attr; | ||
30 | ssize_t (*store)(struct dlpar_io_attr *dlpar_attr, const char *buf, | ||
31 | size_t nbytes); | ||
32 | }; | ||
33 | 26 | ||
34 | /* Common show callback for all attrs, display the return code | 27 | static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr, |
35 | * of the dlpar op */ | 28 | const char *buf, size_t nbytes) |
36 | static ssize_t | ||
37 | dlpar_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | ||
38 | { | ||
39 | struct dlpar_io_attr *dlpar_attr = container_of(attr, | ||
40 | struct dlpar_io_attr, attr); | ||
41 | return sprintf(buf, "%d\n", dlpar_attr->rc); | ||
42 | } | ||
43 | |||
44 | static ssize_t | ||
45 | dlpar_attr_store(struct kobject * kobj, struct attribute * attr, | ||
46 | const char *buf, size_t nbytes) | ||
47 | { | ||
48 | struct dlpar_io_attr *dlpar_attr = container_of(attr, | ||
49 | struct dlpar_io_attr, attr); | ||
50 | return dlpar_attr->store ? | ||
51 | dlpar_attr->store(dlpar_attr, buf, nbytes) : -EIO; | ||
52 | } | ||
53 | |||
54 | static struct sysfs_ops dlpar_attr_sysfs_ops = { | ||
55 | .show = dlpar_attr_show, | ||
56 | .store = dlpar_attr_store, | ||
57 | }; | ||
58 | |||
59 | static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr, | ||
60 | const char *buf, size_t nbytes) | ||
61 | { | 29 | { |
62 | char drc_name[MAX_DRC_NAME_LEN]; | 30 | char drc_name[MAX_DRC_NAME_LEN]; |
63 | char *end; | 31 | char *end; |
32 | int rc; | ||
64 | 33 | ||
65 | if (nbytes >= MAX_DRC_NAME_LEN) | 34 | if (nbytes >= MAX_DRC_NAME_LEN) |
66 | return 0; | 35 | return 0; |
@@ -72,15 +41,25 @@ static ssize_t add_slot_store(struct dlpar_io_attr *dlpar_attr, | |||
72 | end = &drc_name[nbytes]; | 41 | end = &drc_name[nbytes]; |
73 | *end = '\0'; | 42 | *end = '\0'; |
74 | 43 | ||
75 | dlpar_attr->rc = dlpar_add_slot(drc_name); | 44 | rc = dlpar_add_slot(drc_name); |
45 | if (rc) | ||
46 | return rc; | ||
76 | 47 | ||
77 | return nbytes; | 48 | return nbytes; |
78 | } | 49 | } |
79 | 50 | ||
80 | static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr, | 51 | static ssize_t add_slot_show(struct kobject *kobj, |
81 | const char *buf, size_t nbytes) | 52 | struct kobj_attribute *attr, char *buf) |
53 | { | ||
54 | return sprintf(buf, "0\n"); | ||
55 | } | ||
56 | |||
57 | static ssize_t remove_slot_store(struct kobject *kobj, | ||
58 | struct kobj_attribute *attr, | ||
59 | const char *buf, size_t nbytes) | ||
82 | { | 60 | { |
83 | char drc_name[MAX_DRC_NAME_LEN]; | 61 | char drc_name[MAX_DRC_NAME_LEN]; |
62 | int rc; | ||
84 | char *end; | 63 | char *end; |
85 | 64 | ||
86 | if (nbytes >= MAX_DRC_NAME_LEN) | 65 | if (nbytes >= MAX_DRC_NAME_LEN) |
@@ -93,22 +72,24 @@ static ssize_t remove_slot_store(struct dlpar_io_attr *dlpar_attr, | |||
93 | end = &drc_name[nbytes]; | 72 | end = &drc_name[nbytes]; |
94 | *end = '\0'; | 73 | *end = '\0'; |
95 | 74 | ||
96 | dlpar_attr->rc = dlpar_remove_slot(drc_name); | 75 | rc = dlpar_remove_slot(drc_name); |
76 | if (rc) | ||
77 | return rc; | ||
97 | 78 | ||
98 | return nbytes; | 79 | return nbytes; |
99 | } | 80 | } |
100 | 81 | ||
101 | static struct dlpar_io_attr add_slot_attr = { | 82 | static ssize_t remove_slot_show(struct kobject *kobj, |
102 | .rc = 0, | 83 | struct kobj_attribute *attr, char *buf) |
103 | .attr = { .name = ADD_SLOT_ATTR_NAME, .mode = 0644, }, | 84 | { |
104 | .store = add_slot_store, | 85 | return sprintf(buf, "0\n"); |
105 | }; | 86 | } |
106 | 87 | ||
107 | static struct dlpar_io_attr remove_slot_attr = { | 88 | static struct kobj_attribute add_slot_attr = |
108 | .rc = 0, | 89 | __ATTR(ADD_SLOT_ATTR_NAME, 0644, add_slot_show, add_slot_store); |
109 | .attr = { .name = REMOVE_SLOT_ATTR_NAME, .mode = 0644}, | 90 | |
110 | .store = remove_slot_store, | 91 | static struct kobj_attribute remove_slot_attr = |
111 | }; | 92 | __ATTR(REMOVE_SLOT_ATTR_NAME, 0644, remove_slot_show, remove_slot_store); |
112 | 93 | ||
113 | static struct attribute *default_attrs[] = { | 94 | static struct attribute *default_attrs[] = { |
114 | &add_slot_attr.attr, | 95 | &add_slot_attr.attr, |
@@ -116,37 +97,29 @@ static struct attribute *default_attrs[] = { | |||
116 | NULL, | 97 | NULL, |
117 | }; | 98 | }; |
118 | 99 | ||
119 | static void dlpar_io_release(struct kobject *kobj) | 100 | static struct attribute_group dlpar_attr_group = { |
120 | { | 101 | .attrs = default_attrs, |
121 | /* noop */ | ||
122 | return; | ||
123 | } | ||
124 | |||
125 | struct kobj_type ktype_dlpar_io = { | ||
126 | .release = dlpar_io_release, | ||
127 | .sysfs_ops = &dlpar_attr_sysfs_ops, | ||
128 | .default_attrs = default_attrs, | ||
129 | }; | 102 | }; |
130 | 103 | ||
131 | struct kset dlpar_io_kset = { | 104 | static struct kobject *dlpar_kobj; |
132 | .kobj = {.ktype = &ktype_dlpar_io, | ||
133 | .parent = &pci_hotplug_slots_subsys.kobj}, | ||
134 | .ktype = &ktype_dlpar_io, | ||
135 | }; | ||
136 | 105 | ||
137 | int dlpar_sysfs_init(void) | 106 | int dlpar_sysfs_init(void) |
138 | { | 107 | { |
139 | kobject_set_name(&dlpar_io_kset.kobj, DLPAR_KOBJ_NAME); | 108 | int error; |
140 | if (kset_register(&dlpar_io_kset)) { | 109 | |
141 | printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n", | 110 | dlpar_kobj = kobject_create_and_add(DLPAR_KOBJ_NAME, |
142 | kobject_name(&dlpar_io_kset.kobj)); | 111 | &pci_hotplug_slots_kset->kobj); |
112 | if (!dlpar_kobj) | ||
143 | return -EINVAL; | 113 | return -EINVAL; |
144 | } | ||
145 | 114 | ||
146 | return 0; | 115 | error = sysfs_create_group(dlpar_kobj, &dlpar_attr_group); |
116 | if (error) | ||
117 | kobject_put(dlpar_kobj); | ||
118 | return error; | ||
147 | } | 119 | } |
148 | 120 | ||
149 | void dlpar_sysfs_exit(void) | 121 | void dlpar_sysfs_exit(void) |
150 | { | 122 | { |
151 | kset_unregister(&dlpar_io_kset); | 123 | sysfs_remove_group(dlpar_kobj, &dlpar_attr_group); |
124 | kobject_put(dlpar_kobj); | ||
152 | } | 125 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 6d1a21611818..c4fa35d1dd77 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -1,6 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/pci/pci-driver.c | 2 | * drivers/pci/pci-driver.c |
3 | * | 3 | * |
4 | * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com> | ||
5 | * (C) Copyright 2007 Novell Inc. | ||
6 | * | ||
7 | * Released under the GPL v2 only. | ||
8 | * | ||
4 | */ | 9 | */ |
5 | 10 | ||
6 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
@@ -96,17 +101,21 @@ pci_create_newid_file(struct pci_driver *drv) | |||
96 | { | 101 | { |
97 | int error = 0; | 102 | int error = 0; |
98 | if (drv->probe != NULL) | 103 | if (drv->probe != NULL) |
99 | error = sysfs_create_file(&drv->driver.kobj, | 104 | error = driver_create_file(&drv->driver, &driver_attr_new_id); |
100 | &driver_attr_new_id.attr); | ||
101 | return error; | 105 | return error; |
102 | } | 106 | } |
103 | 107 | ||
108 | static void pci_remove_newid_file(struct pci_driver *drv) | ||
109 | { | ||
110 | driver_remove_file(&drv->driver, &driver_attr_new_id); | ||
111 | } | ||
104 | #else /* !CONFIG_HOTPLUG */ | 112 | #else /* !CONFIG_HOTPLUG */ |
105 | static inline void pci_free_dynids(struct pci_driver *drv) {} | 113 | static inline void pci_free_dynids(struct pci_driver *drv) {} |
106 | static inline int pci_create_newid_file(struct pci_driver *drv) | 114 | static inline int pci_create_newid_file(struct pci_driver *drv) |
107 | { | 115 | { |
108 | return 0; | 116 | return 0; |
109 | } | 117 | } |
118 | static inline void pci_remove_newid_file(struct pci_driver *drv) {} | ||
110 | #endif | 119 | #endif |
111 | 120 | ||
112 | /** | 121 | /** |
@@ -352,50 +361,6 @@ static void pci_device_shutdown(struct device *dev) | |||
352 | drv->shutdown(pci_dev); | 361 | drv->shutdown(pci_dev); |
353 | } | 362 | } |
354 | 363 | ||
355 | #define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj) | ||
356 | #define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr) | ||
357 | |||
358 | static ssize_t | ||
359 | pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) | ||
360 | { | ||
361 | struct device_driver *driver = kobj_to_pci_driver(kobj); | ||
362 | struct driver_attribute *dattr = attr_to_driver_attribute(attr); | ||
363 | ssize_t ret; | ||
364 | |||
365 | if (!get_driver(driver)) | ||
366 | return -ENODEV; | ||
367 | |||
368 | ret = dattr->show ? dattr->show(driver, buf) : -EIO; | ||
369 | |||
370 | put_driver(driver); | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static ssize_t | ||
375 | pci_driver_attr_store(struct kobject * kobj, struct attribute *attr, | ||
376 | const char *buf, size_t count) | ||
377 | { | ||
378 | struct device_driver *driver = kobj_to_pci_driver(kobj); | ||
379 | struct driver_attribute *dattr = attr_to_driver_attribute(attr); | ||
380 | ssize_t ret; | ||
381 | |||
382 | if (!get_driver(driver)) | ||
383 | return -ENODEV; | ||
384 | |||
385 | ret = dattr->store ? dattr->store(driver, buf, count) : -EIO; | ||
386 | |||
387 | put_driver(driver); | ||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | static struct sysfs_ops pci_driver_sysfs_ops = { | ||
392 | .show = pci_driver_attr_show, | ||
393 | .store = pci_driver_attr_store, | ||
394 | }; | ||
395 | static struct kobj_type pci_driver_kobj_type = { | ||
396 | .sysfs_ops = &pci_driver_sysfs_ops, | ||
397 | }; | ||
398 | |||
399 | /** | 364 | /** |
400 | * __pci_register_driver - register a new pci driver | 365 | * __pci_register_driver - register a new pci driver |
401 | * @drv: the driver structure to register | 366 | * @drv: the driver structure to register |
@@ -417,7 +382,6 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, | |||
417 | drv->driver.bus = &pci_bus_type; | 382 | drv->driver.bus = &pci_bus_type; |
418 | drv->driver.owner = owner; | 383 | drv->driver.owner = owner; |
419 | drv->driver.mod_name = mod_name; | 384 | drv->driver.mod_name = mod_name; |
420 | drv->driver.kobj.ktype = &pci_driver_kobj_type; | ||
421 | 385 | ||
422 | spin_lock_init(&drv->dynids.lock); | 386 | spin_lock_init(&drv->dynids.lock); |
423 | INIT_LIST_HEAD(&drv->dynids.list); | 387 | INIT_LIST_HEAD(&drv->dynids.list); |
@@ -447,6 +411,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, | |||
447 | void | 411 | void |
448 | pci_unregister_driver(struct pci_driver *drv) | 412 | pci_unregister_driver(struct pci_driver *drv) |
449 | { | 413 | { |
414 | pci_remove_newid_file(drv); | ||
450 | driver_unregister(&drv->driver); | 415 | driver_unregister(&drv->driver); |
451 | pci_free_dynids(drv); | 416 | pci_free_dynids(drv); |
452 | } | 417 | } |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c5ca3134513a..5fd585293e79 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1210,16 +1210,19 @@ static void __init pci_sort_breadthfirst_klist(void) | |||
1210 | struct klist_node *n; | 1210 | struct klist_node *n; |
1211 | struct device *dev; | 1211 | struct device *dev; |
1212 | struct pci_dev *pdev; | 1212 | struct pci_dev *pdev; |
1213 | struct klist *device_klist; | ||
1213 | 1214 | ||
1214 | spin_lock(&pci_bus_type.klist_devices.k_lock); | 1215 | device_klist = bus_get_device_klist(&pci_bus_type); |
1215 | list_for_each_safe(pos, tmp, &pci_bus_type.klist_devices.k_list) { | 1216 | |
1217 | spin_lock(&device_klist->k_lock); | ||
1218 | list_for_each_safe(pos, tmp, &device_klist->k_list) { | ||
1216 | n = container_of(pos, struct klist_node, n_node); | 1219 | n = container_of(pos, struct klist_node, n_node); |
1217 | dev = container_of(n, struct device, knode_bus); | 1220 | dev = container_of(n, struct device, knode_bus); |
1218 | pdev = to_pci_dev(dev); | 1221 | pdev = to_pci_dev(dev); |
1219 | pci_insertion_sort_klist(pdev, &sorted_devices); | 1222 | pci_insertion_sort_klist(pdev, &sorted_devices); |
1220 | } | 1223 | } |
1221 | list_splice(&sorted_devices, &pci_bus_type.klist_devices.k_list); | 1224 | list_splice(&sorted_devices, &device_klist->k_list); |
1222 | spin_unlock(&pci_bus_type.klist_devices.k_lock); | 1225 | spin_unlock(&device_klist->k_lock); |
1223 | } | 1226 | } |
1224 | 1227 | ||
1225 | static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list) | 1228 | static void __init pci_insertion_sort_devices(struct pci_dev *a, struct list_head *list) |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 5cf89a91da1e..15c18f5246d6 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -312,8 +312,7 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) | |||
312 | { | 312 | { |
313 | int error = 0; | 313 | int error = 0; |
314 | if (drv->probe != NULL) | 314 | if (drv->probe != NULL) |
315 | error = sysfs_create_file(&drv->drv.kobj, | 315 | error = driver_create_file(&drv->drv, &driver_attr_new_id); |
316 | &driver_attr_new_id.attr); | ||
317 | return error; | 316 | return error; |
318 | } | 317 | } |
319 | 318 | ||
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c index bbf3ee10da04..7e29b90a4f63 100644 --- a/drivers/power/apm_power.c +++ b/drivers/power/apm_power.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/power_supply.h> | 13 | #include <linux/power_supply.h> |
14 | #include <linux/apm-emulation.h> | 14 | #include <linux/apm-emulation.h> |
15 | 15 | ||
16 | static DEFINE_MUTEX(apm_mutex); | ||
16 | #define PSY_PROP(psy, prop, val) psy->get_property(psy, \ | 17 | #define PSY_PROP(psy, prop, val) psy->get_property(psy, \ |
17 | POWER_SUPPLY_PROP_##prop, val) | 18 | POWER_SUPPLY_PROP_##prop, val) |
18 | 19 | ||
@@ -23,67 +24,86 @@ | |||
23 | 24 | ||
24 | static struct power_supply *main_battery; | 25 | static struct power_supply *main_battery; |
25 | 26 | ||
26 | static void find_main_battery(void) | 27 | struct find_bat_param { |
27 | { | 28 | struct power_supply *main; |
28 | struct device *dev; | 29 | struct power_supply *bat; |
29 | struct power_supply *bat = NULL; | 30 | struct power_supply *max_charge_bat; |
30 | struct power_supply *max_charge_bat = NULL; | 31 | struct power_supply *max_energy_bat; |
31 | struct power_supply *max_energy_bat = NULL; | ||
32 | union power_supply_propval full; | 32 | union power_supply_propval full; |
33 | int max_charge = 0; | 33 | int max_charge; |
34 | int max_energy = 0; | 34 | int max_energy; |
35 | }; | ||
35 | 36 | ||
36 | main_battery = NULL; | 37 | static int __find_main_battery(struct device *dev, void *data) |
38 | { | ||
39 | struct find_bat_param *bp = (struct find_bat_param *)data; | ||
37 | 40 | ||
38 | list_for_each_entry(dev, &power_supply_class->devices, node) { | 41 | bp->bat = dev_get_drvdata(dev); |
39 | bat = dev_get_drvdata(dev); | ||
40 | 42 | ||
41 | if (bat->use_for_apm) { | 43 | if (bp->bat->use_for_apm) { |
42 | /* nice, we explicitly asked to report this battery. */ | 44 | /* nice, we explicitly asked to report this battery. */ |
43 | main_battery = bat; | 45 | bp->main = bp->bat; |
44 | return; | 46 | return 1; |
45 | } | 47 | } |
46 | 48 | ||
47 | if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full) || | 49 | if (!PSY_PROP(bp->bat, CHARGE_FULL_DESIGN, &bp->full) || |
48 | !PSY_PROP(bat, CHARGE_FULL, &full)) { | 50 | !PSY_PROP(bp->bat, CHARGE_FULL, &bp->full)) { |
49 | if (full.intval > max_charge) { | 51 | if (bp->full.intval > bp->max_charge) { |
50 | max_charge_bat = bat; | 52 | bp->max_charge_bat = bp->bat; |
51 | max_charge = full.intval; | 53 | bp->max_charge = bp->full.intval; |
52 | } | 54 | } |
53 | } else if (!PSY_PROP(bat, ENERGY_FULL_DESIGN, &full) || | 55 | } else if (!PSY_PROP(bp->bat, ENERGY_FULL_DESIGN, &bp->full) || |
54 | !PSY_PROP(bat, ENERGY_FULL, &full)) { | 56 | !PSY_PROP(bp->bat, ENERGY_FULL, &bp->full)) { |
55 | if (full.intval > max_energy) { | 57 | if (bp->full.intval > bp->max_energy) { |
56 | max_energy_bat = bat; | 58 | bp->max_energy_bat = bp->bat; |
57 | max_energy = full.intval; | 59 | bp->max_energy = bp->full.intval; |
58 | } | ||
59 | } | 60 | } |
60 | } | 61 | } |
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static void find_main_battery(void) | ||
66 | { | ||
67 | struct find_bat_param bp; | ||
68 | int error; | ||
69 | |||
70 | memset(&bp, 0, sizeof(struct find_bat_param)); | ||
71 | main_battery = NULL; | ||
72 | bp.main = main_battery; | ||
73 | |||
74 | error = class_for_each_device(power_supply_class, &bp, | ||
75 | __find_main_battery); | ||
76 | if (error) { | ||
77 | main_battery = bp.main; | ||
78 | return; | ||
79 | } | ||
61 | 80 | ||
62 | if ((max_energy_bat && max_charge_bat) && | 81 | if ((bp.max_energy_bat && bp.max_charge_bat) && |
63 | (max_energy_bat != max_charge_bat)) { | 82 | (bp.max_energy_bat != bp.max_charge_bat)) { |
64 | /* try guess battery with more capacity */ | 83 | /* try guess battery with more capacity */ |
65 | if (!PSY_PROP(max_charge_bat, VOLTAGE_MAX_DESIGN, &full)) { | 84 | if (!PSY_PROP(bp.max_charge_bat, VOLTAGE_MAX_DESIGN, |
66 | if (max_energy > max_charge * full.intval) | 85 | &bp.full)) { |
67 | main_battery = max_energy_bat; | 86 | if (bp.max_energy > bp.max_charge * bp.full.intval) |
87 | main_battery = bp.max_energy_bat; | ||
68 | else | 88 | else |
69 | main_battery = max_charge_bat; | 89 | main_battery = bp.max_charge_bat; |
70 | } else if (!PSY_PROP(max_energy_bat, VOLTAGE_MAX_DESIGN, | 90 | } else if (!PSY_PROP(bp.max_energy_bat, VOLTAGE_MAX_DESIGN, |
71 | &full)) { | 91 | &bp.full)) { |
72 | if (max_charge > max_energy / full.intval) | 92 | if (bp.max_charge > bp.max_energy / bp.full.intval) |
73 | main_battery = max_charge_bat; | 93 | main_battery = bp.max_charge_bat; |
74 | else | 94 | else |
75 | main_battery = max_energy_bat; | 95 | main_battery = bp.max_energy_bat; |
76 | } else { | 96 | } else { |
77 | /* give up, choice any */ | 97 | /* give up, choice any */ |
78 | main_battery = max_energy_bat; | 98 | main_battery = bp.max_energy_bat; |
79 | } | 99 | } |
80 | } else if (max_charge_bat) { | 100 | } else if (bp.max_charge_bat) { |
81 | main_battery = max_charge_bat; | 101 | main_battery = bp.max_charge_bat; |
82 | } else if (max_energy_bat) { | 102 | } else if (bp.max_energy_bat) { |
83 | main_battery = max_energy_bat; | 103 | main_battery = bp.max_energy_bat; |
84 | } else { | 104 | } else { |
85 | /* give up, try the last if any */ | 105 | /* give up, try the last if any */ |
86 | main_battery = bat; | 106 | main_battery = bp.bat; |
87 | } | 107 | } |
88 | } | 108 | } |
89 | 109 | ||
@@ -207,10 +227,10 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info) | |||
207 | union power_supply_propval status; | 227 | union power_supply_propval status; |
208 | union power_supply_propval capacity, time_to_full, time_to_empty; | 228 | union power_supply_propval capacity, time_to_full, time_to_empty; |
209 | 229 | ||
210 | down(&power_supply_class->sem); | 230 | mutex_lock(&apm_mutex); |
211 | find_main_battery(); | 231 | find_main_battery(); |
212 | if (!main_battery) { | 232 | if (!main_battery) { |
213 | up(&power_supply_class->sem); | 233 | mutex_unlock(&apm_mutex); |
214 | return; | 234 | return; |
215 | } | 235 | } |
216 | 236 | ||
@@ -278,7 +298,7 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info) | |||
278 | } | 298 | } |
279 | } | 299 | } |
280 | 300 | ||
281 | up(&power_supply_class->sem); | 301 | mutex_unlock(&apm_mutex); |
282 | } | 302 | } |
283 | 303 | ||
284 | static int __init apm_battery_init(void) | 304 | static int __init apm_battery_init(void) |
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index a63b75cf75e2..03d6a38464ef 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
@@ -20,28 +20,29 @@ | |||
20 | 20 | ||
21 | struct class *power_supply_class; | 21 | struct class *power_supply_class; |
22 | 22 | ||
23 | static int __power_supply_changed_work(struct device *dev, void *data) | ||
24 | { | ||
25 | struct power_supply *psy = (struct power_supply *)data; | ||
26 | struct power_supply *pst = dev_get_drvdata(dev); | ||
27 | int i; | ||
28 | |||
29 | for (i = 0; i < psy->num_supplicants; i++) | ||
30 | if (!strcmp(psy->supplied_to[i], pst->name)) { | ||
31 | if (pst->external_power_changed) | ||
32 | pst->external_power_changed(pst); | ||
33 | } | ||
34 | return 0; | ||
35 | } | ||
36 | |||
23 | static void power_supply_changed_work(struct work_struct *work) | 37 | static void power_supply_changed_work(struct work_struct *work) |
24 | { | 38 | { |
25 | struct power_supply *psy = container_of(work, struct power_supply, | 39 | struct power_supply *psy = container_of(work, struct power_supply, |
26 | changed_work); | 40 | changed_work); |
27 | int i; | ||
28 | 41 | ||
29 | dev_dbg(psy->dev, "%s\n", __FUNCTION__); | 42 | dev_dbg(psy->dev, "%s\n", __FUNCTION__); |
30 | 43 | ||
31 | for (i = 0; i < psy->num_supplicants; i++) { | 44 | class_for_each_device(power_supply_class, psy, |
32 | struct device *dev; | 45 | __power_supply_changed_work); |
33 | |||
34 | down(&power_supply_class->sem); | ||
35 | list_for_each_entry(dev, &power_supply_class->devices, node) { | ||
36 | struct power_supply *pst = dev_get_drvdata(dev); | ||
37 | |||
38 | if (!strcmp(psy->supplied_to[i], pst->name)) { | ||
39 | if (pst->external_power_changed) | ||
40 | pst->external_power_changed(pst); | ||
41 | } | ||
42 | } | ||
43 | up(&power_supply_class->sem); | ||
44 | } | ||
45 | 46 | ||
46 | power_supply_update_leds(psy); | 47 | power_supply_update_leds(psy); |
47 | 48 | ||
@@ -55,32 +56,35 @@ void power_supply_changed(struct power_supply *psy) | |||
55 | schedule_work(&psy->changed_work); | 56 | schedule_work(&psy->changed_work); |
56 | } | 57 | } |
57 | 58 | ||
58 | int power_supply_am_i_supplied(struct power_supply *psy) | 59 | static int __power_supply_am_i_supplied(struct device *dev, void *data) |
59 | { | 60 | { |
60 | union power_supply_propval ret = {0,}; | 61 | union power_supply_propval ret = {0,}; |
61 | struct device *dev; | 62 | struct power_supply *psy = (struct power_supply *)data; |
62 | 63 | struct power_supply *epsy = dev_get_drvdata(dev); | |
63 | down(&power_supply_class->sem); | 64 | int i; |
64 | list_for_each_entry(dev, &power_supply_class->devices, node) { | 65 | |
65 | struct power_supply *epsy = dev_get_drvdata(dev); | 66 | for (i = 0; i < epsy->num_supplicants; i++) { |
66 | int i; | 67 | if (!strcmp(epsy->supplied_to[i], psy->name)) { |
67 | 68 | if (epsy->get_property(epsy, | |
68 | for (i = 0; i < epsy->num_supplicants; i++) { | 69 | POWER_SUPPLY_PROP_ONLINE, &ret)) |
69 | if (!strcmp(epsy->supplied_to[i], psy->name)) { | 70 | continue; |
70 | if (epsy->get_property(epsy, | 71 | if (ret.intval) |
71 | POWER_SUPPLY_PROP_ONLINE, &ret)) | 72 | return ret.intval; |
72 | continue; | ||
73 | if (ret.intval) | ||
74 | goto out; | ||
75 | } | ||
76 | } | 73 | } |
77 | } | 74 | } |
78 | out: | 75 | return 0; |
79 | up(&power_supply_class->sem); | 76 | } |
77 | |||
78 | int power_supply_am_i_supplied(struct power_supply *psy) | ||
79 | { | ||
80 | int error; | ||
81 | |||
82 | error = class_for_each_device(power_supply_class, psy, | ||
83 | __power_supply_am_i_supplied); | ||
80 | 84 | ||
81 | dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, ret.intval); | 85 | dev_dbg(psy->dev, "%s %d\n", __FUNCTION__, error); |
82 | 86 | ||
83 | return ret.intval; | 87 | return error; |
84 | } | 88 | } |
85 | 89 | ||
86 | int power_supply_register(struct device *parent, struct power_supply *psy) | 90 | int power_supply_register(struct device *parent, struct power_supply *psy) |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index f1e00ff54ce8..7e3ad4f3b343 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -251,20 +251,23 @@ void rtc_update_irq(struct rtc_device *rtc, | |||
251 | } | 251 | } |
252 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 252 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
253 | 253 | ||
254 | static int __rtc_match(struct device *dev, void *data) | ||
255 | { | ||
256 | char *name = (char *)data; | ||
257 | |||
258 | if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) | ||
259 | return 1; | ||
260 | return 0; | ||
261 | } | ||
262 | |||
254 | struct rtc_device *rtc_class_open(char *name) | 263 | struct rtc_device *rtc_class_open(char *name) |
255 | { | 264 | { |
256 | struct device *dev; | 265 | struct device *dev; |
257 | struct rtc_device *rtc = NULL; | 266 | struct rtc_device *rtc = NULL; |
258 | 267 | ||
259 | down(&rtc_class->sem); | 268 | dev = class_find_device(rtc_class, name, __rtc_match); |
260 | list_for_each_entry(dev, &rtc_class->devices, node) { | 269 | if (dev) |
261 | if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) { | 270 | rtc = to_rtc_device(dev); |
262 | dev = get_device(dev); | ||
263 | if (dev) | ||
264 | rtc = to_rtc_device(dev); | ||
265 | break; | ||
266 | } | ||
267 | } | ||
268 | 271 | ||
269 | if (rtc) { | 272 | if (rtc) { |
270 | if (!try_module_get(rtc->owner)) { | 273 | if (!try_module_get(rtc->owner)) { |
@@ -272,7 +275,6 @@ struct rtc_device *rtc_class_open(char *name) | |||
272 | rtc = NULL; | 275 | rtc = NULL; |
273 | } | 276 | } |
274 | } | 277 | } |
275 | up(&rtc_class->sem); | ||
276 | 278 | ||
277 | return rtc; | 279 | return rtc; |
278 | } | 280 | } |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index c7ea9381db9f..d6e93f15440e 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -2089,6 +2089,11 @@ static struct attribute_group netiucv_drv_attr_group = { | |||
2089 | .attrs = netiucv_drv_attrs, | 2089 | .attrs = netiucv_drv_attrs, |
2090 | }; | 2090 | }; |
2091 | 2091 | ||
2092 | static struct attribute_group *netiucv_drv_attr_groups[] = { | ||
2093 | &netiucv_drv_attr_group, | ||
2094 | NULL, | ||
2095 | }; | ||
2096 | |||
2092 | static void netiucv_banner(void) | 2097 | static void netiucv_banner(void) |
2093 | { | 2098 | { |
2094 | PRINT_INFO("NETIUCV driver initialized\n"); | 2099 | PRINT_INFO("NETIUCV driver initialized\n"); |
@@ -2113,7 +2118,6 @@ static void __exit netiucv_exit(void) | |||
2113 | netiucv_unregister_device(dev); | 2118 | netiucv_unregister_device(dev); |
2114 | } | 2119 | } |
2115 | 2120 | ||
2116 | sysfs_remove_group(&netiucv_driver.kobj, &netiucv_drv_attr_group); | ||
2117 | driver_unregister(&netiucv_driver); | 2121 | driver_unregister(&netiucv_driver); |
2118 | iucv_unregister(&netiucv_handler, 1); | 2122 | iucv_unregister(&netiucv_handler, 1); |
2119 | iucv_unregister_dbf_views(); | 2123 | iucv_unregister_dbf_views(); |
@@ -2133,6 +2137,7 @@ static int __init netiucv_init(void) | |||
2133 | if (rc) | 2137 | if (rc) |
2134 | goto out_dbf; | 2138 | goto out_dbf; |
2135 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); | 2139 | IUCV_DBF_TEXT(trace, 3, __FUNCTION__); |
2140 | netiucv_driver.groups = netiucv_drv_attr_groups; | ||
2136 | rc = driver_register(&netiucv_driver); | 2141 | rc = driver_register(&netiucv_driver); |
2137 | if (rc) { | 2142 | if (rc) { |
2138 | PRINT_ERR("NETIUCV: failed to register driver.\n"); | 2143 | PRINT_ERR("NETIUCV: failed to register driver.\n"); |
@@ -2140,18 +2145,9 @@ static int __init netiucv_init(void) | |||
2140 | goto out_iucv; | 2145 | goto out_iucv; |
2141 | } | 2146 | } |
2142 | 2147 | ||
2143 | rc = sysfs_create_group(&netiucv_driver.kobj, &netiucv_drv_attr_group); | ||
2144 | if (rc) { | ||
2145 | PRINT_ERR("NETIUCV: failed to add driver attributes.\n"); | ||
2146 | IUCV_DBF_TEXT_(setup, 2, | ||
2147 | "ret %d - netiucv_drv_attr_group\n", rc); | ||
2148 | goto out_driver; | ||
2149 | } | ||
2150 | netiucv_banner(); | 2148 | netiucv_banner(); |
2151 | return rc; | 2149 | return rc; |
2152 | 2150 | ||
2153 | out_driver: | ||
2154 | driver_unregister(&netiucv_driver); | ||
2155 | out_iucv: | 2151 | out_iucv: |
2156 | iucv_unregister(&netiucv_handler, 1); | 2152 | iucv_unregister(&netiucv_handler, 1); |
2157 | out_dbf: | 2153 | out_dbf: |
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index e01cbf152a81..86c3f6539a7d 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -52,6 +52,9 @@ static struct ccw_driver zfcp_ccw_driver = { | |||
52 | .set_offline = zfcp_ccw_set_offline, | 52 | .set_offline = zfcp_ccw_set_offline, |
53 | .notify = zfcp_ccw_notify, | 53 | .notify = zfcp_ccw_notify, |
54 | .shutdown = zfcp_ccw_shutdown, | 54 | .shutdown = zfcp_ccw_shutdown, |
55 | .driver = { | ||
56 | .groups = zfcp_driver_attr_groups, | ||
57 | }, | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); | 60 | MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); |
@@ -251,16 +254,7 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event) | |||
251 | int __init | 254 | int __init |
252 | zfcp_ccw_register(void) | 255 | zfcp_ccw_register(void) |
253 | { | 256 | { |
254 | int retval; | 257 | return ccw_driver_register(&zfcp_ccw_driver); |
255 | |||
256 | retval = ccw_driver_register(&zfcp_ccw_driver); | ||
257 | if (retval) | ||
258 | goto out; | ||
259 | retval = zfcp_sysfs_driver_create_files(&zfcp_ccw_driver.driver); | ||
260 | if (retval) | ||
261 | ccw_driver_unregister(&zfcp_ccw_driver); | ||
262 | out: | ||
263 | return retval; | ||
264 | } | 258 | } |
265 | 259 | ||
266 | /** | 260 | /** |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 8534cf09546c..06b1079b7f3d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -27,8 +27,7 @@ | |||
27 | extern struct zfcp_data zfcp_data; | 27 | extern struct zfcp_data zfcp_data; |
28 | 28 | ||
29 | /******************************** SYSFS *************************************/ | 29 | /******************************** SYSFS *************************************/ |
30 | extern int zfcp_sysfs_driver_create_files(struct device_driver *); | 30 | extern struct attribute_group *zfcp_driver_attr_groups[]; |
31 | extern void zfcp_sysfs_driver_remove_files(struct device_driver *); | ||
32 | extern int zfcp_sysfs_adapter_create_files(struct device *); | 31 | extern int zfcp_sysfs_adapter_create_files(struct device *); |
33 | extern void zfcp_sysfs_adapter_remove_files(struct device *); | 32 | extern void zfcp_sysfs_adapter_remove_files(struct device *); |
34 | extern int zfcp_sysfs_port_create_files(struct device *, u32); | 33 | extern int zfcp_sysfs_port_create_files(struct device *, u32); |
diff --git a/drivers/s390/scsi/zfcp_sysfs_driver.c b/drivers/s390/scsi/zfcp_sysfs_driver.c index 005e62f8593b..651edd58906a 100644 --- a/drivers/s390/scsi/zfcp_sysfs_driver.c +++ b/drivers/s390/scsi/zfcp_sysfs_driver.c | |||
@@ -98,28 +98,9 @@ static struct attribute_group zfcp_driver_attr_group = { | |||
98 | .attrs = zfcp_driver_attrs, | 98 | .attrs = zfcp_driver_attrs, |
99 | }; | 99 | }; |
100 | 100 | ||
101 | /** | 101 | struct attribute_group *zfcp_driver_attr_groups[] = { |
102 | * zfcp_sysfs_create_driver_files - create sysfs driver files | 102 | &zfcp_driver_attr_group, |
103 | * @dev: pointer to belonging device | 103 | NULL, |
104 | * | 104 | }; |
105 | * Create all sysfs attributes of the zfcp device driver | ||
106 | */ | ||
107 | int | ||
108 | zfcp_sysfs_driver_create_files(struct device_driver *drv) | ||
109 | { | ||
110 | return sysfs_create_group(&drv->kobj, &zfcp_driver_attr_group); | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * zfcp_sysfs_remove_driver_files - remove sysfs driver files | ||
115 | * @dev: pointer to belonging device | ||
116 | * | ||
117 | * Remove all sysfs attributes of the zfcp device driver | ||
118 | */ | ||
119 | void | ||
120 | zfcp_sysfs_driver_remove_files(struct device_driver *drv) | ||
121 | { | ||
122 | sysfs_remove_group(&drv->kobj, &zfcp_driver_attr_group); | ||
123 | } | ||
124 | 105 | ||
125 | #undef ZFCP_LOG_AREA | 106 | #undef ZFCP_LOG_AREA |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 24271a871b8c..6325115e5b3d 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -429,6 +429,15 @@ void scsi_unregister(struct Scsi_Host *shost) | |||
429 | } | 429 | } |
430 | EXPORT_SYMBOL(scsi_unregister); | 430 | EXPORT_SYMBOL(scsi_unregister); |
431 | 431 | ||
432 | static int __scsi_host_match(struct class_device *cdev, void *data) | ||
433 | { | ||
434 | struct Scsi_Host *p; | ||
435 | unsigned short *hostnum = (unsigned short *)data; | ||
436 | |||
437 | p = class_to_shost(cdev); | ||
438 | return p->host_no == *hostnum; | ||
439 | } | ||
440 | |||
432 | /** | 441 | /** |
433 | * scsi_host_lookup - get a reference to a Scsi_Host by host no | 442 | * scsi_host_lookup - get a reference to a Scsi_Host by host no |
434 | * | 443 | * |
@@ -439,19 +448,12 @@ EXPORT_SYMBOL(scsi_unregister); | |||
439 | **/ | 448 | **/ |
440 | struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) | 449 | struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) |
441 | { | 450 | { |
442 | struct class *class = &shost_class; | ||
443 | struct class_device *cdev; | 451 | struct class_device *cdev; |
444 | struct Scsi_Host *shost = ERR_PTR(-ENXIO), *p; | 452 | struct Scsi_Host *shost = ERR_PTR(-ENXIO); |
445 | 453 | ||
446 | down(&class->sem); | 454 | cdev = class_find_child(&shost_class, &hostnum, __scsi_host_match); |
447 | list_for_each_entry(cdev, &class->children, node) { | 455 | if (cdev) |
448 | p = class_to_shost(cdev); | 456 | shost = scsi_host_get(class_to_shost(cdev)); |
449 | if (p->host_no == hostnum) { | ||
450 | shost = scsi_host_get(p); | ||
451 | break; | ||
452 | } | ||
453 | } | ||
454 | up(&class->sem); | ||
455 | 457 | ||
456 | return shost; | 458 | return shost; |
457 | } | 459 | } |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 7663841eb4cf..a3fdc57e2673 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -464,7 +464,7 @@ int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd) | |||
464 | res = sas_phy_reset(phy, 1); | 464 | res = sas_phy_reset(phy, 1); |
465 | if (res) | 465 | if (res) |
466 | SAS_DPRINTK("Bus reset of %s failed 0x%x\n", | 466 | SAS_DPRINTK("Bus reset of %s failed 0x%x\n", |
467 | phy->dev.kobj.k_name, | 467 | kobject_name(&phy->dev.kobj), |
468 | res); | 468 | res); |
469 | if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE) | 469 | if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE) |
470 | return SUCCESS; | 470 | return SUCCESS; |
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 9d3105b64a7a..9c2df5c857cf 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include <linux/vmalloc.h> | 48 | #include <linux/vmalloc.h> |
49 | #include <linux/smp.h> | 49 | #include <linux/smp.h> |
50 | #include <linux/spinlock.h> | 50 | #include <linux/spinlock.h> |
51 | #include <linux/kobject.h> | 51 | #include <linux/kref.h> |
52 | #include <linux/firmware.h> | 52 | #include <linux/firmware.h> |
53 | #include <linux/bitops.h> | 53 | #include <linux/bitops.h> |
54 | 54 | ||
@@ -65,7 +65,7 @@ | |||
65 | #define ICOM_VERSION_STR "1.3.1" | 65 | #define ICOM_VERSION_STR "1.3.1" |
66 | #define NR_PORTS 128 | 66 | #define NR_PORTS 128 |
67 | #define ICOM_PORT ((struct icom_port *)port) | 67 | #define ICOM_PORT ((struct icom_port *)port) |
68 | #define to_icom_adapter(d) container_of(d, struct icom_adapter, kobj) | 68 | #define to_icom_adapter(d) container_of(d, struct icom_adapter, kref) |
69 | 69 | ||
70 | static const struct pci_device_id icom_pci_table[] = { | 70 | static const struct pci_device_id icom_pci_table[] = { |
71 | { | 71 | { |
@@ -141,6 +141,7 @@ static inline void trace(struct icom_port *, char *, unsigned long) {}; | |||
141 | #else | 141 | #else |
142 | static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {}; | 142 | static inline void trace(struct icom_port *icom_port, char *trace_pt, unsigned long trace_data) {}; |
143 | #endif | 143 | #endif |
144 | static void icom_kref_release(struct kref *kref); | ||
144 | 145 | ||
145 | static void free_port_memory(struct icom_port *icom_port) | 146 | static void free_port_memory(struct icom_port *icom_port) |
146 | { | 147 | { |
@@ -1063,11 +1064,11 @@ static int icom_open(struct uart_port *port) | |||
1063 | { | 1064 | { |
1064 | int retval; | 1065 | int retval; |
1065 | 1066 | ||
1066 | kobject_get(&ICOM_PORT->adapter->kobj); | 1067 | kref_get(&ICOM_PORT->adapter->kref); |
1067 | retval = startup(ICOM_PORT); | 1068 | retval = startup(ICOM_PORT); |
1068 | 1069 | ||
1069 | if (retval) { | 1070 | if (retval) { |
1070 | kobject_put(&ICOM_PORT->adapter->kobj); | 1071 | kref_put(&ICOM_PORT->adapter->kref, icom_kref_release); |
1071 | trace(ICOM_PORT, "STARTUP_ERROR", 0); | 1072 | trace(ICOM_PORT, "STARTUP_ERROR", 0); |
1072 | return retval; | 1073 | return retval; |
1073 | } | 1074 | } |
@@ -1088,7 +1089,7 @@ static void icom_close(struct uart_port *port) | |||
1088 | 1089 | ||
1089 | shutdown(ICOM_PORT); | 1090 | shutdown(ICOM_PORT); |
1090 | 1091 | ||
1091 | kobject_put(&ICOM_PORT->adapter->kobj); | 1092 | kref_put(&ICOM_PORT->adapter->kref, icom_kref_release); |
1092 | } | 1093 | } |
1093 | 1094 | ||
1094 | static void icom_set_termios(struct uart_port *port, | 1095 | static void icom_set_termios(struct uart_port *port, |
@@ -1485,18 +1486,14 @@ static void icom_remove_adapter(struct icom_adapter *icom_adapter) | |||
1485 | pci_release_regions(icom_adapter->pci_dev); | 1486 | pci_release_regions(icom_adapter->pci_dev); |
1486 | } | 1487 | } |
1487 | 1488 | ||
1488 | static void icom_kobj_release(struct kobject *kobj) | 1489 | static void icom_kref_release(struct kref *kref) |
1489 | { | 1490 | { |
1490 | struct icom_adapter *icom_adapter; | 1491 | struct icom_adapter *icom_adapter; |
1491 | 1492 | ||
1492 | icom_adapter = to_icom_adapter(kobj); | 1493 | icom_adapter = to_icom_adapter(kref); |
1493 | icom_remove_adapter(icom_adapter); | 1494 | icom_remove_adapter(icom_adapter); |
1494 | } | 1495 | } |
1495 | 1496 | ||
1496 | static struct kobj_type icom_kobj_type = { | ||
1497 | .release = icom_kobj_release, | ||
1498 | }; | ||
1499 | |||
1500 | static int __devinit icom_probe(struct pci_dev *dev, | 1497 | static int __devinit icom_probe(struct pci_dev *dev, |
1501 | const struct pci_device_id *ent) | 1498 | const struct pci_device_id *ent) |
1502 | { | 1499 | { |
@@ -1592,8 +1589,7 @@ static int __devinit icom_probe(struct pci_dev *dev, | |||
1592 | } | 1589 | } |
1593 | } | 1590 | } |
1594 | 1591 | ||
1595 | kobject_init(&icom_adapter->kobj); | 1592 | kref_init(&icom_adapter->kref); |
1596 | icom_adapter->kobj.ktype = &icom_kobj_type; | ||
1597 | return 0; | 1593 | return 0; |
1598 | 1594 | ||
1599 | probe_exit2: | 1595 | probe_exit2: |
@@ -1619,7 +1615,7 @@ static void __devexit icom_remove(struct pci_dev *dev) | |||
1619 | icom_adapter = list_entry(tmp, struct icom_adapter, | 1615 | icom_adapter = list_entry(tmp, struct icom_adapter, |
1620 | icom_adapter_entry); | 1616 | icom_adapter_entry); |
1621 | if (icom_adapter->pci_dev == dev) { | 1617 | if (icom_adapter->pci_dev == dev) { |
1622 | kobject_put(&icom_adapter->kobj); | 1618 | kref_put(&icom_adapter->kref, icom_kref_release); |
1623 | return; | 1619 | return; |
1624 | } | 1620 | } |
1625 | } | 1621 | } |
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h index e8578d8cd35e..027455496745 100644 --- a/drivers/serial/icom.h +++ b/drivers/serial/icom.h | |||
@@ -270,7 +270,7 @@ struct icom_adapter { | |||
270 | #define V2_ONE_PORT_RVX_ONE_PORT_IMBED_MDM 0x0251 | 270 | #define V2_ONE_PORT_RVX_ONE_PORT_IMBED_MDM 0x0251 |
271 | int numb_ports; | 271 | int numb_ports; |
272 | struct list_head icom_adapter_entry; | 272 | struct list_head icom_adapter_entry; |
273 | struct kobject kobj; | 273 | struct kref kref; |
274 | }; | 274 | }; |
275 | 275 | ||
276 | /* prototype */ | 276 | /* prototype */ |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 93e9de46977a..682a6a48fec3 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -485,6 +485,15 @@ void spi_unregister_master(struct spi_master *master) | |||
485 | } | 485 | } |
486 | EXPORT_SYMBOL_GPL(spi_unregister_master); | 486 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
487 | 487 | ||
488 | static int __spi_master_match(struct device *dev, void *data) | ||
489 | { | ||
490 | struct spi_master *m; | ||
491 | u16 *bus_num = data; | ||
492 | |||
493 | m = container_of(dev, struct spi_master, dev); | ||
494 | return m->bus_num == *bus_num; | ||
495 | } | ||
496 | |||
488 | /** | 497 | /** |
489 | * spi_busnum_to_master - look up master associated with bus_num | 498 | * spi_busnum_to_master - look up master associated with bus_num |
490 | * @bus_num: the master's bus number | 499 | * @bus_num: the master's bus number |
@@ -499,17 +508,12 @@ struct spi_master *spi_busnum_to_master(u16 bus_num) | |||
499 | { | 508 | { |
500 | struct device *dev; | 509 | struct device *dev; |
501 | struct spi_master *master = NULL; | 510 | struct spi_master *master = NULL; |
502 | struct spi_master *m; | 511 | |
503 | 512 | dev = class_find_device(&spi_master_class, &bus_num, | |
504 | down(&spi_master_class.sem); | 513 | __spi_master_match); |
505 | list_for_each_entry(dev, &spi_master_class.children, node) { | 514 | if (dev) |
506 | m = container_of(dev, struct spi_master, dev); | 515 | master = container_of(dev, struct spi_master, dev); |
507 | if (m->bus_num == bus_num) { | 516 | /* reference got in class_find_device */ |
508 | master = spi_master_get(m); | ||
509 | break; | ||
510 | } | ||
511 | } | ||
512 | up(&spi_master_class.sem); | ||
513 | return master; | 517 | return master; |
514 | } | 518 | } |
515 | EXPORT_SYMBOL_GPL(spi_busnum_to_master); | 519 | EXPORT_SYMBOL_GPL(spi_busnum_to_master); |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 865f32b63b5c..cc246faa3590 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -34,12 +34,12 @@ struct uio_device { | |||
34 | wait_queue_head_t wait; | 34 | wait_queue_head_t wait; |
35 | int vma_count; | 35 | int vma_count; |
36 | struct uio_info *info; | 36 | struct uio_info *info; |
37 | struct kset map_attr_kset; | 37 | struct kobject *map_dir; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static int uio_major; | 40 | static int uio_major; |
41 | static DEFINE_IDR(uio_idr); | 41 | static DEFINE_IDR(uio_idr); |
42 | static struct file_operations uio_fops; | 42 | static const struct file_operations uio_fops; |
43 | 43 | ||
44 | /* UIO class infrastructure */ | 44 | /* UIO class infrastructure */ |
45 | static struct uio_class { | 45 | static struct uio_class { |
@@ -51,47 +51,48 @@ static struct uio_class { | |||
51 | * attributes | 51 | * attributes |
52 | */ | 52 | */ |
53 | 53 | ||
54 | static struct attribute attr_addr = { | 54 | struct uio_map { |
55 | .name = "addr", | 55 | struct kobject kobj; |
56 | .mode = S_IRUGO, | 56 | struct uio_mem *mem; |
57 | }; | 57 | }; |
58 | #define to_map(map) container_of(map, struct uio_map, kobj) | ||
58 | 59 | ||
59 | static struct attribute attr_size = { | ||
60 | .name = "size", | ||
61 | .mode = S_IRUGO, | ||
62 | }; | ||
63 | 60 | ||
64 | static struct attribute* map_attrs[] = { | 61 | static ssize_t map_attr_show(struct kobject *kobj, struct kobj_attribute *attr, |
65 | &attr_addr, &attr_size, NULL | ||
66 | }; | ||
67 | |||
68 | static ssize_t map_attr_show(struct kobject *kobj, struct attribute *attr, | ||
69 | char *buf) | 62 | char *buf) |
70 | { | 63 | { |
71 | struct uio_mem *mem = container_of(kobj, struct uio_mem, kobj); | 64 | struct uio_map *map = to_map(kobj); |
65 | struct uio_mem *mem = map->mem; | ||
72 | 66 | ||
73 | if (strncmp(attr->name,"addr",4) == 0) | 67 | if (strncmp(attr->attr.name, "addr", 4) == 0) |
74 | return sprintf(buf, "0x%lx\n", mem->addr); | 68 | return sprintf(buf, "0x%lx\n", mem->addr); |
75 | 69 | ||
76 | if (strncmp(attr->name,"size",4) == 0) | 70 | if (strncmp(attr->attr.name, "size", 4) == 0) |
77 | return sprintf(buf, "0x%lx\n", mem->size); | 71 | return sprintf(buf, "0x%lx\n", mem->size); |
78 | 72 | ||
79 | return -ENODEV; | 73 | return -ENODEV; |
80 | } | 74 | } |
81 | 75 | ||
82 | static void map_attr_release(struct kobject *kobj) | 76 | static struct kobj_attribute attr_attribute = |
83 | { | 77 | __ATTR(addr, S_IRUGO, map_attr_show, NULL); |
84 | /* TODO ??? */ | 78 | static struct kobj_attribute size_attribute = |
85 | } | 79 | __ATTR(size, S_IRUGO, map_attr_show, NULL); |
86 | 80 | ||
87 | static struct sysfs_ops map_attr_ops = { | 81 | static struct attribute *attrs[] = { |
88 | .show = map_attr_show, | 82 | &attr_attribute.attr, |
83 | &size_attribute.attr, | ||
84 | NULL, /* need to NULL terminate the list of attributes */ | ||
89 | }; | 85 | }; |
90 | 86 | ||
87 | static void map_release(struct kobject *kobj) | ||
88 | { | ||
89 | struct uio_map *map = to_map(kobj); | ||
90 | kfree(map); | ||
91 | } | ||
92 | |||
91 | static struct kobj_type map_attr_type = { | 93 | static struct kobj_type map_attr_type = { |
92 | .release = map_attr_release, | 94 | .release = map_release, |
93 | .sysfs_ops = &map_attr_ops, | 95 | .default_attrs = attrs, |
94 | .default_attrs = map_attrs, | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | static ssize_t show_name(struct device *dev, | 98 | static ssize_t show_name(struct device *dev, |
@@ -148,6 +149,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) | |||
148 | int mi; | 149 | int mi; |
149 | int map_found = 0; | 150 | int map_found = 0; |
150 | struct uio_mem *mem; | 151 | struct uio_mem *mem; |
152 | struct uio_map *map; | ||
151 | 153 | ||
152 | ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp); | 154 | ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp); |
153 | if (ret) | 155 | if (ret) |
@@ -159,31 +161,34 @@ static int uio_dev_add_attributes(struct uio_device *idev) | |||
159 | break; | 161 | break; |
160 | if (!map_found) { | 162 | if (!map_found) { |
161 | map_found = 1; | 163 | map_found = 1; |
162 | kobject_set_name(&idev->map_attr_kset.kobj,"maps"); | 164 | idev->map_dir = kobject_create_and_add("maps", |
163 | idev->map_attr_kset.ktype = &map_attr_type; | 165 | &idev->dev->kobj); |
164 | idev->map_attr_kset.kobj.parent = &idev->dev->kobj; | 166 | if (!idev->map_dir) |
165 | ret = kset_register(&idev->map_attr_kset); | 167 | goto err; |
166 | if (ret) | ||
167 | goto err_remove_group; | ||
168 | } | 168 | } |
169 | kobject_init(&mem->kobj); | 169 | map = kzalloc(sizeof(*map), GFP_KERNEL); |
170 | kobject_set_name(&mem->kobj,"map%d",mi); | 170 | if (!map) |
171 | mem->kobj.parent = &idev->map_attr_kset.kobj; | 171 | goto err; |
172 | mem->kobj.kset = &idev->map_attr_kset; | 172 | kobject_init(&map->kobj, &map_attr_type); |
173 | ret = kobject_add(&mem->kobj); | 173 | map->mem = mem; |
174 | mem->map = map; | ||
175 | ret = kobject_add(&map->kobj, idev->map_dir, "map%d", mi); | ||
176 | if (ret) | ||
177 | goto err; | ||
178 | ret = kobject_uevent(&map->kobj, KOBJ_ADD); | ||
174 | if (ret) | 179 | if (ret) |
175 | goto err_remove_maps; | 180 | goto err; |
176 | } | 181 | } |
177 | 182 | ||
178 | return 0; | 183 | return 0; |
179 | 184 | ||
180 | err_remove_maps: | 185 | err: |
181 | for (mi--; mi>=0; mi--) { | 186 | for (mi--; mi>=0; mi--) { |
182 | mem = &idev->info->mem[mi]; | 187 | mem = &idev->info->mem[mi]; |
183 | kobject_unregister(&mem->kobj); | 188 | map = mem->map; |
189 | kobject_put(&map->kobj); | ||
184 | } | 190 | } |
185 | kset_unregister(&idev->map_attr_kset); /* Needed ? */ | 191 | kobject_put(idev->map_dir); |
186 | err_remove_group: | ||
187 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); | 192 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); |
188 | err_group: | 193 | err_group: |
189 | dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); | 194 | dev_err(idev->dev, "error creating sysfs files (%d)\n", ret); |
@@ -198,9 +203,9 @@ static void uio_dev_del_attributes(struct uio_device *idev) | |||
198 | mem = &idev->info->mem[mi]; | 203 | mem = &idev->info->mem[mi]; |
199 | if (mem->size == 0) | 204 | if (mem->size == 0) |
200 | break; | 205 | break; |
201 | kobject_unregister(&mem->kobj); | 206 | kobject_put(&mem->map->kobj); |
202 | } | 207 | } |
203 | kset_unregister(&idev->map_attr_kset); | 208 | kobject_put(idev->map_dir); |
204 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); | 209 | sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp); |
205 | } | 210 | } |
206 | 211 | ||
@@ -503,7 +508,7 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma) | |||
503 | } | 508 | } |
504 | } | 509 | } |
505 | 510 | ||
506 | static struct file_operations uio_fops = { | 511 | static const struct file_operations uio_fops = { |
507 | .owner = THIS_MODULE, | 512 | .owner = THIS_MODULE, |
508 | .open = uio_open, | 513 | .open = uio_open, |
509 | .release = uio_release, | 514 | .release = uio_release, |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c51f8e9312e0..7c3aaa9c5402 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -91,8 +91,8 @@ static int usb_create_newid_file(struct usb_driver *usb_drv) | |||
91 | goto exit; | 91 | goto exit; |
92 | 92 | ||
93 | if (usb_drv->probe != NULL) | 93 | if (usb_drv->probe != NULL) |
94 | error = sysfs_create_file(&usb_drv->drvwrap.driver.kobj, | 94 | error = driver_create_file(&usb_drv->drvwrap.driver, |
95 | &driver_attr_new_id.attr); | 95 | &driver_attr_new_id); |
96 | exit: | 96 | exit: |
97 | return error; | 97 | return error; |
98 | } | 98 | } |
@@ -103,8 +103,8 @@ static void usb_remove_newid_file(struct usb_driver *usb_drv) | |||
103 | return; | 103 | return; |
104 | 104 | ||
105 | if (usb_drv->probe != NULL) | 105 | if (usb_drv->probe != NULL) |
106 | sysfs_remove_file(&usb_drv->drvwrap.driver.kobj, | 106 | driver_remove_file(&usb_drv->drvwrap.driver, |
107 | &driver_attr_new_id.attr); | 107 | &driver_attr_new_id); |
108 | } | 108 | } |
109 | 109 | ||
110 | static void usb_free_dynids(struct usb_driver *usb_drv) | 110 | static void usb_free_dynids(struct usb_driver *usb_drv) |