diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-17 16:53:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-17 16:53:16 -0400 |
commit | 74a205a3f1a07cf0b72bf7816d75735a0d9c4c6b (patch) | |
tree | d977fe81c74a0728130c7e212f2c27eef8146e91 | |
parent | dd26bf6d95f050c42cc8f15e750b09851e1fd30b (diff) | |
parent | 912335c43bb10d124471bf063a85e132aa814214 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6:
UIO: fix specific device driver missing statement for depmod
Driver core: remove pr_fmt() from dynamic_dev_dbg() printk
driver core: prevent device_for_each_child from oopsing
dynamic debug: resurrect old pr_debug() semantics as pr_devel()
Driver Core: early platform driver
proc: mounts_poll() make consistent to mdstat_poll
sysfs: sysfs poll keep the poll rule of regular file.
driver core: allow non-root users to listen to uevents
driver core: fix driver_match_device
sysfs: don't use global workqueue in sysfs_schedule_callback()
-rw-r--r-- | Documentation/driver-model/platform.txt | 59 | ||||
-rw-r--r-- | drivers/base/base.h | 2 | ||||
-rw-r--r-- | drivers/base/core.c | 3 | ||||
-rw-r--r-- | drivers/base/platform.c | 239 | ||||
-rw-r--r-- | drivers/uio/uio_cif.c | 1 | ||||
-rw-r--r-- | fs/proc/base.c | 4 | ||||
-rw-r--r-- | fs/sysfs/file.c | 16 | ||||
-rw-r--r-- | include/linux/dynamic_debug.h | 2 | ||||
-rw-r--r-- | include/linux/init.h | 1 | ||||
-rw-r--r-- | include/linux/kernel.h | 9 | ||||
-rw-r--r-- | include/linux/platform_device.h | 42 | ||||
-rw-r--r-- | init/main.c | 7 | ||||
-rw-r--r-- | lib/kobject_uevent.c | 2 |
13 files changed, 378 insertions, 9 deletions
diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt index 83009fdcbbc8..2e2c2ea90ceb 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.txt | |||
@@ -169,3 +169,62 @@ three different ways to find such a match: | |||
169 | be probed later if another device registers. (Which is OK, since | 169 | be probed later if another device registers. (Which is OK, since |
170 | this interface is only for use with non-hotpluggable devices.) | 170 | this interface is only for use with non-hotpluggable devices.) |
171 | 171 | ||
172 | |||
173 | Early Platform Devices and Drivers | ||
174 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
175 | The early platform interfaces provide platform data to platform device | ||
176 | drivers early on during the system boot. The code is built on top of the | ||
177 | early_param() command line parsing and can be executed very early on. | ||
178 | |||
179 | Example: "earlyprintk" class early serial console in 6 steps | ||
180 | |||
181 | 1. Registering early platform device data | ||
182 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
183 | The architecture code registers platform device data using the function | ||
184 | early_platform_add_devices(). In the case of early serial console this | ||
185 | should be hardware configuration for the serial port. Devices registered | ||
186 | at this point will later on be matched against early platform drivers. | ||
187 | |||
188 | 2. Parsing kernel command line | ||
189 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
190 | The architecture code calls parse_early_param() to parse the kernel | ||
191 | command line. This will execute all matching early_param() callbacks. | ||
192 | User specified early platform devices will be registered at this point. | ||
193 | For the early serial console case the user can specify port on the | ||
194 | kernel command line as "earlyprintk=serial.0" where "earlyprintk" is | ||
195 | the class string, "serial" is the name of the platfrom driver and | ||
196 | 0 is the platform device id. If the id is -1 then the dot and the | ||
197 | id can be omitted. | ||
198 | |||
199 | 3. Installing early platform drivers belonging to a certain class | ||
200 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
201 | The architecture code may optionally force registration of all early | ||
202 | platform drivers belonging to a certain class using the function | ||
203 | early_platform_driver_register_all(). User specified devices from | ||
204 | step 2 have priority over these. This step is omitted by the serial | ||
205 | driver example since the early serial driver code should be disabled | ||
206 | unless the user has specified port on the kernel command line. | ||
207 | |||
208 | 4. Early platform driver registration | ||
209 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
210 | Compiled-in platform drivers making use of early_platform_init() are | ||
211 | automatically registered during step 2 or 3. The serial driver example | ||
212 | should use early_platform_init("earlyprintk", &platform_driver). | ||
213 | |||
214 | 5. Probing of early platform drivers belonging to a certain class | ||
215 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
216 | The architecture code calls early_platform_driver_probe() to match | ||
217 | registered early platform devices associated with a certain class with | ||
218 | registered early platform drivers. Matched devices will get probed(). | ||
219 | This step can be executed at any point during the early boot. As soon | ||
220 | as possible may be good for the serial port case. | ||
221 | |||
222 | 6. Inside the early platform driver probe() | ||
223 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
224 | The driver code needs to take special care during early boot, especially | ||
225 | when it comes to memory allocation and interrupt registration. The code | ||
226 | in the probe() function can use is_early_platform_device() to check if | ||
227 | it is called at early platform device or at the regular platform device | ||
228 | time. The early serial driver performs register_console() at this point. | ||
229 | |||
230 | For further information, see <linux/platform_device.h>. | ||
diff --git a/drivers/base/base.h b/drivers/base/base.h index ddc97496db4a..b528145a078f 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -115,7 +115,7 @@ extern int driver_probe_device(struct device_driver *drv, struct device *dev); | |||
115 | static inline int driver_match_device(struct device_driver *drv, | 115 | static inline int driver_match_device(struct device_driver *drv, |
116 | struct device *dev) | 116 | struct device *dev) |
117 | { | 117 | { |
118 | return drv->bus->match && drv->bus->match(dev, drv); | 118 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; |
119 | } | 119 | } |
120 | 120 | ||
121 | extern void sysdev_shutdown(void); | 121 | extern void sysdev_shutdown(void); |
diff --git a/drivers/base/core.c b/drivers/base/core.c index e73c92d13a23..d230ff4b3eec 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1142,6 +1142,9 @@ int device_for_each_child(struct device *parent, void *data, | |||
1142 | struct device *child; | 1142 | struct device *child; |
1143 | int error = 0; | 1143 | int error = 0; |
1144 | 1144 | ||
1145 | if (!parent->p) | ||
1146 | return 0; | ||
1147 | |||
1145 | klist_iter_init(&parent->p->klist_children, &i); | 1148 | klist_iter_init(&parent->p->klist_children, &i); |
1146 | while ((child = next_device(&i)) && !error) | 1149 | while ((child = next_device(&i)) && !error) |
1147 | error = fn(child, data); | 1150 | error = fn(child, data); |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index d2198f64ad4e..b5b6c973a2e0 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -990,6 +990,8 @@ int __init platform_bus_init(void) | |||
990 | { | 990 | { |
991 | int error; | 991 | int error; |
992 | 992 | ||
993 | early_platform_cleanup(); | ||
994 | |||
993 | error = device_register(&platform_bus); | 995 | error = device_register(&platform_bus); |
994 | if (error) | 996 | if (error) |
995 | return error; | 997 | return error; |
@@ -1020,3 +1022,240 @@ u64 dma_get_required_mask(struct device *dev) | |||
1020 | } | 1022 | } |
1021 | EXPORT_SYMBOL_GPL(dma_get_required_mask); | 1023 | EXPORT_SYMBOL_GPL(dma_get_required_mask); |
1022 | #endif | 1024 | #endif |
1025 | |||
1026 | static __initdata LIST_HEAD(early_platform_driver_list); | ||
1027 | static __initdata LIST_HEAD(early_platform_device_list); | ||
1028 | |||
1029 | /** | ||
1030 | * early_platform_driver_register | ||
1031 | * @edrv: early_platform driver structure | ||
1032 | * @buf: string passed from early_param() | ||
1033 | */ | ||
1034 | int __init early_platform_driver_register(struct early_platform_driver *epdrv, | ||
1035 | char *buf) | ||
1036 | { | ||
1037 | unsigned long index; | ||
1038 | int n; | ||
1039 | |||
1040 | /* Simply add the driver to the end of the global list. | ||
1041 | * Drivers will by default be put on the list in compiled-in order. | ||
1042 | */ | ||
1043 | if (!epdrv->list.next) { | ||
1044 | INIT_LIST_HEAD(&epdrv->list); | ||
1045 | list_add_tail(&epdrv->list, &early_platform_driver_list); | ||
1046 | } | ||
1047 | |||
1048 | /* If the user has specified device then make sure the driver | ||
1049 | * gets prioritized. The driver of the last device specified on | ||
1050 | * command line will be put first on the list. | ||
1051 | */ | ||
1052 | n = strlen(epdrv->pdrv->driver.name); | ||
1053 | if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { | ||
1054 | list_move(&epdrv->list, &early_platform_driver_list); | ||
1055 | |||
1056 | if (!strcmp(buf, epdrv->pdrv->driver.name)) | ||
1057 | epdrv->requested_id = -1; | ||
1058 | else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10, | ||
1059 | &index) == 0) | ||
1060 | epdrv->requested_id = index; | ||
1061 | else | ||
1062 | epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; | ||
1063 | } | ||
1064 | |||
1065 | return 0; | ||
1066 | } | ||
1067 | |||
1068 | /** | ||
1069 | * early_platform_add_devices - add a numbers of early platform devices | ||
1070 | * @devs: array of early platform devices to add | ||
1071 | * @num: number of early platform devices in array | ||
1072 | */ | ||
1073 | void __init early_platform_add_devices(struct platform_device **devs, int num) | ||
1074 | { | ||
1075 | struct device *dev; | ||
1076 | int i; | ||
1077 | |||
1078 | /* simply add the devices to list */ | ||
1079 | for (i = 0; i < num; i++) { | ||
1080 | dev = &devs[i]->dev; | ||
1081 | |||
1082 | if (!dev->devres_head.next) { | ||
1083 | INIT_LIST_HEAD(&dev->devres_head); | ||
1084 | list_add_tail(&dev->devres_head, | ||
1085 | &early_platform_device_list); | ||
1086 | } | ||
1087 | } | ||
1088 | } | ||
1089 | |||
1090 | /** | ||
1091 | * early_platform_driver_register_all | ||
1092 | * @class_str: string to identify early platform driver class | ||
1093 | */ | ||
1094 | void __init early_platform_driver_register_all(char *class_str) | ||
1095 | { | ||
1096 | /* The "class_str" parameter may or may not be present on the kernel | ||
1097 | * command line. If it is present then there may be more than one | ||
1098 | * matching parameter. | ||
1099 | * | ||
1100 | * Since we register our early platform drivers using early_param() | ||
1101 | * we need to make sure that they also get registered in the case | ||
1102 | * when the parameter is missing from the kernel command line. | ||
1103 | * | ||
1104 | * We use parse_early_options() to make sure the early_param() gets | ||
1105 | * called at least once. The early_param() may be called more than | ||
1106 | * once since the name of the preferred device may be specified on | ||
1107 | * the kernel command line. early_platform_driver_register() handles | ||
1108 | * this case for us. | ||
1109 | */ | ||
1110 | parse_early_options(class_str); | ||
1111 | } | ||
1112 | |||
1113 | /** | ||
1114 | * early_platform_match | ||
1115 | * @edrv: early platform driver structure | ||
1116 | * @id: id to match against | ||
1117 | */ | ||
1118 | static __init struct platform_device * | ||
1119 | early_platform_match(struct early_platform_driver *epdrv, int id) | ||
1120 | { | ||
1121 | struct platform_device *pd; | ||
1122 | |||
1123 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) | ||
1124 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) | ||
1125 | if (pd->id == id) | ||
1126 | return pd; | ||
1127 | |||
1128 | return NULL; | ||
1129 | } | ||
1130 | |||
1131 | /** | ||
1132 | * early_platform_left | ||
1133 | * @edrv: early platform driver structure | ||
1134 | * @id: return true if id or above exists | ||
1135 | */ | ||
1136 | static __init int early_platform_left(struct early_platform_driver *epdrv, | ||
1137 | int id) | ||
1138 | { | ||
1139 | struct platform_device *pd; | ||
1140 | |||
1141 | list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) | ||
1142 | if (platform_match(&pd->dev, &epdrv->pdrv->driver)) | ||
1143 | if (pd->id >= id) | ||
1144 | return 1; | ||
1145 | |||
1146 | return 0; | ||
1147 | } | ||
1148 | |||
1149 | /** | ||
1150 | * early_platform_driver_probe_id | ||
1151 | * @class_str: string to identify early platform driver class | ||
1152 | * @id: id to match against | ||
1153 | * @nr_probe: number of platform devices to successfully probe before exiting | ||
1154 | */ | ||
1155 | static int __init early_platform_driver_probe_id(char *class_str, | ||
1156 | int id, | ||
1157 | int nr_probe) | ||
1158 | { | ||
1159 | struct early_platform_driver *epdrv; | ||
1160 | struct platform_device *match; | ||
1161 | int match_id; | ||
1162 | int n = 0; | ||
1163 | int left = 0; | ||
1164 | |||
1165 | list_for_each_entry(epdrv, &early_platform_driver_list, list) { | ||
1166 | /* only use drivers matching our class_str */ | ||
1167 | if (strcmp(class_str, epdrv->class_str)) | ||
1168 | continue; | ||
1169 | |||
1170 | if (id == -2) { | ||
1171 | match_id = epdrv->requested_id; | ||
1172 | left = 1; | ||
1173 | |||
1174 | } else { | ||
1175 | match_id = id; | ||
1176 | left += early_platform_left(epdrv, id); | ||
1177 | |||
1178 | /* skip requested id */ | ||
1179 | switch (epdrv->requested_id) { | ||
1180 | case EARLY_PLATFORM_ID_ERROR: | ||
1181 | case EARLY_PLATFORM_ID_UNSET: | ||
1182 | break; | ||
1183 | default: | ||
1184 | if (epdrv->requested_id == id) | ||
1185 | match_id = EARLY_PLATFORM_ID_UNSET; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | switch (match_id) { | ||
1190 | case EARLY_PLATFORM_ID_ERROR: | ||
1191 | pr_warning("%s: unable to parse %s parameter\n", | ||
1192 | class_str, epdrv->pdrv->driver.name); | ||
1193 | /* fall-through */ | ||
1194 | case EARLY_PLATFORM_ID_UNSET: | ||
1195 | match = NULL; | ||
1196 | break; | ||
1197 | default: | ||
1198 | match = early_platform_match(epdrv, match_id); | ||
1199 | } | ||
1200 | |||
1201 | if (match) { | ||
1202 | if (epdrv->pdrv->probe(match)) | ||
1203 | pr_warning("%s: unable to probe %s early.\n", | ||
1204 | class_str, match->name); | ||
1205 | else | ||
1206 | n++; | ||
1207 | } | ||
1208 | |||
1209 | if (n >= nr_probe) | ||
1210 | break; | ||
1211 | } | ||
1212 | |||
1213 | if (left) | ||
1214 | return n; | ||
1215 | else | ||
1216 | return -ENODEV; | ||
1217 | } | ||
1218 | |||
1219 | /** | ||
1220 | * early_platform_driver_probe | ||
1221 | * @class_str: string to identify early platform driver class | ||
1222 | * @nr_probe: number of platform devices to successfully probe before exiting | ||
1223 | * @user_only: only probe user specified early platform devices | ||
1224 | */ | ||
1225 | int __init early_platform_driver_probe(char *class_str, | ||
1226 | int nr_probe, | ||
1227 | int user_only) | ||
1228 | { | ||
1229 | int k, n, i; | ||
1230 | |||
1231 | n = 0; | ||
1232 | for (i = -2; n < nr_probe; i++) { | ||
1233 | k = early_platform_driver_probe_id(class_str, i, nr_probe - n); | ||
1234 | |||
1235 | if (k < 0) | ||
1236 | break; | ||
1237 | |||
1238 | n += k; | ||
1239 | |||
1240 | if (user_only) | ||
1241 | break; | ||
1242 | } | ||
1243 | |||
1244 | return n; | ||
1245 | } | ||
1246 | |||
1247 | /** | ||
1248 | * early_platform_cleanup - clean up early platform code | ||
1249 | */ | ||
1250 | void __init early_platform_cleanup(void) | ||
1251 | { | ||
1252 | struct platform_device *pd, *pd2; | ||
1253 | |||
1254 | /* clean up the devres list used to chain devices */ | ||
1255 | list_for_each_entry_safe(pd, pd2, &early_platform_device_list, | ||
1256 | dev.devres_head) { | ||
1257 | list_del(&pd->dev.devres_head); | ||
1258 | memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); | ||
1259 | } | ||
1260 | } | ||
1261 | |||
diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index c60b8fcf0e3e..28034c812914 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c | |||
@@ -147,5 +147,6 @@ static void __exit hilscher_exit_module(void) | |||
147 | module_init(hilscher_init_module); | 147 | module_init(hilscher_init_module); |
148 | module_exit(hilscher_exit_module); | 148 | module_exit(hilscher_exit_module); |
149 | 149 | ||
150 | MODULE_DEVICE_TABLE(pci, hilscher_pci_ids); | ||
150 | MODULE_LICENSE("GPL v2"); | 151 | MODULE_LICENSE("GPL v2"); |
151 | MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); | 152 | MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index f71559784bfb..aa763ab00777 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -648,14 +648,14 @@ static unsigned mounts_poll(struct file *file, poll_table *wait) | |||
648 | { | 648 | { |
649 | struct proc_mounts *p = file->private_data; | 649 | struct proc_mounts *p = file->private_data; |
650 | struct mnt_namespace *ns = p->ns; | 650 | struct mnt_namespace *ns = p->ns; |
651 | unsigned res = 0; | 651 | unsigned res = POLLIN | POLLRDNORM; |
652 | 652 | ||
653 | poll_wait(file, &ns->poll, wait); | 653 | poll_wait(file, &ns->poll, wait); |
654 | 654 | ||
655 | spin_lock(&vfsmount_lock); | 655 | spin_lock(&vfsmount_lock); |
656 | if (p->event != ns->event) { | 656 | if (p->event != ns->event) { |
657 | p->event = ns->event; | 657 | p->event = ns->event; |
658 | res = POLLERR; | 658 | res |= POLLERR | POLLPRI; |
659 | } | 659 | } |
660 | spin_unlock(&vfsmount_lock); | 660 | spin_unlock(&vfsmount_lock); |
661 | 661 | ||
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 289c43a47263..b1606e07b7a3 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -446,11 +446,11 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | |||
446 | if (buffer->event != atomic_read(&od->event)) | 446 | if (buffer->event != atomic_read(&od->event)) |
447 | goto trigger; | 447 | goto trigger; |
448 | 448 | ||
449 | return 0; | 449 | return DEFAULT_POLLMASK; |
450 | 450 | ||
451 | trigger: | 451 | trigger: |
452 | buffer->needs_read_fill = 1; | 452 | buffer->needs_read_fill = 1; |
453 | return POLLERR|POLLPRI; | 453 | return DEFAULT_POLLMASK|POLLERR|POLLPRI; |
454 | } | 454 | } |
455 | 455 | ||
456 | void sysfs_notify_dirent(struct sysfs_dirent *sd) | 456 | void sysfs_notify_dirent(struct sysfs_dirent *sd) |
@@ -667,6 +667,7 @@ struct sysfs_schedule_callback_struct { | |||
667 | struct work_struct work; | 667 | struct work_struct work; |
668 | }; | 668 | }; |
669 | 669 | ||
670 | static struct workqueue_struct *sysfs_workqueue; | ||
670 | static DEFINE_MUTEX(sysfs_workq_mutex); | 671 | static DEFINE_MUTEX(sysfs_workq_mutex); |
671 | static LIST_HEAD(sysfs_workq); | 672 | static LIST_HEAD(sysfs_workq); |
672 | static void sysfs_schedule_callback_work(struct work_struct *work) | 673 | static void sysfs_schedule_callback_work(struct work_struct *work) |
@@ -715,11 +716,20 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | |||
715 | mutex_lock(&sysfs_workq_mutex); | 716 | mutex_lock(&sysfs_workq_mutex); |
716 | list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) | 717 | list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) |
717 | if (ss->kobj == kobj) { | 718 | if (ss->kobj == kobj) { |
719 | module_put(owner); | ||
718 | mutex_unlock(&sysfs_workq_mutex); | 720 | mutex_unlock(&sysfs_workq_mutex); |
719 | return -EAGAIN; | 721 | return -EAGAIN; |
720 | } | 722 | } |
721 | mutex_unlock(&sysfs_workq_mutex); | 723 | mutex_unlock(&sysfs_workq_mutex); |
722 | 724 | ||
725 | if (sysfs_workqueue == NULL) { | ||
726 | sysfs_workqueue = create_workqueue("sysfsd"); | ||
727 | if (sysfs_workqueue == NULL) { | ||
728 | module_put(owner); | ||
729 | return -ENOMEM; | ||
730 | } | ||
731 | } | ||
732 | |||
723 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); | 733 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); |
724 | if (!ss) { | 734 | if (!ss) { |
725 | module_put(owner); | 735 | module_put(owner); |
@@ -735,7 +745,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | |||
735 | mutex_lock(&sysfs_workq_mutex); | 745 | mutex_lock(&sysfs_workq_mutex); |
736 | list_add_tail(&ss->workq_list, &sysfs_workq); | 746 | list_add_tail(&ss->workq_list, &sysfs_workq); |
737 | mutex_unlock(&sysfs_workq_mutex); | 747 | mutex_unlock(&sysfs_workq_mutex); |
738 | schedule_work(&ss->work); | 748 | queue_work(sysfs_workqueue, &ss->work); |
739 | return 0; | 749 | return 0; |
740 | } | 750 | } |
741 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | 751 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); |
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index baabf33be244..a0d9422a1569 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h | |||
@@ -70,7 +70,7 @@ extern int ddebug_remove_module(char *mod_name); | |||
70 | DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \ | 70 | DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \ |
71 | if (__dynamic_dbg_enabled(descriptor)) \ | 71 | if (__dynamic_dbg_enabled(descriptor)) \ |
72 | dev_printk(KERN_DEBUG, dev, \ | 72 | dev_printk(KERN_DEBUG, dev, \ |
73 | KBUILD_MODNAME ": " pr_fmt(fmt),\ | 73 | KBUILD_MODNAME ": " fmt, \ |
74 | ##__VA_ARGS__); \ | 74 | ##__VA_ARGS__); \ |
75 | } while (0) | 75 | } while (0) |
76 | 76 | ||
diff --git a/include/linux/init.h b/include/linux/init.h index 68cb0265d009..f121a7a10c3d 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -247,6 +247,7 @@ struct obs_kernel_param { | |||
247 | 247 | ||
248 | /* Relies on boot_command_line being set */ | 248 | /* Relies on boot_command_line being set */ |
249 | void __init parse_early_param(void); | 249 | void __init parse_early_param(void); |
250 | void __init parse_early_options(char *cmdline); | ||
250 | #endif /* __ASSEMBLY__ */ | 251 | #endif /* __ASSEMBLY__ */ |
251 | 252 | ||
252 | /** | 253 | /** |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index d9e75ec7def5..883cd44ff765 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -377,6 +377,15 @@ static inline char *pack_hex_byte(char *buf, u8 byte) | |||
377 | #define pr_cont(fmt, ...) \ | 377 | #define pr_cont(fmt, ...) \ |
378 | printk(KERN_CONT fmt, ##__VA_ARGS__) | 378 | printk(KERN_CONT fmt, ##__VA_ARGS__) |
379 | 379 | ||
380 | /* pr_devel() should produce zero code unless DEBUG is defined */ | ||
381 | #ifdef DEBUG | ||
382 | #define pr_devel(fmt, ...) \ | ||
383 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) | ||
384 | #else | ||
385 | #define pr_devel(fmt, ...) \ | ||
386 | ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) | ||
387 | #endif | ||
388 | |||
380 | /* If you are writing a driver, please use dev_dbg instead */ | 389 | /* If you are writing a driver, please use dev_dbg instead */ |
381 | #if defined(DEBUG) | 390 | #if defined(DEBUG) |
382 | #define pr_debug(fmt, ...) \ | 391 | #define pr_debug(fmt, ...) \ |
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 76e470a299bf..72736fd8223c 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h | |||
@@ -77,4 +77,46 @@ extern int platform_driver_probe(struct platform_driver *driver, | |||
77 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) | 77 | #define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev) |
78 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) | 78 | #define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data)) |
79 | 79 | ||
80 | /* early platform driver interface */ | ||
81 | struct early_platform_driver { | ||
82 | const char *class_str; | ||
83 | struct platform_driver *pdrv; | ||
84 | struct list_head list; | ||
85 | int requested_id; | ||
86 | }; | ||
87 | |||
88 | #define EARLY_PLATFORM_ID_UNSET -2 | ||
89 | #define EARLY_PLATFORM_ID_ERROR -3 | ||
90 | |||
91 | extern int early_platform_driver_register(struct early_platform_driver *epdrv, | ||
92 | char *buf); | ||
93 | extern void early_platform_add_devices(struct platform_device **devs, int num); | ||
94 | |||
95 | static inline int is_early_platform_device(struct platform_device *pdev) | ||
96 | { | ||
97 | return !pdev->dev.driver; | ||
98 | } | ||
99 | |||
100 | extern void early_platform_driver_register_all(char *class_str); | ||
101 | extern int early_platform_driver_probe(char *class_str, | ||
102 | int nr_probe, int user_only); | ||
103 | extern void early_platform_cleanup(void); | ||
104 | |||
105 | |||
106 | #ifndef MODULE | ||
107 | #define early_platform_init(class_string, platform_driver) \ | ||
108 | static __initdata struct early_platform_driver early_driver = { \ | ||
109 | .class_str = class_string, \ | ||
110 | .pdrv = platform_driver, \ | ||
111 | .requested_id = EARLY_PLATFORM_ID_UNSET, \ | ||
112 | }; \ | ||
113 | static int __init early_platform_driver_setup_func(char *buf) \ | ||
114 | { \ | ||
115 | return early_platform_driver_register(&early_driver, buf); \ | ||
116 | } \ | ||
117 | early_param(class_string, early_platform_driver_setup_func) | ||
118 | #else /* MODULE */ | ||
119 | #define early_platform_init(class_string, platform_driver) | ||
120 | #endif /* MODULE */ | ||
121 | |||
80 | #endif /* _PLATFORM_DEVICE_H_ */ | 122 | #endif /* _PLATFORM_DEVICE_H_ */ |
diff --git a/init/main.c b/init/main.c index 3585f073d636..3bbf93be744c 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -492,6 +492,11 @@ static int __init do_early_param(char *param, char *val) | |||
492 | return 0; | 492 | return 0; |
493 | } | 493 | } |
494 | 494 | ||
495 | void __init parse_early_options(char *cmdline) | ||
496 | { | ||
497 | parse_args("early options", cmdline, NULL, 0, do_early_param); | ||
498 | } | ||
499 | |||
495 | /* Arch code calls this early on, or if not, just before other parsing. */ | 500 | /* Arch code calls this early on, or if not, just before other parsing. */ |
496 | void __init parse_early_param(void) | 501 | void __init parse_early_param(void) |
497 | { | 502 | { |
@@ -503,7 +508,7 @@ void __init parse_early_param(void) | |||
503 | 508 | ||
504 | /* All fall through to do_early_param. */ | 509 | /* All fall through to do_early_param. */ |
505 | strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); | 510 | strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
506 | parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); | 511 | parse_early_options(tmp_cmdline); |
507 | done = 1; | 512 | done = 1; |
508 | } | 513 | } |
509 | 514 | ||
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index dafeecf5b143..920a3ca6e259 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
@@ -328,7 +328,7 @@ static int __init kobject_uevent_init(void) | |||
328 | "kobject_uevent: unable to create netlink socket!\n"); | 328 | "kobject_uevent: unable to create netlink socket!\n"); |
329 | return -ENODEV; | 329 | return -ENODEV; |
330 | } | 330 | } |
331 | 331 | netlink_set_nonroot(NETLINK_KOBJECT_UEVENT, NL_NONROOT_RECV); | |
332 | return 0; | 332 | return 0; |
333 | } | 333 | } |
334 | 334 | ||