From patchwork Thu May 5 13:29:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lee Jones X-Patchwork-Id: 67205 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp751907qge; Thu, 5 May 2016 06:32:09 -0700 (PDT) X-Received: by 10.98.17.153 with SMTP id 25mr20556554pfr.105.1462455129381; Thu, 05 May 2016 06:32:09 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id pk5si5870247pab.73.2016.05.05.06.32.09; Thu, 05 May 2016 06:32:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757213AbcEENbs (ORCPT + 29 others); Thu, 5 May 2016 09:31:48 -0400 Received: from mail-wm0-f46.google.com ([74.125.82.46]:38585 "EHLO mail-wm0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756734AbcEENbp (ORCPT ); Thu, 5 May 2016 09:31:45 -0400 Received: by mail-wm0-f46.google.com with SMTP id g17so28020062wme.1 for ; Thu, 05 May 2016 06:31:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=U264cMAyfez3USc5zovvqf59xHzPNtJNIoHwTOHQbIg=; b=iehoKwnaIjyFTzrFs2xjHb7IDluIceBtI4vZOiPdYormlO9yERgNrtsZOcBCia173g K41S5FfvCOMK2Ut20KArCkMjoPZ2SMQYUqyM7TqRV6sMRKmacfq+/WyFTh2lltb3qvKo NIaX5E/GsdI06PSnRghkSrBc+CLtyplCE/BA4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=U264cMAyfez3USc5zovvqf59xHzPNtJNIoHwTOHQbIg=; b=iaE1UmkqEYOJGFfX0fq8FXDfOhlnPcT5tce8EGV3WH5bhfDK0BshODeVYJa7RMcTQW HG4qvoUr6xQiUXBqqPRmkcESeCUmrK193+ctsMsBPSmg5PgLRQDU9yoop41ocbVcqtT6 uMdKVdRjPHSAvEKpEfJrbjMc7d5f0V+WnBKubzk+SbYSMzbc3q1XNdHO0wZjOiQglFsw 0RNMLsQa6YL15SQYOK1s9tIiTQH/B6fDWC5sbGspdc6csOuJ1OXE0GCuSXjoAZeUeCmw 80lrdnOKdH6GaLURM5XwVBtTdgQuWZPlXxk2qS+eXV2wF0quUZLZXFWrDu4rQgCkoTJd kEpQ== X-Gm-Message-State: AOPr4FWZVP9n9Ahq4r4owHPCEjIzyWBC1PfZzhTKgR00IUBf3doI73U3IvPACQlPzFHP6AWZ X-Received: by 10.28.24.82 with SMTP id 79mr3675655wmy.42.1462455103933; Thu, 05 May 2016 06:31:43 -0700 (PDT) Received: from localhost.localdomain (host81-129-173-198.range81-129.btcentralplus.com. [81.129.173.198]) by smtp.gmail.com with ESMTPSA id lf9sm9776868wjc.44.2016.05.05.06.31.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 May 2016 06:31:43 -0700 (PDT) From: Lee Jones To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Cc: kernel@stlinux.com, maxime.coquelin@st.com, ohad@wizery.com, bjorn.andersson@linaro.org, linux-remoteproc@vger.kernel.org, Lee Jones , Ludovic Barre Subject: [PATCH 3/5] remoteproc: core: Add ability to select a firmware from the client Date: Thu, 5 May 2016 14:29:41 +0100 Message-Id: <1462454983-13168-4-git-send-email-lee.jones@linaro.org> X-Mailer: git-send-email 2.8.0 In-Reply-To: <1462454983-13168-1-git-send-email-lee.jones@linaro.org> References: <1462454983-13168-1-git-send-email-lee.jones@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ST Co-Processors can be loaded with different firmwares to execute specific tasks without the need for unloading the rproc module. This patch provides a function which can update the firmware name. NB: This can only happen if the rproc is offline. Signed-off-by: Ludovic Barre Signed-off-by: Lee Jones --- drivers/remoteproc/remoteproc_core.c | 63 ++++++++++++++++++++++++++++++++++++ include/linux/remoteproc.h | 13 ++++++++ 2 files changed, 76 insertions(+) -- 2.8.0 diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 85e5fd8..03720c0 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1004,6 +1004,7 @@ int rproc_trigger_recovery(struct rproc *rproc) /* Free the copy of the resource table */ kfree(rproc->cached_table); + rproc->cached_table = NULL; return rproc_add_virtio_devices(rproc); } @@ -1329,6 +1330,66 @@ struct rproc *rproc_get_by_phandle(phandle phandle) EXPORT_SYMBOL(rproc_get_by_phandle); /** + * rproc_set_fw_name() - change rproc fw name + * @rproc: rproc handle + * @firmware: name of firmware file to load + * + * set a new firmware name for rproc handle + * firmware name can be updated only if the rproc is offline + * if firmware name is NULL the fw name is set on default name + * + * this function can wait, if the old fw config virtio is not yet finish + * (fw config request is asynchronous) + * + * Returns 0 on success and an appropriate error code otherwise. + */ +int rproc_set_fw_name(struct rproc *rproc, const char *firmware) +{ + struct rproc_vdev *rvdev, *rvtmp; + + if (!rproc) + return -EINVAL; + + /* if rproc is just being registered, wait */ + wait_for_completion(&rproc->firmware_loading_complete); + + mutex_lock(&rproc->lock); + + if (rproc->state != RPROC_OFFLINE) { + mutex_unlock(&rproc->lock); + return -EBUSY; + } + + if (rproc->firmware && rproc->firmware != rproc->orig_firmware) + kfree(rproc->firmware); + + /* restore original fw name */ + if (!firmware) { + rproc->firmware = rproc->orig_firmware; + } else { + rproc->firmware = kstrdup(firmware, GFP_KERNEL); + if (!rproc->firmware) + rproc->firmware = rproc->orig_firmware; + } + + dev_info(&rproc->dev, "%s, fw name updated with:%s\n", + rproc->name, rproc->firmware); + + mutex_unlock(&rproc->lock); + + /* clean up remote vdev entries */ + list_for_each_entry_safe(rvdev, rvtmp, &rproc->rvdevs, node) + rproc_remove_virtio_dev(rvdev); + + /* Free the copy of the resource table */ + kfree(rproc->cached_table); + rproc->cached_table = NULL; + + return rproc_add_virtio_devices(rproc); +} +EXPORT_SYMBOL(rproc_set_fw_name); + +/** * rproc_add() - register a remote processor * @rproc: the remote processor handle to register * @@ -1467,6 +1528,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, } rproc->firmware = p; + rproc->orig_firmware = p; rproc->name = name; rproc->ops = ops; rproc->priv = &rproc[1]; @@ -1554,6 +1616,7 @@ int rproc_del(struct rproc *rproc) /* Free the copy of the resource table */ kfree(rproc->cached_table); + rproc->cached_table = NULL; /* the rproc is downref'ed as soon as it's removed from the klist */ mutex_lock(&rproc_list_mutex); diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 4c96e78..978e866 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -414,6 +414,7 @@ struct rproc { struct iommu_domain *domain; const char *name; const char *firmware; + const char *orig_firmware; void *priv; const struct rproc_ops *ops; struct device dev; @@ -484,6 +485,18 @@ struct rproc_vdev { u32 rsc_offset; }; +struct rproc_subdev { + struct device dev; + struct rproc *rproc; + struct resource *res; +}; + +#define to_subdevice(d) container_of(d, struct rproc_subdev, dev) +struct rproc_subdev *rproc_subdev_add(struct rproc *rproc, + struct resource *res); +void rproc_subdev_del(struct rproc_subdev *subdev); +struct device *rproc_subdev_lookup(struct rproc *rproc, const char *name); +int rproc_set_fw_name(struct rproc *rproc, const char *firmware); struct rproc *rproc_get_by_phandle(phandle phandle); struct rproc *rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops,