linux/drivers/of/device.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/string.h>
   3#include <linux/kernel.h>
   4#include <linux/of.h>
   5#include <linux/of_device.h>
   6#include <linux/of_address.h>
   7#include <linux/of_iommu.h>
   8#include <linux/dma-mapping.h>
   9#include <linux/init.h>
  10#include <linux/module.h>
  11#include <linux/mod_devicetable.h>
  12#include <linux/slab.h>
  13#include <linux/platform_device.h>
  14
  15#include <asm/errno.h>
  16#include "of_private.h"
  17
  18/**
  19 * of_match_device - Tell if a struct device matches an of_device_id list
  20 * @matches: array of of device match structures to search in
  21 * @dev: the of device structure to match against
  22 *
  23 * Used by a driver to check whether an platform_device present in the
  24 * system is in its list of supported devices.
  25 */
  26const struct of_device_id *of_match_device(const struct of_device_id *matches,
  27                                           const struct device *dev)
  28{
  29        if ((!matches) || (!dev->of_node))
  30                return NULL;
  31        return of_match_node(matches, dev->of_node);
  32}
  33EXPORT_SYMBOL(of_match_device);
  34
  35struct platform_device *of_dev_get(struct platform_device *dev)
  36{
  37        struct device *tmp;
  38
  39        if (!dev)
  40                return NULL;
  41        tmp = get_device(&dev->dev);
  42        if (tmp)
  43                return to_platform_device(tmp);
  44        else
  45                return NULL;
  46}
  47EXPORT_SYMBOL(of_dev_get);
  48
  49void of_dev_put(struct platform_device *dev)
  50{
  51        if (dev)
  52                put_device(&dev->dev);
  53}
  54EXPORT_SYMBOL(of_dev_put);
  55
  56int of_device_add(struct platform_device *ofdev)
  57{
  58        BUG_ON(ofdev->dev.of_node == NULL);
  59
  60        /* name and id have to be set so that the platform bus doesn't get
  61         * confused on matching */
  62        ofdev->name = dev_name(&ofdev->dev);
  63        ofdev->id = PLATFORM_DEVID_NONE;
  64
  65        /*
  66         * If this device has not binding numa node in devicetree, that is
  67         * of_node_to_nid returns NUMA_NO_NODE. device_add will assume that this
  68         * device is on the same node as the parent.
  69         */
  70        set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node));
  71
  72        return device_add(&ofdev->dev);
  73}
  74
  75/**
  76 * of_dma_configure - Setup DMA configuration
  77 * @dev:        Device to apply DMA configuration
  78 * @np:         Pointer to OF node having DMA configuration
  79 * @force_dma:  Whether device is to be set up by of_dma_configure() even if
  80 *              DMA capability is not explicitly described by firmware.
  81 *
  82 * Try to get devices's DMA configuration from DT and update it
  83 * accordingly.
  84 *
  85 * If platform code needs to use its own special DMA configuration, it
  86 * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events
  87 * to fix up DMA configuration.
  88 */
  89int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
  90{
  91        u64 dma_addr, paddr, size = 0;
  92        int ret;
  93        bool coherent;
  94        unsigned long offset;
  95        const struct iommu_ops *iommu;
  96        u64 mask, end;
  97
  98        ret = of_dma_get_range(np, &dma_addr, &paddr, &size);
  99        if (ret < 0) {
 100                /*
 101                 * For legacy reasons, we have to assume some devices need
 102                 * DMA configuration regardless of whether "dma-ranges" is
 103                 * correctly specified or not.
 104                 */
 105                if (!force_dma)
 106                        return ret == -ENODEV ? 0 : ret;
 107
 108                dma_addr = offset = 0;
 109        } else {
 110                offset = PFN_DOWN(paddr - dma_addr);
 111
 112                /*
 113                 * Add a work around to treat the size as mask + 1 in case
 114                 * it is defined in DT as a mask.
 115                 */
 116                if (size & 1) {
 117                        dev_warn(dev, "Invalid size 0x%llx for dma-range\n",
 118                                 size);
 119                        size = size + 1;
 120                }
 121
 122                if (!size) {
 123                        dev_err(dev, "Adjusted size 0x%llx invalid\n", size);
 124                        return -EINVAL;
 125                }
 126                dev_dbg(dev, "dma_pfn_offset(%#08lx)\n", offset);
 127        }
 128
 129        /*
 130         * If @dev is expected to be DMA-capable then the bus code that created
 131         * it should have initialised its dma_mask pointer by this point. For
 132         * now, we'll continue the legacy behaviour of coercing it to the
 133         * coherent mask if not, but we'll no longer do so quietly.
 134         */
 135        if (!dev->dma_mask) {
 136                dev_warn(dev, "DMA mask not set\n");
 137                dev->dma_mask = &dev->coherent_dma_mask;
 138        }
 139
 140        if (!size && dev->coherent_dma_mask)
 141                size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 142        else if (!size)
 143                size = 1ULL << 32;
 144
 145        dev->dma_pfn_offset = offset;
 146
 147        /*
 148         * Limit coherent and dma mask based on size and default mask
 149         * set by the driver.
 150         */
 151        end = dma_addr + size - 1;
 152        mask = DMA_BIT_MASK(ilog2(end) + 1);
 153        dev->coherent_dma_mask &= mask;
 154        *dev->dma_mask &= mask;
 155        /* ...but only set bus limit if we found valid dma-ranges earlier */
 156        if (!ret)
 157                dev->bus_dma_limit = end;
 158
 159        coherent = of_dma_is_coherent(np);
 160        dev_dbg(dev, "device is%sdma coherent\n",
 161                coherent ? " " : " not ");
 162
 163        iommu = of_iommu_configure(dev, np);
 164        if (PTR_ERR(iommu) == -EPROBE_DEFER)
 165                return -EPROBE_DEFER;
 166
 167        dev_dbg(dev, "device is%sbehind an iommu\n",
 168                iommu ? " " : " not ");
 169
 170        arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
 171
 172        return 0;
 173}
 174EXPORT_SYMBOL_GPL(of_dma_configure);
 175
 176int of_device_register(struct platform_device *pdev)
 177{
 178        device_initialize(&pdev->dev);
 179        return of_device_add(pdev);
 180}
 181EXPORT_SYMBOL(of_device_register);
 182
 183void of_device_unregister(struct platform_device *ofdev)
 184{
 185        device_unregister(&ofdev->dev);
 186}
 187EXPORT_SYMBOL(of_device_unregister);
 188
 189const void *of_device_get_match_data(const struct device *dev)
 190{
 191        const struct of_device_id *match;
 192
 193        match = of_match_device(dev->driver->of_match_table, dev);
 194        if (!match)
 195                return NULL;
 196
 197        return match->data;
 198}
 199EXPORT_SYMBOL(of_device_get_match_data);
 200
 201static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 202{
 203        const char *compat;
 204        char *c;
 205        struct property *p;
 206        ssize_t csize;
 207        ssize_t tsize;
 208
 209        if ((!dev) || (!dev->of_node))
 210                return -ENODEV;
 211
 212        /* Name & Type */
 213        /* %p eats all alphanum characters, so %c must be used here */
 214        csize = snprintf(str, len, "of:N%pOFn%c%s", dev->of_node, 'T',
 215                         of_node_get_device_type(dev->of_node));
 216        tsize = csize;
 217        len -= csize;
 218        if (str)
 219                str += csize;
 220
 221        of_property_for_each_string(dev->of_node, "compatible", p, compat) {
 222                csize = strlen(compat) + 1;
 223                tsize += csize;
 224                if (csize > len)
 225                        continue;
 226
 227                csize = snprintf(str, len, "C%s", compat);
 228                for (c = str; c; ) {
 229                        c = strchr(c, ' ');
 230                        if (c)
 231                                *c++ = '_';
 232                }
 233                len -= csize;
 234                str += csize;
 235        }
 236
 237        return tsize;
 238}
 239
 240int of_device_request_module(struct device *dev)
 241{
 242        char *str;
 243        ssize_t size;
 244        int ret;
 245
 246        size = of_device_get_modalias(dev, NULL, 0);
 247        if (size < 0)
 248                return size;
 249
 250        str = kmalloc(size + 1, GFP_KERNEL);
 251        if (!str)
 252                return -ENOMEM;
 253
 254        of_device_get_modalias(dev, str, size);
 255        str[size] = '\0';
 256        ret = request_module(str);
 257        kfree(str);
 258
 259        return ret;
 260}
 261EXPORT_SYMBOL_GPL(of_device_request_module);
 262
 263/**
 264 * of_device_modalias - Fill buffer with newline terminated modalias string
 265 */
 266ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
 267{
 268        ssize_t sl = of_device_get_modalias(dev, str, len - 2);
 269        if (sl < 0)
 270                return sl;
 271        if (sl > len - 2)
 272                return -ENOMEM;
 273
 274        str[sl++] = '\n';
 275        str[sl] = 0;
 276        return sl;
 277}
 278EXPORT_SYMBOL_GPL(of_device_modalias);
 279
 280/**
 281 * of_device_uevent - Display OF related uevent information
 282 */
 283void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 284{
 285        const char *compat, *type;
 286        struct alias_prop *app;
 287        struct property *p;
 288        int seen = 0;
 289
 290        if ((!dev) || (!dev->of_node))
 291                return;
 292
 293        add_uevent_var(env, "OF_NAME=%pOFn", dev->of_node);
 294        add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node);
 295        type = of_node_get_device_type(dev->of_node);
 296        if (type)
 297                add_uevent_var(env, "OF_TYPE=%s", type);
 298
 299        /* Since the compatible field can contain pretty much anything
 300         * it's not really legal to split it out with commas. We split it
 301         * up using a number of environment variables instead. */
 302        of_property_for_each_string(dev->of_node, "compatible", p, compat) {
 303                add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
 304                seen++;
 305        }
 306        add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
 307
 308        seen = 0;
 309        mutex_lock(&of_mutex);
 310        list_for_each_entry(app, &aliases_lookup, link) {
 311                if (dev->of_node == app->np) {
 312                        add_uevent_var(env, "OF_ALIAS_%d=%s", seen,
 313                                       app->alias);
 314                        seen++;
 315                }
 316        }
 317        mutex_unlock(&of_mutex);
 318}
 319
 320int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
 321{
 322        int sl;
 323
 324        if ((!dev) || (!dev->of_node))
 325                return -ENODEV;
 326
 327        /* Devicetree modalias is tricky, we add it in 2 steps */
 328        if (add_uevent_var(env, "MODALIAS="))
 329                return -ENOMEM;
 330
 331        sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
 332                                    sizeof(env->buf) - env->buflen);
 333        if (sl >= (sizeof(env->buf) - env->buflen))
 334                return -ENOMEM;
 335        env->buflen += sl;
 336
 337        return 0;
 338}
 339EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
 340