2011-10-20 18:52:46 +04:00
/*
* Remote Processor Framework
*
* Copyright ( C ) 2011 Texas Instruments , Inc .
* Copyright ( C ) 2011 Google , Inc .
*
* Ohad Ben - Cohen < ohad @ wizery . com >
* Brian Swetland < swetland @ google . com >
* Mark Grosen < mgrosen @ ti . com >
* Fernando Guzman Lugo < fernando . lugo @ ti . com >
* Suman Anna < s - anna @ ti . com >
* Robert Tivy < rtivy @ ti . com >
* Armando Uribe De Leon < x0095078 @ ti . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# define pr_fmt(fmt) "%s: " fmt, __func__
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/device.h>
# include <linux/slab.h>
# include <linux/mutex.h>
# include <linux/dma-mapping.h>
# include <linux/firmware.h>
# include <linux/string.h>
# include <linux/debugfs.h>
# include <linux/remoteproc.h>
# include <linux/iommu.h>
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
# include <linux/idr.h>
2011-10-20 18:52:46 +04:00
# include <linux/elf.h>
2013-04-07 15:06:07 +04:00
# include <linux/crc32.h>
2011-10-20 18:52:46 +04:00
# include <linux/virtio_ids.h>
# include <linux/virtio_ring.h>
2012-01-31 17:23:41 +04:00
# include <asm/byteorder.h>
2011-10-20 18:52:46 +04:00
# include "remoteproc_internal.h"
2015-05-22 23:45:27 +03:00
static DEFINE_MUTEX ( rproc_list_mutex ) ;
static LIST_HEAD ( rproc_list ) ;
2011-10-20 18:52:46 +04:00
typedef int ( * rproc_handle_resources_t ) ( struct rproc * rproc ,
2012-02-01 23:56:16 +04:00
struct resource_table * table , int len ) ;
2013-04-07 15:06:07 +04:00
typedef int ( * rproc_handle_resource_t ) ( struct rproc * rproc ,
void * , int offset , int avail ) ;
2011-10-20 18:52:46 +04:00
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
/* Unique indices for remoteproc devices */
static DEFINE_IDA ( rproc_dev_index ) ;
2012-08-30 22:26:12 +04:00
static const char * const rproc_crash_names [ ] = {
[ RPROC_MMUFAULT ] = " mmufault " ,
} ;
/* translate rproc_crash_type to string */
static const char * rproc_crash_to_string ( enum rproc_crash_type type )
{
if ( type < ARRAY_SIZE ( rproc_crash_names ) )
return rproc_crash_names [ type ] ;
2013-04-17 19:12:55 +04:00
return " unknown " ;
2012-08-30 22:26:12 +04:00
}
2011-10-20 18:52:46 +04:00
/*
* This is the IOMMU fault handler we register with the IOMMU API
* ( when relevant ; not all remote processors access memory through
* an IOMMU ) .
*
* IOMMU core will invoke this handler whenever the remote processor
* will try to access an unmapped device address .
*/
static int rproc_iommu_fault ( struct iommu_domain * domain , struct device * dev ,
2012-05-21 21:20:05 +04:00
unsigned long iova , int flags , void * token )
2011-10-20 18:52:46 +04:00
{
2012-08-30 22:26:12 +04:00
struct rproc * rproc = token ;
2011-10-20 18:52:46 +04:00
dev_err ( dev , " iommu fault: da 0x%lx flags 0x%x \n " , iova , flags ) ;
2012-08-30 22:26:12 +04:00
rproc_report_crash ( rproc , RPROC_MMUFAULT ) ;
2011-10-20 18:52:46 +04:00
/*
* Let the iommu core know we ' re not really handling this fault ;
2012-08-30 22:26:12 +04:00
* we just used it as a recovery trigger .
2011-10-20 18:52:46 +04:00
*/
return - ENOSYS ;
}
static int rproc_enable_iommu ( struct rproc * rproc )
{
struct iommu_domain * domain ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = rproc - > dev . parent ;
2011-10-20 18:52:46 +04:00
int ret ;
2015-01-10 00:21:58 +03:00
if ( ! rproc - > has_iommu ) {
dev_dbg ( dev , " iommu not present \n " ) ;
2011-12-13 10:41:47 +04:00
return 0 ;
2011-10-20 18:52:46 +04:00
}
domain = iommu_domain_alloc ( dev - > bus ) ;
if ( ! domain ) {
dev_err ( dev , " can't alloc iommu domain \n " ) ;
return - ENOMEM ;
}
2012-05-21 21:20:05 +04:00
iommu_set_fault_handler ( domain , rproc_iommu_fault , rproc ) ;
2011-10-20 18:52:46 +04:00
ret = iommu_attach_device ( domain , dev ) ;
if ( ret ) {
dev_err ( dev , " can't attach iommu device: %d \n " , ret ) ;
goto free_domain ;
}
rproc - > domain = domain ;
return 0 ;
free_domain :
iommu_domain_free ( domain ) ;
return ret ;
}
static void rproc_disable_iommu ( struct rproc * rproc )
{
struct iommu_domain * domain = rproc - > domain ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = rproc - > dev . parent ;
2011-10-20 18:52:46 +04:00
if ( ! domain )
return ;
iommu_detach_device ( domain , dev ) ;
iommu_domain_free ( domain ) ;
}
2015-05-22 23:45:28 +03:00
/**
* rproc_da_to_va ( ) - lookup the kernel virtual address for a remoteproc address
* @ rproc : handle of a remote processor
* @ da : remoteproc device address to translate
* @ len : length of the memory region @ da is pointing to
*
2011-10-20 18:52:46 +04:00
* Some remote processors will ask us to allocate them physically contiguous
* memory regions ( which we call " carveouts " ) , and map them to specific
2015-05-22 23:45:28 +03:00
* device addresses ( which are hardcoded in the firmware ) . They may also have
* dedicated memory regions internal to the processors , and use them either
* exclusively or alongside carveouts .
2011-10-20 18:52:46 +04:00
*
* They may then ask us to copy objects into specific device addresses ( e . g .
* code / data sections ) or expose us certain symbols in other device address
* ( e . g . their trace buffer ) .
*
2015-05-22 23:45:28 +03:00
* This function is a helper function with which we can go over the allocated
* carveouts and translate specific device addresses to kernel virtual addresses
* so we can access the referenced memory . This function also allows to perform
* translations on the internal remoteproc memory regions through a platform
* implementation specific da_to_va ops , if present .
*
* The function returns a valid kernel address on success or NULL on failure .
2011-10-20 18:52:46 +04:00
*
* Note : phys_to_virt ( iommu_iova_to_phys ( rproc - > domain , da ) ) will work too ,
* but only on kernel direct mapped RAM memory . Instead , we ' re just using
2015-05-22 23:45:28 +03:00
* here the output of the DMA API for the carveouts , which should be more
* correct .
2011-10-20 18:52:46 +04:00
*/
2012-07-15 12:25:27 +04:00
void * rproc_da_to_va ( struct rproc * rproc , u64 da , int len )
2011-10-20 18:52:46 +04:00
{
struct rproc_mem_entry * carveout ;
void * ptr = NULL ;
2015-05-22 23:45:28 +03:00
if ( rproc - > ops - > da_to_va ) {
ptr = rproc - > ops - > da_to_va ( rproc , da , len ) ;
if ( ptr )
goto out ;
}
2011-10-20 18:52:46 +04:00
list_for_each_entry ( carveout , & rproc - > carveouts , node ) {
int offset = da - carveout - > da ;
/* try next carveout if da is too small */
if ( offset < 0 )
continue ;
/* try next carveout if da is too large */
if ( offset + len > carveout - > len )
continue ;
ptr = carveout - > va + offset ;
break ;
}
2015-05-22 23:45:28 +03:00
out :
2011-10-20 18:52:46 +04:00
return ptr ;
}
2012-06-19 11:08:18 +04:00
EXPORT_SYMBOL ( rproc_da_to_va ) ;
2011-10-20 18:52:46 +04:00
2012-05-17 15:23:59 +04:00
int rproc_alloc_vring ( struct rproc_vdev * rvdev , int i )
2011-10-20 18:52:46 +04:00
{
2012-02-14 01:30:39 +04:00
struct rproc * rproc = rvdev - > rproc ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2012-05-17 15:23:59 +04:00
struct rproc_vring * rvring = & rvdev - > vring [ i ] ;
2013-02-21 21:15:40 +04:00
struct fw_rsc_vdev * rsc ;
2012-02-14 01:30:39 +04:00
dma_addr_t dma ;
void * va ;
int ret , size , notifyid ;
2011-10-20 18:52:46 +04:00
2012-02-14 01:30:39 +04:00
/* actual size of vring (in bytes) */
2012-05-17 15:23:59 +04:00
size = PAGE_ALIGN ( vring_size ( rvring - > len , rvring - > align ) ) ;
2012-02-14 01:30:39 +04:00
/*
* Allocate non - cacheable memory for the vring . In the future
* this call will also configure the IOMMU for us
*/
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
va = dma_alloc_coherent ( dev - > parent , size , & dma , GFP_KERNEL ) ;
2012-02-14 01:30:39 +04:00
if ( ! va ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev - > parent , " dma_alloc_coherent failed \n " ) ;
2011-10-20 18:52:46 +04:00
return - EINVAL ;
}
2012-05-17 15:23:59 +04:00
/*
* Assign an rproc - wide unique index for this vring
* TODO : assign a notifyid for rvdev updates as well
* TODO : support predefined notifyids ( via resource table )
*/
2013-02-28 05:04:39 +04:00
ret = idr_alloc ( & rproc - > notifyids , rvring , 0 , 0 , GFP_KERNEL ) ;
2013-03-07 02:56:48 +04:00
if ( ret < 0 ) {
2013-02-28 05:04:39 +04:00
dev_err ( dev , " idr_alloc failed: %d \n " , ret ) ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dma_free_coherent ( dev - > parent , size , va , dma ) ;
2012-02-14 01:30:39 +04:00
return ret ;
}
2013-02-28 05:04:39 +04:00
notifyid = ret ;
2011-10-20 18:52:46 +04:00
2012-09-28 19:35:06 +04:00
dev_dbg ( dev , " vring%d: va %p dma %llx size %x idr %d \n " , i , va ,
( unsigned long long ) dma , size , notifyid ) ;
2012-02-14 01:30:39 +04:00
2012-05-17 15:23:59 +04:00
rvring - > va = va ;
rvring - > dma = dma ;
rvring - > notifyid = notifyid ;
2011-10-20 18:52:46 +04:00
2013-02-21 21:15:40 +04:00
/*
* Let the rproc know the notifyid and da of this vring .
* Not all platforms use dma_alloc_coherent to automatically
* set up the iommu . In this case the device address ( da ) will
* hold the physical address and not the device address .
*/
rsc = ( void * ) rproc - > table_ptr + rvdev - > rsc_offset ;
rsc - > vring [ i ] . da = dma ;
rsc - > vring [ i ] . notifyid = notifyid ;
2011-10-20 18:52:46 +04:00
return 0 ;
}
2012-05-17 15:23:59 +04:00
static int
rproc_parse_vring ( struct rproc_vdev * rvdev , struct fw_rsc_vdev * rsc , int i )
2012-02-14 01:30:39 +04:00
{
struct rproc * rproc = rvdev - > rproc ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2012-05-17 15:23:59 +04:00
struct fw_rsc_vdev_vring * vring = & rsc - > vring [ i ] ;
struct rproc_vring * rvring = & rvdev - > vring [ i ] ;
2012-02-14 01:30:39 +04:00
2012-05-17 15:23:59 +04:00
dev_dbg ( dev , " vdev rsc: vring%d: da %x, qsz %d, align %d \n " ,
i , vring - > da , vring - > num , vring - > align ) ;
2012-02-14 01:30:39 +04:00
2012-05-17 15:23:59 +04:00
/* make sure reserved bytes are zeroes */
if ( vring - > reserved ) {
dev_err ( dev , " vring rsc has non zero reserved bytes \n " ) ;
return - EINVAL ;
}
2012-02-14 01:30:39 +04:00
2012-05-17 15:23:59 +04:00
/* verify queue size and vring alignment are sane */
if ( ! vring - > num | | ! vring - > align ) {
dev_err ( dev , " invalid qsz (%d) or alignment (%d) \n " ,
vring - > num , vring - > align ) ;
return - EINVAL ;
2012-02-14 01:30:39 +04:00
}
2012-05-17 15:23:59 +04:00
rvring - > len = vring - > num ;
rvring - > align = vring - > align ;
rvring - > rvdev = rvdev ;
return 0 ;
}
void rproc_free_vring ( struct rproc_vring * rvring )
{
int size = PAGE_ALIGN ( vring_size ( rvring - > len , rvring - > align ) ) ;
struct rproc * rproc = rvring - > rvdev - > rproc ;
2013-02-21 21:15:40 +04:00
int idx = rvring - > rvdev - > vring - rvring ;
struct fw_rsc_vdev * rsc ;
2012-05-17 15:23:59 +04:00
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dma_free_coherent ( rproc - > dev . parent , size , rvring - > va , rvring - > dma ) ;
2012-05-17 15:23:59 +04:00
idr_remove ( & rproc - > notifyids , rvring - > notifyid ) ;
2012-09-18 22:32:45 +04:00
2013-02-21 21:15:40 +04:00
/* reset resource entry info */
rsc = ( void * ) rproc - > table_ptr + rvring - > rvdev - > rsc_offset ;
rsc - > vring [ idx ] . da = 0 ;
rsc - > vring [ idx ] . notifyid = - 1 ;
2012-02-14 01:30:39 +04:00
}
2011-10-20 18:52:46 +04:00
/**
2012-02-01 23:56:16 +04:00
* rproc_handle_vdev ( ) - handle a vdev fw resource
2011-10-20 18:52:46 +04:00
* @ rproc : the remote processor
* @ rsc : the vring resource descriptor
2012-02-01 23:56:16 +04:00
* @ avail : size of available data ( for sanity checking the image )
2011-10-20 18:52:46 +04:00
*
2012-02-14 01:30:39 +04:00
* This resource entry requests the host to statically register a virtio
* device ( vdev ) , and setup everything needed to support it . It contains
* everything needed to make it possible : the virtio device id , virtio
* device features , vrings information , virtio config space , etc . . .
*
* Before registering the vdev , the vrings are allocated from non - cacheable
* physically contiguous memory . Currently we only support two vrings per
* remote processor ( temporary limitation ) . We might also want to consider
* doing the vring allocation only later when - > find_vqs ( ) is invoked , and
* then release them upon - > del_vqs ( ) .
*
* Note : @ da is currently not really handled correctly : we dynamically
* allocate it using the DMA API , ignoring requested hard coded addresses ,
* and we don ' t take care of any required IOMMU programming . This is all
* going to be taken care of when the generic iommu - based DMA API will be
* merged . Meanwhile , statically - addressed iommu - based firmware images should
* use RSC_DEVMEM resource entries to map their required @ da to the physical
* address of their base CMA region ( ouch , hacky ! ) .
2011-10-20 18:52:46 +04:00
*
* Returns 0 on success , or an appropriate error code otherwise
*/
2012-02-01 23:56:16 +04:00
static int rproc_handle_vdev ( struct rproc * rproc , struct fw_rsc_vdev * rsc ,
2013-04-07 15:06:07 +04:00
int offset , int avail )
2011-10-20 18:52:46 +04:00
{
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2012-02-14 01:30:39 +04:00
struct rproc_vdev * rvdev ;
int i , ret ;
2011-10-20 18:52:46 +04:00
2012-02-01 23:56:16 +04:00
/* make sure resource isn't truncated */
if ( sizeof ( * rsc ) + rsc - > num_of_vrings * sizeof ( struct fw_rsc_vdev_vring )
+ rsc - > config_len > avail ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev , " vdev rsc is truncated \n " ) ;
2011-10-20 18:52:46 +04:00
return - EINVAL ;
}
2012-02-01 23:56:16 +04:00
/* make sure reserved bytes are zeroes */
if ( rsc - > reserved [ 0 ] | | rsc - > reserved [ 1 ] ) {
dev_err ( dev , " vdev rsc has non zero reserved bytes \n " ) ;
2011-10-20 18:52:46 +04:00
return - EINVAL ;
}
2012-02-01 23:56:16 +04:00
dev_dbg ( dev , " vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings \n " ,
rsc - > id , rsc - > dfeatures , rsc - > config_len , rsc - > num_of_vrings ) ;
2012-02-14 01:30:39 +04:00
/* we currently support only two vrings per rvdev */
if ( rsc - > num_of_vrings > ARRAY_SIZE ( rvdev - > vring ) ) {
2012-02-01 23:56:16 +04:00
dev_err ( dev , " too many vrings: %d \n " , rsc - > num_of_vrings ) ;
2011-10-20 18:52:46 +04:00
return - EINVAL ;
}
2012-02-14 01:30:39 +04:00
rvdev = kzalloc ( sizeof ( struct rproc_vdev ) , GFP_KERNEL ) ;
if ( ! rvdev )
return - ENOMEM ;
2011-10-20 18:52:46 +04:00
2012-02-14 01:30:39 +04:00
rvdev - > rproc = rproc ;
2011-10-20 18:52:46 +04:00
2012-05-17 15:23:59 +04:00
/* parse the vrings */
2012-02-14 01:30:39 +04:00
for ( i = 0 ; i < rsc - > num_of_vrings ; i + + ) {
2012-05-17 15:23:59 +04:00
ret = rproc_parse_vring ( rvdev , rsc , i ) ;
2012-02-14 01:30:39 +04:00
if ( ret )
2012-05-17 15:23:59 +04:00
goto free_rvdev ;
2012-02-14 01:30:39 +04:00
}
2011-10-20 18:52:46 +04:00
2013-04-07 15:06:07 +04:00
/* remember the resource offset*/
rvdev - > rsc_offset = offset ;
2012-02-01 23:56:16 +04:00
2012-02-14 01:30:39 +04:00
list_add_tail ( & rvdev - > node , & rproc - > rvdevs ) ;
2012-02-01 23:56:16 +04:00
2012-02-14 01:30:39 +04:00
/* it is now safe to add the virtio device */
ret = rproc_add_virtio_dev ( rvdev , rsc - > id ) ;
if ( ret )
2013-02-21 21:15:32 +04:00
goto remove_rvdev ;
2011-10-20 18:52:46 +04:00
return 0 ;
2012-02-14 01:30:39 +04:00
2013-02-21 21:15:32 +04:00
remove_rvdev :
list_del ( & rvdev - > node ) ;
2012-05-17 15:23:59 +04:00
free_rvdev :
2012-02-14 01:30:39 +04:00
kfree ( rvdev ) ;
return ret ;
2011-10-20 18:52:46 +04:00
}
/**
* rproc_handle_trace ( ) - handle a shared trace buffer resource
* @ rproc : the remote processor
* @ rsc : the trace resource descriptor
2012-02-01 23:56:16 +04:00
* @ avail : size of available data ( for sanity checking the image )
2011-10-20 18:52:46 +04:00
*
* In case the remote processor dumps trace logs into memory ,
* export it via debugfs .
*
* Currently , the ' da ' member of @ rsc should contain the device address
* where the remote processor is dumping the traces . Later we could also
* support dynamically allocating this address using the generic
* DMA API ( but currently there isn ' t a use case for that ) .
*
* Returns 0 on success , or an appropriate error code otherwise
*/
2012-02-01 23:56:16 +04:00
static int rproc_handle_trace ( struct rproc * rproc , struct fw_rsc_trace * rsc ,
2013-04-07 15:06:07 +04:00
int offset , int avail )
2011-10-20 18:52:46 +04:00
{
struct rproc_mem_entry * trace ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
void * ptr ;
char name [ 15 ] ;
2012-02-01 23:56:16 +04:00
if ( sizeof ( * rsc ) > avail ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev , " trace rsc is truncated \n " ) ;
2012-02-01 23:56:16 +04:00
return - EINVAL ;
}
/* make sure reserved bytes are zeroes */
if ( rsc - > reserved ) {
dev_err ( dev , " trace rsc has non zero reserved bytes \n " ) ;
return - EINVAL ;
}
2011-10-20 18:52:46 +04:00
/* what's the kernel address of this resource ? */
ptr = rproc_da_to_va ( rproc , rsc - > da , rsc - > len ) ;
if ( ! ptr ) {
dev_err ( dev , " erroneous trace resource entry \n " ) ;
return - EINVAL ;
}
trace = kzalloc ( sizeof ( * trace ) , GFP_KERNEL ) ;
2015-02-28 02:18:23 +03:00
if ( ! trace )
2011-10-20 18:52:46 +04:00
return - ENOMEM ;
/* set the trace buffer dma properties */
trace - > len = rsc - > len ;
trace - > va = ptr ;
/* make sure snprintf always null terminates, even if truncating */
snprintf ( name , sizeof ( name ) , " trace%d " , rproc - > num_traces ) ;
/* create the debugfs entry */
trace - > priv = rproc_create_trace_file ( name , rproc , trace ) ;
if ( ! trace - > priv ) {
trace - > va = NULL ;
kfree ( trace ) ;
return - EINVAL ;
}
list_add_tail ( & trace - > node , & rproc - > traces ) ;
rproc - > num_traces + + ;
2012-02-01 23:56:16 +04:00
dev_dbg ( dev , " %s added: va %p, da 0x%x, len 0x%x \n " , name , ptr ,
2011-10-20 18:52:46 +04:00
rsc - > da , rsc - > len ) ;
return 0 ;
}
/**
* rproc_handle_devmem ( ) - handle devmem resource entry
* @ rproc : remote processor handle
* @ rsc : the devmem resource entry
2012-02-01 23:56:16 +04:00
* @ avail : size of available data ( for sanity checking the image )
2011-10-20 18:52:46 +04:00
*
* Remote processors commonly need to access certain on - chip peripherals .
*
* Some of these remote processors access memory via an iommu device ,
* and might require us to configure their iommu before they can access
* the on - chip peripherals they need .
*
* This resource entry is a request to map such a peripheral device .
*
* These devmem entries will contain the physical address of the device in
* the ' pa ' member . If a specific device address is expected , then ' da ' will
* contain it ( currently this is the only use case supported ) . ' len ' will
* contain the size of the physical region we need to map .
*
* Currently we just " trust " those devmem entries to contain valid physical
* addresses , but this is going to change : we want the implementations to
* tell us ranges of physical addresses the firmware is allowed to request ,
* and not allow firmwares to request access to physical addresses that
* are outside those ranges .
*/
2012-02-01 23:56:16 +04:00
static int rproc_handle_devmem ( struct rproc * rproc , struct fw_rsc_devmem * rsc ,
2013-04-07 15:06:07 +04:00
int offset , int avail )
2011-10-20 18:52:46 +04:00
{
struct rproc_mem_entry * mapping ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
int ret ;
/* no point in handling this resource without a valid iommu domain */
if ( ! rproc - > domain )
return - EINVAL ;
2012-02-01 23:56:16 +04:00
if ( sizeof ( * rsc ) > avail ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev , " devmem rsc is truncated \n " ) ;
2012-02-01 23:56:16 +04:00
return - EINVAL ;
}
/* make sure reserved bytes are zeroes */
if ( rsc - > reserved ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev , " devmem rsc has non zero reserved bytes \n " ) ;
2012-02-01 23:56:16 +04:00
return - EINVAL ;
}
2011-10-20 18:52:46 +04:00
mapping = kzalloc ( sizeof ( * mapping ) , GFP_KERNEL ) ;
2015-02-28 02:18:23 +03:00
if ( ! mapping )
2011-10-20 18:52:46 +04:00
return - ENOMEM ;
ret = iommu_map ( rproc - > domain , rsc - > da , rsc - > pa , rsc - > len , rsc - > flags ) ;
if ( ret ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev , " failed to map devmem: %d \n " , ret ) ;
2011-10-20 18:52:46 +04:00
goto out ;
}
/*
* We ' ll need this info later when we ' ll want to unmap everything
* ( e . g . on shutdown ) .
*
* We can ' t trust the remote processor not to change the resource
* table , so we must maintain this info independently .
*/
mapping - > da = rsc - > da ;
mapping - > len = rsc - > len ;
list_add_tail ( & mapping - > node , & rproc - > mappings ) ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_dbg ( dev , " mapped devmem pa 0x%x, da 0x%x, len 0x%x \n " ,
2011-10-20 18:52:46 +04:00
rsc - > pa , rsc - > da , rsc - > len ) ;
return 0 ;
out :
kfree ( mapping ) ;
return ret ;
}
/**
* rproc_handle_carveout ( ) - handle phys contig memory allocation requests
* @ rproc : rproc handle
* @ rsc : the resource entry
2012-02-01 23:56:16 +04:00
* @ avail : size of available data ( for image validation )
2011-10-20 18:52:46 +04:00
*
* This function will handle firmware requests for allocation of physically
* contiguous memory regions .
*
* These request entries should come first in the firmware ' s resource table ,
* as other firmware entries might request placing other data objects inside
* these memory regions ( e . g . data / code segments , trace resource entries , . . . ) .
*
* Allocating memory this way helps utilizing the reserved physical memory
* ( e . g . CMA ) more efficiently , and also minimizes the number of TLB entries
* needed to map it ( in case @ rproc is using an IOMMU ) . Reducing the TLB
* pressure is important ; it may have a substantial impact on performance .
*/
2012-02-01 23:56:16 +04:00
static int rproc_handle_carveout ( struct rproc * rproc ,
2013-04-07 15:06:07 +04:00
struct fw_rsc_carveout * rsc ,
int offset , int avail )
2011-10-20 18:52:46 +04:00
{
struct rproc_mem_entry * carveout , * mapping ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
dma_addr_t dma ;
void * va ;
int ret ;
2012-02-01 23:56:16 +04:00
if ( sizeof ( * rsc ) > avail ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev , " carveout rsc is truncated \n " ) ;
2012-02-01 23:56:16 +04:00
return - EINVAL ;
}
/* make sure reserved bytes are zeroes */
if ( rsc - > reserved ) {
dev_err ( dev , " carveout rsc has non zero reserved bytes \n " ) ;
return - EINVAL ;
}
dev_dbg ( dev , " carveout rsc: da %x, pa %x, len %x, flags %x \n " ,
rsc - > da , rsc - > pa , rsc - > len , rsc - > flags ) ;
2011-10-20 18:52:46 +04:00
carveout = kzalloc ( sizeof ( * carveout ) , GFP_KERNEL ) ;
2015-02-28 02:18:23 +03:00
if ( ! carveout )
2012-09-25 11:01:56 +04:00
return - ENOMEM ;
2011-10-20 18:52:46 +04:00
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
va = dma_alloc_coherent ( dev - > parent , rsc - > len , & dma , GFP_KERNEL ) ;
2011-10-20 18:52:46 +04:00
if ( ! va ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_err ( dev - > parent , " dma_alloc_coherent err: %d \n " , rsc - > len ) ;
2011-10-20 18:52:46 +04:00
ret = - ENOMEM ;
goto free_carv ;
}
2012-09-28 19:35:06 +04:00
dev_dbg ( dev , " carveout va %p, dma %llx, len 0x%x \n " , va ,
( unsigned long long ) dma , rsc - > len ) ;
2011-10-20 18:52:46 +04:00
/*
* Ok , this is non - standard .
*
* Sometimes we can ' t rely on the generic iommu - based DMA API
* to dynamically allocate the device address and then set the IOMMU
* tables accordingly , because some remote processors might
* _require_ us to use hard coded device addresses that their
* firmware was compiled with .
*
* In this case , we must use the IOMMU API directly and map
* the memory to the device address as expected by the remote
* processor .
*
* Obviously such remote processor devices should not be configured
* to use the iommu - based DMA API : we expect ' dma ' to contain the
* physical address in this case .
*/
if ( rproc - > domain ) {
2012-09-25 11:01:56 +04:00
mapping = kzalloc ( sizeof ( * mapping ) , GFP_KERNEL ) ;
if ( ! mapping ) {
dev_err ( dev , " kzalloc mapping failed \n " ) ;
ret = - ENOMEM ;
goto dma_free ;
}
2011-10-20 18:52:46 +04:00
ret = iommu_map ( rproc - > domain , rsc - > da , dma , rsc - > len ,
rsc - > flags ) ;
if ( ret ) {
dev_err ( dev , " iommu_map failed: %d \n " , ret ) ;
2012-09-25 11:01:56 +04:00
goto free_mapping ;
2011-10-20 18:52:46 +04:00
}
/*
* We ' ll need this info later when we ' ll want to unmap
* everything ( e . g . on shutdown ) .
*
* We can ' t trust the remote processor not to change the
* resource table , so we must maintain this info independently .
*/
mapping - > da = rsc - > da ;
mapping - > len = rsc - > len ;
list_add_tail ( & mapping - > node , & rproc - > mappings ) ;
2012-09-28 19:35:06 +04:00
dev_dbg ( dev , " carveout mapped 0x%x to 0x%llx \n " ,
rsc - > da , ( unsigned long long ) dma ) ;
2011-10-20 18:52:46 +04:00
}
2012-07-01 12:30:57 +04:00
/*
* Some remote processors might need to know the pa
* even though they are behind an IOMMU . E . g . , OMAP4 ' s
* remote M3 processor needs this so it can control
* on - chip hardware accelerators that are not behind
* the IOMMU , and therefor must know the pa .
*
* Generally we don ' t want to expose physical addresses
* if we don ' t have to ( remote processors are generally
* _not_ trusted ) , so we might want to do this only for
* remote processor that _must_ have this ( e . g . OMAP4 ' s
* dual M3 subsystem ) .
*
* Non - IOMMU processors might also want to have this info .
* In this case , the device address and the physical address
* are the same .
*/
rsc - > pa = dma ;
2011-10-20 18:52:46 +04:00
carveout - > va = va ;
carveout - > len = rsc - > len ;
carveout - > dma = dma ;
carveout - > da = rsc - > da ;
list_add_tail ( & carveout - > node , & rproc - > carveouts ) ;
return 0 ;
2012-09-25 11:01:56 +04:00
free_mapping :
kfree ( mapping ) ;
2011-10-20 18:52:46 +04:00
dma_free :
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dma_free_coherent ( dev - > parent , rsc - > len , va , dma ) ;
2011-10-20 18:52:46 +04:00
free_carv :
kfree ( carveout ) ;
return ret ;
}
2013-02-21 21:15:37 +04:00
static int rproc_count_vrings ( struct rproc * rproc , struct fw_rsc_vdev * rsc ,
2013-04-07 15:06:07 +04:00
int offset , int avail )
2013-02-21 21:15:37 +04:00
{
/* Summarize the number of notification IDs */
rproc - > max_notifyid + = rsc - > num_of_vrings ;
return 0 ;
}
2012-01-31 18:07:27 +04:00
/*
* A lookup table for resource handlers . The indices are defined in
* enum fw_resource_type .
*/
2013-02-21 21:15:36 +04:00
static rproc_handle_resource_t rproc_loading_handlers [ RSC_LAST ] = {
2012-02-01 23:56:16 +04:00
[ 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 ,
2012-02-14 01:30:39 +04:00
[ RSC_VDEV ] = NULL , /* VDEVs were handled upon registrarion */
2012-01-31 18:07:27 +04:00
} ;
2013-02-21 21:15:36 +04:00
static rproc_handle_resource_t rproc_vdev_handler [ RSC_LAST ] = {
[ RSC_VDEV ] = ( rproc_handle_resource_t ) rproc_handle_vdev ,
} ;
2013-02-21 21:15:37 +04:00
static rproc_handle_resource_t rproc_count_vrings_handler [ RSC_LAST ] = {
[ RSC_VDEV ] = ( rproc_handle_resource_t ) rproc_count_vrings ,
} ;
2011-10-20 18:52:46 +04:00
/* handle firmware resource entries before booting the remote processor */
2013-04-07 15:06:07 +04:00
static int rproc_handle_resources ( struct rproc * rproc , int len ,
2013-02-21 21:15:36 +04:00
rproc_handle_resource_t handlers [ RSC_LAST ] )
2011-10-20 18:52:46 +04:00
{
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2012-01-31 18:07:27 +04:00
rproc_handle_resource_t handler ;
2012-02-01 23:56:16 +04:00
int ret = 0 , i ;
2013-04-07 15:06:07 +04:00
for ( i = 0 ; i < rproc - > table_ptr - > num ; i + + ) {
int offset = rproc - > table_ptr - > offset [ i ] ;
struct fw_rsc_hdr * hdr = ( void * ) rproc - > table_ptr + offset ;
2012-02-01 23:56:16 +04:00
int avail = len - offset - sizeof ( * hdr ) ;
void * rsc = ( void * ) hdr + sizeof ( * hdr ) ;
/* make sure table isn't truncated */
if ( avail < 0 ) {
dev_err ( dev , " rsc table is truncated \n " ) ;
return - EINVAL ;
}
2011-10-20 18:52:46 +04:00
2012-02-01 23:56:16 +04:00
dev_dbg ( dev , " rsc: type %d \n " , hdr - > type ) ;
2011-10-20 18:52:46 +04:00
2012-02-01 23:56:16 +04:00
if ( hdr - > type > = RSC_LAST ) {
dev_warn ( dev , " unsupported resource %d \n " , hdr - > type ) ;
2012-01-31 18:07:27 +04:00
continue ;
2011-10-20 18:52:46 +04:00
}
2013-02-21 21:15:36 +04:00
handler = handlers [ hdr - > type ] ;
2012-01-31 18:07:27 +04:00
if ( ! handler )
continue ;
2013-04-07 15:06:07 +04:00
ret = handler ( rproc , rsc , offset + sizeof ( * hdr ) , avail ) ;
2012-02-14 01:30:39 +04:00
if ( ret )
2011-10-20 18:52:46 +04:00
break ;
2012-02-01 23:56:16 +04:00
}
2011-10-20 18:52:46 +04:00
return ret ;
}
/**
* rproc_resource_cleanup ( ) - clean up and free all acquired resources
* @ rproc : rproc handle
*
* This function will free all resources acquired for @ rproc , and it
2012-02-14 01:30:39 +04:00
* is called whenever @ rproc either shuts down or fails to boot .
2011-10-20 18:52:46 +04:00
*/
static void rproc_resource_cleanup ( struct rproc * rproc )
{
struct rproc_mem_entry * entry , * tmp ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
/* clean up debugfs trace entries */
list_for_each_entry_safe ( entry , tmp , & rproc - > traces , node ) {
rproc_remove_trace_file ( entry - > priv ) ;
rproc - > num_traces - - ;
list_del ( & entry - > node ) ;
kfree ( entry ) ;
}
/* clean up iommu mapping entries */
list_for_each_entry_safe ( entry , tmp , & rproc - > mappings , node ) {
size_t unmapped ;
unmapped = iommu_unmap ( rproc - > domain , entry - > da , entry - > len ) ;
if ( unmapped ! = entry - > len ) {
/* nothing much to do besides complaining */
2012-06-10 15:37:07 +04:00
dev_err ( dev , " failed to unmap %u/%zu \n " , entry - > len ,
2011-10-20 18:52:46 +04:00
unmapped ) ;
}
list_del ( & entry - > node ) ;
kfree ( entry ) ;
}
2013-07-01 18:01:56 +04:00
/* clean up carveout allocations */
list_for_each_entry_safe ( entry , tmp , & rproc - > carveouts , node ) {
2015-02-28 02:18:23 +03:00
dma_free_coherent ( dev - > parent , entry - > len , entry - > va ,
entry - > dma ) ;
2013-07-01 18:01:56 +04:00
list_del ( & entry - > node ) ;
kfree ( entry ) ;
}
2011-10-20 18:52:46 +04:00
}
/*
* take a firmware and boot a remote processor with it .
*/
static int rproc_fw_boot ( struct rproc * rproc , const struct firmware * fw )
{
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
const char * name = rproc - > firmware ;
2013-04-07 15:06:07 +04:00
struct resource_table * table , * loaded_table ;
2012-02-14 00:47:49 +04:00
int ret , tablesz ;
2011-10-20 18:52:46 +04:00
2013-04-07 15:06:07 +04:00
if ( ! rproc - > table_ptr )
return - ENOMEM ;
2011-10-20 18:52:46 +04:00
ret = rproc_fw_sanity_check ( rproc , fw ) ;
if ( ret )
return ret ;
2012-06-10 15:37:07 +04:00
dev_info ( dev , " Booting fw image %s, size %zd \n " , name , fw - > size ) ;
2011-10-20 18:52:46 +04:00
/*
* if enabling an IOMMU isn ' t relevant for this rproc , this is
* just a nop
*/
ret = rproc_enable_iommu ( rproc ) ;
if ( ret ) {
dev_err ( dev , " can't enable iommu: %d \n " , ret ) ;
return ret ;
}
2012-06-19 10:56:44 +04:00
rproc - > bootaddr = rproc_get_boot_addr ( rproc , fw ) ;
2013-06-30 12:07:13 +04:00
ret = - EINVAL ;
2011-10-20 18:52:46 +04:00
2012-02-14 00:47:49 +04:00
/* look for the resource table */
2012-06-19 10:55:34 +04:00
table = rproc_find_rsc_table ( rproc , fw , & tablesz ) ;
2015-02-28 02:18:23 +03:00
if ( ! table )
2012-02-14 00:47:49 +04:00
goto clean_up ;
2013-04-07 15:06:07 +04:00
/* Verify that resource table in loaded fw is unchanged */
if ( rproc - > table_csum ! = crc32 ( 0 , table , tablesz ) ) {
dev_err ( dev , " resource checksum failed, fw changed? \n " ) ;
goto clean_up ;
}
2011-10-20 18:52:46 +04:00
/* handle fw resources which are required to boot rproc */
2013-04-07 15:06:07 +04:00
ret = rproc_handle_resources ( rproc , tablesz , rproc_loading_handlers ) ;
2011-10-20 18:52:46 +04:00
if ( ret ) {
dev_err ( dev , " Failed to process resources: %d \n " , ret ) ;
goto clean_up ;
}
/* load the ELF segments to memory */
2012-06-19 10:55:34 +04:00
ret = rproc_load_segments ( rproc , fw ) ;
2011-10-20 18:52:46 +04:00
if ( ret ) {
dev_err ( dev , " Failed to load program segments: %d \n " , ret ) ;
goto clean_up ;
}
2013-04-07 15:06:07 +04:00
/*
* The starting device has been given the rproc - > cached_table as the
* resource table . The address of the vring along with the other
* allocated resources ( carveouts etc ) is stored in cached_table .
* In order to pass this information to the remote device we must
* copy this information to device memory .
*/
loaded_table = rproc_find_loaded_rsc_table ( rproc , fw ) ;
2013-06-30 12:07:13 +04:00
if ( ! loaded_table ) {
ret = - EINVAL ;
2013-04-07 15:06:07 +04:00
goto clean_up ;
2013-06-30 12:07:13 +04:00
}
2013-04-07 15:06:07 +04:00
memcpy ( loaded_table , rproc - > cached_table , tablesz ) ;
2011-10-20 18:52:46 +04:00
/* power up the remote processor */
ret = rproc - > ops - > start ( rproc ) ;
if ( ret ) {
dev_err ( dev , " can't start rproc %s: %d \n " , rproc - > name , ret ) ;
goto clean_up ;
}
2013-04-07 15:06:07 +04:00
/*
* Update table_ptr so that all subsequent vring allocations and
* virtio fields manipulation update the actual loaded resource table
* in device memory .
*/
rproc - > table_ptr = loaded_table ;
2011-10-20 18:52:46 +04:00
rproc - > state = RPROC_RUNNING ;
dev_info ( dev , " remote processor %s is now up \n " , rproc - > name ) ;
return 0 ;
clean_up :
rproc_resource_cleanup ( rproc ) ;
rproc_disable_iommu ( rproc ) ;
return ret ;
}
/*
* take a firmware and look for virtio devices to register .
*
* Note : this function is called asynchronously upon registration of the
* remote processor ( so we must wait until it completes before we try
* to unregister the device . one other option is just to use kref here ,
* that might be cleaner ) .
*/
static void rproc_fw_config_virtio ( const struct firmware * fw , void * context )
{
struct rproc * rproc = context ;
2012-02-14 00:47:49 +04:00
struct resource_table * table ;
int ret , tablesz ;
2011-10-20 18:52:46 +04:00
if ( rproc_fw_sanity_check ( rproc , fw ) < 0 )
goto out ;
2012-02-14 00:47:49 +04:00
/* look for the resource table */
2012-06-19 10:55:34 +04:00
table = rproc_find_rsc_table ( rproc , fw , & tablesz ) ;
2012-02-14 00:47:49 +04:00
if ( ! table )
goto out ;
2013-04-07 15:06:07 +04:00
rproc - > table_csum = crc32 ( 0 , table , tablesz ) ;
/*
* Create a copy of the resource table . When a virtio device starts
* and calls vring_new_virtqueue ( ) the address of the allocated vring
* will be stored in the cached_table . Before the device is started ,
* cached_table will be copied into devic memory .
*/
2013-07-01 18:23:58 +04:00
rproc - > cached_table = kmemdup ( table , tablesz , GFP_KERNEL ) ;
2013-04-07 15:06:07 +04:00
if ( ! rproc - > cached_table )
goto out ;
rproc - > table_ptr = rproc - > cached_table ;
2013-02-21 21:15:37 +04:00
/* count the number of notify-ids */
rproc - > max_notifyid = - 1 ;
2015-02-28 02:18:23 +03:00
ret = rproc_handle_resources ( rproc , tablesz ,
rproc_count_vrings_handler ) ;
2012-02-14 00:47:49 +04:00
if ( ret )
2011-10-20 18:52:46 +04:00
goto out ;
2013-04-07 15:06:07 +04:00
/* look for virtio devices and register them */
ret = rproc_handle_resources ( rproc , tablesz , rproc_vdev_handler ) ;
2011-10-20 18:52:46 +04:00
out :
2012-04-10 00:51:25 +04:00
release_firmware ( fw ) ;
2012-07-04 17:25:06 +04:00
/* allow rproc_del() contexts, if any, to proceed */
2011-10-20 18:52:46 +04:00
complete_all ( & rproc - > firmware_loading_complete ) ;
}
2012-08-30 22:26:13 +04:00
static int rproc_add_virtio_devices ( struct rproc * rproc )
{
int ret ;
/* rproc_del() calls must wait until async loader completes */
init_completion ( & rproc - > firmware_loading_complete ) ;
/*
* We must retrieve early virtio configuration info from
* the firmware ( e . g . whether to register a virtio device ,
* what virtio features does it support , . . . ) .
*
* We ' re initiating an asynchronous firmware loading , so we can
* be built - in kernel code , without hanging the boot process .
*/
ret = request_firmware_nowait ( THIS_MODULE , FW_ACTION_HOTPLUG ,
rproc - > firmware , & rproc - > dev , GFP_KERNEL ,
rproc , rproc_fw_config_virtio ) ;
if ( ret < 0 ) {
dev_err ( & rproc - > dev , " request_firmware_nowait err: %d \n " , ret ) ;
complete_all ( & rproc - > firmware_loading_complete ) ;
}
return ret ;
}
/**
* rproc_trigger_recovery ( ) - recover a remoteproc
* @ rproc : the remote processor
*
* The recovery is done by reseting all the virtio devices , that way all the
* rpmsg drivers will be reseted along with the remote processor making the
* remoteproc functional again .
*
* This function can sleep , so it cannot be called from atomic context .
*/
int rproc_trigger_recovery ( struct rproc * rproc )
{
struct rproc_vdev * rvdev , * rvtmp ;
dev_err ( & rproc - > dev , " recovering %s \n " , rproc - > name ) ;
init_completion ( & rproc - > crash_comp ) ;
/* clean up remote vdev entries */
list_for_each_entry_safe ( rvdev , rvtmp , & rproc - > rvdevs , node )
rproc_remove_virtio_dev ( rvdev ) ;
/* wait until there is no more rproc users */
wait_for_completion ( & rproc - > crash_comp ) ;
2013-04-07 15:06:07 +04:00
/* Free the copy of the resource table */
kfree ( rproc - > cached_table ) ;
2012-08-30 22:26:13 +04:00
return rproc_add_virtio_devices ( rproc ) ;
}
2012-08-30 22:26:12 +04:00
/**
* rproc_crash_handler_work ( ) - handle a crash
*
* This function needs to handle everything related to a crash , like cpu
* registers and stack dump , information to help to debug the fatal error , etc .
*/
static void rproc_crash_handler_work ( struct work_struct * work )
{
struct rproc * rproc = container_of ( work , struct rproc , crash_handler ) ;
struct device * dev = & rproc - > dev ;
dev_dbg ( dev , " enter %s \n " , __func__ ) ;
mutex_lock ( & rproc - > lock ) ;
if ( rproc - > state = = RPROC_CRASHED | | rproc - > state = = RPROC_OFFLINE ) {
/* handle only the first crash detected */
mutex_unlock ( & rproc - > lock ) ;
return ;
}
rproc - > state = RPROC_CRASHED ;
dev_err ( dev , " handling crash #%u in %s \n " , + + rproc - > crash_cnt ,
rproc - > name ) ;
mutex_unlock ( & rproc - > lock ) ;
2012-09-18 13:26:35 +04:00
if ( ! rproc - > recovery_disabled )
rproc_trigger_recovery ( rproc ) ;
2012-08-30 22:26:12 +04:00
}
2011-10-20 18:52:46 +04:00
/**
* rproc_boot ( ) - boot a remote processor
* @ rproc : handle of a remote processor
*
* Boot a remote processor ( i . e . load its firmware , power it on , . . . ) .
*
* If the remote processor is already powered on , this function immediately
* returns ( successfully ) .
*
* Returns 0 on success , and an appropriate error value otherwise .
*/
int rproc_boot ( struct rproc * rproc )
{
const struct firmware * firmware_p ;
struct device * dev ;
int ret ;
if ( ! rproc ) {
pr_err ( " invalid rproc handle \n " ) ;
return - EINVAL ;
}
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
ret = mutex_lock_interruptible ( & rproc - > lock ) ;
if ( ret ) {
dev_err ( dev , " can't lock rproc %s: %d \n " , rproc - > name , ret ) ;
return ret ;
}
/* loading a firmware is required */
if ( ! rproc - > firmware ) {
dev_err ( dev , " %s: no firmware to load \n " , __func__ ) ;
ret = - EINVAL ;
goto unlock_mutex ;
}
/* prevent underlying implementation from being removed */
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
if ( ! try_module_get ( dev - > parent - > driver - > owner ) ) {
2011-10-20 18:52:46 +04:00
dev_err ( dev , " %s: can't get owner \n " , __func__ ) ;
ret = - EINVAL ;
goto unlock_mutex ;
}
/* skip the boot process if rproc is already powered up */
if ( atomic_inc_return ( & rproc - > power ) > 1 ) {
ret = 0 ;
goto unlock_mutex ;
}
dev_info ( dev , " powering up %s \n " , rproc - > name ) ;
/* load firmware */
ret = request_firmware ( & firmware_p , rproc - > firmware , dev ) ;
if ( ret < 0 ) {
dev_err ( dev , " request_firmware failed: %d \n " , ret ) ;
goto downref_rproc ;
}
ret = rproc_fw_boot ( rproc , firmware_p ) ;
release_firmware ( firmware_p ) ;
downref_rproc :
if ( ret ) {
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
module_put ( dev - > parent - > driver - > owner ) ;
2011-10-20 18:52:46 +04:00
atomic_dec ( & rproc - > power ) ;
}
unlock_mutex :
mutex_unlock ( & rproc - > lock ) ;
return ret ;
}
EXPORT_SYMBOL ( rproc_boot ) ;
/**
* rproc_shutdown ( ) - power off the remote processor
* @ rproc : the remote processor
*
* Power off a remote processor ( previously booted with rproc_boot ( ) ) .
*
* In case @ rproc is still being used by an additional user ( s ) , then
* this function will just decrement the power refcount and exit ,
* without really powering off the device .
*
* Every call to rproc_boot ( ) must ( eventually ) be accompanied by a call
* to rproc_shutdown ( ) . Calling rproc_shutdown ( ) redundantly is a bug .
*
* Notes :
* - we ' re not decrementing the rproc ' s refcount , only the power refcount .
* which means that the @ rproc handle stays valid even after rproc_shutdown ( )
* returns , and users can still use it with a subsequent rproc_boot ( ) , if
* needed .
*/
void rproc_shutdown ( struct rproc * rproc )
{
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2011-10-20 18:52:46 +04:00
int ret ;
ret = mutex_lock_interruptible ( & rproc - > lock ) ;
if ( ret ) {
dev_err ( dev , " can't lock rproc %s: %d \n " , rproc - > name , ret ) ;
return ;
}
/* if the remote proc is still needed, bail out */
if ( ! atomic_dec_and_test ( & rproc - > power ) )
goto out ;
/* power off the remote processor */
ret = rproc - > ops - > stop ( rproc ) ;
if ( ret ) {
atomic_inc ( & rproc - > power ) ;
dev_err ( dev , " can't stop rproc: %d \n " , ret ) ;
goto out ;
}
/* clean up all acquired resources */
rproc_resource_cleanup ( rproc ) ;
rproc_disable_iommu ( rproc ) ;
2013-04-07 15:06:07 +04:00
/* Give the next start a clean resource table */
rproc - > table_ptr = rproc - > cached_table ;
2012-08-30 22:26:13 +04:00
/* if in crash state, unlock crash handler */
if ( rproc - > state = = RPROC_CRASHED )
complete_all ( & rproc - > crash_comp ) ;
2011-10-20 18:52:46 +04:00
rproc - > state = RPROC_OFFLINE ;
dev_info ( dev , " stopped remote processor %s \n " , rproc - > name ) ;
out :
mutex_unlock ( & rproc - > lock ) ;
if ( ! ret )
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
module_put ( dev - > parent - > driver - > owner ) ;
2011-10-20 18:52:46 +04:00
}
EXPORT_SYMBOL ( rproc_shutdown ) ;
2015-05-22 23:45:27 +03:00
/**
* rproc_get_by_phandle ( ) - find a remote processor by phandle
* @ phandle : phandle to the rproc
*
* Finds an rproc handle using the remote processor ' s phandle , and then
* return a handle to the rproc .
*
* This function increments the remote processor ' s refcount , so always
* use rproc_put ( ) to decrement it back once rproc isn ' t needed anymore .
*
* Returns the rproc handle on success , and NULL on failure .
*/
2015-06-18 11:44:41 +03:00
# ifdef CONFIG_OF
2015-05-22 23:45:27 +03:00
struct rproc * rproc_get_by_phandle ( phandle phandle )
{
struct rproc * rproc = NULL , * r ;
struct device_node * np ;
np = of_find_node_by_phandle ( phandle ) ;
if ( ! np )
return NULL ;
mutex_lock ( & rproc_list_mutex ) ;
list_for_each_entry ( r , & rproc_list , node ) {
if ( r - > dev . parent & & r - > dev . parent - > of_node = = np ) {
rproc = r ;
get_device ( & rproc - > dev ) ;
break ;
}
}
mutex_unlock ( & rproc_list_mutex ) ;
of_node_put ( np ) ;
return rproc ;
}
2015-06-18 11:44:41 +03:00
# else
struct rproc * rproc_get_by_phandle ( phandle phandle )
{
return NULL ;
}
# endif
2015-05-22 23:45:27 +03:00
EXPORT_SYMBOL ( rproc_get_by_phandle ) ;
2011-10-20 18:52:46 +04:00
/**
2012-07-04 17:25:06 +04:00
* rproc_add ( ) - register a remote processor
2011-10-20 18:52:46 +04:00
* @ rproc : the remote processor handle to register
*
* Registers @ rproc with the remoteproc framework , after it has been
* allocated with rproc_alloc ( ) .
*
* This is called by the platform - specific rproc implementation , whenever
* a new remote processor device is probed .
*
* Returns 0 on success and an appropriate error code otherwise .
*
* Note : this function initiates an asynchronous firmware loading
* context , which will look for virtio devices supported by the rproc ' s
* firmware .
*
* If found , those virtio devices will be created and added , so as a result
2012-02-14 01:30:39 +04:00
* of registering this remote processor , additional virtio drivers might be
2011-10-20 18:52:46 +04:00
* probed .
*/
2012-07-04 17:25:06 +04:00
int rproc_add ( struct rproc * rproc )
2011-10-20 18:52:46 +04:00
{
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
struct device * dev = & rproc - > dev ;
2012-08-30 22:26:13 +04:00
int ret ;
2011-10-20 18:52:46 +04:00
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
ret = device_add ( dev ) ;
if ( ret < 0 )
return ret ;
2011-10-20 18:52:46 +04:00
2015-05-22 23:45:27 +03:00
/* expose to rproc_get_by_phandle users */
mutex_lock ( & rproc_list_mutex ) ;
list_add ( & rproc - > node , & rproc_list ) ;
mutex_unlock ( & rproc_list_mutex ) ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
dev_info ( dev , " %s is available \n " , rproc - > name ) ;
2011-10-20 18:52:46 +04:00
2011-12-21 13:25:43 +04:00
dev_info ( dev , " Note: remoteproc is still under development and considered experimental. \n " ) ;
dev_info ( dev , " THE BINARY FORMAT IS NOT YET FINALIZED, and backward compatibility isn't yet guaranteed. \n " ) ;
2011-10-20 18:52:46 +04:00
/* create debugfs entries */
rproc_create_debug_dir ( rproc ) ;
2012-08-30 22:26:13 +04:00
return rproc_add_virtio_devices ( rproc ) ;
2011-10-20 18:52:46 +04:00
}
2012-07-04 17:25:06 +04:00
EXPORT_SYMBOL ( rproc_add ) ;
2011-10-20 18:52:46 +04:00
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
/**
* rproc_type_release ( ) - release a remote processor instance
* @ dev : the rproc ' s device
*
* This function should _never_ be called directly .
*
* It will be called by the driver core when no one holds a valid pointer
* to @ dev anymore .
*/
static void rproc_type_release ( struct device * dev )
{
struct rproc * rproc = container_of ( dev , struct rproc , dev ) ;
2012-05-30 23:02:24 +04:00
dev_info ( & rproc - > dev , " releasing %s \n " , rproc - > name ) ;
rproc_delete_debug_dir ( rproc ) ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
idr_destroy ( & rproc - > notifyids ) ;
if ( rproc - > index > = 0 )
ida_simple_remove ( & rproc_dev_index , rproc - > index ) ;
kfree ( rproc ) ;
}
static struct device_type rproc_type = {
. name = " remoteproc " ,
. release = rproc_type_release ,
} ;
2011-10-20 18:52:46 +04:00
/**
* rproc_alloc ( ) - allocate a remote processor handle
* @ dev : the underlying device
* @ name : name of this remote processor
* @ ops : platform - specific handlers ( mainly start / stop )
2013-03-29 05:41:44 +04:00
* @ firmware : name of firmware file to load , can be NULL
2011-10-20 18:52:46 +04:00
* @ len : length of private data needed by the rproc driver ( in bytes )
*
* Allocates a new remote processor handle , but does not register
2013-03-29 05:41:44 +04:00
* it yet . if @ firmware is NULL , a default name is used .
2011-10-20 18:52:46 +04:00
*
* This function should be used by rproc implementations during initialization
* of the remote processor .
*
* After creating an rproc handle using this function , and when ready ,
2012-07-04 17:25:06 +04:00
* implementations should then call rproc_add ( ) to complete
2011-10-20 18:52:46 +04:00
* the registration of the remote processor .
*
* On success the new rproc is returned , and on failure , NULL .
*
* Note : _never_ directly deallocate @ rproc , even if it was not registered
2012-07-04 17:25:06 +04:00
* yet . Instead , when you need to unroll rproc_alloc ( ) , use rproc_put ( ) .
2011-10-20 18:52:46 +04:00
*/
struct rproc * rproc_alloc ( struct device * dev , const char * name ,
const struct rproc_ops * ops ,
const char * firmware , int len )
{
struct rproc * rproc ;
2013-03-29 05:41:44 +04:00
char * p , * template = " rproc-%s-fw " ;
int name_len = 0 ;
2011-10-20 18:52:46 +04:00
if ( ! dev | | ! name | | ! ops )
return NULL ;
2013-03-29 05:41:44 +04:00
if ( ! firmware )
/*
* Make room for default firmware name ( minus % s plus ' \0 ' ) .
* If the caller didn ' t pass in a firmware name then
* construct a default name . We ' re already glomming ' len '
* bytes onto the end of the struct rproc allocation , so do
* a few more for the default firmware name ( but only if
* the caller doesn ' t pass one ) .
*/
name_len = strlen ( name ) + strlen ( template ) - 2 + 1 ;
rproc = kzalloc ( sizeof ( struct rproc ) + len + name_len , GFP_KERNEL ) ;
2015-02-28 02:18:23 +03:00
if ( ! rproc )
2011-10-20 18:52:46 +04:00
return NULL ;
2013-03-29 05:41:44 +04:00
if ( ! firmware ) {
p = ( char * ) rproc + sizeof ( struct rproc ) + len ;
snprintf ( p , name_len , template , name ) ;
} else {
p = ( char * ) firmware ;
}
rproc - > firmware = p ;
2011-10-20 18:52:46 +04:00
rproc - > name = name ;
rproc - > ops = ops ;
rproc - > priv = & rproc [ 1 ] ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
device_initialize ( & rproc - > dev ) ;
rproc - > dev . parent = dev ;
rproc - > dev . type = & rproc_type ;
/* Assign a unique device index and name */
rproc - > index = ida_simple_get ( & rproc_dev_index , 0 , 0 , GFP_KERNEL ) ;
if ( rproc - > index < 0 ) {
dev_err ( dev , " ida_simple_get failed: %d \n " , rproc - > index ) ;
put_device ( & rproc - > dev ) ;
return NULL ;
}
dev_set_name ( & rproc - > dev , " remoteproc%d " , rproc - > index ) ;
2011-10-20 18:52:46 +04:00
atomic_set ( & rproc - > power , 0 ) ;
2012-06-19 11:08:18 +04:00
/* Set ELF as the default fw_ops handler */
rproc - > fw_ops = & rproc_elf_fw_ops ;
2011-10-20 18:52:46 +04:00
mutex_init ( & rproc - > lock ) ;
2012-02-14 01:30:39 +04:00
idr_init ( & rproc - > notifyids ) ;
2011-10-20 18:52:46 +04:00
INIT_LIST_HEAD ( & rproc - > carveouts ) ;
INIT_LIST_HEAD ( & rproc - > mappings ) ;
INIT_LIST_HEAD ( & rproc - > traces ) ;
2012-02-14 01:30:39 +04:00
INIT_LIST_HEAD ( & rproc - > rvdevs ) ;
2011-10-20 18:52:46 +04:00
2012-08-30 22:26:12 +04:00
INIT_WORK ( & rproc - > crash_handler , rproc_crash_handler_work ) ;
2012-08-30 22:26:13 +04:00
init_completion ( & rproc - > crash_comp ) ;
2012-08-30 22:26:12 +04:00
2011-10-20 18:52:46 +04:00
rproc - > state = RPROC_OFFLINE ;
return rproc ;
}
EXPORT_SYMBOL ( rproc_alloc ) ;
/**
2012-07-04 17:25:06 +04:00
* rproc_put ( ) - unroll rproc_alloc ( )
2011-10-20 18:52:46 +04:00
* @ rproc : the remote processor handle
*
2012-07-02 12:41:16 +04:00
* This function decrements the rproc dev refcount .
2011-10-20 18:52:46 +04:00
*
2012-07-02 12:41:16 +04:00
* If no one holds any reference to rproc anymore , then its refcount would
* now drop to zero , and it would be freed .
2011-10-20 18:52:46 +04:00
*/
2012-07-04 17:25:06 +04:00
void rproc_put ( struct rproc * rproc )
2011-10-20 18:52:46 +04:00
{
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
put_device ( & rproc - > dev ) ;
2011-10-20 18:52:46 +04:00
}
2012-07-04 17:25:06 +04:00
EXPORT_SYMBOL ( rproc_put ) ;
2011-10-20 18:52:46 +04:00
/**
2012-07-04 17:25:06 +04:00
* rproc_del ( ) - unregister a remote processor
2011-10-20 18:52:46 +04:00
* @ rproc : rproc handle to unregister
*
* This function should be called when the platform specific rproc
* implementation decides to remove the rproc device . it should
2012-07-04 17:25:06 +04:00
* _only_ be called if a previous invocation of rproc_add ( )
2011-10-20 18:52:46 +04:00
* has completed successfully .
*
2012-07-04 17:25:06 +04:00
* After rproc_del ( ) returns , @ rproc isn ' t freed yet , because
2012-07-02 12:41:16 +04:00
* of the outstanding reference created by rproc_alloc . To decrement that
2012-07-04 17:25:06 +04:00
* one last refcount , one still needs to call rproc_put ( ) .
2011-10-20 18:52:46 +04:00
*
* Returns 0 on success and - EINVAL if @ rproc isn ' t valid .
*/
2012-07-04 17:25:06 +04:00
int rproc_del ( struct rproc * rproc )
2011-10-20 18:52:46 +04:00
{
2012-05-17 15:23:59 +04:00
struct rproc_vdev * rvdev , * tmp ;
2012-02-14 01:30:39 +04:00
2011-10-20 18:52:46 +04:00
if ( ! rproc )
return - EINVAL ;
/* if rproc is just being registered, wait */
wait_for_completion ( & rproc - > firmware_loading_complete ) ;
2012-02-14 01:30:39 +04:00
/* clean up remote vdev entries */
2012-05-17 15:23:59 +04:00
list_for_each_entry_safe ( rvdev , tmp , & rproc - > rvdevs , node )
2012-02-14 01:30:39 +04:00
rproc_remove_virtio_dev ( rvdev ) ;
2011-10-20 18:52:46 +04:00
2013-04-07 15:06:07 +04:00
/* Free the copy of the resource table */
kfree ( rproc - > cached_table ) ;
2015-05-22 23:45:27 +03:00
/* the rproc is downref'ed as soon as it's removed from the klist */
mutex_lock ( & rproc_list_mutex ) ;
list_del ( & rproc - > node ) ;
mutex_unlock ( & rproc_list_mutex ) ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
device_del ( & rproc - > dev ) ;
2011-10-20 18:52:46 +04:00
return 0 ;
}
2012-07-04 17:25:06 +04:00
EXPORT_SYMBOL ( rproc_del ) ;
2011-10-20 18:52:46 +04:00
2012-08-30 22:26:12 +04:00
/**
* rproc_report_crash ( ) - rproc crash reporter function
* @ rproc : remote processor
* @ type : crash type
*
* This function must be called every time a crash is detected by the low - level
* drivers implementing a specific remoteproc . This should not be called from a
* non - remoteproc driver .
*
* This function can be called from atomic / interrupt context .
*/
void rproc_report_crash ( struct rproc * rproc , enum rproc_crash_type type )
{
if ( ! rproc ) {
pr_err ( " NULL rproc pointer \n " ) ;
return ;
}
dev_err ( & rproc - > dev , " crash detected in %s: type %s \n " ,
rproc - > name , rproc_crash_to_string ( type ) ) ;
/* create a new task to handle the error */
schedule_work ( & rproc - > crash_handler ) ;
}
EXPORT_SYMBOL ( rproc_report_crash ) ;
2011-10-20 18:52:46 +04:00
static int __init remoteproc_init ( void )
{
rproc_init_debugfs ( ) ;
remoteproc: maintain a generic child device for each rproc
For each registered rproc, maintain a generic remoteproc device whose
parent is the low level platform-specific device (commonly a pdev, but
it may certainly be any other type of device too).
With this in hand, the resulting device hierarchy might then look like:
omap-rproc.0
|
- remoteproc0 <---- new !
|
- virtio0
|
- virtio1
|
- rpmsg0
|
- rpmsg1
|
- rpmsg2
Where:
- omap-rproc.0 is the low level device that's bound to the
driver which invokes rproc_register()
- remoteproc0 is the result of this patch, and will be added by the
remoteproc framework when rproc_register() is invoked
- virtio0 and virtio1 are vdevs that are registered by remoteproc
when it realizes that they are supported by the firmware
of the physical remote processor represented by omap-rproc.0
- rpmsg0, rpmsg1 and rpmsg2 are rpmsg devices that represent rpmsg
channels, and are registerd by the rpmsg bus when it gets notified
about their existence
Technically, this patch:
- changes 'struct rproc' to contain this generic remoteproc.x device
- creates a new "remoteproc" type, to which this new generic remoteproc.x
device belong to.
- adds a super simple enumeration method for the indices of the
remoteproc.x devices
- updates all dev_* messaging to use the generic remoteproc.x device
instead of the low level platform-specific device
- updates all dma_* allocations to use the parent of remoteproc.x (where
the platform-specific memory pools, most commonly CMA, are to be found)
Adding this generic device has several merits:
- we can now add remoteproc runtime PM support simply by hooking onto the
new "remoteproc" type
- all remoteproc log messages will now carry a common name prefix
instead of having a platform-specific one
- having a device as part of the rproc struct makes it possible to simplify
refcounting (see subsequent patch)
Thanks to Stephen Boyd <sboyd@codeaurora.org> for suggesting and
discussing these ideas in one of the remoteproc review threads and
to Fernando Guzman Lugo <fernando.lugo@ti.com> for trying them out
with the (upcoming) runtime PM support for remoteproc.
Cc: Fernando Guzman Lugo <fernando.lugo@ti.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com>
2012-05-30 23:01:25 +04:00
2011-10-20 18:52:46 +04:00
return 0 ;
}
module_init ( remoteproc_init ) ;
static void __exit remoteproc_exit ( void )
{
2015-09-17 03:29:18 +03:00
ida_destroy ( & rproc_dev_index ) ;
2011-10-20 18:52:46 +04:00
rproc_exit_debugfs ( ) ;
}
module_exit ( remoteproc_exit ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_DESCRIPTION ( " Generic Remote Processor Framework " ) ;