Branch data Line data Source code
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 : : */ 26 : 3 : const struct of_device_id *of_match_device(const struct of_device_id *matches, 27 : : const struct device *dev) 28 : : { 29 : 3 : if ((!matches) || (!dev->of_node)) 30 : : return NULL; 31 : 3 : return of_match_node(matches, dev->of_node); 32 : : } 33 : : EXPORT_SYMBOL(of_match_device); 34 : : 35 : 0 : struct platform_device *of_dev_get(struct platform_device *dev) 36 : : { 37 : : struct device *tmp; 38 : : 39 : 0 : if (!dev) 40 : : return NULL; 41 : 0 : tmp = get_device(&dev->dev); 42 : 0 : if (tmp) 43 : 0 : return to_platform_device(tmp); 44 : : else 45 : : return NULL; 46 : : } 47 : : EXPORT_SYMBOL(of_dev_get); 48 : : 49 : 0 : void of_dev_put(struct platform_device *dev) 50 : : { 51 : 0 : if (dev) 52 : 0 : put_device(&dev->dev); 53 : 0 : } 54 : : EXPORT_SYMBOL(of_dev_put); 55 : : 56 : 3 : int of_device_add(struct platform_device *ofdev) 57 : : { 58 : 3 : 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 : 3 : ofdev->name = dev_name(&ofdev->dev); 63 : 3 : 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 : 3 : 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 : : */ 89 : 3 : int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) 90 : : { 91 : 3 : 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 : 3 : ret = of_dma_get_range(np, &dma_addr, &paddr, &size); 99 : 3 : 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 : 3 : if (!force_dma) 106 : 0 : return ret == -ENODEV ? 0 : ret; 107 : : 108 : 3 : dma_addr = offset = 0; 109 : : } else { 110 : 3 : 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 : 3 : if (size & 1) { 117 : 0 : dev_warn(dev, "Invalid size 0x%llx for dma-range\n", 118 : : size); 119 : 0 : size = size + 1; 120 : : } 121 : : 122 : 3 : if (!size) { 123 : 0 : dev_err(dev, "Adjusted size 0x%llx invalid\n", size); 124 : 0 : 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 : 3 : if (!dev->dma_mask) { 136 : 0 : dev_warn(dev, "DMA mask not set\n"); 137 : 0 : dev->dma_mask = &dev->coherent_dma_mask; 138 : : } 139 : : 140 : 3 : if (!size && dev->coherent_dma_mask) 141 : 3 : size = max(dev->coherent_dma_mask, dev->coherent_dma_mask + 1); 142 : 3 : else if (!size) 143 : 0 : size = 1ULL << 32; 144 : : 145 : 3 : 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 : 3 : end = dma_addr + size - 1; 152 : 3 : mask = DMA_BIT_MASK(ilog2(end) + 1); 153 : 3 : dev->coherent_dma_mask &= mask; 154 : 3 : *dev->dma_mask &= mask; 155 : : /* ...but only set bus limit if we found valid dma-ranges earlier */ 156 : 3 : if (!ret) 157 : 3 : dev->bus_dma_limit = end; 158 : : 159 : 3 : 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 (IS_ERR(iommu) && 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 : 3 : arch_setup_dma_ops(dev, dma_addr, size, iommu, coherent); 171 : : 172 : 3 : return 0; 173 : : } 174 : : EXPORT_SYMBOL_GPL(of_dma_configure); 175 : : 176 : 0 : int of_device_register(struct platform_device *pdev) 177 : : { 178 : 0 : device_initialize(&pdev->dev); 179 : 0 : return of_device_add(pdev); 180 : : } 181 : : EXPORT_SYMBOL(of_device_register); 182 : : 183 : 0 : void of_device_unregister(struct platform_device *ofdev) 184 : : { 185 : 0 : device_unregister(&ofdev->dev); 186 : 0 : } 187 : : EXPORT_SYMBOL(of_device_unregister); 188 : : 189 : 3 : const void *of_device_get_match_data(const struct device *dev) 190 : : { 191 : : const struct of_device_id *match; 192 : : 193 : 3 : match = of_match_device(dev->driver->of_match_table, dev); 194 : 3 : if (!match) 195 : : return NULL; 196 : : 197 : 3 : return match->data; 198 : : } 199 : : EXPORT_SYMBOL(of_device_get_match_data); 200 : : 201 : 3 : static 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 : 3 : 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 : 3 : 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 : 3 : len -= csize; 218 : 3 : if (str) 219 : 3 : str += csize; 220 : : 221 : 3 : of_property_for_each_string(dev->of_node, "compatible", p, compat) { 222 : 3 : csize = strlen(compat) + 1; 223 : 3 : tsize += csize; 224 : 3 : if (csize > len) 225 : 3 : continue; 226 : : 227 : 3 : csize = snprintf(str, len, "C%s", compat); 228 : 3 : for (c = str; c; ) { 229 : 3 : c = strchr(c, ' '); 230 : 3 : if (c) 231 : 3 : *c++ = '_'; 232 : : } 233 : 3 : len -= csize; 234 : 3 : str += csize; 235 : : } 236 : : 237 : 3 : return tsize; 238 : : } 239 : : 240 : 0 : int of_device_request_module(struct device *dev) 241 : : { 242 : : char *str; 243 : : ssize_t size; 244 : : int ret; 245 : : 246 : 0 : size = of_device_get_modalias(dev, NULL, 0); 247 : 0 : if (size < 0) 248 : : return size; 249 : : 250 : 0 : str = kmalloc(size + 1, GFP_KERNEL); 251 : 0 : if (!str) 252 : : return -ENOMEM; 253 : : 254 : 0 : of_device_get_modalias(dev, str, size); 255 : 0 : str[size] = '\0'; 256 : 0 : ret = request_module(str); 257 : 0 : kfree(str); 258 : : 259 : 0 : return ret; 260 : : } 261 : : EXPORT_SYMBOL_GPL(of_device_request_module); 262 : : 263 : : /** 264 : : * of_device_modalias - Fill buffer with newline terminated modalias string 265 : : */ 266 : 0 : ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) 267 : : { 268 : 0 : ssize_t sl = of_device_get_modalias(dev, str, len - 2); 269 : 0 : if (sl < 0) 270 : : return sl; 271 : 0 : if (sl > len - 2) 272 : : return -ENOMEM; 273 : : 274 : 0 : str[sl++] = '\n'; 275 : 0 : str[sl] = 0; 276 : 0 : return sl; 277 : : } 278 : : EXPORT_SYMBOL_GPL(of_device_modalias); 279 : : 280 : : /** 281 : : * of_device_uevent - Display OF related uevent information 282 : : */ 283 : 3 : void 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 : 3 : if ((!dev) || (!dev->of_node)) 291 : 3 : return; 292 : : 293 : 3 : add_uevent_var(env, "OF_NAME=%pOFn", dev->of_node); 294 : 3 : add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node); 295 : 3 : type = of_node_get_device_type(dev->of_node); 296 : 3 : if (type) 297 : 3 : 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 : 3 : of_property_for_each_string(dev->of_node, "compatible", p, compat) { 303 : 3 : add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); 304 : 3 : seen++; 305 : : } 306 : 3 : add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); 307 : : 308 : : seen = 0; 309 : 3 : mutex_lock(&of_mutex); 310 : 3 : list_for_each_entry(app, &aliases_lookup, link) { 311 : 3 : if (dev->of_node == app->np) { 312 : 3 : add_uevent_var(env, "OF_ALIAS_%d=%s", seen, 313 : : app->alias); 314 : 3 : seen++; 315 : : } 316 : : } 317 : 3 : mutex_unlock(&of_mutex); 318 : : } 319 : : 320 : 3 : int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) 321 : : { 322 : : int sl; 323 : : 324 : 3 : if ((!dev) || (!dev->of_node)) 325 : : return -ENODEV; 326 : : 327 : : /* Devicetree modalias is tricky, we add it in 2 steps */ 328 : 3 : if (add_uevent_var(env, "MODALIAS=")) 329 : : return -ENOMEM; 330 : : 331 : 3 : sl = of_device_get_modalias(dev, &env->buf[env->buflen-1], 332 : 3 : sizeof(env->buf) - env->buflen); 333 : 3 : if (sl >= (sizeof(env->buf) - env->buflen)) 334 : : return -ENOMEM; 335 : 3 : env->buflen += sl; 336 : : 337 : 3 : return 0; 338 : : } 339 : : EXPORT_SYMBOL_GPL(of_device_uevent_modalias);