aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <damm@opensource.se>2009-11-27 03:38:51 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:24:55 -0500
commitc60e0504c8e4fa14179d0687d80ef25148dd6dd4 (patch)
tree01e8ba58e367cb6bd2ae4ee334265e5bd2800769
parente16acb503b42ef241a9396de7c5a1614c74d8ca6 (diff)
Driver Core: Early platform driver buffer
Add early_platform_init_buffer() support and update the early platform driver code to allow passing parameters to the driver on the kernel command line. early_platform_init_buffer() simply allows early platform drivers to provide a pointer and length to a memory area where the remaining part of the kernel command line option will be stored. Needed to pass baud rate and other serial port options to the reworked early serial console code on SuperH. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/platform.c29
-rw-r--r--include/linux/platform_device.h20
2 files changed, 37 insertions, 12 deletions
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 4fa954b07ac4..9d2ee25deaf5 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -1000,7 +1000,7 @@ static __initdata LIST_HEAD(early_platform_device_list);
1000int __init early_platform_driver_register(struct early_platform_driver *epdrv, 1000int __init early_platform_driver_register(struct early_platform_driver *epdrv,
1001 char *buf) 1001 char *buf)
1002{ 1002{
1003 unsigned long index; 1003 char *tmp;
1004 int n; 1004 int n;
1005 1005
1006 /* Simply add the driver to the end of the global list. 1006 /* Simply add the driver to the end of the global list.
@@ -1019,13 +1019,28 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
1019 if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { 1019 if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
1020 list_move(&epdrv->list, &early_platform_driver_list); 1020 list_move(&epdrv->list, &early_platform_driver_list);
1021 1021
1022 if (!strcmp(buf, epdrv->pdrv->driver.name)) 1022 /* Allow passing parameters after device name */
1023 if (buf[n] == '\0' || buf[n] == ',')
1023 epdrv->requested_id = -1; 1024 epdrv->requested_id = -1;
1024 else if (buf[n] == '.' && strict_strtoul(&buf[n + 1], 10, 1025 else {
1025 &index) == 0) 1026 epdrv->requested_id = simple_strtoul(&buf[n + 1],
1026 epdrv->requested_id = index; 1027 &tmp, 10);
1027 else 1028
1028 epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; 1029 if (buf[n] != '.' || (tmp == &buf[n + 1])) {
1030 epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
1031 n = 0;
1032 } else
1033 n += strcspn(&buf[n + 1], ",") + 1;
1034 }
1035
1036 if (buf[n] == ',')
1037 n++;
1038
1039 if (epdrv->bufsize) {
1040 memcpy(epdrv->buffer, &buf[n],
1041 min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
1042 epdrv->buffer[epdrv->bufsize - 1] = '\0';
1043 }
1029 } 1044 }
1030 1045
1031 return 0; 1046 return 0;
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 3c6675c2444b..71ff887ca44e 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -83,6 +83,8 @@ struct early_platform_driver {
83 struct platform_driver *pdrv; 83 struct platform_driver *pdrv;
84 struct list_head list; 84 struct list_head list;
85 int requested_id; 85 int requested_id;
86 char *buffer;
87 int bufsize;
86}; 88};
87 89
88#define EARLY_PLATFORM_ID_UNSET -2 90#define EARLY_PLATFORM_ID_UNSET -2
@@ -102,21 +104,29 @@ extern int early_platform_driver_probe(char *class_str,
102 int nr_probe, int user_only); 104 int nr_probe, int user_only);
103extern void early_platform_cleanup(void); 105extern void early_platform_cleanup(void);
104 106
107#define early_platform_init(class_string, platdrv) \
108 early_platform_init_buffer(class_string, platdrv, NULL, 0)
105 109
106#ifndef MODULE 110#ifndef MODULE
107#define early_platform_init(class_string, platform_driver) \ 111#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
108static __initdata struct early_platform_driver early_driver = { \ 112static __initdata struct early_platform_driver early_driver = { \
109 .class_str = class_string, \ 113 .class_str = class_string, \
110 .pdrv = platform_driver, \ 114 .buffer = buf, \
115 .bufsize = bufsiz, \
116 .pdrv = platdrv, \
111 .requested_id = EARLY_PLATFORM_ID_UNSET, \ 117 .requested_id = EARLY_PLATFORM_ID_UNSET, \
112}; \ 118}; \
113static int __init early_platform_driver_setup_func(char *buf) \ 119static int __init early_platform_driver_setup_func(char *buffer) \
114{ \ 120{ \
115 return early_platform_driver_register(&early_driver, buf); \ 121 return early_platform_driver_register(&early_driver, buffer); \
116} \ 122} \
117early_param(class_string, early_platform_driver_setup_func) 123early_param(class_string, early_platform_driver_setup_func)
118#else /* MODULE */ 124#else /* MODULE */
119#define early_platform_init(class_string, platform_driver) 125#define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \
126static inline char *early_platform_driver_setup_func(void) \
127{ \
128 return bufsiz ? buf : NULL; \
129}
120#endif /* MODULE */ 130#endif /* MODULE */
121 131
122#endif /* _PLATFORM_DEVICE_H_ */ 132#endif /* _PLATFORM_DEVICE_H_ */