@@ -896,6 +896,41 @@ void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem)
EXPORT_SYMBOL(rproc_add_carveout);
/**
+ * rproc_handle_vendor_rsc() - provide implementation specific hook
+ * to handle vendor/custom resources
+ * @rproc: the remote processor
+ * @rsc: vendor resource to be handled by remoteproc drivers
+ * @offset: offset of the resource data in resource table
+ * @avail: size of available data
+ *
+ * Remoteproc implementations might want to add resource table entries
+ * that are not generic enough to be handled by the framework. This
+ * provides a hook to handle such custom resources.
+ *
+ * Returns 0 on success, or an appropriate error code otherwise
+ */
+static int rproc_handle_vendor_rsc(struct rproc *rproc,
+ struct fw_rsc_vendor *rsc,
+ int offset, int avail)
+{
+ struct device *dev = &rproc->dev;
+
+ if (sizeof(*rsc) > avail) {
+ dev_err(dev, "vendor rsc is truncated\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "vendor rsc:");
+
+ if (!rproc->ops->handle_vendor_rsc) {
+ dev_err(dev, "no vendor rsc handler! ignoring resource\n");
+ return 0;
+ }
+
+ return rproc->ops->handle_vendor_rsc(rproc, (void *)rsc);
+}
+
+/**
* rproc_mem_entry_init() - allocate and initialize rproc_mem_entry struct
* @dev: pointer on device struct
* @va: virtual address
@@ -983,6 +1018,7 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = {
[RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
[RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
[RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
+ [RSC_VENDOR] = (rproc_handle_resource_t)rproc_handle_vendor_rsc,
[RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev,
};
@@ -230,6 +230,9 @@ static int rproc_rsc_table_show(struct seq_file *seq, void *p)
v->vring[j].pa);
}
break;
+ case RSC_VENDOR:
+ seq_printf(seq, "Entry %d is of type %s [Vendor specific]\n",
+ i, types[hdr->type]);
default:
seq_printf(seq, "Unknown resource type found: %d [hdr: %pK]\n",
hdr->type, hdr);
@@ -100,6 +100,7 @@ struct fw_rsc_hdr {
* the remote processor will be writing logs.
* @RSC_VDEV: declare support for a virtio device, and serve as its
* virtio header.
+ * @RSC_VENDOR: vendor specific resource type.
* @RSC_LAST: just keep this one at the end
*
* For more details regarding a specific resource type, please see its
@@ -115,7 +116,8 @@ enum fw_resource_type {
RSC_DEVMEM = 1,
RSC_TRACE = 2,
RSC_VDEV = 3,
- RSC_LAST = 4,
+ RSC_VENDOR = 4,
+ RSC_LAST,
};
#define FW_RSC_ADDR_ANY (-1)
@@ -308,6 +310,14 @@ struct fw_rsc_vdev {
struct rproc;
/**
+ * struct fw_rsc_vendor - vendor specific resource definition
+ * @data: resource data. vendor defined.
+ */
+struct fw_rsc_vendor {
+ u8 data[0];
+} __packed;
+
+/**
* struct rproc_mem_entry - memory entry descriptor
* @va: virtual address
* @dma: dma address
@@ -347,7 +357,8 @@ struct firmware;
* @da_to_va: optional platform hook to perform address translations
* @load_rsc_table: load resource table from firmware image
* @find_loaded_rsc_table: find the loaded resouce table
- * @load: load firmeware to memory, where the remote processor
+ * @handle_vendor_rsc: hook to handle device specific resource table entries
+ * @load: load firmware to memory, where the remote processor
* expects to find it
* @sanity_check: sanity check the fw image
* @get_boot_addr: get boot address to entry point specified in firmware
@@ -360,6 +371,8 @@ struct rproc_ops {
int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
struct resource_table *(*find_loaded_rsc_table)(
struct rproc *rproc, const struct firmware *fw);
+ int (*handle_vendor_rsc)(struct rproc *rproc,
+ struct fw_rsc_vendor *rsc);
int (*load)(struct rproc *rproc, const struct firmware *fw);
int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);