aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/base.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 18:57:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-05 18:57:35 -0400
commit03c0c29aff7e56b722eb6c47eace222b140d0377 (patch)
tree47267a19b523159cf36a050ef3c35f4dbdb33016 /drivers/of/base.c
parentc60c6a96b7bb0f1f8bb635fdfcf5b592aaf062b4 (diff)
parent7fb8f881c54beb05dd4d2c947dada1c636581d87 (diff)
Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6: (63 commits) of/platform: Register of_platform_drivers with an "of:" prefix of/address: Clean up function declarations of/spi: call of_register_spi_devices() from spi core code of: Provide default of_node_to_nid() implementation. of/device: Make of_device_make_bus_id() usable by other code. of/irq: Fix endian issues in parsing interrupt specifiers of: Fix phandle endian issues of/flattree: fix of_flat_dt_is_compatible() to match the full compatible string of: remove of_default_bus_ids of: make of_find_device_by_node generic microblaze: remove references to of_device and to_of_device sparc: remove references to of_device and to_of_device powerpc: remove references to of_device and to_of_device of/device: Replace of_device with platform_device in includes and core code of/device: Protect against binding of_platform_drivers to non-OF devices of: remove asm/of_device.h of: remove asm/of_platform.h of/platform: remove all of_bus_type and of_platform_bus_type references of: Merge of_platform_bus_type with platform_bus_type drivercore/of: Add OF style matching to platform bus ... Fix up trivial conflicts in arch/microblaze/kernel/Makefile due to just some obj-y removals by the devicetree branch, while the microblaze updates added a new file.
Diffstat (limited to 'drivers/of/base.c')
-rw-r--r--drivers/of/base.c76
1 files changed, 15 insertions, 61 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index b5ad9740d8b2..aa805250de76 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -545,74 +545,28 @@ struct device_node *of_find_matching_node(struct device_node *from,
545EXPORT_SYMBOL(of_find_matching_node); 545EXPORT_SYMBOL(of_find_matching_node);
546 546
547/** 547/**
548 * of_modalias_table: Table of explicit compatible ==> modalias mappings
549 *
550 * This table allows particulare compatible property values to be mapped
551 * to modalias strings. This is useful for busses which do not directly
552 * understand the OF device tree but are populated based on data contained
553 * within the device tree. SPI and I2C are the two current users of this
554 * table.
555 *
556 * In most cases, devices do not need to be listed in this table because
557 * the modalias value can be derived directly from the compatible table.
558 * However, if for any reason a value cannot be derived, then this table
559 * provides a method to override the implicit derivation.
560 *
561 * At the moment, a single table is used for all bus types because it is
562 * assumed that the data size is small and that the compatible values
563 * should already be distinct enough to differentiate between SPI, I2C
564 * and other devices.
565 */
566struct of_modalias_table {
567 char *of_device;
568 char *modalias;
569};
570static struct of_modalias_table of_modalias_table[] = {
571 { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
572 { "mmc-spi-slot", "mmc_spi" },
573};
574
575/**
576 * of_modalias_node - Lookup appropriate modalias for a device node 548 * of_modalias_node - Lookup appropriate modalias for a device node
577 * @node: pointer to a device tree node 549 * @node: pointer to a device tree node
578 * @modalias: Pointer to buffer that modalias value will be copied into 550 * @modalias: Pointer to buffer that modalias value will be copied into
579 * @len: Length of modalias value 551 * @len: Length of modalias value
580 * 552 *
581 * Based on the value of the compatible property, this routine will determine 553 * Based on the value of the compatible property, this routine will attempt
582 * an appropriate modalias value for a particular device tree node. Two 554 * to choose an appropriate modalias value for a particular device tree node.
583 * separate methods are attempted to derive a modalias value. 555 * It does this by stripping the manufacturer prefix (as delimited by a ',')
556 * from the first entry in the compatible list property.
584 * 557 *
585 * First method is to lookup the compatible value in of_modalias_table. 558 * This routine returns 0 on success, <0 on failure.
586 * Second is to strip off the manufacturer prefix from the first
587 * compatible entry and use the remainder as modalias
588 *
589 * This routine returns 0 on success
590 */ 559 */
591int of_modalias_node(struct device_node *node, char *modalias, int len) 560int of_modalias_node(struct device_node *node, char *modalias, int len)
592{ 561{
593 int i, cplen; 562 const char *compatible, *p;
594 const char *compatible; 563 int cplen;
595 const char *p;
596
597 /* 1. search for exception list entry */
598 for (i = 0; i < ARRAY_SIZE(of_modalias_table); i++) {
599 compatible = of_modalias_table[i].of_device;
600 if (!of_device_is_compatible(node, compatible))
601 continue;
602 strlcpy(modalias, of_modalias_table[i].modalias, len);
603 return 0;
604 }
605 564
606 compatible = of_get_property(node, "compatible", &cplen); 565 compatible = of_get_property(node, "compatible", &cplen);
607 if (!compatible) 566 if (!compatible || strlen(compatible) > cplen)
608 return -ENODEV; 567 return -ENODEV;
609
610 /* 2. take first compatible entry and strip manufacturer */
611 p = strchr(compatible, ','); 568 p = strchr(compatible, ',');
612 if (!p) 569 strlcpy(modalias, p ? p + 1 : compatible, len);
613 return -ENODEV;
614 p++;
615 strlcpy(modalias, p, len);
616 return 0; 570 return 0;
617} 571}
618EXPORT_SYMBOL_GPL(of_modalias_node); 572EXPORT_SYMBOL_GPL(of_modalias_node);
@@ -651,14 +605,14 @@ EXPORT_SYMBOL(of_find_node_by_phandle);
651struct device_node * 605struct device_node *
652of_parse_phandle(struct device_node *np, const char *phandle_name, int index) 606of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
653{ 607{
654 const phandle *phandle; 608 const __be32 *phandle;
655 int size; 609 int size;
656 610
657 phandle = of_get_property(np, phandle_name, &size); 611 phandle = of_get_property(np, phandle_name, &size);
658 if ((!phandle) || (size < sizeof(*phandle) * (index + 1))) 612 if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
659 return NULL; 613 return NULL;
660 614
661 return of_find_node_by_phandle(phandle[index]); 615 return of_find_node_by_phandle(be32_to_cpup(phandle + index));
662} 616}
663EXPORT_SYMBOL(of_parse_phandle); 617EXPORT_SYMBOL(of_parse_phandle);
664 618
@@ -714,16 +668,16 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
714 668
715 while (list < list_end) { 669 while (list < list_end) {
716 const __be32 *cells; 670 const __be32 *cells;
717 const phandle *phandle; 671 phandle phandle;
718 672
719 phandle = list++; 673 phandle = be32_to_cpup(list++);
720 args = list; 674 args = list;
721 675
722 /* one cell hole in the list = <>; */ 676 /* one cell hole in the list = <>; */
723 if (!*phandle) 677 if (!phandle)
724 goto next; 678 goto next;
725 679
726 node = of_find_node_by_phandle(*phandle); 680 node = of_find_node_by_phandle(phandle);
727 if (!node) { 681 if (!node) {
728 pr_debug("%s: could not find phandle\n", 682 pr_debug("%s: could not find phandle\n",
729 np->full_name); 683 np->full_name);