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 * @ids: 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;
  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         * Set default coherent_dma_mask to 32 bit.  Drivers are expected to
 131         * setup the correct supported mask.
 132         */
 133        if (!dev->coherent_dma_mask)
 134                dev->coherent_dma_mask = DMA_BIT_MASK(32);
 135        /*
 136         * Set it to coherent_dma_mask by default if the architecture
 137         * code has not set it.
 138         */
 139        if (!dev->dma_mask)
 140                dev->dma_mask = &dev->coherent_dma_mask;
 141
 142        if (!size)
 143                size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1);
 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        mask = DMA_BIT_MASK(ilog2(dma_addr + size - 1) + 1);
 152        dev->coherent_dma_mask &= mask;
 153        *dev->dma_mask &= mask;
 154
 155        coherent = of_dma_is_coherent(np);
 156        dev_dbg(dev, "device is%sdma coherent\n",
 157                coherent ? " " : " not ");
 158
 159        iommu = of_iommu_configure(dev, np);
 160        if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
 161                return -EPROBE_DEFER;
 162
 163        dev_dbg(dev, "device is%sbehind an iommu\n",
 164                iommu ? " " : " not ");
 165
 166        arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent);
 167
 168        return 0;
 169}
 170EXPORT_SYMBOL_GPL(of_dma_configure);
 171
 172/**
 173 * of_dma_deconfigure - Clean up DMA configuration
 174 * @dev:        Device for which to clean up DMA configuration
 175 *
 176 * Clean up all configuration performed by of_dma_configure_ops() and free all
 177 * resources that have been allocated.
 178 */
 179void of_dma_deconfigure(struct device *dev)
 180{
 181        arch_teardown_dma_ops(dev);
 182}
 183
 184int of_device_register(struct platform_device *pdev)
 185{
 186        device_initialize(&pdev->dev);
 187        return of_device_add(pdev);
 188}
 189EXPORT_SYMBOL(of_device_register);
 190
 191void of_device_unregister(struct platform_device *ofdev)
 192{
 193        device_unregister(&ofdev->dev);
 194}
 195EXPORT_SYMBOL(of_device_unregister);
 196
 197const void *of_device_get_match_data(const struct device *dev)
 198{
 199        const struct of_device_id *match;
 200
 201        match = of_match_device(dev->driver->of_match_table, dev);
 202        if (!match)
 203                return NULL;
 204
 205        return match->data;
 206}
 207EXPORT_SYMBOL(of_device_get_match_data);
 208
 209static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
 210{
 211        const char *compat;
 212        char *c;
 213        struct property *p;
 214        ssize_t csize;
 215        ssize_t tsize;
 216
 217        if ((!dev) || (!dev->of_node))
 218                return -ENODEV;
 219
 220        /* Name & Type */
 221        csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name,
 222                         dev->of_node->type);
 223        tsize = csize;
 224        len -= csize;
 225        if (str)
 226                str += csize;
 227
 228        of_property_for_each_string(dev->of_node, "compatible", p, compat) {
 229                csize = strlen(compat) + 1;
 230                tsize += csize;
 231                if (csize > len)
 232                        continue;
 233
 234                csize = snprintf(str, len, "C%s", compat);
 235                for (c = str; c; ) {
 236                        c = strchr(c, ' ');
 237                        if (c)
 238                                *c++ = '_';
 239                }
 240                len -= csize;
 241                str += csize;
 242        }
 243
 244        return tsize;
 245}
 246
 247int of_device_request_module(struct device *dev)
 248{
 249        char *str;
 250        ssize_t size;
 251        int ret;
 252
 253        size = of_device_get_modalias(dev, NULL, 0);
 254        if (size < 0)
 255                return size;
 256
 257        str = kmalloc(size + 1, GFP_KERNEL);
 258        if (!str)
 259                return -ENOMEM;
 260
 261        of_device_get_modalias(dev, str, size);
 262        str[size] = '\0';
 263        ret = request_module(str);
 264        kfree(str);
 265
 266        return ret;
 267}
 268EXPORT_SYMBOL_GPL(of_device_request_module);
 269
 270/**
 271 * of_device_modalias - Fill buffer with newline terminated modalias string
 272 */
 273ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len)
 274{
 275        ssize_t sl = of_device_get_modalias(dev, str, len - 2);
 276        if (sl < 0)
 277                return sl;
 278        if (sl > len - 2)
 279                return -ENOMEM;
 280
 281        str[sl++] = '\n';
 282        str[sl] = 0;
 283        return sl;
 284}
 285EXPORT_SYMBOL_GPL(of_device_modalias);
 286
 287/**
 288 * of_device_uevent - Display OF related uevent information
 289 */
 290void of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
 291{
 292        const char *compat;
 293        struct alias_prop *app;
 294        struct property *p;
 295        int seen = 0;
 296
 297        if ((!dev) || (!dev->of_node))
 298                return;
 299
 300        add_uevent_var(env, "OF_NAME=%s", dev->of_node->name);
 301        add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node);
 302        if (dev->of_node->type && strcmp("<NULL>", dev->of_node->type) != 0)
 303                add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type);
 304
 305        /* Since the compatible field can contain pretty much anything
 306         * it's not really legal to split it out with commas. We split it
 307         * up using a number of environment variables instead. */
 308        of_property_for_each_string(dev->of_node, "compatible", p, compat) {
 309                add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
 310                seen++;
 311        }
 312        add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
 313
 314        seen = 0;
 315        mutex_lock(&of_mutex);
 316        list_for_each_entry(app, &aliases_lookup, link) {
 317                if (dev->of_node == app->np) {
 318                        add_uevent_var(env, "OF_ALIAS_%d=%s", seen,
 319                                       app->alias);
 320                        seen++;
 321                }
 322        }
 323        mutex_unlock(&of_mutex);
 324}
 325
 326int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
 327{
 328        int sl;
 329
 330        if ((!dev) || (!dev->of_node))
 331                return -ENODEV;
 332
 333        /* Devicetree modalias is tricky, we add it in 2 steps */
 334        if (add_uevent_var(env, "MODALIAS="))
 335                return -ENOMEM;
 336
 337        sl = of_device_get_modalias(dev, &env->buf[env->buflen-1],
 338                                    sizeof(env->buf) - env->buflen);
 339        if (sl >= (sizeof(env->buf) - env->buflen))
 340                return -ENOMEM;
 341        env->buflen += sl;
 342
 343        return 0;
 344}
 345EXPORT_SYMBOL_GPL(of_device_uevent_modalias);
 346