diff options
author | Paul Walmsley <paul@pwsan.com> | 2012-04-18 21:10:06 -0400 |
---|---|---|
committer | Paul Walmsley <paul@pwsan.com> | 2012-04-19 06:03:11 -0400 |
commit | 5e8370f1fa01bf232ca4770c6d81bbf42437d2a3 (patch) | |
tree | 66cd1d02d461d5b81afb4a36ea8b7a5a64aff8c7 /arch/arm/mach-omap2/omap_hwmod.c | |
parent | c9aafd23d6c1b466f37f554e9916886e7d4645d0 (diff) |
ARM: OMAP2+: hwmod: add omap_hwmod_get_resource_byname()
The timer integration code pokes around in hwmod data structures.
Those data structures are about to change. Define a function,
omap_hwmod_get_resource_byname(), for the timer integration code to
use instead.
The original patch has been changed to use struct resource by Tony's
request, although the caller of this function should not be a driver._
Platform drivers should get their data through the regular platform_*
functions; DT drivers through the appropriate of_* functions. This a
function is only for use by OMAP core code in arch/arm/*omap*.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: BenoƮt Cousson <b-cousson@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap_hwmod.c')
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 52c69d265f7c..230119756504 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -850,6 +850,147 @@ static int _count_ocp_if_addr_spaces(struct omap_hwmod_ocp_if *os) | |||
850 | } | 850 | } |
851 | 851 | ||
852 | /** | 852 | /** |
853 | * _get_mpu_irq_by_name - fetch MPU interrupt line number by name | ||
854 | * @oh: struct omap_hwmod * to operate on | ||
855 | * @name: pointer to the name of the MPU interrupt number to fetch (optional) | ||
856 | * @irq: pointer to an unsigned int to store the MPU IRQ number to | ||
857 | * | ||
858 | * Retrieve a MPU hardware IRQ line number named by @name associated | ||
859 | * with the IP block pointed to by @oh. The IRQ number will be filled | ||
860 | * into the address pointed to by @dma. When @name is non-null, the | ||
861 | * IRQ line number associated with the named entry will be returned. | ||
862 | * If @name is null, the first matching entry will be returned. Data | ||
863 | * order is not meaningful in hwmod data, so callers are strongly | ||
864 | * encouraged to use a non-null @name whenever possible to avoid | ||
865 | * unpredictable effects if hwmod data is later added that causes data | ||
866 | * ordering to change. Returns 0 upon success or a negative error | ||
867 | * code upon error. | ||
868 | */ | ||
869 | static int _get_mpu_irq_by_name(struct omap_hwmod *oh, const char *name, | ||
870 | unsigned int *irq) | ||
871 | { | ||
872 | int i; | ||
873 | bool found = false; | ||
874 | |||
875 | if (!oh->mpu_irqs) | ||
876 | return -ENOENT; | ||
877 | |||
878 | i = 0; | ||
879 | while (oh->mpu_irqs[i].irq != -1) { | ||
880 | if (name == oh->mpu_irqs[i].name || | ||
881 | !strcmp(name, oh->mpu_irqs[i].name)) { | ||
882 | found = true; | ||
883 | break; | ||
884 | } | ||
885 | i++; | ||
886 | } | ||
887 | |||
888 | if (!found) | ||
889 | return -ENOENT; | ||
890 | |||
891 | *irq = oh->mpu_irqs[i].irq; | ||
892 | |||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | /** | ||
897 | * _get_sdma_req_by_name - fetch SDMA request line ID by name | ||
898 | * @oh: struct omap_hwmod * to operate on | ||
899 | * @name: pointer to the name of the SDMA request line to fetch (optional) | ||
900 | * @dma: pointer to an unsigned int to store the request line ID to | ||
901 | * | ||
902 | * Retrieve an SDMA request line ID named by @name on the IP block | ||
903 | * pointed to by @oh. The ID will be filled into the address pointed | ||
904 | * to by @dma. When @name is non-null, the request line ID associated | ||
905 | * with the named entry will be returned. If @name is null, the first | ||
906 | * matching entry will be returned. Data order is not meaningful in | ||
907 | * hwmod data, so callers are strongly encouraged to use a non-null | ||
908 | * @name whenever possible to avoid unpredictable effects if hwmod | ||
909 | * data is later added that causes data ordering to change. Returns 0 | ||
910 | * upon success or a negative error code upon error. | ||
911 | */ | ||
912 | static int _get_sdma_req_by_name(struct omap_hwmod *oh, const char *name, | ||
913 | unsigned int *dma) | ||
914 | { | ||
915 | int i; | ||
916 | bool found = false; | ||
917 | |||
918 | if (!oh->sdma_reqs) | ||
919 | return -ENOENT; | ||
920 | |||
921 | i = 0; | ||
922 | while (oh->sdma_reqs[i].dma_req != -1) { | ||
923 | if (name == oh->sdma_reqs[i].name || | ||
924 | !strcmp(name, oh->sdma_reqs[i].name)) { | ||
925 | found = true; | ||
926 | break; | ||
927 | } | ||
928 | i++; | ||
929 | } | ||
930 | |||
931 | if (!found) | ||
932 | return -ENOENT; | ||
933 | |||
934 | *dma = oh->sdma_reqs[i].dma_req; | ||
935 | |||
936 | return 0; | ||
937 | } | ||
938 | |||
939 | /** | ||
940 | * _get_addr_space_by_name - fetch address space start & end by name | ||
941 | * @oh: struct omap_hwmod * to operate on | ||
942 | * @name: pointer to the name of the address space to fetch (optional) | ||
943 | * @pa_start: pointer to a u32 to store the starting address to | ||
944 | * @pa_end: pointer to a u32 to store the ending address to | ||
945 | * | ||
946 | * Retrieve address space start and end addresses for the IP block | ||
947 | * pointed to by @oh. The data will be filled into the addresses | ||
948 | * pointed to by @pa_start and @pa_end. When @name is non-null, the | ||
949 | * address space data associated with the named entry will be | ||
950 | * returned. If @name is null, the first matching entry will be | ||
951 | * returned. Data order is not meaningful in hwmod data, so callers | ||
952 | * are strongly encouraged to use a non-null @name whenever possible | ||
953 | * to avoid unpredictable effects if hwmod data is later added that | ||
954 | * causes data ordering to change. Returns 0 upon success or a | ||
955 | * negative error code upon error. | ||
956 | */ | ||
957 | static int _get_addr_space_by_name(struct omap_hwmod *oh, const char *name, | ||
958 | u32 *pa_start, u32 *pa_end) | ||
959 | { | ||
960 | int i, j; | ||
961 | struct omap_hwmod_ocp_if *os; | ||
962 | bool found = false; | ||
963 | |||
964 | for (i = 0; i < oh->slaves_cnt; i++) { | ||
965 | os = oh->slaves[i]; | ||
966 | |||
967 | if (!os->addr) | ||
968 | return -ENOENT; | ||
969 | |||
970 | j = 0; | ||
971 | while (os->addr[j].pa_start != os->addr[j].pa_end) { | ||
972 | if (name == os->addr[j].name || | ||
973 | !strcmp(name, os->addr[j].name)) { | ||
974 | found = true; | ||
975 | break; | ||
976 | } | ||
977 | j++; | ||
978 | } | ||
979 | |||
980 | if (found) | ||
981 | break; | ||
982 | } | ||
983 | |||
984 | if (!found) | ||
985 | return -ENOENT; | ||
986 | |||
987 | *pa_start = os->addr[j].pa_start; | ||
988 | *pa_end = os->addr[j].pa_end; | ||
989 | |||
990 | return 0; | ||
991 | } | ||
992 | |||
993 | /** | ||
853 | * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use | 994 | * _find_mpu_port_index - find hwmod OCP slave port ID intended for MPU use |
854 | * @oh: struct omap_hwmod * | 995 | * @oh: struct omap_hwmod * |
855 | * | 996 | * |
@@ -2443,6 +2584,10 @@ int omap_hwmod_reset(struct omap_hwmod *oh) | |||
2443 | return r; | 2584 | return r; |
2444 | } | 2585 | } |
2445 | 2586 | ||
2587 | /* | ||
2588 | * IP block data retrieval functions | ||
2589 | */ | ||
2590 | |||
2446 | /** | 2591 | /** |
2447 | * omap_hwmod_count_resources - count number of struct resources needed by hwmod | 2592 | * omap_hwmod_count_resources - count number of struct resources needed by hwmod |
2448 | * @oh: struct omap_hwmod * | 2593 | * @oh: struct omap_hwmod * |
@@ -2526,6 +2671,69 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res) | |||
2526 | } | 2671 | } |
2527 | 2672 | ||
2528 | /** | 2673 | /** |
2674 | * omap_hwmod_get_resource_byname - fetch IP block integration data by name | ||
2675 | * @oh: struct omap_hwmod * to operate on | ||
2676 | * @type: one of the IORESOURCE_* constants from include/linux/ioport.h | ||
2677 | * @name: pointer to the name of the data to fetch (optional) | ||
2678 | * @rsrc: pointer to a struct resource, allocated by the caller | ||
2679 | * | ||
2680 | * Retrieve MPU IRQ, SDMA request line, or address space start/end | ||
2681 | * data for the IP block pointed to by @oh. The data will be filled | ||
2682 | * into a struct resource record pointed to by @rsrc. The struct | ||
2683 | * resource must be allocated by the caller. When @name is non-null, | ||
2684 | * the data associated with the matching entry in the IRQ/SDMA/address | ||
2685 | * space hwmod data arrays will be returned. If @name is null, the | ||
2686 | * first array entry will be returned. Data order is not meaningful | ||
2687 | * in hwmod data, so callers are strongly encouraged to use a non-null | ||
2688 | * @name whenever possible to avoid unpredictable effects if hwmod | ||
2689 | * data is later added that causes data ordering to change. This | ||
2690 | * function is only intended for use by OMAP core code. Device | ||
2691 | * drivers should not call this function - the appropriate bus-related | ||
2692 | * data accessor functions should be used instead. Returns 0 upon | ||
2693 | * success or a negative error code upon error. | ||
2694 | */ | ||
2695 | int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type, | ||
2696 | const char *name, struct resource *rsrc) | ||
2697 | { | ||
2698 | int r; | ||
2699 | unsigned int irq, dma; | ||
2700 | u32 pa_start, pa_end; | ||
2701 | |||
2702 | if (!oh || !rsrc) | ||
2703 | return -EINVAL; | ||
2704 | |||
2705 | if (type == IORESOURCE_IRQ) { | ||
2706 | r = _get_mpu_irq_by_name(oh, name, &irq); | ||
2707 | if (r) | ||
2708 | return r; | ||
2709 | |||
2710 | rsrc->start = irq; | ||
2711 | rsrc->end = irq; | ||
2712 | } else if (type == IORESOURCE_DMA) { | ||
2713 | r = _get_sdma_req_by_name(oh, name, &dma); | ||
2714 | if (r) | ||
2715 | return r; | ||
2716 | |||
2717 | rsrc->start = dma; | ||
2718 | rsrc->end = dma; | ||
2719 | } else if (type == IORESOURCE_MEM) { | ||
2720 | r = _get_addr_space_by_name(oh, name, &pa_start, &pa_end); | ||
2721 | if (r) | ||
2722 | return r; | ||
2723 | |||
2724 | rsrc->start = pa_start; | ||
2725 | rsrc->end = pa_end; | ||
2726 | } else { | ||
2727 | return -EINVAL; | ||
2728 | } | ||
2729 | |||
2730 | rsrc->flags = type; | ||
2731 | rsrc->name = name; | ||
2732 | |||
2733 | return 0; | ||
2734 | } | ||
2735 | |||
2736 | /** | ||
2529 | * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain | 2737 | * omap_hwmod_get_pwrdm - return pointer to this module's main powerdomain |
2530 | * @oh: struct omap_hwmod * | 2738 | * @oh: struct omap_hwmod * |
2531 | * | 2739 | * |