This set provides support for the remoteproc core to release resources
associated with a remote processor without having to switch it off. That
way a platform driver can be removed or the application processor power
cycled while the remote processor is still operating.
This revision fixes a couple of minor problems with patch 11 and 12 as
pointed out by Arnaud and the kernel test robot (detailed in the change
log for each patch). Other patches have not changed.
Applies cleanly on rproc-next and v5.12-rc2.
Thanks,
Mathieu
Arnaud POULIQUEN (1):
remoteproc: stm32: Move memory parsing to rproc_ops
Mathieu Poirier (16):
remoteproc: Remove useless check in rproc_del()
remoteproc: Rename function rproc_actuate()
remoteproc: Add new RPROC_ATTACHED state
remoteproc: Properly represent the attached state
remoteproc: Add new get_loaded_rsc_table() to rproc_ops
remoteproc: stm32: Move resource table setup to rproc_ops
remoteproc: Add new detach() remoteproc operation
remoteproc: Introduce function __rproc_detach()
remoteproc: Introduce function rproc_detach()
remoteproc: Properly deal with the resource table when detaching
remoteproc: Properly deal with the resource table when stopping
remoteproc: Properly deal with a kernel panic when attached
remoteproc: Properly deal with a start request when attached
remoteproc: Properly deal with a stop request when attached
remoteproc: Properly deal with a detach request when attached
remoteproc: Refactor function rproc_cdev_release()
drivers/remoteproc/remoteproc_cdev.c | 21 +-
drivers/remoteproc/remoteproc_core.c | 302 ++++++++++++++++++++---
drivers/remoteproc/remoteproc_internal.h | 10 +
drivers/remoteproc/remoteproc_sysfs.c | 17 +-
drivers/remoteproc/stm32_rproc.c | 168 ++++++-------
include/linux/remoteproc.h | 21 +-
6 files changed, 401 insertions(+), 138 deletions(-)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Whether started at probe() time or thereafter from the command
line, a remote processor needs to be shut down before the final
cleanup phases can happen. Otherwise the system may be left in
an unpredictable state where the remote processor is expecting
the remoteproc core to be providing services when in fact it
no longer exist.
Invariably calling rproc_shutdown() is fine since it will return
immediately if the remote processor has already been switched
off.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
@@ -2347,10 +2347,8 @@ int rproc_del(struct rproc *rproc)if(!rproc)return-EINVAL;-/* if rproc is marked always-on, rproc_add() booted it *//* TODO: make sure this works with rproc->power > 1 */-if(rproc->auto_boot)-rproc_shutdown(rproc);+rproc_shutdown(rproc);mutex_lock(&rproc->lock);rproc->state=RPROC_DELETED;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Rename function rproc_actuate() to rproc_attach(). That way it is
easy to understand that it does the opposite of rproc_detach().
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
@@ -1581,7 +1581,7 @@ static int rproc_actuate(struct rproc *rproc)gotoclean_up_resources;}-ret=rproc_attach(rproc);+ret=__rproc_attach(rproc);if(ret)gotoclean_up_resources;
@@ -1802,7 +1802,7 @@ int rproc_boot(struct rproc *rproc)if(rproc->state==RPROC_DETACHED){dev_info(dev,"attaching to %s\n",rproc->name);-ret=rproc_actuate(rproc);+ret=rproc_attach(rproc);}else{dev_info(dev,"powering up %s\n",rproc->name);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Add a new RPROC_ATTACHED state to take into account scenarios
where the remoteproc core needs to attach to a remote processor
that is booted by another entity.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_sysfs.c | 1 +
include/linux/remoteproc.h | 7 +++++--
2 files changed, 6 insertions(+), 2 deletions(-)
Move the setting of the resource table installed by an external
entity to rproc_ops::get_loaded_rsc_table(). This is to support
scenarios where a remote processor has been attached to but is
detached at a later stage. To re-attach the remote processor,
the address of the resource table needs to be available
at a later time than the platform driver's probe() function.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/stm32_rproc.c | 141 +++++++++++++++----------------
1 file changed, 68 insertions(+), 73 deletions(-)
@@ -546,6 +546,73 @@ static void stm32_rproc_kick(struct rproc *rproc, int vqid)}}+staticintstm32_rproc_da_to_pa(structrproc*rproc,+u64da,phys_addr_t*pa)+{+structstm32_rproc*ddata=rproc->priv;+structdevice*dev=rproc->dev.parent;+structstm32_rproc_mem*p_mem;+unsignedinti;++for(i=0;i<ddata->nb_rmems;i++){+p_mem=&ddata->rmems[i];++if(da<p_mem->dev_addr||+da>=p_mem->dev_addr+p_mem->size)+continue;++*pa=da-p_mem->dev_addr+p_mem->bus_addr;+dev_dbg(dev,"da %llx to pa %#x\n",da,*pa);++return0;+}++dev_err(dev,"can't translate da %llx\n",da);++return-EINVAL;+}++staticstructresource_table*+stm32_rproc_get_loaded_rsc_table(structrproc*rproc,size_t*table_sz)+{+structstm32_rproc*ddata=rproc->priv;+structdevice*dev=rproc->dev.parent;+phys_addr_trsc_pa;+u32rsc_da;+interr;++/* The resource table has already been mapped, nothing to do */+if(ddata->rsc_va)+gotodone;++err=regmap_read(ddata->rsctbl.map,ddata->rsctbl.reg,&rsc_da);+if(err){+dev_err(dev,"failed to read rsc tbl addr\n");+returnERR_PTR(-EINVAL);+}++if(!rsc_da)+/* no rsc table */+returnERR_PTR(-ENOENT);++err=stm32_rproc_da_to_pa(rproc,rsc_da,&rsc_pa);+if(err)+returnERR_PTR(err);++ddata->rsc_va=devm_ioremap_wc(dev,rsc_pa,RSC_TBL_SIZE);+if(IS_ERR_OR_NULL(ddata->rsc_va)){+dev_err(dev,"Unable to map memory region: %pa+%zx\n",+&rsc_pa,RSC_TBL_SIZE);+ddata->rsc_va=NULL;+returnERR_PTR(-ENOMEM);+}++done:+/* Assuming the resource table fits in 1kB is fair */+*table_sz=RSC_TBL_SIZE;+return(structresource_table*)ddata->rsc_va;+}+staticconststructrproc_opsst_rproc_ops={.start=stm32_rproc_start,.stop=stm32_rproc_stop,
@@ -695,75 +763,6 @@ static int stm32_rproc_get_m4_status(struct stm32_rproc *ddata,returnregmap_read(ddata->m4_state.map,ddata->m4_state.reg,state);}-staticintstm32_rproc_da_to_pa(structplatform_device*pdev,-structstm32_rproc*ddata,-u64da,phys_addr_t*pa)-{-structdevice*dev=&pdev->dev;-structstm32_rproc_mem*p_mem;-unsignedinti;--for(i=0;i<ddata->nb_rmems;i++){-p_mem=&ddata->rmems[i];--if(da<p_mem->dev_addr||-da>=p_mem->dev_addr+p_mem->size)-continue;--*pa=da-p_mem->dev_addr+p_mem->bus_addr;-dev_dbg(dev,"da %llx to pa %#x\n",da,*pa);--return0;-}--dev_err(dev,"can't translate da %llx\n",da);--return-EINVAL;-}--staticintstm32_rproc_get_loaded_rsc_table(structplatform_device*pdev,-structrproc*rproc,-structstm32_rproc*ddata)-{-structdevice*dev=&pdev->dev;-phys_addr_trsc_pa;-u32rsc_da;-interr;--err=regmap_read(ddata->rsctbl.map,ddata->rsctbl.reg,&rsc_da);-if(err){-dev_err(dev,"failed to read rsc tbl addr\n");-returnerr;-}--if(!rsc_da)-/* no rsc table */-return0;--err=stm32_rproc_da_to_pa(pdev,ddata,rsc_da,&rsc_pa);-if(err)-returnerr;--ddata->rsc_va=devm_ioremap_wc(dev,rsc_pa,RSC_TBL_SIZE);-if(IS_ERR_OR_NULL(ddata->rsc_va)){-dev_err(dev,"Unable to map memory region: %pa+%zx\n",-&rsc_pa,RSC_TBL_SIZE);-ddata->rsc_va=NULL;-return-ENOMEM;-}--/*-*Theresourcetableisalreadyloadedindevicememory,noneed-*toworkwithacachedtable.-*/-rproc->cached_table=NULL;-/* Assuming the resource table fits in 1kB is fair */-rproc->table_sz=RSC_TBL_SIZE;-rproc->table_ptr=(structresource_table*)ddata->rsc_va;--return0;-}-staticintstm32_rproc_probe(structplatform_device*pdev){structdevice*dev=&pdev->dev;
@@ -803,10 +802,6 @@ static int stm32_rproc_probe(struct platform_device *pdev)ret=stm32_rproc_parse_memory_regions(rproc);if(ret)gotofree_resources;--ret=stm32_rproc_get_loaded_rsc_table(pdev,rproc,ddata);-if(ret)-gotofree_resources;}rproc->has_iommu=false;
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
There is a need to know when a remote processor has been attached
to rather than booted by the remoteproc core. In order to avoid
manipulating two variables, i.e rproc::autonomous and
rproc::state, get rid of the former and simply use the newly
introduced RPROC_ATTACHED state.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 20 +-------------------
drivers/remoteproc/remoteproc_sysfs.c | 5 +----
include/linux/remoteproc.h | 2 --
3 files changed, 2 insertions(+), 25 deletions(-)
@@ -1444,7 +1444,7 @@ static int __rproc_attach(struct rproc *rproc)gotostop_rproc;}-rproc->state=RPROC_RUNNING;+rproc->state=RPROC_ATTACHED;dev_info(dev,"remote processor %s is now attached\n",rproc->name);
@@ -2077,16 +2069,6 @@ int rproc_add(struct rproc *rproc)if(ret<0)returnret;-/*-*Remindourselvestheremoteprocessorhasbeenattachedtorather-*thanbootedbytheremoteproccore.Thisisimportantbecausethe-*RPROC_DETACHEDstatewillbelostassoonastheremoteprocessor-*hasbeenattachedto.Usedinfirmware_show()andresetin-*rproc_stop().-*/-if(rproc->state==RPROC_DETACHED)-rproc->autonomous=true;-/* if rproc is marked always-on, request it to boot */if(rproc->auto_boot){ret=rproc_trigger_auto_boot(rproc);
Introduce function __rproc_detach() to perform the same kind of
operation as rproc_stop(), but instead of switching off the
remote processor using rproc->ops->stop(), it uses
rproc->ops->detach(). That way it is possible for the core
to release the resources associated with a remote processor while
the latter is kept operating.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 30 ++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
@@ -1706,6 +1706,36 @@ static int rproc_stop(struct rproc *rproc, bool crashed)return0;}+/*+*__rproc_detach():Doestheoppositeof__rproc_attach()+*/+staticint__maybe_unused__rproc_detach(structrproc*rproc)+{+structdevice*dev=&rproc->dev;+intret;++/* No need to continue if a detach() operation has not been provided */+if(!rproc->ops->detach)+return-EINVAL;++/* Stop any subdevices for the remote processor */+rproc_stop_subdevices(rproc,false);++/* Tell the remote processor the core isn't available anymore */+ret=rproc->ops->detach(rproc);+if(ret){+dev_err(dev,"can't detach from rproc: %d\n",ret);+returnret;+}++rproc_unprepare_subdevices(rproc);++rproc->state=RPROC_DETACHED;++dev_info(dev,"detached remote processor %s\n",rproc->name);++return0;+}/***rproc_trigger_recovery()-recoveraremoteproc
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
Some actions such as memory resources reallocation are needed when
trying to reattach a co-processor. Use the prepare() operation for
these actions.
Co-developed-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Arnaud POULIQUEN <arnaud.pouliquen@foss.st.com>
---
drivers/remoteproc/remoteproc_core.c | 14 ++++++++++++--
drivers/remoteproc/stm32_rproc.c | 27 ++++++---------------------
2 files changed, 18 insertions(+), 23 deletions(-)
@@ -1582,10 +1582,17 @@ static int rproc_attach(struct rproc *rproc)returnret;}+/* Do anything that is needed to boot the remote processor */+ret=rproc_prepare_device(rproc);+if(ret){+dev_err(dev,"can't prepare rproc %s: %d\n",rproc->name,ret);+gotodisable_iommu;+}+ret=rproc_set_rsc_table(rproc);if(ret){dev_err(dev,"can't load resource table: %d\n",ret);-gotodisable_iommu;+gotounprepare_device;}/* reset max_notifyid */
@@ -1602,7 +1609,7 @@ static int rproc_attach(struct rproc *rproc)ret=rproc_handle_resources(rproc,rproc_loading_handlers);if(ret){dev_err(dev,"Failed to process resources: %d\n",ret);-gotodisable_iommu;+gotounprepare_device;}/* Allocate carveout resources associated to rproc */
@@ -1621,6 +1628,9 @@ static int rproc_attach(struct rproc *rproc)clean_up_resources:rproc_resource_cleanup(rproc);+unprepare_device:+/* release HW resources if needed */+rproc_unprepare_device(rproc);disable_iommu:rproc_disable_iommu(rproc);returnret;
@@ -207,16 +207,7 @@ static int stm32_rproc_mbox_idx(struct rproc *rproc, const unsigned char *name)return-EINVAL;}-staticintstm32_rproc_elf_load_rsc_table(structrproc*rproc,-conststructfirmware*fw)-{-if(rproc_elf_load_rsc_table(rproc,fw))-dev_warn(&rproc->dev,"no resource table found for this firmware\n");--return0;-}--staticintstm32_rproc_parse_memory_regions(structrproc*rproc)+staticintstm32_rproc_prepare(structrproc*rproc){structdevice*dev=rproc->dev.parent;structdevice_node*np=dev->of_node;
@@ -274,12 +265,10 @@ static int stm32_rproc_parse_memory_regions(struct rproc *rproc)staticintstm32_rproc_parse_fw(structrproc*rproc,conststructfirmware*fw){-intret=stm32_rproc_parse_memory_regions(rproc);--if(ret)-returnret;+if(rproc_elf_load_rsc_table(rproc,fw))+dev_warn(&rproc->dev,"no resource table found for this firmware\n");-returnstm32_rproc_elf_load_rsc_table(rproc,fw);+return0;}staticirqreturn_tstm32_rproc_wdg(intirq,void*data)
Add a new get_loaded_rsc_table() operation in order to support
scenarios where the remoteproc core has booted a remote processor
and detaches from it. When re-attaching to the remote processor,
the core needs to know where the resource table has been placed
in memory.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 32 ++++++++++++++++++++++++
drivers/remoteproc/remoteproc_internal.h | 10 ++++++++
include/linux/remoteproc.h | 6 ++++-
3 files changed, 47 insertions(+), 1 deletion(-)
@@ -1537,6 +1537,32 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)returnret;}+staticintrproc_set_rsc_table(structrproc*rproc)+{+structresource_table*table_ptr;+structdevice*dev=&rproc->dev;+size_ttable_sz;+intret;++table_ptr=rproc_get_loaded_rsc_table(rproc,&table_sz);+if(!table_ptr){+/* Not having a resource table is acceptable */+return0;+}++if(IS_ERR(table_ptr)){+ret=PTR_ERR(table_ptr);+dev_err(dev,"can't load resource table: %d\n",ret);+returnret;+}++rproc->cached_table=NULL;+rproc->table_ptr=table_ptr;+rproc->table_sz=table_sz;++return0;+}+/**Attachtoremoteprocessor-similartorproc_fw_boot()butwithout*thestepsthatdealwiththefirmwareimage.
Add an new detach() operation in order to support scenarios where
the remoteproc core is going away but the remote processor is
kept operating. This could be the case when the system is
rebooted or when the platform driver is removed.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
include/linux/remoteproc.h | 2 ++
1 file changed, 2 insertions(+)
Introduce function rproc_detach() to enable the remoteproc
core to release the resources associated with a remote processor
without stopping its operation.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 58 +++++++++++++++++++++++++++-
include/linux/remoteproc.h | 1 +
2 files changed, 58 insertions(+), 1 deletion(-)
@@ -1948,6 +1948,62 @@ void rproc_shutdown(struct rproc *rproc)}EXPORT_SYMBOL(rproc_shutdown);+/**+*rproc_detach()-Detachtheremoteprocessorfromthe+*remoteproccore+*+*@rproc:theremoteprocessor+*+*Detacharemoteprocessor(previouslyattachedtowithrproc_attach()).+*+*Incase@rprocisstillbeingusedbyanadditionaluser(s),then+*thisfunctionwilljustdecrementthepowerrefcountandexit,+*withoutdisconnectingthedevice.+*+*Functionrproc_detach()calls__rproc_detach()inordertoletaremote+*processorknowthatservicesprovidedbytheapplicationprocessorare+*nolongeravailable.Fromthereitshouldbepossibletoremovethe+*platformdriverandevenpowercycletheapplicationprocessor(iftheHW+*supportsit)withoutneedingtoswitchofftheremoteprocessor.+*/+intrproc_detach(structrproc*rproc)+{+structdevice*dev=&rproc->dev;+intret;++ret=mutex_lock_interruptible(&rproc->lock);+if(ret){+dev_err(dev,"can't lock rproc %s: %d\n",rproc->name,ret);+returnret;+}++/* if the remote proc is still needed, bail out */+if(!atomic_dec_and_test(&rproc->power)){+ret=0;+gotoout;+}++ret=__rproc_detach(rproc);+if(ret){+atomic_inc(&rproc->power);+gotoout;+}++/* clean up all acquired resources */+rproc_resource_cleanup(rproc);++/* release HW resources if needed */+rproc_unprepare_device(rproc);++rproc_disable_iommu(rproc);++rproc->table_ptr=NULL;+out:+mutex_unlock(&rproc->lock);+returnret;+}+EXPORT_SYMBOL(rproc_detach);+/***rproc_get_by_phandle()-findaremoteprocessorbyphandle*@phandle:phandletotherproc
The panic handler operation of registered remote processors
should also be called when remote processors have been
attached to.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_core.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
This patch takes into account scenarios where a remote processor
has been attached to when receiving a "start" command from sysfs.
As with the case with the running state, the command can't be
carried out if the remote processor is already in operation.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_cdev.c | 3 ++-
drivers/remoteproc/remoteproc_sysfs.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
Allow a remote processor that was started by another entity to be
switched off by the remoteproc core. For that to happen a
rproc::ops::stop() operation needs to be available.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_cdev.c | 3 ++-
drivers/remoteproc/remoteproc_core.c | 4 ++++
drivers/remoteproc/remoteproc_sysfs.c | 3 ++-
3 files changed, 8 insertions(+), 2 deletions(-)
@@ -1796,6 +1796,10 @@ static int rproc_stop(struct rproc *rproc, bool crashed)structdevice*dev=&rproc->dev;intret;+/* No need to continue if a stop() operation has not been provided */+if(!rproc->ops->stop)+return-EINVAL;+/* Stop any subdevices for the remote processor */rproc_stop_subdevices(rproc,crashed);
If it is possible to detach the remote processor, keep an untouched
copy of the resource table. That way we can start from the same
resource table without having to worry about original values or what
elements the startup code has changed when re-attaching to the remote
processor.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
New for V8:
- Checking return code for error in __rproc_datch().
---
drivers/remoteproc/remoteproc_core.c | 82 ++++++++++++++++++++++++++++
include/linux/remoteproc.h | 3 +
2 files changed, 85 insertions(+)
@@ -1556,6 +1556,24 @@ static int rproc_set_rsc_table(struct rproc *rproc)returnret;}+/*+*Ifitispossibletodetachtheremoteprocessor,keepanuntouched+*copyoftheresourcetable.Thatwaywecanstartfreshagainwhen+*theremoteprocessorisre-attached,thatis:+*+*DETACHED->ATTACHED->DETACHED->ATTACHED+*+*Free'dinrproc_reset_rsc_table_on_detach()and+*rproc_reset_rsc_table_on_stop().+*/+if(rproc->ops->detach){+rproc->clean_table=kmemdup(table_ptr,table_sz,GFP_KERNEL);+if(!rproc->clean_table)+return-ENOMEM;+}else{+rproc->clean_table=NULL;+}+rproc->cached_table=NULL;rproc->table_ptr=table_ptr;rproc->table_sz=table_sz;
@@ -1563,6 +1581,59 @@ static int rproc_set_rsc_table(struct rproc *rproc)return0;}+staticintrproc_reset_rsc_table_on_detach(structrproc*rproc)+{+structresource_table*table_ptr;++/* A resource table was never retrieved, nothing to do here */+if(!rproc->table_ptr)+return0;++/*+*Ifwemadeittothispointaclean_table_must_havebeen+*allocatedinrproc_set_rsc_table().Ifoneisn'tpresent+*somethingwentreallywrongandwemustcomplain.+*/+if(WARN_ON(!rproc->clean_table))+return-EINVAL;++/* Remember where the external entity installed the resource table */+table_ptr=rproc->table_ptr;++/*+*Ifwemadeitheretheremoteprocessorwasstartedbyanother+*entityandacachetabledoesn'texist.Assuchmakeacopyof+*theresourcetablecurrentlyusedbytheremoteprocessorand+*usethatfortherestoftheshutdownprocess.Thememory+*allocatedhereisfree'dinrproc_detach().+*/+rproc->cached_table=kmemdup(rproc->table_ptr,+rproc->table_sz,GFP_KERNEL);+if(!rproc->cached_table)+return-ENOMEM;++/*+*Useacopyoftheresourcetablefortheremainderofthe+*shutdownprocess.+*/+rproc->table_ptr=rproc->cached_table;++/*+*Resetthememoryareawherethefirmwareloadedtheresourcetable+*toitsoriginalvalue.Thatwaywhenwere-attachtheremote+*processortheresourcetableiscleanandreadytobeusedagain.+*/+memcpy(table_ptr,rproc->clean_table,rproc->table_sz);++/*+*Thecleanresourcetableisnolongerneeded.Allocatedin+*rproc_set_rsc_table().+*/+kfree(rproc->clean_table);++return0;+}+/**Attachtoremoteprocessor-similartorproc_fw_boot()butwithout*thestepsthatdealwiththefirmwareimage.
@@ -1721,6 +1792,14 @@ static int __rproc_detach(struct rproc *rproc)/* Stop any subdevices for the remote processor */rproc_stop_subdevices(rproc,false);+/* the installed resource table is no longer accessible */+ret=rproc_reset_rsc_table_on_detach(rproc);+if(ret){+dev_err(dev,"can't reset resource table: %d\n",ret);+returnret;+}++/* Tell the remote processor the core isn't available anymore */ret=rproc->ops->detach(rproc);if(ret){
@@ -1997,6 +2076,9 @@ int rproc_detach(struct rproc *rproc)rproc_disable_iommu(rproc);+/* Free the copy of the resource table */+kfree(rproc->cached_table);+rproc->cached_table=NULL;rproc->table_ptr=NULL;out:mutex_unlock(&rproc->lock);
When a remote processor that was attached to is stopped, special care
must be taken to make sure the shutdown process is similar to what
it would be had it been started by the remoteproc core.
This patch takes care of that by making a copy of the resource
table currently used by the remote processor. From that point on
the copy is used, as if the remote processor had been started by
the remoteproc core.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
Reported-by: kernel test robot <redacted>
---
New for V8:
- Removed variable @table_ptr as it served no purpose.
---
drivers/remoteproc/remoteproc_core.c | 48 +++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
@@ -1634,6 +1634,47 @@ static int rproc_reset_rsc_table_on_detach(struct rproc *rproc)return0;}+staticintrproc_reset_rsc_table_on_stop(structrproc*rproc)+{+/* A resource table was never retrieved, nothing to do here */+if(!rproc->table_ptr)+return0;++/*+*Ifacachetableexiststheremoteprocessorwasstartedby+*theremoteproccore.Thatcachetableshouldbeusedfor+*therestoftheshutdownprocess.+*/+if(rproc->cached_table)+gotoout;++/*+*Ifwemadeitheretheremoteprocessorwasstartedbyanother+*entityandacachetabledoesn'texist.Assuchmakeacopyof+*theresourcetablecurrentlyusedbytheremoteprocessorand+*usethatfortherestoftheshutdownprocess.Thememory+*allocatedhereisfree'dinrproc_shutdown().+*/+rproc->cached_table=kmemdup(rproc->table_ptr,+rproc->table_sz,GFP_KERNEL);+if(!rproc->cached_table)+return-ENOMEM;++/*+*Sincetheremoteprocessorisbeingswitchedoffthecleantable+*won'tbeneeded.Allocatedinrproc_set_rsc_table().+*/+kfree(rproc->clean_table);++out:+/*+*Useacopyoftheresourcetablefortheremainderofthe+*shutdownprocess.+*/+rproc->table_ptr=rproc->cached_table;+return0;+}+/**Attachtoremoteprocessor-similartorproc_fw_boot()butwithout*thestepsthatdealwiththefirmwareimage.
@@ -1759,7 +1800,12 @@ static int rproc_stop(struct rproc *rproc, bool crashed)rproc_stop_subdevices(rproc,crashed);/* the installed resource table is no longer accessible */-rproc->table_ptr=rproc->cached_table;+ret=rproc_reset_rsc_table_on_stop(rproc);+if(ret){+dev_err(dev,"can't reset resource table: %d\n",ret);+returnret;+}+/* power off the remote processor */ret=rproc->ops->stop(rproc);
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Refactor function rproc_cdev_release() to take into account the
current state of the remote processor when choosing the state to
transition to.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
drivers/remoteproc/remoteproc_cdev.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
This patch introduces the capability to detach a remote processor
that has been attached to by the remoteproc core. For that to happen
a rproc::ops::detach() operation needs to be available.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: Arnaud Pouliquen <redacted>
---
drivers/remoteproc/remoteproc_cdev.c | 5 +++++
drivers/remoteproc/remoteproc_sysfs.c | 5 +++++
2 files changed, 10 insertions(+)