Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'remoteproc-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc

Pull remoteproc updates from Ohad Ben-Cohen:

- remoteproc fixes/cleanups from Suman Anna

- new remoteproc TI Wakeup M3 driver from Dave Gerlach

- remoteproc core support for TI's Wakeup M3 driver from both Dave and Suman

- tiny remoteproc build fix from myself

* tag 'remoteproc-4.2' of git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc:
remoteproc: fix !CONFIG_OF build breakage
remoteproc/wkup_m3: add a remoteproc driver for TI Wakeup M3
Documentation: dt: add bindings for TI Wakeup M3 processor
remoteproc: add a rproc ops for performing address translation
remoteproc: introduce rproc_get_by_phandle API
remoteproc: fix various checkpatch warnings
remoteproc/davinci: fix quoted split string checkpatch warning
remoteproc/ste: add blank lines after declarations

+460 -32
+52
Documentation/devicetree/bindings/remoteproc/wkup_m3_rproc.txt
··· 1 + TI Wakeup M3 Remoteproc Driver 2 + ============================== 3 + 4 + The TI AM33xx and AM43xx family of devices use a small Cortex M3 co-processor 5 + (commonly referred to as Wakeup M3 or CM3) to help with various low power tasks 6 + that cannot be controlled from the MPU. This CM3 processor requires a firmware 7 + binary to accomplish this. The wkup_m3 remoteproc driver handles the loading of 8 + the firmware and booting of the CM3. 9 + 10 + Wkup M3 Device Node: 11 + ==================== 12 + A wkup_m3 device node is used to represent the Wakeup M3 processor instance 13 + within the SoC. It is added as a child node of the parent interconnect bus 14 + (l4_wkup) through which it is accessible to the MPU. 15 + 16 + Required properties: 17 + -------------------- 18 + - compatible: Should be one of, 19 + "ti,am3352-wkup-m3" for AM33xx SoCs 20 + "ti,am4372-wkup-m3" for AM43xx SoCs 21 + - reg: Should contain the address ranges for the two internal 22 + memory regions, UMEM and DMEM. The parent node should 23 + provide an appropriate ranges property for properly 24 + translating these into bus addresses. 25 + - reg-names: Contains the corresponding names for the two memory 26 + regions. These should be named "umem" & "dmem". 27 + - ti,hwmods: Name of the hwmod associated with the wkupm3 device. 28 + - ti,pm-firmware: Name of firmware file to be used for loading and 29 + booting the wkup_m3 remote processor. 30 + 31 + Example: 32 + -------- 33 + /* AM33xx */ 34 + ocp { 35 + l4_wkup: l4_wkup@44c00000 { 36 + compatible = "am335-l4-wkup", "simple-bus"; 37 + ranges = <0 0x44c00000 0x400000>; 38 + #address-cells = <1>; 39 + #size-cells = <1>; 40 + 41 + wkup_m3: wkup_m3@100000 { 42 + compatible = "ti,am3352-wkup-m3"; 43 + reg = <0x100000 0x4000>, 44 + <0x180000 0x2000>; 45 + reg-names = "umem", "dmem"; 46 + ti,hwmods = "wkup_m3"; 47 + ti,pm-firmware = "am335x-pm-firmware.elf"; 48 + }; 49 + }; 50 + 51 + ... 52 + };
+6
Documentation/remoteproc.txt
··· 51 51 rproc_shutdown() returns, and users can still use it with a subsequent 52 52 rproc_boot(), if needed. 53 53 54 + struct rproc *rproc_get_by_phandle(phandle phandle) 55 + - Find an rproc handle using a device tree phandle. Returns the rproc 56 + handle on success, and NULL on failure. This function increments 57 + the remote processor's refcount, so always use rproc_put() to 58 + decrement it back once rproc isn't needed anymore. 59 + 54 60 3. Typical usage 55 61 56 62 #include <linux/remoteproc.h>
+13
drivers/remoteproc/Kconfig
··· 41 41 This can be either built-in or a loadable module. 42 42 If unsure say N. 43 43 44 + config WKUP_M3_RPROC 45 + tristate "AMx3xx Wakeup M3 remoteproc support" 46 + depends on SOC_AM33XX || SOC_AM43XX 47 + select REMOTEPROC 48 + help 49 + Say y here to support Wakeup M3 remote processor on TI AM33xx 50 + and AM43xx family of SoCs. 51 + 52 + Required for Suspend-to-RAM on AM33xx and AM43xx SoCs. Also needed 53 + for deep CPUIdle states on AM33xx SoCs. Allows for loading of the 54 + firmware onto these remote processors. 55 + If unsure say N. 56 + 44 57 config DA8XX_REMOTEPROC 45 58 tristate "DA8xx/OMAP-L13x remoteproc support" 46 59 depends on ARCH_DAVINCI_DA8XX
+1
drivers/remoteproc/Makefile
··· 9 9 remoteproc-y += remoteproc_elf_loader.o 10 10 obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o 11 11 obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o 12 + obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o 12 13 obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o
+1 -2
drivers/remoteproc/da8xx_remoteproc.c
··· 26 26 static char *da8xx_fw_name; 27 27 module_param(da8xx_fw_name, charp, S_IRUGO); 28 28 MODULE_PARM_DESC(da8xx_fw_name, 29 - "\n\t\tName of DSP firmware file in /lib/firmware" 30 - " (if not specified defaults to 'rproc-dsp-fw')"); 29 + "Name of DSP firmware file in /lib/firmware (if not specified defaults to 'rproc-dsp-fw')"); 31 30 32 31 /* 33 32 * OMAP-L138 Technical References:
+91 -24
drivers/remoteproc/remoteproc_core.c
··· 44 44 45 45 #include "remoteproc_internal.h" 46 46 47 + static DEFINE_MUTEX(rproc_list_mutex); 48 + static LIST_HEAD(rproc_list); 49 + 47 50 typedef int (*rproc_handle_resources_t)(struct rproc *rproc, 48 51 struct resource_table *table, int len); 49 52 typedef int (*rproc_handle_resource_t)(struct rproc *rproc, ··· 135 132 136 133 iommu_detach_device(domain, dev); 137 134 iommu_domain_free(domain); 138 - 139 - return; 140 135 } 141 136 142 - /* 137 + /** 138 + * rproc_da_to_va() - lookup the kernel virtual address for a remoteproc address 139 + * @rproc: handle of a remote processor 140 + * @da: remoteproc device address to translate 141 + * @len: length of the memory region @da is pointing to 142 + * 143 143 * Some remote processors will ask us to allocate them physically contiguous 144 144 * memory regions (which we call "carveouts"), and map them to specific 145 - * device addresses (which are hardcoded in the firmware). 145 + * device addresses (which are hardcoded in the firmware). They may also have 146 + * dedicated memory regions internal to the processors, and use them either 147 + * exclusively or alongside carveouts. 146 148 * 147 149 * They may then ask us to copy objects into specific device addresses (e.g. 148 150 * code/data sections) or expose us certain symbols in other device address 149 151 * (e.g. their trace buffer). 150 152 * 151 - * This function is an internal helper with which we can go over the allocated 152 - * carveouts and translate specific device address to kernel virtual addresses 153 - * so we can access the referenced memory. 153 + * This function is a helper function with which we can go over the allocated 154 + * carveouts and translate specific device addresses to kernel virtual addresses 155 + * so we can access the referenced memory. This function also allows to perform 156 + * translations on the internal remoteproc memory regions through a platform 157 + * implementation specific da_to_va ops, if present. 158 + * 159 + * The function returns a valid kernel address on success or NULL on failure. 154 160 * 155 161 * Note: phys_to_virt(iommu_iova_to_phys(rproc->domain, da)) will work too, 156 162 * but only on kernel direct mapped RAM memory. Instead, we're just using 157 - * here the output of the DMA API, which should be more correct. 163 + * here the output of the DMA API for the carveouts, which should be more 164 + * correct. 158 165 */ 159 166 void *rproc_da_to_va(struct rproc *rproc, u64 da, int len) 160 167 { 161 168 struct rproc_mem_entry *carveout; 162 169 void *ptr = NULL; 170 + 171 + if (rproc->ops->da_to_va) { 172 + ptr = rproc->ops->da_to_va(rproc, da, len); 173 + if (ptr) 174 + goto out; 175 + } 163 176 164 177 list_for_each_entry(carveout, &rproc->carveouts, node) { 165 178 int offset = da - carveout->da; ··· 193 174 break; 194 175 } 195 176 177 + out: 196 178 return ptr; 197 179 } 198 180 EXPORT_SYMBOL(rproc_da_to_va); ··· 431 411 } 432 412 433 413 trace = kzalloc(sizeof(*trace), GFP_KERNEL); 434 - if (!trace) { 435 - dev_err(dev, "kzalloc trace failed\n"); 414 + if (!trace) 436 415 return -ENOMEM; 437 - } 438 416 439 417 /* set the trace buffer dma properties */ 440 418 trace->len = rsc->len; ··· 507 489 } 508 490 509 491 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 510 - if (!mapping) { 511 - dev_err(dev, "kzalloc mapping failed\n"); 492 + if (!mapping) 512 493 return -ENOMEM; 513 - } 514 494 515 495 ret = iommu_map(rproc->domain, rsc->da, rsc->pa, rsc->len, rsc->flags); 516 496 if (ret) { ··· 581 565 rsc->da, rsc->pa, rsc->len, rsc->flags); 582 566 583 567 carveout = kzalloc(sizeof(*carveout), GFP_KERNEL); 584 - if (!carveout) { 585 - dev_err(dev, "kzalloc carveout failed\n"); 568 + if (!carveout) 586 569 return -ENOMEM; 587 - } 588 570 589 571 va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL); 590 572 if (!va) { ··· 782 768 783 769 /* clean up carveout allocations */ 784 770 list_for_each_entry_safe(entry, tmp, &rproc->carveouts, node) { 785 - dma_free_coherent(dev->parent, entry->len, entry->va, entry->dma); 771 + dma_free_coherent(dev->parent, entry->len, entry->va, 772 + entry->dma); 786 773 list_del(&entry->node); 787 774 kfree(entry); 788 775 } ··· 823 808 824 809 /* look for the resource table */ 825 810 table = rproc_find_rsc_table(rproc, fw, &tablesz); 826 - if (!table) { 811 + if (!table) 827 812 goto clean_up; 828 - } 829 813 830 814 /* Verify that resource table in loaded fw is unchanged */ 831 815 if (rproc->table_csum != crc32(0, table, tablesz)) { ··· 925 911 926 912 /* count the number of notify-ids */ 927 913 rproc->max_notifyid = -1; 928 - ret = rproc_handle_resources(rproc, tablesz, rproc_count_vrings_handler); 914 + ret = rproc_handle_resources(rproc, tablesz, 915 + rproc_count_vrings_handler); 929 916 if (ret) 930 917 goto out; 931 918 ··· 1167 1152 EXPORT_SYMBOL(rproc_shutdown); 1168 1153 1169 1154 /** 1155 + * rproc_get_by_phandle() - find a remote processor by phandle 1156 + * @phandle: phandle to the rproc 1157 + * 1158 + * Finds an rproc handle using the remote processor's phandle, and then 1159 + * return a handle to the rproc. 1160 + * 1161 + * This function increments the remote processor's refcount, so always 1162 + * use rproc_put() to decrement it back once rproc isn't needed anymore. 1163 + * 1164 + * Returns the rproc handle on success, and NULL on failure. 1165 + */ 1166 + #ifdef CONFIG_OF 1167 + struct rproc *rproc_get_by_phandle(phandle phandle) 1168 + { 1169 + struct rproc *rproc = NULL, *r; 1170 + struct device_node *np; 1171 + 1172 + np = of_find_node_by_phandle(phandle); 1173 + if (!np) 1174 + return NULL; 1175 + 1176 + mutex_lock(&rproc_list_mutex); 1177 + list_for_each_entry(r, &rproc_list, node) { 1178 + if (r->dev.parent && r->dev.parent->of_node == np) { 1179 + rproc = r; 1180 + get_device(&rproc->dev); 1181 + break; 1182 + } 1183 + } 1184 + mutex_unlock(&rproc_list_mutex); 1185 + 1186 + of_node_put(np); 1187 + 1188 + return rproc; 1189 + } 1190 + #else 1191 + struct rproc *rproc_get_by_phandle(phandle phandle) 1192 + { 1193 + return NULL; 1194 + } 1195 + #endif 1196 + EXPORT_SYMBOL(rproc_get_by_phandle); 1197 + 1198 + /** 1170 1199 * rproc_add() - register a remote processor 1171 1200 * @rproc: the remote processor handle to register 1172 1201 * ··· 1238 1179 ret = device_add(dev); 1239 1180 if (ret < 0) 1240 1181 return ret; 1182 + 1183 + /* expose to rproc_get_by_phandle users */ 1184 + mutex_lock(&rproc_list_mutex); 1185 + list_add(&rproc->node, &rproc_list); 1186 + mutex_unlock(&rproc_list_mutex); 1241 1187 1242 1188 dev_info(dev, "%s is available\n", rproc->name); 1243 1189 ··· 1332 1268 name_len = strlen(name) + strlen(template) - 2 + 1; 1333 1269 1334 1270 rproc = kzalloc(sizeof(struct rproc) + len + name_len, GFP_KERNEL); 1335 - if (!rproc) { 1336 - dev_err(dev, "%s: kzalloc failed\n", __func__); 1271 + if (!rproc) 1337 1272 return NULL; 1338 - } 1339 1273 1340 1274 if (!firmware) { 1341 1275 p = (char *)rproc + sizeof(struct rproc) + len; ··· 1430 1368 1431 1369 /* Free the copy of the resource table */ 1432 1370 kfree(rproc->cached_table); 1371 + 1372 + /* the rproc is downref'ed as soon as it's removed from the klist */ 1373 + mutex_lock(&rproc_list_mutex); 1374 + list_del(&rproc->node); 1375 + mutex_unlock(&rproc_list_mutex); 1433 1376 1434 1377 device_del(&rproc->dev); 1435 1378
+1 -1
drivers/remoteproc/remoteproc_internal.h
··· 35 35 * @get_boot_addr: get boot address to entry point specified in firmware 36 36 */ 37 37 struct rproc_fw_ops { 38 - struct resource_table *(*find_rsc_table) (struct rproc *rproc, 38 + struct resource_table *(*find_rsc_table)(struct rproc *rproc, 39 39 const struct firmware *fw, 40 40 int *tablesz); 41 41 struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc,
+2 -2
drivers/remoteproc/ste_modem_rproc.c
··· 67 67 static const struct ste_toc_entry *sproc_find_rsc_entry(const void *data) 68 68 { 69 69 int i; 70 - const struct ste_toc *toc; 71 - toc = data; 70 + const struct ste_toc *toc = data; 72 71 73 72 /* Search the table for the resource table */ 74 73 for (i = 0; i < SPROC_MAX_TOC_ENTRIES && ··· 229 230 static int sproc_stop(struct rproc *rproc) 230 231 { 231 232 struct sproc *sproc = rproc->priv; 233 + 232 234 sproc_dbg(sproc, "stop ste-modem\n"); 233 235 234 236 return sproc->mdev->ops.power(sproc->mdev, false);
+257
drivers/remoteproc/wkup_m3_rproc.c
··· 1 + /* 2 + * TI AMx3 Wakeup M3 Remote Processor driver 3 + * 4 + * Copyright (C) 2014-2015 Texas Instruments, Inc. 5 + * 6 + * Dave Gerlach <d-gerlach@ti.com> 7 + * Suman Anna <s-anna@ti.com> 8 + * 9 + * This program is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License 11 + * version 2 as published by the Free Software Foundation. 12 + * 13 + * This program is distributed in the hope that it will be useful, 14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 + * GNU General Public License for more details. 17 + */ 18 + 19 + #include <linux/err.h> 20 + #include <linux/interrupt.h> 21 + #include <linux/kernel.h> 22 + #include <linux/module.h> 23 + #include <linux/of_device.h> 24 + #include <linux/of_address.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/pm_runtime.h> 27 + #include <linux/remoteproc.h> 28 + 29 + #include <linux/platform_data/wkup_m3.h> 30 + 31 + #include "remoteproc_internal.h" 32 + 33 + #define WKUPM3_MEM_MAX 2 34 + 35 + /** 36 + * struct wkup_m3_mem - WkupM3 internal memory structure 37 + * @cpu_addr: MPU virtual address of the memory region 38 + * @bus_addr: Bus address used to access the memory region 39 + * @dev_addr: Device address from Wakeup M3 view 40 + * @size: Size of the memory region 41 + */ 42 + struct wkup_m3_mem { 43 + void __iomem *cpu_addr; 44 + phys_addr_t bus_addr; 45 + u32 dev_addr; 46 + size_t size; 47 + }; 48 + 49 + /** 50 + * struct wkup_m3_rproc - WkupM3 remote processor state 51 + * @rproc: rproc handle 52 + * @pdev: pointer to platform device 53 + * @mem: WkupM3 memory information 54 + */ 55 + struct wkup_m3_rproc { 56 + struct rproc *rproc; 57 + struct platform_device *pdev; 58 + struct wkup_m3_mem mem[WKUPM3_MEM_MAX]; 59 + }; 60 + 61 + static int wkup_m3_rproc_start(struct rproc *rproc) 62 + { 63 + struct wkup_m3_rproc *wkupm3 = rproc->priv; 64 + struct platform_device *pdev = wkupm3->pdev; 65 + struct device *dev = &pdev->dev; 66 + struct wkup_m3_platform_data *pdata = dev_get_platdata(dev); 67 + 68 + if (pdata->deassert_reset(pdev, pdata->reset_name)) { 69 + dev_err(dev, "Unable to reset wkup_m3!\n"); 70 + return -ENODEV; 71 + } 72 + 73 + return 0; 74 + } 75 + 76 + static int wkup_m3_rproc_stop(struct rproc *rproc) 77 + { 78 + struct wkup_m3_rproc *wkupm3 = rproc->priv; 79 + struct platform_device *pdev = wkupm3->pdev; 80 + struct device *dev = &pdev->dev; 81 + struct wkup_m3_platform_data *pdata = dev_get_platdata(dev); 82 + 83 + if (pdata->assert_reset(pdev, pdata->reset_name)) { 84 + dev_err(dev, "Unable to assert reset of wkup_m3!\n"); 85 + return -ENODEV; 86 + } 87 + 88 + return 0; 89 + } 90 + 91 + static void *wkup_m3_rproc_da_to_va(struct rproc *rproc, u64 da, int len) 92 + { 93 + struct wkup_m3_rproc *wkupm3 = rproc->priv; 94 + void *va = NULL; 95 + int i; 96 + u32 offset; 97 + 98 + if (len <= 0) 99 + return NULL; 100 + 101 + for (i = 0; i < WKUPM3_MEM_MAX; i++) { 102 + if (da >= wkupm3->mem[i].dev_addr && da + len <= 103 + wkupm3->mem[i].dev_addr + wkupm3->mem[i].size) { 104 + offset = da - wkupm3->mem[i].dev_addr; 105 + /* __force to make sparse happy with type conversion */ 106 + va = (__force void *)(wkupm3->mem[i].cpu_addr + offset); 107 + break; 108 + } 109 + } 110 + 111 + return va; 112 + } 113 + 114 + static struct rproc_ops wkup_m3_rproc_ops = { 115 + .start = wkup_m3_rproc_start, 116 + .stop = wkup_m3_rproc_stop, 117 + .da_to_va = wkup_m3_rproc_da_to_va, 118 + }; 119 + 120 + static const struct of_device_id wkup_m3_rproc_of_match[] = { 121 + { .compatible = "ti,am3352-wkup-m3", }, 122 + { .compatible = "ti,am4372-wkup-m3", }, 123 + {}, 124 + }; 125 + 126 + static int wkup_m3_rproc_probe(struct platform_device *pdev) 127 + { 128 + struct device *dev = &pdev->dev; 129 + struct wkup_m3_platform_data *pdata = dev->platform_data; 130 + /* umem always needs to be processed first */ 131 + const char *mem_names[WKUPM3_MEM_MAX] = { "umem", "dmem" }; 132 + struct wkup_m3_rproc *wkupm3; 133 + const char *fw_name; 134 + struct rproc *rproc; 135 + struct resource *res; 136 + const __be32 *addrp; 137 + u32 l4_offset = 0; 138 + u64 size; 139 + int ret; 140 + int i; 141 + 142 + if (!(pdata && pdata->deassert_reset && pdata->assert_reset && 143 + pdata->reset_name)) { 144 + dev_err(dev, "Platform data missing!\n"); 145 + return -ENODEV; 146 + } 147 + 148 + ret = of_property_read_string(dev->of_node, "ti,pm-firmware", 149 + &fw_name); 150 + if (ret) { 151 + dev_err(dev, "No firmware filename given\n"); 152 + return -ENODEV; 153 + } 154 + 155 + pm_runtime_enable(&pdev->dev); 156 + ret = pm_runtime_get_sync(&pdev->dev); 157 + if (ret < 0) { 158 + dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); 159 + goto err; 160 + } 161 + 162 + rproc = rproc_alloc(dev, "wkup_m3", &wkup_m3_rproc_ops, 163 + fw_name, sizeof(*wkupm3)); 164 + if (!rproc) { 165 + ret = -ENOMEM; 166 + goto err; 167 + } 168 + 169 + wkupm3 = rproc->priv; 170 + wkupm3->rproc = rproc; 171 + wkupm3->pdev = pdev; 172 + 173 + for (i = 0; i < ARRAY_SIZE(mem_names); i++) { 174 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 175 + mem_names[i]); 176 + wkupm3->mem[i].cpu_addr = devm_ioremap_resource(dev, res); 177 + if (IS_ERR(wkupm3->mem[i].cpu_addr)) { 178 + dev_err(&pdev->dev, "devm_ioremap_resource failed for resource %d\n", 179 + i); 180 + ret = PTR_ERR(wkupm3->mem[i].cpu_addr); 181 + goto err; 182 + } 183 + wkupm3->mem[i].bus_addr = res->start; 184 + wkupm3->mem[i].size = resource_size(res); 185 + addrp = of_get_address(dev->of_node, i, &size, NULL); 186 + /* 187 + * The wkupm3 has umem at address 0 in its view, so the device 188 + * addresses for each memory region is computed as a relative 189 + * offset of the bus address for umem, and therefore needs to be 190 + * processed first. 191 + */ 192 + if (!strcmp(mem_names[i], "umem")) 193 + l4_offset = be32_to_cpu(*addrp); 194 + wkupm3->mem[i].dev_addr = be32_to_cpu(*addrp) - l4_offset; 195 + } 196 + 197 + dev_set_drvdata(dev, rproc); 198 + 199 + ret = rproc_add(rproc); 200 + if (ret) { 201 + dev_err(dev, "rproc_add failed\n"); 202 + goto err_put_rproc; 203 + } 204 + 205 + return 0; 206 + 207 + err_put_rproc: 208 + rproc_put(rproc); 209 + err: 210 + pm_runtime_put_noidle(dev); 211 + pm_runtime_disable(dev); 212 + return ret; 213 + } 214 + 215 + static int wkup_m3_rproc_remove(struct platform_device *pdev) 216 + { 217 + struct rproc *rproc = platform_get_drvdata(pdev); 218 + 219 + rproc_del(rproc); 220 + rproc_put(rproc); 221 + pm_runtime_put_sync(&pdev->dev); 222 + pm_runtime_disable(&pdev->dev); 223 + 224 + return 0; 225 + } 226 + 227 + #ifdef CONFIG_PM 228 + static int wkup_m3_rpm_suspend(struct device *dev) 229 + { 230 + return -EBUSY; 231 + } 232 + 233 + static int wkup_m3_rpm_resume(struct device *dev) 234 + { 235 + return 0; 236 + } 237 + #endif 238 + 239 + static const struct dev_pm_ops wkup_m3_rproc_pm_ops = { 240 + SET_RUNTIME_PM_OPS(wkup_m3_rpm_suspend, wkup_m3_rpm_resume, NULL) 241 + }; 242 + 243 + static struct platform_driver wkup_m3_rproc_driver = { 244 + .probe = wkup_m3_rproc_probe, 245 + .remove = wkup_m3_rproc_remove, 246 + .driver = { 247 + .name = "wkup_m3_rproc", 248 + .of_match_table = wkup_m3_rproc_of_match, 249 + .pm = &wkup_m3_rproc_pm_ops, 250 + }, 251 + }; 252 + 253 + module_platform_driver(wkup_m3_rproc_driver); 254 + 255 + MODULE_LICENSE("GPL v2"); 256 + MODULE_DESCRIPTION("TI Wakeup M3 remote processor control driver"); 257 + MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
+30
include/linux/platform_data/wkup_m3.h
··· 1 + /* 2 + * TI Wakeup M3 remote processor platform data 3 + * 4 + * Copyright (C) 2014-2015 Texas Instruments, Inc. 5 + * 6 + * Dave Gerlach <d-gerlach@ti.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #ifndef _LINUX_PLATFORM_DATA_WKUP_M3_H 19 + #define _LINUX_PLATFORM_DATA_WKUP_M3_H 20 + 21 + struct platform_device; 22 + 23 + struct wkup_m3_platform_data { 24 + const char *reset_name; 25 + 26 + int (*assert_reset)(struct platform_device *pdev, const char *name); 27 + int (*deassert_reset)(struct platform_device *pdev, const char *name); 28 + }; 29 + 30 + #endif /* _LINUX_PLATFORM_DATA_WKUP_M3_H */
+6 -3
include/linux/remoteproc.h
··· 36 36 #define REMOTEPROC_H 37 37 38 38 #include <linux/types.h> 39 - #include <linux/klist.h> 40 39 #include <linux/mutex.h> 41 40 #include <linux/virtio.h> 42 41 #include <linux/completion.h> 43 42 #include <linux/idr.h> 43 + #include <linux/of.h> 44 44 45 45 /** 46 46 * struct resource_table - firmware resource table header ··· 330 330 * @start: power on the device and boot it 331 331 * @stop: power off the device 332 332 * @kick: kick a virtqueue (virtqueue id given as a parameter) 333 + * @da_to_va: optional platform hook to perform address translations 333 334 */ 334 335 struct rproc_ops { 335 336 int (*start)(struct rproc *rproc); 336 337 int (*stop)(struct rproc *rproc); 337 338 void (*kick)(struct rproc *rproc, int vqid); 339 + void * (*da_to_va)(struct rproc *rproc, u64 da, int len); 338 340 }; 339 341 340 342 /** ··· 377 375 378 376 /** 379 377 * struct rproc - represents a physical remote processor device 380 - * @node: klist node of this rproc object 378 + * @node: list node of this rproc object 381 379 * @domain: iommu domain 382 380 * @name: human readable name of the rproc 383 381 * @firmware: name of firmware file to be loaded ··· 409 407 * @has_iommu: flag to indicate if remote processor is behind an MMU 410 408 */ 411 409 struct rproc { 412 - struct klist_node node; 410 + struct list_head node; 413 411 struct iommu_domain *domain; 414 412 const char *name; 415 413 const char *firmware; ··· 483 481 u32 rsc_offset; 484 482 }; 485 483 484 + struct rproc *rproc_get_by_phandle(phandle phandle); 486 485 struct rproc *rproc_alloc(struct device *dev, const char *name, 487 486 const struct rproc_ops *ops, 488 487 const char *firmware, int len);