Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: move the early platform device support to arch/sh

SuperH is the only user of the current implementation of early platform
device support. We want to introduce a more robust approach to early
probing. As the first step - move all the current early platform code
to arch/sh.

In order not to export internal drivers/base functions to arch code for
this temporary solution - copy the two needed routines for driver
matching from drivers/base/platform.c to arch/sh/drivers/platform_early.c.

Also: call early_platform_cleanup() from subsys_initcall() so that it's
called after all early devices are probed.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Cc: Rich Felker <dalias@libc.org>
Link: https://lore.kernel.org/r/20191003092913.10731-2-brgl@bgdev.pl
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Bartosz Golaszewski and committed by
Greg Kroah-Hartman
507fd01d d4387cd1

+480 -342
+1 -1
arch/sh/drivers/Makefile
··· 3 3 # Makefile for the Linux SuperH-specific device drivers. 4 4 # 5 5 6 - obj-y += dma/ 6 + obj-y += dma/ platform_early.o 7 7 8 8 obj-$(CONFIG_PCI) += pci/ 9 9 obj-$(CONFIG_SUPERHYWAY) += superhyway/
+347
arch/sh/drivers/platform_early.c
··· 1 + // SPDX--License-Identifier: GPL-2.0 2 + 3 + #include <asm/platform_early.h> 4 + #include <linux/mod_devicetable.h> 5 + #include <linux/pm.h> 6 + 7 + static __initdata LIST_HEAD(early_platform_driver_list); 8 + static __initdata LIST_HEAD(early_platform_device_list); 9 + 10 + static const struct platform_device_id * 11 + platform_match_id(const struct platform_device_id *id, 12 + struct platform_device *pdev) 13 + { 14 + while (id->name[0]) { 15 + if (strcmp(pdev->name, id->name) == 0) { 16 + pdev->id_entry = id; 17 + return id; 18 + } 19 + id++; 20 + } 21 + return NULL; 22 + } 23 + 24 + static int platform_match(struct device *dev, struct device_driver *drv) 25 + { 26 + struct platform_device *pdev = to_platform_device(dev); 27 + struct platform_driver *pdrv = to_platform_driver(drv); 28 + 29 + /* When driver_override is set, only bind to the matching driver */ 30 + if (pdev->driver_override) 31 + return !strcmp(pdev->driver_override, drv->name); 32 + 33 + /* Then try to match against the id table */ 34 + if (pdrv->id_table) 35 + return platform_match_id(pdrv->id_table, pdev) != NULL; 36 + 37 + /* fall-back to driver name match */ 38 + return (strcmp(pdev->name, drv->name) == 0); 39 + } 40 + 41 + #ifdef CONFIG_PM 42 + static void device_pm_init_common(struct device *dev) 43 + { 44 + if (!dev->power.early_init) { 45 + spin_lock_init(&dev->power.lock); 46 + dev->power.qos = NULL; 47 + dev->power.early_init = true; 48 + } 49 + } 50 + 51 + static void pm_runtime_early_init(struct device *dev) 52 + { 53 + dev->power.disable_depth = 1; 54 + device_pm_init_common(dev); 55 + } 56 + #else 57 + static void pm_runtime_early_init(struct device *dev) {} 58 + #endif 59 + 60 + /** 61 + * early_platform_driver_register - register early platform driver 62 + * @epdrv: early_platform driver structure 63 + * @buf: string passed from early_param() 64 + * 65 + * Helper function for early_platform_init() / early_platform_init_buffer() 66 + */ 67 + int __init early_platform_driver_register(struct early_platform_driver *epdrv, 68 + char *buf) 69 + { 70 + char *tmp; 71 + int n; 72 + 73 + /* Simply add the driver to the end of the global list. 74 + * Drivers will by default be put on the list in compiled-in order. 75 + */ 76 + if (!epdrv->list.next) { 77 + INIT_LIST_HEAD(&epdrv->list); 78 + list_add_tail(&epdrv->list, &early_platform_driver_list); 79 + } 80 + 81 + /* If the user has specified device then make sure the driver 82 + * gets prioritized. The driver of the last device specified on 83 + * command line will be put first on the list. 84 + */ 85 + n = strlen(epdrv->pdrv->driver.name); 86 + if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { 87 + list_move(&epdrv->list, &early_platform_driver_list); 88 + 89 + /* Allow passing parameters after device name */ 90 + if (buf[n] == '\0' || buf[n] == ',') 91 + epdrv->requested_id = -1; 92 + else { 93 + epdrv->requested_id = simple_strtoul(&buf[n + 1], 94 + &tmp, 10); 95 + 96 + if (buf[n] != '.' || (tmp == &buf[n + 1])) { 97 + epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; 98 + n = 0; 99 + } else 100 + n += strcspn(&buf[n + 1], ",") + 1; 101 + } 102 + 103 + if (buf[n] == ',') 104 + n++; 105 + 106 + if (epdrv->bufsize) { 107 + memcpy(epdrv->buffer, &buf[n], 108 + min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); 109 + epdrv->buffer[epdrv->bufsize - 1] = '\0'; 110 + } 111 + } 112 + 113 + return 0; 114 + } 115 + 116 + /** 117 + * early_platform_add_devices - adds a number of early platform devices 118 + * @devs: array of early platform devices to add 119 + * @num: number of early platform devices in array 120 + * 121 + * Used by early architecture code to register early platform devices and 122 + * their platform data. 123 + */ 124 + void __init early_platform_add_devices(struct platform_device **devs, int num) 125 + { 126 + struct device *dev; 127 + int i; 128 + 129 + /* simply add the devices to list */ 130 + for (i = 0; i < num; i++) { 131 + dev = &devs[i]->dev; 132 + 133 + if (!dev->devres_head.next) { 134 + pm_runtime_early_init(dev); 135 + INIT_LIST_HEAD(&dev->devres_head); 136 + list_add_tail(&dev->devres_head, 137 + &early_platform_device_list); 138 + } 139 + } 140 + } 141 + 142 + /** 143 + * early_platform_driver_register_all - register early platform drivers 144 + * @class_str: string to identify early platform driver class 145 + * 146 + * Used by architecture code to register all early platform drivers 147 + * for a certain class. If omitted then only early platform drivers 148 + * with matching kernel command line class parameters will be registered. 149 + */ 150 + void __init early_platform_driver_register_all(char *class_str) 151 + { 152 + /* The "class_str" parameter may or may not be present on the kernel 153 + * command line. If it is present then there may be more than one 154 + * matching parameter. 155 + * 156 + * Since we register our early platform drivers using early_param() 157 + * we need to make sure that they also get registered in the case 158 + * when the parameter is missing from the kernel command line. 159 + * 160 + * We use parse_early_options() to make sure the early_param() gets 161 + * called at least once. The early_param() may be called more than 162 + * once since the name of the preferred device may be specified on 163 + * the kernel command line. early_platform_driver_register() handles 164 + * this case for us. 165 + */ 166 + parse_early_options(class_str); 167 + } 168 + 169 + /** 170 + * early_platform_match - find early platform device matching driver 171 + * @epdrv: early platform driver structure 172 + * @id: id to match against 173 + */ 174 + static struct platform_device * __init 175 + early_platform_match(struct early_platform_driver *epdrv, int id) 176 + { 177 + struct platform_device *pd; 178 + 179 + list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) 180 + if (platform_match(&pd->dev, &epdrv->pdrv->driver)) 181 + if (pd->id == id) 182 + return pd; 183 + 184 + return NULL; 185 + } 186 + 187 + /** 188 + * early_platform_left - check if early platform driver has matching devices 189 + * @epdrv: early platform driver structure 190 + * @id: return true if id or above exists 191 + */ 192 + static int __init early_platform_left(struct early_platform_driver *epdrv, 193 + int id) 194 + { 195 + struct platform_device *pd; 196 + 197 + list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) 198 + if (platform_match(&pd->dev, &epdrv->pdrv->driver)) 199 + if (pd->id >= id) 200 + return 1; 201 + 202 + return 0; 203 + } 204 + 205 + /** 206 + * early_platform_driver_probe_id - probe drivers matching class_str and id 207 + * @class_str: string to identify early platform driver class 208 + * @id: id to match against 209 + * @nr_probe: number of platform devices to successfully probe before exiting 210 + */ 211 + static int __init early_platform_driver_probe_id(char *class_str, 212 + int id, 213 + int nr_probe) 214 + { 215 + struct early_platform_driver *epdrv; 216 + struct platform_device *match; 217 + int match_id; 218 + int n = 0; 219 + int left = 0; 220 + 221 + list_for_each_entry(epdrv, &early_platform_driver_list, list) { 222 + /* only use drivers matching our class_str */ 223 + if (strcmp(class_str, epdrv->class_str)) 224 + continue; 225 + 226 + if (id == -2) { 227 + match_id = epdrv->requested_id; 228 + left = 1; 229 + 230 + } else { 231 + match_id = id; 232 + left += early_platform_left(epdrv, id); 233 + 234 + /* skip requested id */ 235 + switch (epdrv->requested_id) { 236 + case EARLY_PLATFORM_ID_ERROR: 237 + case EARLY_PLATFORM_ID_UNSET: 238 + break; 239 + default: 240 + if (epdrv->requested_id == id) 241 + match_id = EARLY_PLATFORM_ID_UNSET; 242 + } 243 + } 244 + 245 + switch (match_id) { 246 + case EARLY_PLATFORM_ID_ERROR: 247 + pr_warn("%s: unable to parse %s parameter\n", 248 + class_str, epdrv->pdrv->driver.name); 249 + /* fall-through */ 250 + case EARLY_PLATFORM_ID_UNSET: 251 + match = NULL; 252 + break; 253 + default: 254 + match = early_platform_match(epdrv, match_id); 255 + } 256 + 257 + if (match) { 258 + /* 259 + * Set up a sensible init_name to enable 260 + * dev_name() and others to be used before the 261 + * rest of the driver core is initialized. 262 + */ 263 + if (!match->dev.init_name && slab_is_available()) { 264 + if (match->id != -1) 265 + match->dev.init_name = 266 + kasprintf(GFP_KERNEL, "%s.%d", 267 + match->name, 268 + match->id); 269 + else 270 + match->dev.init_name = 271 + kasprintf(GFP_KERNEL, "%s", 272 + match->name); 273 + 274 + if (!match->dev.init_name) 275 + return -ENOMEM; 276 + } 277 + 278 + if (epdrv->pdrv->probe(match)) 279 + pr_warn("%s: unable to probe %s early.\n", 280 + class_str, match->name); 281 + else 282 + n++; 283 + } 284 + 285 + if (n >= nr_probe) 286 + break; 287 + } 288 + 289 + if (left) 290 + return n; 291 + else 292 + return -ENODEV; 293 + } 294 + 295 + /** 296 + * early_platform_driver_probe - probe a class of registered drivers 297 + * @class_str: string to identify early platform driver class 298 + * @nr_probe: number of platform devices to successfully probe before exiting 299 + * @user_only: only probe user specified early platform devices 300 + * 301 + * Used by architecture code to probe registered early platform drivers 302 + * within a certain class. For probe to happen a registered early platform 303 + * device matching a registered early platform driver is needed. 304 + */ 305 + int __init early_platform_driver_probe(char *class_str, 306 + int nr_probe, 307 + int user_only) 308 + { 309 + int k, n, i; 310 + 311 + n = 0; 312 + for (i = -2; n < nr_probe; i++) { 313 + k = early_platform_driver_probe_id(class_str, i, nr_probe - n); 314 + 315 + if (k < 0) 316 + break; 317 + 318 + n += k; 319 + 320 + if (user_only) 321 + break; 322 + } 323 + 324 + return n; 325 + } 326 + 327 + /** 328 + * early_platform_cleanup - clean up early platform code 329 + */ 330 + static int __init early_platform_cleanup(void) 331 + { 332 + struct platform_device *pd, *pd2; 333 + 334 + /* clean up the devres list used to chain devices */ 335 + list_for_each_entry_safe(pd, pd2, &early_platform_device_list, 336 + dev.devres_head) { 337 + list_del(&pd->dev.devres_head); 338 + memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); 339 + } 340 + 341 + return 0; 342 + } 343 + /* 344 + * This must happen once after all early devices are probed but before probing 345 + * real platform devices. 346 + */ 347 + subsys_initcall(early_platform_cleanup);
+61
arch/sh/include/asm/platform_early.h
··· 1 + /* SPDX--License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __PLATFORM_EARLY__ 4 + #define __PLATFORM_EARLY__ 5 + 6 + #include <linux/types.h> 7 + #include <linux/platform_device.h> 8 + #include <linux/pm_runtime.h> 9 + #include <linux/slab.h> 10 + 11 + struct early_platform_driver { 12 + const char *class_str; 13 + struct platform_driver *pdrv; 14 + struct list_head list; 15 + int requested_id; 16 + char *buffer; 17 + int bufsize; 18 + }; 19 + 20 + #define EARLY_PLATFORM_ID_UNSET -2 21 + #define EARLY_PLATFORM_ID_ERROR -3 22 + 23 + extern int early_platform_driver_register(struct early_platform_driver *epdrv, 24 + char *buf); 25 + extern void early_platform_add_devices(struct platform_device **devs, int num); 26 + 27 + static inline int is_early_platform_device(struct platform_device *pdev) 28 + { 29 + return !pdev->dev.driver; 30 + } 31 + 32 + extern void early_platform_driver_register_all(char *class_str); 33 + extern int early_platform_driver_probe(char *class_str, 34 + int nr_probe, int user_only); 35 + 36 + #define early_platform_init(class_string, platdrv) \ 37 + early_platform_init_buffer(class_string, platdrv, NULL, 0) 38 + 39 + #ifndef MODULE 40 + #define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ 41 + static __initdata struct early_platform_driver early_driver = { \ 42 + .class_str = class_string, \ 43 + .buffer = buf, \ 44 + .bufsize = bufsiz, \ 45 + .pdrv = platdrv, \ 46 + .requested_id = EARLY_PLATFORM_ID_UNSET, \ 47 + }; \ 48 + static int __init early_platform_driver_setup_func(char *buffer) \ 49 + { \ 50 + return early_platform_driver_register(&early_driver, buffer); \ 51 + } \ 52 + early_param(class_string, early_platform_driver_setup_func) 53 + #else /* MODULE */ 54 + #define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ 55 + static inline char *early_platform_driver_setup_func(void) \ 56 + { \ 57 + return bufsiz ? buf : NULL; \ 58 + } 59 + #endif /* MODULE */ 60 + 61 + #endif /* __PLATFORM_EARLY__ */
+1
arch/sh/kernel/cpu/sh2/setup-sh7619.c
··· 12 12 #include <linux/sh_eth.h> 13 13 #include <linux/sh_timer.h> 14 14 #include <linux/io.h> 15 + #include <asm/platform_early.h> 15 16 16 17 enum { 17 18 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh2a/setup-mxg.c
··· 9 9 #include <linux/serial.h> 10 10 #include <linux/serial_sci.h> 11 11 #include <linux/sh_timer.h> 12 + #include <asm/platform_early.h> 12 13 13 14 enum { 14 15 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh2a/setup-sh7201.c
··· 11 11 #include <linux/serial_sci.h> 12 12 #include <linux/sh_timer.h> 13 13 #include <linux/io.h> 14 + #include <asm/platform_early.h> 14 15 15 16 enum { 16 17 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh2a/setup-sh7203.c
··· 10 10 #include <linux/serial_sci.h> 11 11 #include <linux/sh_timer.h> 12 12 #include <linux/io.h> 13 + #include <asm/platform_early.h> 13 14 14 15 enum { 15 16 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh2a/setup-sh7206.c
··· 11 11 #include <linux/serial_sci.h> 12 12 #include <linux/sh_timer.h> 13 13 #include <linux/io.h> 14 + #include <asm/platform_early.h> 14 15 15 16 enum { 16 17 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh2a/setup-sh7264.c
··· 11 11 #include <linux/usb/r8a66597.h> 12 12 #include <linux/sh_timer.h> 13 13 #include <linux/io.h> 14 + #include <asm/platform_early.h> 14 15 15 16 enum { 16 17 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh2a/setup-sh7269.c
··· 12 12 #include <linux/usb/r8a66597.h> 13 13 #include <linux/sh_timer.h> 14 14 #include <linux/io.h> 15 + #include <asm/platform_early.h> 15 16 16 17 enum { 17 18 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh3/setup-sh3.c
··· 8 8 #include <linux/init.h> 9 9 #include <linux/irq.h> 10 10 #include <linux/io.h> 11 + #include <asm/platform_early.h> 11 12 12 13 /* All SH3 devices are equipped with IRQ0->5 (except sh7708) */ 13 14
+1
arch/sh/kernel/cpu/sh3/setup-sh7705.c
··· 14 14 #include <linux/sh_intc.h> 15 15 #include <asm/rtc.h> 16 16 #include <cpu/serial.h> 17 + #include <asm/platform_early.h> 17 18 18 19 enum { 19 20 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh3/setup-sh770x.c
··· 18 18 #include <linux/sh_timer.h> 19 19 #include <linux/sh_intc.h> 20 20 #include <cpu/serial.h> 21 + #include <asm/platform_early.h> 21 22 22 23 enum { 23 24 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh3/setup-sh7710.c
··· 13 13 #include <linux/sh_timer.h> 14 14 #include <linux/sh_intc.h> 15 15 #include <asm/rtc.h> 16 + #include <asm/platform_early.h> 16 17 17 18 enum { 18 19 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh3/setup-sh7720.c
··· 19 19 #include <linux/sh_intc.h> 20 20 #include <linux/usb/ohci_pdriver.h> 21 21 #include <asm/rtc.h> 22 + #include <asm/platform_early.h> 22 23 #include <cpu/serial.h> 23 24 24 25 static struct resource rtc_resources[] = {
+1
arch/sh/kernel/cpu/sh4/setup-sh4-202.c
··· 12 12 #include <linux/sh_timer.h> 13 13 #include <linux/sh_intc.h> 14 14 #include <linux/io.h> 15 + #include <asm/platform_early.h> 15 16 16 17 static struct plat_sci_port scif0_platform_data = { 17 18 .scscr = SCSCR_REIE,
+1
arch/sh/kernel/cpu/sh4/setup-sh7750.c
··· 13 13 #include <linux/sh_intc.h> 14 14 #include <linux/serial_sci.h> 15 15 #include <generated/machtypes.h> 16 + #include <asm/platform_early.h> 16 17 17 18 static struct resource rtc_resources[] = { 18 19 [0] = {
+1
arch/sh/kernel/cpu/sh4/setup-sh7760.c
··· 11 11 #include <linux/sh_intc.h> 12 12 #include <linux/serial_sci.h> 13 13 #include <linux/io.h> 14 + #include <asm/platform_early.h> 14 15 15 16 enum { 16 17 UNUSED = 0,
+1
arch/sh/kernel/cpu/sh4a/setup-sh7343.c
··· 12 12 #include <linux/sh_timer.h> 13 13 #include <linux/sh_intc.h> 14 14 #include <asm/clock.h> 15 + #include <asm/platform_early.h> 15 16 16 17 /* Serial */ 17 18 static struct plat_sci_port scif0_platform_data = {
+1
arch/sh/kernel/cpu/sh4a/setup-sh7366.c
··· 15 15 #include <linux/sh_intc.h> 16 16 #include <linux/usb/r8a66597.h> 17 17 #include <asm/clock.h> 18 + #include <asm/platform_early.h> 18 19 19 20 static struct plat_sci_port scif0_platform_data = { 20 21 .scscr = SCSCR_REIE,
+1
arch/sh/kernel/cpu/sh4a/setup-sh7722.c
··· 18 18 #include <asm/clock.h> 19 19 #include <asm/mmzone.h> 20 20 #include <asm/siu.h> 21 + #include <asm/platform_early.h> 21 22 22 23 #include <cpu/dma-register.h> 23 24 #include <cpu/sh7722.h>
+1
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
··· 16 16 #include <linux/io.h> 17 17 #include <asm/clock.h> 18 18 #include <asm/mmzone.h> 19 + #include <asm/platform_early.h> 19 20 #include <cpu/sh7723.h> 20 21 21 22 /* Serial */
+1
arch/sh/kernel/cpu/sh4a/setup-sh7724.c
··· 24 24 #include <asm/suspend.h> 25 25 #include <asm/clock.h> 26 26 #include <asm/mmzone.h> 27 + #include <asm/platform_early.h> 27 28 28 29 #include <cpu/dma-register.h> 29 30 #include <cpu/sh7724.h>
+1
arch/sh/kernel/cpu/sh4a/setup-sh7734.c
··· 18 18 #include <linux/io.h> 19 19 #include <asm/clock.h> 20 20 #include <asm/irq.h> 21 + #include <asm/platform_early.h> 21 22 #include <cpu/sh7734.h> 22 23 23 24 /* SCIF */
+1
arch/sh/kernel/cpu/sh4a/setup-sh7757.c
··· 19 19 #include <linux/usb/ohci_pdriver.h> 20 20 #include <cpu/dma-register.h> 21 21 #include <cpu/sh7757.h> 22 + #include <asm/platform_early.h> 22 23 23 24 static struct plat_sci_port scif2_platform_data = { 24 25 .scscr = SCSCR_REIE,
+1
arch/sh/kernel/cpu/sh4a/setup-sh7763.c
··· 14 14 #include <linux/io.h> 15 15 #include <linux/serial_sci.h> 16 16 #include <linux/usb/ohci_pdriver.h> 17 + #include <asm/platform_early.h> 17 18 18 19 static struct plat_sci_port scif0_platform_data = { 19 20 .scscr = SCSCR_REIE,
+1
arch/sh/kernel/cpu/sh4a/setup-sh7770.c
··· 11 11 #include <linux/sh_timer.h> 12 12 #include <linux/sh_intc.h> 13 13 #include <linux/io.h> 14 + #include <asm/platform_early.h> 14 15 15 16 static struct plat_sci_port scif0_platform_data = { 16 17 .scscr = SCSCR_REIE | SCSCR_TOIE,
+1
arch/sh/kernel/cpu/sh4a/setup-sh7780.c
··· 13 13 #include <linux/sh_timer.h> 14 14 #include <linux/sh_intc.h> 15 15 #include <cpu/dma-register.h> 16 + #include <asm/platform_early.h> 16 17 17 18 static struct plat_sci_port scif0_platform_data = { 18 19 .scscr = SCSCR_REIE | SCSCR_CKE1,
+1
arch/sh/kernel/cpu/sh4a/setup-sh7785.c
··· 14 14 #include <linux/sh_timer.h> 15 15 #include <linux/sh_intc.h> 16 16 #include <asm/mmzone.h> 17 + #include <asm/platform_early.h> 17 18 #include <cpu/dma-register.h> 18 19 19 20 static struct plat_sci_port scif0_platform_data = {
+1
arch/sh/kernel/cpu/sh4a/setup-sh7786.c
··· 23 23 #include <linux/usb/ohci_pdriver.h> 24 24 #include <cpu/dma-register.h> 25 25 #include <asm/mmzone.h> 26 + #include <asm/platform_early.h> 26 27 27 28 static struct plat_sci_port scif0_platform_data = { 28 29 .scscr = SCSCR_REIE | SCSCR_CKE1,
+1
arch/sh/kernel/cpu/sh4a/setup-shx3.c
··· 14 14 #include <linux/sh_intc.h> 15 15 #include <cpu/shx3.h> 16 16 #include <asm/mmzone.h> 17 + #include <asm/platform_early.h> 17 18 18 19 /* 19 20 * This intentionally only registers SCIF ports 0, 1, and 3. SCIF 2
+1
arch/sh/kernel/cpu/sh5/setup-sh5.c
··· 12 12 #include <linux/mm.h> 13 13 #include <linux/sh_timer.h> 14 14 #include <asm/addrspace.h> 15 + #include <asm/platform_early.h> 15 16 16 17 static struct plat_sci_port scif0_platform_data = { 17 18 .flags = UPF_IOREMAP,
+1
arch/sh/kernel/setup.c
··· 44 44 #include <asm/mmu_context.h> 45 45 #include <asm/mmzone.h> 46 46 #include <asm/sparsemem.h> 47 + #include <asm/platform_early.h> 47 48 48 49 /* 49 50 * Initialize loops_per_jiffy as 10000000 (1000MIPS).
+1
arch/sh/kernel/time.c
··· 18 18 #include <linux/rtc.h> 19 19 #include <asm/clock.h> 20 20 #include <asm/rtc.h> 21 + #include <asm/platform_early.h> 21 22 22 23 static void __init sh_late_time_init(void) 23 24 {
-288
drivers/base/platform.c
··· 1264 1264 { 1265 1265 int error; 1266 1266 1267 - early_platform_cleanup(); 1268 - 1269 1267 error = device_register(&platform_bus); 1270 1268 if (error) { 1271 1269 put_device(&platform_bus); ··· 1275 1277 of_platform_register_reconfig_notifier(); 1276 1278 return error; 1277 1279 } 1278 - 1279 - static __initdata LIST_HEAD(early_platform_driver_list); 1280 - static __initdata LIST_HEAD(early_platform_device_list); 1281 - 1282 - /** 1283 - * early_platform_driver_register - register early platform driver 1284 - * @epdrv: early_platform driver structure 1285 - * @buf: string passed from early_param() 1286 - * 1287 - * Helper function for early_platform_init() / early_platform_init_buffer() 1288 - */ 1289 - int __init early_platform_driver_register(struct early_platform_driver *epdrv, 1290 - char *buf) 1291 - { 1292 - char *tmp; 1293 - int n; 1294 - 1295 - /* Simply add the driver to the end of the global list. 1296 - * Drivers will by default be put on the list in compiled-in order. 1297 - */ 1298 - if (!epdrv->list.next) { 1299 - INIT_LIST_HEAD(&epdrv->list); 1300 - list_add_tail(&epdrv->list, &early_platform_driver_list); 1301 - } 1302 - 1303 - /* If the user has specified device then make sure the driver 1304 - * gets prioritized. The driver of the last device specified on 1305 - * command line will be put first on the list. 1306 - */ 1307 - n = strlen(epdrv->pdrv->driver.name); 1308 - if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) { 1309 - list_move(&epdrv->list, &early_platform_driver_list); 1310 - 1311 - /* Allow passing parameters after device name */ 1312 - if (buf[n] == '\0' || buf[n] == ',') 1313 - epdrv->requested_id = -1; 1314 - else { 1315 - epdrv->requested_id = simple_strtoul(&buf[n + 1], 1316 - &tmp, 10); 1317 - 1318 - if (buf[n] != '.' || (tmp == &buf[n + 1])) { 1319 - epdrv->requested_id = EARLY_PLATFORM_ID_ERROR; 1320 - n = 0; 1321 - } else 1322 - n += strcspn(&buf[n + 1], ",") + 1; 1323 - } 1324 - 1325 - if (buf[n] == ',') 1326 - n++; 1327 - 1328 - if (epdrv->bufsize) { 1329 - memcpy(epdrv->buffer, &buf[n], 1330 - min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1)); 1331 - epdrv->buffer[epdrv->bufsize - 1] = '\0'; 1332 - } 1333 - } 1334 - 1335 - return 0; 1336 - } 1337 - 1338 - /** 1339 - * early_platform_add_devices - adds a number of early platform devices 1340 - * @devs: array of early platform devices to add 1341 - * @num: number of early platform devices in array 1342 - * 1343 - * Used by early architecture code to register early platform devices and 1344 - * their platform data. 1345 - */ 1346 - void __init early_platform_add_devices(struct platform_device **devs, int num) 1347 - { 1348 - struct device *dev; 1349 - int i; 1350 - 1351 - /* simply add the devices to list */ 1352 - for (i = 0; i < num; i++) { 1353 - dev = &devs[i]->dev; 1354 - 1355 - if (!dev->devres_head.next) { 1356 - pm_runtime_early_init(dev); 1357 - INIT_LIST_HEAD(&dev->devres_head); 1358 - list_add_tail(&dev->devres_head, 1359 - &early_platform_device_list); 1360 - } 1361 - } 1362 - } 1363 - 1364 - /** 1365 - * early_platform_driver_register_all - register early platform drivers 1366 - * @class_str: string to identify early platform driver class 1367 - * 1368 - * Used by architecture code to register all early platform drivers 1369 - * for a certain class. If omitted then only early platform drivers 1370 - * with matching kernel command line class parameters will be registered. 1371 - */ 1372 - void __init early_platform_driver_register_all(char *class_str) 1373 - { 1374 - /* The "class_str" parameter may or may not be present on the kernel 1375 - * command line. If it is present then there may be more than one 1376 - * matching parameter. 1377 - * 1378 - * Since we register our early platform drivers using early_param() 1379 - * we need to make sure that they also get registered in the case 1380 - * when the parameter is missing from the kernel command line. 1381 - * 1382 - * We use parse_early_options() to make sure the early_param() gets 1383 - * called at least once. The early_param() may be called more than 1384 - * once since the name of the preferred device may be specified on 1385 - * the kernel command line. early_platform_driver_register() handles 1386 - * this case for us. 1387 - */ 1388 - parse_early_options(class_str); 1389 - } 1390 - 1391 - /** 1392 - * early_platform_match - find early platform device matching driver 1393 - * @epdrv: early platform driver structure 1394 - * @id: id to match against 1395 - */ 1396 - static struct platform_device * __init 1397 - early_platform_match(struct early_platform_driver *epdrv, int id) 1398 - { 1399 - struct platform_device *pd; 1400 - 1401 - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) 1402 - if (platform_match(&pd->dev, &epdrv->pdrv->driver)) 1403 - if (pd->id == id) 1404 - return pd; 1405 - 1406 - return NULL; 1407 - } 1408 - 1409 - /** 1410 - * early_platform_left - check if early platform driver has matching devices 1411 - * @epdrv: early platform driver structure 1412 - * @id: return true if id or above exists 1413 - */ 1414 - static int __init early_platform_left(struct early_platform_driver *epdrv, 1415 - int id) 1416 - { 1417 - struct platform_device *pd; 1418 - 1419 - list_for_each_entry(pd, &early_platform_device_list, dev.devres_head) 1420 - if (platform_match(&pd->dev, &epdrv->pdrv->driver)) 1421 - if (pd->id >= id) 1422 - return 1; 1423 - 1424 - return 0; 1425 - } 1426 - 1427 - /** 1428 - * early_platform_driver_probe_id - probe drivers matching class_str and id 1429 - * @class_str: string to identify early platform driver class 1430 - * @id: id to match against 1431 - * @nr_probe: number of platform devices to successfully probe before exiting 1432 - */ 1433 - static int __init early_platform_driver_probe_id(char *class_str, 1434 - int id, 1435 - int nr_probe) 1436 - { 1437 - struct early_platform_driver *epdrv; 1438 - struct platform_device *match; 1439 - int match_id; 1440 - int n = 0; 1441 - int left = 0; 1442 - 1443 - list_for_each_entry(epdrv, &early_platform_driver_list, list) { 1444 - /* only use drivers matching our class_str */ 1445 - if (strcmp(class_str, epdrv->class_str)) 1446 - continue; 1447 - 1448 - if (id == -2) { 1449 - match_id = epdrv->requested_id; 1450 - left = 1; 1451 - 1452 - } else { 1453 - match_id = id; 1454 - left += early_platform_left(epdrv, id); 1455 - 1456 - /* skip requested id */ 1457 - switch (epdrv->requested_id) { 1458 - case EARLY_PLATFORM_ID_ERROR: 1459 - case EARLY_PLATFORM_ID_UNSET: 1460 - break; 1461 - default: 1462 - if (epdrv->requested_id == id) 1463 - match_id = EARLY_PLATFORM_ID_UNSET; 1464 - } 1465 - } 1466 - 1467 - switch (match_id) { 1468 - case EARLY_PLATFORM_ID_ERROR: 1469 - pr_warn("%s: unable to parse %s parameter\n", 1470 - class_str, epdrv->pdrv->driver.name); 1471 - /* fall-through */ 1472 - case EARLY_PLATFORM_ID_UNSET: 1473 - match = NULL; 1474 - break; 1475 - default: 1476 - match = early_platform_match(epdrv, match_id); 1477 - } 1478 - 1479 - if (match) { 1480 - /* 1481 - * Set up a sensible init_name to enable 1482 - * dev_name() and others to be used before the 1483 - * rest of the driver core is initialized. 1484 - */ 1485 - if (!match->dev.init_name && slab_is_available()) { 1486 - if (match->id != -1) 1487 - match->dev.init_name = 1488 - kasprintf(GFP_KERNEL, "%s.%d", 1489 - match->name, 1490 - match->id); 1491 - else 1492 - match->dev.init_name = 1493 - kasprintf(GFP_KERNEL, "%s", 1494 - match->name); 1495 - 1496 - if (!match->dev.init_name) 1497 - return -ENOMEM; 1498 - } 1499 - 1500 - if (epdrv->pdrv->probe(match)) 1501 - pr_warn("%s: unable to probe %s early.\n", 1502 - class_str, match->name); 1503 - else 1504 - n++; 1505 - } 1506 - 1507 - if (n >= nr_probe) 1508 - break; 1509 - } 1510 - 1511 - if (left) 1512 - return n; 1513 - else 1514 - return -ENODEV; 1515 - } 1516 - 1517 - /** 1518 - * early_platform_driver_probe - probe a class of registered drivers 1519 - * @class_str: string to identify early platform driver class 1520 - * @nr_probe: number of platform devices to successfully probe before exiting 1521 - * @user_only: only probe user specified early platform devices 1522 - * 1523 - * Used by architecture code to probe registered early platform drivers 1524 - * within a certain class. For probe to happen a registered early platform 1525 - * device matching a registered early platform driver is needed. 1526 - */ 1527 - int __init early_platform_driver_probe(char *class_str, 1528 - int nr_probe, 1529 - int user_only) 1530 - { 1531 - int k, n, i; 1532 - 1533 - n = 0; 1534 - for (i = -2; n < nr_probe; i++) { 1535 - k = early_platform_driver_probe_id(class_str, i, nr_probe - n); 1536 - 1537 - if (k < 0) 1538 - break; 1539 - 1540 - n += k; 1541 - 1542 - if (user_only) 1543 - break; 1544 - } 1545 - 1546 - return n; 1547 - } 1548 - 1549 - /** 1550 - * early_platform_cleanup - clean up early platform code 1551 - */ 1552 - void __init early_platform_cleanup(void) 1553 - { 1554 - struct platform_device *pd, *pd2; 1555 - 1556 - /* clean up the devres list used to chain devices */ 1557 - list_for_each_entry_safe(pd, pd2, &early_platform_device_list, 1558 - dev.devres_head) { 1559 - list_del(&pd->dev.devres_head); 1560 - memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head)); 1561 - } 1562 - } 1563 -
+7
drivers/clocksource/sh_cmt.c
··· 25 25 #include <linux/slab.h> 26 26 #include <linux/spinlock.h> 27 27 28 + #ifdef CONFIG_SUPERH 29 + #include <asm/platform_early.h> 30 + #endif 31 + 28 32 struct sh_cmt_device; 29 33 30 34 /* ··· 1113 1109 platform_driver_unregister(&sh_cmt_device_driver); 1114 1110 } 1115 1111 1112 + #ifdef CONFIG_SUPERH 1116 1113 early_platform_init("earlytimer", &sh_cmt_device_driver); 1114 + #endif 1115 + 1117 1116 subsys_initcall(sh_cmt_init); 1118 1117 module_exit(sh_cmt_exit); 1119 1118
+7
drivers/clocksource/sh_mtu2.c
··· 23 23 #include <linux/slab.h> 24 24 #include <linux/spinlock.h> 25 25 26 + #ifdef CONFIG_SUPERH 27 + #include <asm/platform_early.h> 28 + #endif 29 + 26 30 struct sh_mtu2_device; 27 31 28 32 struct sh_mtu2_channel { ··· 515 511 platform_driver_unregister(&sh_mtu2_device_driver); 516 512 } 517 513 514 + #ifdef CONFIG_SUPERH 518 515 early_platform_init("earlytimer", &sh_mtu2_device_driver); 516 + #endif 517 + 519 518 subsys_initcall(sh_mtu2_init); 520 519 module_exit(sh_mtu2_exit); 521 520
+8
drivers/clocksource/sh_tmu.c
··· 24 24 #include <linux/slab.h> 25 25 #include <linux/spinlock.h> 26 26 27 + #ifdef CONFIG_SUPERH 28 + #include <asm/platform_early.h> 29 + #endif 30 + 27 31 enum sh_tmu_model { 28 32 SH_TMU, 29 33 SH_TMU_SH3, ··· 619 615 pm_runtime_idle(&pdev->dev); 620 616 return ret; 621 617 } 618 + 622 619 if (is_early_platform_device(pdev)) 623 620 return 0; 624 621 ··· 670 665 platform_driver_unregister(&sh_tmu_device_driver); 671 666 } 672 667 668 + #ifdef CONFIG_SUPERH 673 669 early_platform_init("earlytimer", &sh_tmu_device_driver); 670 + #endif 671 + 674 672 subsys_initcall(sh_tmu_init); 675 673 module_exit(sh_tmu_exit); 676 674
+6 -1
drivers/tty/serial/sh-sci.c
··· 54 54 55 55 #ifdef CONFIG_SUPERH 56 56 #include <asm/sh_bios.h> 57 + #include <asm/platform_early.h> 57 58 #endif 58 59 59 60 #include "serial_mctrl_gpio.h" ··· 3087 3086 .data = &sci_uart_driver, 3088 3087 }; 3089 3088 3089 + #ifdef CONFIG_SUPERH 3090 3090 static struct console early_serial_console = { 3091 3091 .name = "early_ttySC", 3092 3092 .write = serial_console_write, ··· 3116 3114 register_console(&early_serial_console); 3117 3115 return 0; 3118 3116 } 3117 + #endif 3119 3118 3120 3119 #define SCI_CONSOLE (&serial_console) 3121 3120 ··· 3317 3314 * the special early probe. We don't have sufficient device state 3318 3315 * to make it beyond this yet. 3319 3316 */ 3317 + #ifdef CONFIG_SUPERH 3320 3318 if (is_early_platform_device(dev)) 3321 3319 return sci_probe_earlyprintk(dev); 3320 + #endif 3322 3321 3323 3322 if (dev->dev.of_node) { 3324 3323 p = sci_parse_dt(dev, &dev_id); ··· 3415 3410 uart_unregister_driver(&sci_uart_driver); 3416 3411 } 3417 3412 3418 - #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE 3413 + #if defined(CONFIG_SUPERH) && defined(CONFIG_SERIAL_SH_SCI_CONSOLE) 3419 3414 early_platform_init_buffer("earlyprintk", &sci_driver, 3420 3415 early_serial_buf, ARRAY_SIZE(early_serial_buf)); 3421 3416 #endif
+12 -52
include/linux/platform_device.h
··· 292 292 #define platform_register_drivers(drivers, count) \ 293 293 __platform_register_drivers(drivers, count, THIS_MODULE) 294 294 295 - /* early platform driver interface */ 296 - struct early_platform_driver { 297 - const char *class_str; 298 - struct platform_driver *pdrv; 299 - struct list_head list; 300 - int requested_id; 301 - char *buffer; 302 - int bufsize; 303 - }; 304 - 305 - #define EARLY_PLATFORM_ID_UNSET -2 306 - #define EARLY_PLATFORM_ID_ERROR -3 307 - 308 - extern int early_platform_driver_register(struct early_platform_driver *epdrv, 309 - char *buf); 310 - extern void early_platform_add_devices(struct platform_device **devs, int num); 311 - 312 - static inline int is_early_platform_device(struct platform_device *pdev) 313 - { 314 - return !pdev->dev.driver; 315 - } 316 - 317 - extern void early_platform_driver_register_all(char *class_str); 318 - extern int early_platform_driver_probe(char *class_str, 319 - int nr_probe, int user_only); 320 - extern void early_platform_cleanup(void); 321 - 322 - #define early_platform_init(class_string, platdrv) \ 323 - early_platform_init_buffer(class_string, platdrv, NULL, 0) 324 - 325 - #ifndef MODULE 326 - #define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ 327 - static __initdata struct early_platform_driver early_driver = { \ 328 - .class_str = class_string, \ 329 - .buffer = buf, \ 330 - .bufsize = bufsiz, \ 331 - .pdrv = platdrv, \ 332 - .requested_id = EARLY_PLATFORM_ID_UNSET, \ 333 - }; \ 334 - static int __init early_platform_driver_setup_func(char *buffer) \ 335 - { \ 336 - return early_platform_driver_register(&early_driver, buffer); \ 337 - } \ 338 - early_param(class_string, early_platform_driver_setup_func) 339 - #else /* MODULE */ 340 - #define early_platform_init_buffer(class_string, platdrv, buf, bufsiz) \ 341 - static inline char *early_platform_driver_setup_func(void) \ 342 - { \ 343 - return bufsiz ? buf : NULL; \ 344 - } 345 - #endif /* MODULE */ 346 - 347 295 #ifdef CONFIG_SUSPEND 348 296 extern int platform_pm_suspend(struct device *dev); 349 297 extern int platform_pm_resume(struct device *dev); ··· 325 377 #else 326 378 #define USE_PLATFORM_PM_SLEEP_OPS 327 379 #endif 380 + 381 + #ifndef CONFIG_SUPERH 382 + /* 383 + * REVISIT: This stub is needed for all non-SuperH users of early platform 384 + * drivers. It should go away once we introduce the new platform_device-based 385 + * early driver framework. 386 + */ 387 + static inline int is_early_platform_device(struct platform_device *pdev) 388 + { 389 + return 0; 390 + } 391 + #endif /* CONFIG_SUPERH */ 328 392 329 393 #endif /* _PLATFORM_DEVICE_H_ */