diff options
author | Ohad Ben-Cohen <ohad@wizery.com> | 2012-02-13 15:47:49 -0500 |
---|---|---|
committer | Ohad Ben-Cohen <ohad@wizery.com> | 2012-03-06 12:14:44 -0500 |
commit | 1e3e2c7c46b2e6e90f3a26ba9be6326c00ca31e4 (patch) | |
tree | d859740dfb2402d361ddb1e4260c04eeeb1ff6fa /drivers/remoteproc | |
parent | 63140e0ed2e69bdafe62bc19fd6551d9213f80a7 (diff) |
remoteproc: cleanup resource table parsing paths
rproc_handle_resources() looks for the resource table and then
invokes a resource handler function which it took as a parameter.
This works, but it's a bit unintuitive to follow.
Instead of passing around function pointers, this patch changes
rproc_handle_resource() to just find and return the resource table,
and then the calling sites of rproc_handle_resource() invoke their
resource handlers directly.
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
Cc: Brian Swetland <swetland@google.com>
Cc: Iliyan Malchev <malchev@google.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Mark Grosen <mgrosen@ti.com>
Cc: John Williams <john.williams@petalogix.com>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Loic PALLARDY <loic.pallardy@stericsson.com>
Cc: Ludovic BARRE <ludovic.barre@stericsson.com>
Cc: Omar Ramirez Luna <omar.luna@linaro.org>
Cc: Guzman Lugo Fernando <fernando.lugo@ti.com>
Cc: Anna Suman <s-anna@ti.com>
Cc: Clark Rob <rob@ti.com>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Cc: Saravana Kannan <skannan@codeaurora.org>
Cc: David Brown <davidb@codeaurora.org>
Cc: Kieran Bingham <kieranbingham@gmail.com>
Cc: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 72 |
1 files changed, 39 insertions, 33 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 9be5dadaa3a3..ee15c68fb519 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c | |||
@@ -822,32 +822,31 @@ rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int l | |||
822 | } | 822 | } |
823 | 823 | ||
824 | /** | 824 | /** |
825 | * rproc_handle_resources() - find and handle the resource table | 825 | * rproc_find_rsc_table() - find the resource table |
826 | * @rproc: the rproc handle | 826 | * @rproc: the rproc handle |
827 | * @elf_data: the content of the ELF firmware image | 827 | * @elf_data: the content of the ELF firmware image |
828 | * @len: firmware size (in bytes) | 828 | * @len: firmware size (in bytes) |
829 | * @handler: function that should be used to handle the resource table | 829 | * @tablesz: place holder for providing back the table size |
830 | * | 830 | * |
831 | * This function finds the resource table inside the remote processor's | 831 | * This function finds the resource table inside the remote processor's |
832 | * firmware, and invoke a user-supplied handler with it (we have two | 832 | * firmware. It is used both upon the registration of @rproc (in order |
833 | * possible handlers: one is invoked upon registration of @rproc, | 833 | * to look for and register the supported virito devices), and when the |
834 | * in order to register the supported virito devices, and the other is | 834 | * @rproc is booted. |
835 | * invoked when @rproc is actually booted). | 835 | * |
836 | * | 836 | * Returns the pointer to the resource table if it is found, and write its |
837 | * Currently this function fails if a resource table doesn't exist. | 837 | * size into @tablesz. If a valid table isn't found, NULL is returned |
838 | * This restriction will be removed when we'll start supporting remote | 838 | * (and @tablesz isn't set). |
839 | * processors that don't need a resource table. | ||
840 | */ | 839 | */ |
841 | static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data, | 840 | static struct resource_table * |
842 | size_t len, rproc_handle_resources_t handler) | 841 | rproc_find_rsc_table(struct rproc *rproc, const u8 *elf_data, size_t len, |
843 | 842 | int *tablesz) | |
844 | { | 843 | { |
845 | struct elf32_hdr *ehdr; | 844 | struct elf32_hdr *ehdr; |
846 | struct elf32_shdr *shdr; | 845 | struct elf32_shdr *shdr; |
847 | const char *name_table; | 846 | const char *name_table; |
848 | struct device *dev = rproc->dev; | 847 | struct device *dev = rproc->dev; |
849 | int i, ret = -EINVAL; | 848 | struct resource_table *table = NULL; |
850 | struct resource_table *table; | 849 | int i; |
851 | 850 | ||
852 | ehdr = (struct elf32_hdr *)elf_data; | 851 | ehdr = (struct elf32_hdr *)elf_data; |
853 | shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); | 852 | shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); |
@@ -866,39 +865,39 @@ static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data, | |||
866 | /* make sure we have the entire table */ | 865 | /* make sure we have the entire table */ |
867 | if (offset + size > len) { | 866 | if (offset + size > len) { |
868 | dev_err(dev, "resource table truncated\n"); | 867 | dev_err(dev, "resource table truncated\n"); |
869 | return -EINVAL; | 868 | return NULL; |
870 | } | 869 | } |
871 | 870 | ||
872 | /* make sure table has at least the header */ | 871 | /* make sure table has at least the header */ |
873 | if (sizeof(struct resource_table) > size) { | 872 | if (sizeof(struct resource_table) > size) { |
874 | dev_err(dev, "header-less resource table\n"); | 873 | dev_err(dev, "header-less resource table\n"); |
875 | return -EINVAL; | 874 | return NULL; |
876 | } | 875 | } |
877 | 876 | ||
878 | /* we don't support any version beyond the first */ | 877 | /* we don't support any version beyond the first */ |
879 | if (table->ver != 1) { | 878 | if (table->ver != 1) { |
880 | dev_err(dev, "unsupported fw ver: %d\n", table->ver); | 879 | dev_err(dev, "unsupported fw ver: %d\n", table->ver); |
881 | return -EINVAL; | 880 | return NULL; |
882 | } | 881 | } |
883 | 882 | ||
884 | /* make sure reserved bytes are zeroes */ | 883 | /* make sure reserved bytes are zeroes */ |
885 | if (table->reserved[0] || table->reserved[1]) { | 884 | if (table->reserved[0] || table->reserved[1]) { |
886 | dev_err(dev, "non zero reserved bytes\n"); | 885 | dev_err(dev, "non zero reserved bytes\n"); |
887 | return -EINVAL; | 886 | return NULL; |
888 | } | 887 | } |
889 | 888 | ||
890 | /* make sure the offsets array isn't truncated */ | 889 | /* make sure the offsets array isn't truncated */ |
891 | if (table->num * sizeof(table->offset[0]) + | 890 | if (table->num * sizeof(table->offset[0]) + |
892 | sizeof(struct resource_table) > size) { | 891 | sizeof(struct resource_table) > size) { |
893 | dev_err(dev, "resource table incomplete\n"); | 892 | dev_err(dev, "resource table incomplete\n"); |
894 | return -EINVAL; | 893 | return NULL; |
895 | } | 894 | } |
896 | 895 | ||
897 | ret = handler(rproc, table, shdr->sh_size); | 896 | *tablesz = shdr->sh_size; |
898 | break; | 897 | break; |
899 | } | 898 | } |
900 | 899 | ||
901 | return ret; | 900 | return table; |
902 | } | 901 | } |
903 | 902 | ||
904 | /** | 903 | /** |
@@ -1012,7 +1011,8 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) | |||
1012 | struct device *dev = rproc->dev; | 1011 | struct device *dev = rproc->dev; |
1013 | const char *name = rproc->firmware; | 1012 | const char *name = rproc->firmware; |
1014 | struct elf32_hdr *ehdr; | 1013 | struct elf32_hdr *ehdr; |
1015 | int ret; | 1014 | struct resource_table *table; |
1015 | int ret, tablesz; | ||
1016 | 1016 | ||
1017 | ret = rproc_fw_sanity_check(rproc, fw); | 1017 | ret = rproc_fw_sanity_check(rproc, fw); |
1018 | if (ret) | 1018 | if (ret) |
@@ -1039,9 +1039,13 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) | |||
1039 | */ | 1039 | */ |
1040 | rproc->bootaddr = ehdr->e_entry; | 1040 | rproc->bootaddr = ehdr->e_entry; |
1041 | 1041 | ||
1042 | /* look for the resource table */ | ||
1043 | table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); | ||
1044 | if (!table) | ||
1045 | goto clean_up; | ||
1046 | |||
1042 | /* handle fw resources which are required to boot rproc */ | 1047 | /* handle fw resources which are required to boot rproc */ |
1043 | ret = rproc_handle_resources(rproc, fw->data, fw->size, | 1048 | ret = rproc_handle_boot_rsc(rproc, table, tablesz); |
1044 | rproc_handle_boot_rsc); | ||
1045 | if (ret) { | 1049 | if (ret) { |
1046 | dev_err(dev, "Failed to process resources: %d\n", ret); | 1050 | dev_err(dev, "Failed to process resources: %d\n", ret); |
1047 | goto clean_up; | 1051 | goto clean_up; |
@@ -1084,19 +1088,21 @@ clean_up: | |||
1084 | static void rproc_fw_config_virtio(const struct firmware *fw, void *context) | 1088 | static void rproc_fw_config_virtio(const struct firmware *fw, void *context) |
1085 | { | 1089 | { |
1086 | struct rproc *rproc = context; | 1090 | struct rproc *rproc = context; |
1087 | struct device *dev = rproc->dev; | 1091 | struct resource_table *table; |
1088 | int ret; | 1092 | int ret, tablesz; |
1089 | 1093 | ||
1090 | if (rproc_fw_sanity_check(rproc, fw) < 0) | 1094 | if (rproc_fw_sanity_check(rproc, fw) < 0) |
1091 | goto out; | 1095 | goto out; |
1092 | 1096 | ||
1093 | /* does the fw support any virtio devices ? */ | 1097 | /* look for the resource table */ |
1094 | ret = rproc_handle_resources(rproc, fw->data, fw->size, | 1098 | table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); |
1095 | rproc_handle_virtio_rsc); | 1099 | if (!table) |
1096 | if (ret) { | 1100 | goto out; |
1097 | dev_info(dev, "No fw virtio device was found\n"); | 1101 | |
1102 | /* look for virtio devices and register them */ | ||
1103 | ret = rproc_handle_virtio_rsc(rproc, table, tablesz); | ||
1104 | if (ret) | ||
1098 | goto out; | 1105 | goto out; |
1099 | } | ||
1100 | 1106 | ||
1101 | out: | 1107 | out: |
1102 | if (fw) | 1108 | if (fw) |