aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 23ffb7c0caf2..ad8ac1a8af28 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -385,3 +385,91 @@ struct device_node *of_find_matching_node(struct device_node *from,
385 return np; 385 return np;
386} 386}
387EXPORT_SYMBOL(of_find_matching_node); 387EXPORT_SYMBOL(of_find_matching_node);
388
389/**
390 * of_modalias_table: Table of explicit compatible ==> modalias mappings
391 *
392 * This table allows particulare compatible property values to be mapped
393 * to modalias strings. This is useful for busses which do not directly
394 * understand the OF device tree but are populated based on data contained
395 * within the device tree. SPI and I2C are the two current users of this
396 * table.
397 *
398 * In most cases, devices do not need to be listed in this table because
399 * the modalias value can be derived directly from the compatible table.
400 * However, if for any reason a value cannot be derived, then this table
401 * provides a method to override the implicit derivation.
402 *
403 * At the moment, a single table is used for all bus types because it is
404 * assumed that the data size is small and that the compatible values
405 * should already be distinct enough to differentiate between SPI, I2C
406 * and other devices.
407 */
408struct of_modalias_table {
409 char *of_device;
410 char *modalias;
411};
412static struct of_modalias_table of_modalias_table[] = {
413 /* Empty for now; add entries as needed */
414};
415
416/**
417 * of_modalias_node - Lookup appropriate modalias for a device node
418 * @node: pointer to a device tree node
419 * @modalias: Pointer to buffer that modalias value will be copied into
420 * @len: Length of modalias value
421 *
422 * Based on the value of the compatible property, this routine will determine
423 * an appropriate modalias value for a particular device tree node. Three
424 * separate methods are used to derive a modalias value.
425 *
426 * First method is to lookup the compatible value in of_modalias_table.
427 * Second is to look for a "linux,<modalias>" entry in the compatible list
428 * and used that for modalias. Third is to strip off the manufacturer
429 * prefix from the first compatible entry and use the remainder as modalias
430 *
431 * This routine returns 0 on success
432 */
433int of_modalias_node(struct device_node *node, char *modalias, int len)
434{
435 int i, cplen;
436 const char *compatible;
437 const char *p;
438
439 /* 1. search for exception list entry */
440 for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) {
441 compatible = of_modalias_table[i].of_device;
442 if (!of_device_is_compatible(node, compatible))
443 continue;
444 strlcpy(modalias, of_modalias_table[i].modalias, len);
445 return 0;
446 }
447
448 compatible = of_get_property(node, "compatible", &cplen);
449 if (!compatible)
450 return -ENODEV;
451
452 /* 2. search for linux,<modalias> entry */
453 p = compatible;
454 while (cplen > 0) {
455 if (!strncmp(p, "linux,", 6)) {
456 p += 6;
457 strlcpy(modalias, p, len);
458 return 0;
459 }
460
461 i = strlen(p) + 1;
462 p += i;
463 cplen -= i;
464 }
465
466 /* 3. take first compatible entry and strip manufacturer */
467 p = strchr(compatible, ',');
468 if (!p)
469 return -ENODEV;
470 p++;
471 strlcpy(modalias, p, len);
472 return 0;
473}
474EXPORT_SYMBOL_GPL(of_modalias_node);
475