linux/arch/sh/drivers/platform_early.c
<<
>>
Prefs
   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
   7static __initdata LIST_HEAD(sh_early_platform_driver_list);
   8static __initdata LIST_HEAD(sh_early_platform_device_list);
   9
  10static const struct platform_device_id *
  11platform_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
  24static 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
  42static 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
  51static void pm_runtime_early_init(struct device *dev)
  52{
  53        dev->power.disable_depth = 1;
  54        device_pm_init_common(dev);
  55}
  56#else
  57static void pm_runtime_early_init(struct device *dev) {}
  58#endif
  59
  60/**
  61 * sh_early_platform_driver_register - register early platform driver
  62 * @epdrv: sh_early_platform driver structure
  63 * @buf: string passed from early_param()
  64 *
  65 * Helper function for sh_early_platform_init() / sh_early_platform_init_buffer()
  66 */
  67int __init sh_early_platform_driver_register(struct sh_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, &sh_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, &sh_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 * sh_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 */
 124void __init sh_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                                      &sh_early_platform_device_list);
 138                }
 139        }
 140}
 141
 142/**
 143 * sh_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 */
 150void __init sh_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. sh_early_platform_driver_register() handles
 164         * this case for us.
 165         */
 166        parse_early_options(class_str);
 167}
 168
 169/**
 170 * sh_early_platform_match - find early platform device matching driver
 171 * @epdrv: early platform driver structure
 172 * @id: id to match against
 173 */
 174static struct platform_device * __init
 175sh_early_platform_match(struct sh_early_platform_driver *epdrv, int id)
 176{
 177        struct platform_device *pd;
 178
 179        list_for_each_entry(pd, &sh_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 * sh_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 */
 192static int __init sh_early_platform_left(struct sh_early_platform_driver *epdrv,
 193                                       int id)
 194{
 195        struct platform_device *pd;
 196
 197        list_for_each_entry(pd, &sh_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 * sh_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 */
 211static int __init sh_early_platform_driver_probe_id(char *class_str,
 212                                                 int id,
 213                                                 int nr_probe)
 214{
 215        struct sh_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, &sh_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 += sh_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                        fallthrough;
 250                case EARLY_PLATFORM_ID_UNSET:
 251                        match = NULL;
 252                        break;
 253                default:
 254                        match = sh_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 * sh_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 */
 305int __init sh_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 = sh_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 */
 330void __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, &sh_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