aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-17 16:53:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-17 16:53:16 -0400
commit74a205a3f1a07cf0b72bf7816d75735a0d9c4c6b (patch)
treed977fe81c74a0728130c7e212f2c27eef8146e91
parentdd26bf6d95f050c42cc8f15e750b09851e1fd30b (diff)
parent912335c43bb10d124471bf063a85e132aa814214 (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.txt59
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/core.c3
-rw-r--r--drivers/base/platform.c239
-rw-r--r--drivers/uio/uio_cif.c1
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/sysfs/file.c16
-rw-r--r--include/linux/dynamic_debug.h2
-rw-r--r--include/linux/init.h1
-rw-r--r--include/linux/kernel.h9
-rw-r--r--include/linux/platform_device.h42
-rw-r--r--init/main.c7
-rw-r--r--lib/kobject_uevent.c2
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
173Early Platform Devices and Drivers
174~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
175The early platform interfaces provide platform data to platform device
176drivers early on during the system boot. The code is built on top of the
177early_param() command line parsing and can be executed very early on.
178
179Example: "earlyprintk" class early serial console in 6 steps
180
1811. Registering early platform device data
182~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183The architecture code registers platform device data using the function
184early_platform_add_devices(). In the case of early serial console this
185should be hardware configuration for the serial port. Devices registered
186at this point will later on be matched against early platform drivers.
187
1882. Parsing kernel command line
189~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
190The architecture code calls parse_early_param() to parse the kernel
191command line. This will execute all matching early_param() callbacks.
192User specified early platform devices will be registered at this point.
193For the early serial console case the user can specify port on the
194kernel command line as "earlyprintk=serial.0" where "earlyprintk" is
195the class string, "serial" is the name of the platfrom driver and
1960 is the platform device id. If the id is -1 then the dot and the
197id can be omitted.
198
1993. Installing early platform drivers belonging to a certain class
200~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
201The architecture code may optionally force registration of all early
202platform drivers belonging to a certain class using the function
203early_platform_driver_register_all(). User specified devices from
204step 2 have priority over these. This step is omitted by the serial
205driver example since the early serial driver code should be disabled
206unless the user has specified port on the kernel command line.
207
2084. Early platform driver registration
209~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
210Compiled-in platform drivers making use of early_platform_init() are
211automatically registered during step 2 or 3. The serial driver example
212should use early_platform_init("earlyprintk", &platform_driver).
213
2145. Probing of early platform drivers belonging to a certain class
215~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
216The architecture code calls early_platform_driver_probe() to match
217registered early platform devices associated with a certain class with
218registered early platform drivers. Matched devices will get probed().
219This step can be executed at any point during the early boot. As soon
220as possible may be good for the serial port case.
221
2226. Inside the early platform driver probe()
223~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
224The driver code needs to take special care during early boot, especially
225when it comes to memory allocation and interrupt registration. The code
226in the probe() function can use is_early_platform_device() to check if
227it is called at early platform device or at the regular platform device
228time. The early serial driver performs register_console() at this point.
229
230For 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);
115static inline int driver_match_device(struct device_driver *drv, 115static 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
121extern void sysdev_shutdown(void); 121extern 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}
1021EXPORT_SYMBOL_GPL(dma_get_required_mask); 1023EXPORT_SYMBOL_GPL(dma_get_required_mask);
1022#endif 1024#endif
1025
1026static __initdata LIST_HEAD(early_platform_driver_list);
1027static __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 */
1034int __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 */
1073void __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 */
1094void __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 */
1118static __init struct platform_device *
1119early_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 */
1136static __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 */
1155static 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 */
1225int __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 */
1250void __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)
147module_init(hilscher_init_module); 147module_init(hilscher_init_module);
148module_exit(hilscher_exit_module); 148module_exit(hilscher_exit_module);
149 149
150MODULE_DEVICE_TABLE(pci, hilscher_pci_ids);
150MODULE_LICENSE("GPL v2"); 151MODULE_LICENSE("GPL v2");
151MODULE_AUTHOR("Hans J. Koch, Benedikt Spranger"); 152MODULE_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
456void sysfs_notify_dirent(struct sysfs_dirent *sd) 456void 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
670static struct workqueue_struct *sysfs_workqueue;
670static DEFINE_MUTEX(sysfs_workq_mutex); 671static DEFINE_MUTEX(sysfs_workq_mutex);
671static LIST_HEAD(sysfs_workq); 672static LIST_HEAD(sysfs_workq);
672static void sysfs_schedule_callback_work(struct work_struct *work) 673static 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}
741EXPORT_SYMBOL_GPL(sysfs_schedule_callback); 751EXPORT_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 */
249void __init parse_early_param(void); 249void __init parse_early_param(void);
250void __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 */
81struct 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
91extern int early_platform_driver_register(struct early_platform_driver *epdrv,
92 char *buf);
93extern void early_platform_add_devices(struct platform_device **devs, int num);
94
95static inline int is_early_platform_device(struct platform_device *pdev)
96{
97 return !pdev->dev.driver;
98}
99
100extern void early_platform_driver_register_all(char *class_str);
101extern int early_platform_driver_probe(char *class_str,
102 int nr_probe, int user_only);
103extern void early_platform_cleanup(void);
104
105
106#ifndef MODULE
107#define early_platform_init(class_string, platform_driver) \
108static __initdata struct early_platform_driver early_driver = { \
109 .class_str = class_string, \
110 .pdrv = platform_driver, \
111 .requested_id = EARLY_PLATFORM_ID_UNSET, \
112}; \
113static int __init early_platform_driver_setup_func(char *buf) \
114{ \
115 return early_platform_driver_register(&early_driver, buf); \
116} \
117early_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
495void __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. */
496void __init parse_early_param(void) 501void __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