2018-01-17 19:36:44 +03:00
// SPDX-License-Identifier: GPL-2.0
2015-03-06 04:35:25 +03:00
/*
2016-10-26 19:20:32 +03:00
* fsl - mc object allocator driver
2015-03-06 04:35:25 +03:00
*
2016-10-26 19:20:33 +03:00
* Copyright ( C ) 2013 - 2016 Freescale Semiconductor , Inc .
2015-03-06 04:35:25 +03:00
*
*/
2016-08-24 01:14:23 +03:00
# include <linux/module.h>
# include <linux/msi.h>
2018-02-05 17:07:42 +03:00
# include <linux/fsl/mc.h>
2016-08-24 01:14:23 +03:00
2016-08-24 01:13:30 +03:00
# include "fsl-mc-private.h"
2015-03-06 04:35:25 +03:00
2017-11-17 16:38:34 +03:00
static bool __must_check fsl_mc_is_allocatable ( struct fsl_mc_device * mc_dev )
2017-06-22 16:35:47 +03:00
{
2017-11-17 16:38:34 +03:00
return is_fsl_mc_bus_dpbp ( mc_dev ) | |
is_fsl_mc_bus_dpmcp ( mc_dev ) | |
is_fsl_mc_bus_dpcon ( mc_dev ) ;
2017-06-22 16:35:47 +03:00
}
2016-08-24 01:13:17 +03:00
2015-03-06 04:35:25 +03:00
/**
2016-10-26 19:20:32 +03:00
* fsl_mc_resource_pool_add_device - add allocatable object to a resource
* pool of a given fsl - mc bus
2015-03-06 04:35:25 +03:00
*
2016-10-26 19:20:32 +03:00
* @ mc_bus : pointer to the fsl - mc bus
* @ pool_type : pool type
* @ mc_dev : pointer to allocatable fsl - mc device
2015-03-06 04:35:25 +03:00
*/
static int __must_check fsl_mc_resource_pool_add_device ( struct fsl_mc_bus
* mc_bus ,
enum fsl_mc_pool_type
pool_type ,
struct fsl_mc_device
* mc_dev )
{
struct fsl_mc_resource_pool * res_pool ;
struct fsl_mc_resource * resource ;
struct fsl_mc_device * mc_bus_dev = & mc_bus - > mc_dev ;
int error = - EINVAL ;
2017-11-17 16:38:32 +03:00
if ( pool_type < 0 | | pool_type > = FSL_MC_NUM_POOL_TYPES )
2015-03-06 04:35:25 +03:00
goto out ;
2017-11-17 16:38:34 +03:00
if ( ! fsl_mc_is_allocatable ( mc_dev ) )
2015-03-06 04:35:25 +03:00
goto out ;
2017-11-17 16:38:32 +03:00
if ( mc_dev - > resource )
2015-03-06 04:35:25 +03:00
goto out ;
res_pool = & mc_bus - > resource_pools [ pool_type ] ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > type ! = pool_type )
2015-03-06 04:35:25 +03:00
goto out ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > mc_bus ! = mc_bus )
2015-03-06 04:35:25 +03:00
goto out ;
mutex_lock ( & res_pool - > mutex ) ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > max_count < 0 )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > free_count < 0 | |
res_pool - > free_count > res_pool - > max_count )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
resource = devm_kzalloc ( & mc_bus_dev - > dev , sizeof ( * resource ) ,
GFP_KERNEL ) ;
if ( ! resource ) {
error = - ENOMEM ;
dev_err ( & mc_bus_dev - > dev ,
" Failed to allocate memory for fsl_mc_resource \n " ) ;
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
}
resource - > type = pool_type ;
resource - > id = mc_dev - > obj_desc . id ;
resource - > data = mc_dev ;
resource - > parent_pool = res_pool ;
INIT_LIST_HEAD ( & resource - > node ) ;
list_add_tail ( & resource - > node , & res_pool - > free_list ) ;
mc_dev - > resource = resource ;
res_pool - > free_count + + ;
res_pool - > max_count + + ;
error = 0 ;
2016-04-09 21:45:18 +03:00
out_unlock :
mutex_unlock ( & res_pool - > mutex ) ;
2015-03-06 04:35:25 +03:00
out :
return error ;
}
/**
* fsl_mc_resource_pool_remove_device - remove an allocatable device from a
* resource pool
*
2016-10-26 19:20:32 +03:00
* @ mc_dev : pointer to allocatable fsl - mc device
2015-03-06 04:35:25 +03:00
*
2016-10-26 19:20:32 +03:00
* It permanently removes an allocatable fsl - mc device from the resource
* pool . It ' s an error if the device is in use .
2015-03-06 04:35:25 +03:00
*/
static int __must_check fsl_mc_resource_pool_remove_device ( struct fsl_mc_device
* mc_dev )
{
struct fsl_mc_device * mc_bus_dev ;
struct fsl_mc_bus * mc_bus ;
struct fsl_mc_resource_pool * res_pool ;
struct fsl_mc_resource * resource ;
int error = - EINVAL ;
2017-11-17 16:38:34 +03:00
if ( ! fsl_mc_is_allocatable ( mc_dev ) )
2015-03-06 04:35:25 +03:00
goto out ;
resource = mc_dev - > resource ;
2017-11-17 16:38:32 +03:00
if ( ! resource | | resource - > data ! = mc_dev )
2015-03-06 04:35:25 +03:00
goto out ;
mc_bus_dev = to_fsl_mc_device ( mc_dev - > dev . parent ) ;
mc_bus = to_fsl_mc_bus ( mc_bus_dev ) ;
res_pool = resource - > parent_pool ;
2017-11-17 16:38:32 +03:00
if ( res_pool ! = & mc_bus - > resource_pools [ resource - > type ] )
2015-03-06 04:35:25 +03:00
goto out ;
mutex_lock ( & res_pool - > mutex ) ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > max_count < = 0 )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > free_count < = 0 | |
res_pool - > free_count > res_pool - > max_count )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
/*
* If the device is currently allocated , its resource is not
* in the free list and thus , the device cannot be removed .
*/
if ( list_empty ( & resource - > node ) ) {
error = - EBUSY ;
dev_err ( & mc_bus_dev - > dev ,
" Device %s cannot be removed from resource pool \n " ,
dev_name ( & mc_dev - > dev ) ) ;
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
}
2016-09-15 05:27:04 +03:00
list_del_init ( & resource - > node ) ;
2015-03-06 04:35:25 +03:00
res_pool - > free_count - - ;
res_pool - > max_count - - ;
devm_kfree ( & mc_bus_dev - > dev , resource ) ;
mc_dev - > resource = NULL ;
error = 0 ;
2016-04-09 21:45:18 +03:00
out_unlock :
mutex_unlock ( & res_pool - > mutex ) ;
2015-03-06 04:35:25 +03:00
out :
return error ;
}
static const char * const fsl_mc_pool_type_strings [ ] = {
[ FSL_MC_POOL_DPMCP ] = " dpmcp " ,
[ FSL_MC_POOL_DPBP ] = " dpbp " ,
[ FSL_MC_POOL_DPCON ] = " dpcon " ,
2016-01-07 01:03:23 +03:00
[ FSL_MC_POOL_IRQ ] = " irq " ,
2015-03-06 04:35:25 +03:00
} ;
static int __must_check object_type_to_pool_type ( const char * object_type ,
enum fsl_mc_pool_type
* pool_type )
{
unsigned int i ;
for ( i = 0 ; i < ARRAY_SIZE ( fsl_mc_pool_type_strings ) ; i + + ) {
if ( strcmp ( object_type , fsl_mc_pool_type_strings [ i ] ) = = 0 ) {
* pool_type = i ;
return 0 ;
}
}
return - EINVAL ;
}
int __must_check fsl_mc_resource_allocate ( struct fsl_mc_bus * mc_bus ,
enum fsl_mc_pool_type pool_type ,
struct fsl_mc_resource * * new_resource )
{
struct fsl_mc_resource_pool * res_pool ;
struct fsl_mc_resource * resource ;
struct fsl_mc_device * mc_bus_dev = & mc_bus - > mc_dev ;
int error = - EINVAL ;
BUILD_BUG_ON ( ARRAY_SIZE ( fsl_mc_pool_type_strings ) ! =
FSL_MC_NUM_POOL_TYPES ) ;
* new_resource = NULL ;
2017-11-17 16:38:32 +03:00
if ( pool_type < 0 | | pool_type > = FSL_MC_NUM_POOL_TYPES )
2016-04-09 21:45:18 +03:00
goto out ;
2015-03-06 04:35:25 +03:00
res_pool = & mc_bus - > resource_pools [ pool_type ] ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > mc_bus ! = mc_bus )
2016-04-09 21:45:18 +03:00
goto out ;
2015-03-06 04:35:25 +03:00
mutex_lock ( & res_pool - > mutex ) ;
resource = list_first_entry_or_null ( & res_pool - > free_list ,
struct fsl_mc_resource , node ) ;
if ( ! resource ) {
error = - ENXIO ;
dev_err ( & mc_bus_dev - > dev ,
" No more resources of type %s left \n " ,
fsl_mc_pool_type_strings [ pool_type ] ) ;
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
}
2017-11-17 16:38:32 +03:00
if ( resource - > type ! = pool_type )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2017-11-17 16:38:32 +03:00
if ( resource - > parent_pool ! = res_pool )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > free_count < = 0 | |
res_pool - > free_count > res_pool - > max_count )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
2016-09-15 05:27:04 +03:00
list_del_init ( & resource - > node ) ;
2015-03-06 04:35:25 +03:00
res_pool - > free_count - - ;
2016-04-09 21:45:18 +03:00
error = 0 ;
out_unlock :
2015-03-06 04:35:25 +03:00
mutex_unlock ( & res_pool - > mutex ) ;
* new_resource = resource ;
2016-04-09 21:45:18 +03:00
out :
2015-03-06 04:35:25 +03:00
return error ;
}
EXPORT_SYMBOL_GPL ( fsl_mc_resource_allocate ) ;
void fsl_mc_resource_free ( struct fsl_mc_resource * resource )
{
struct fsl_mc_resource_pool * res_pool ;
res_pool = resource - > parent_pool ;
2017-11-17 16:38:32 +03:00
if ( resource - > type ! = res_pool - > type )
2016-04-09 21:45:18 +03:00
return ;
2015-03-06 04:35:25 +03:00
mutex_lock ( & res_pool - > mutex ) ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > free_count < 0 | |
res_pool - > free_count > = res_pool - > max_count )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
2017-11-17 16:38:32 +03:00
if ( ! list_empty ( & resource - > node ) )
2016-04-09 21:45:18 +03:00
goto out_unlock ;
2015-03-06 04:35:25 +03:00
list_add_tail ( & resource - > node , & res_pool - > free_list ) ;
res_pool - > free_count + + ;
2016-04-09 21:45:18 +03:00
out_unlock :
mutex_unlock ( & res_pool - > mutex ) ;
2015-03-06 04:35:25 +03:00
}
EXPORT_SYMBOL_GPL ( fsl_mc_resource_free ) ;
/**
2016-10-26 19:20:32 +03:00
* fsl_mc_object_allocate - Allocates an fsl - mc object of the given
* pool type from a given fsl - mc bus instance
2015-03-06 04:35:25 +03:00
*
2016-10-26 19:20:32 +03:00
* @ mc_dev : fsl - mc device which is used in conjunction with the
* allocated object
* @ pool_type : pool type
* @ new_mc_dev : pointer to area where the pointer to the allocated device
* is to be returned
2015-03-06 04:35:25 +03:00
*
2016-10-26 19:20:32 +03:00
* Allocatable objects are always used in conjunction with some functional
* device . This function allocates an object of the specified type from
* the DPRC containing the functional device .
2015-03-06 04:35:25 +03:00
*
* NOTE : pool_type must be different from FSL_MC_POOL_MCP , since MC
* portals are allocated using fsl_mc_portal_allocate ( ) , instead of
* this function .
*/
int __must_check fsl_mc_object_allocate ( struct fsl_mc_device * mc_dev ,
enum fsl_mc_pool_type pool_type ,
struct fsl_mc_device * * new_mc_adev )
{
struct fsl_mc_device * mc_bus_dev ;
struct fsl_mc_bus * mc_bus ;
struct fsl_mc_device * mc_adev ;
int error = - EINVAL ;
struct fsl_mc_resource * resource = NULL ;
* new_mc_adev = NULL ;
2017-11-17 16:38:32 +03:00
if ( mc_dev - > flags & FSL_MC_IS_DPRC )
2015-03-06 04:35:25 +03:00
goto error ;
2017-11-17 16:38:32 +03:00
if ( ! dev_is_fsl_mc ( mc_dev - > dev . parent ) )
2015-03-06 04:35:25 +03:00
goto error ;
2017-11-17 16:38:32 +03:00
if ( pool_type = = FSL_MC_POOL_DPMCP )
2015-03-06 04:35:25 +03:00
goto error ;
mc_bus_dev = to_fsl_mc_device ( mc_dev - > dev . parent ) ;
mc_bus = to_fsl_mc_bus ( mc_bus_dev ) ;
error = fsl_mc_resource_allocate ( mc_bus , pool_type , & resource ) ;
if ( error < 0 )
goto error ;
mc_adev = resource - > data ;
2017-11-17 16:38:32 +03:00
if ( ! mc_adev )
2015-03-06 04:35:25 +03:00
goto error ;
2018-12-10 19:50:19 +03:00
mc_adev - > consumer_link = device_link_add ( & mc_dev - > dev ,
& mc_adev - > dev ,
DL_FLAG_AUTOREMOVE_CONSUMER ) ;
if ( ! mc_adev - > consumer_link ) {
error = - EINVAL ;
goto error ;
}
2015-03-06 04:35:25 +03:00
* new_mc_adev = mc_adev ;
return 0 ;
error :
if ( resource )
fsl_mc_resource_free ( resource ) ;
return error ;
}
EXPORT_SYMBOL_GPL ( fsl_mc_object_allocate ) ;
/**
2016-10-26 19:20:32 +03:00
* fsl_mc_object_free - Returns an fsl - mc object to the resource
* pool where it came from .
* @ mc_adev : Pointer to the fsl - mc device
2015-03-06 04:35:25 +03:00
*/
void fsl_mc_object_free ( struct fsl_mc_device * mc_adev )
{
struct fsl_mc_resource * resource ;
resource = mc_adev - > resource ;
2017-11-17 16:38:32 +03:00
if ( resource - > type = = FSL_MC_POOL_DPMCP )
2015-03-06 04:35:25 +03:00
return ;
2017-11-17 16:38:32 +03:00
if ( resource - > data ! = mc_adev )
2015-03-06 04:35:25 +03:00
return ;
fsl_mc_resource_free ( resource ) ;
2018-12-10 19:50:19 +03:00
mc_adev - > consumer_link = NULL ;
2015-03-06 04:35:25 +03:00
}
EXPORT_SYMBOL_GPL ( fsl_mc_object_free ) ;
2016-01-07 01:03:23 +03:00
/*
2016-10-26 19:20:32 +03:00
* A DPRC and the devices in the DPRC all share the same GIC - ITS device
* ID . A block of IRQs is pre - allocated and maintained in a pool
* from which devices can allocate them when needed .
*/
/*
* Initialize the interrupt pool associated with an fsl - mc bus .
* It allocates a block of IRQs from the GIC - ITS .
2016-01-07 01:03:23 +03:00
*/
int fsl_mc_populate_irq_pool ( struct fsl_mc_bus * mc_bus ,
unsigned int irq_count )
{
unsigned int i ;
struct msi_desc * msi_desc ;
struct fsl_mc_device_irq * irq_resources ;
struct fsl_mc_device_irq * mc_dev_irq ;
int error ;
struct fsl_mc_device * mc_bus_dev = & mc_bus - > mc_dev ;
struct fsl_mc_resource_pool * res_pool =
& mc_bus - > resource_pools [ FSL_MC_POOL_IRQ ] ;
2017-11-17 16:38:32 +03:00
if ( irq_count = = 0 | |
irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS )
2016-01-07 01:03:23 +03:00
return - EINVAL ;
error = fsl_mc_msi_domain_alloc_irqs ( & mc_bus_dev - > dev , irq_count ) ;
if ( error < 0 )
return error ;
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
irq_resources = devm_kcalloc ( & mc_bus_dev - > dev ,
irq_count , sizeof ( * irq_resources ) ,
2016-01-07 01:03:23 +03:00
GFP_KERNEL ) ;
if ( ! irq_resources ) {
error = - ENOMEM ;
goto cleanup_msi_irqs ;
}
for ( i = 0 ; i < irq_count ; i + + ) {
mc_dev_irq = & irq_resources [ i ] ;
/*
* NOTE : This mc_dev_irq ' s MSI addr / value pair will be set
* by the fsl_mc_msi_write_msg ( ) callback
*/
mc_dev_irq - > resource . type = res_pool - > type ;
mc_dev_irq - > resource . data = mc_dev_irq ;
mc_dev_irq - > resource . parent_pool = res_pool ;
INIT_LIST_HEAD ( & mc_dev_irq - > resource . node ) ;
list_add_tail ( & mc_dev_irq - > resource . node , & res_pool - > free_list ) ;
}
for_each_msi_entry ( msi_desc , & mc_bus_dev - > dev ) {
mc_dev_irq = & irq_resources [ msi_desc - > fsl_mc . msi_index ] ;
mc_dev_irq - > msi_desc = msi_desc ;
mc_dev_irq - > resource . id = msi_desc - > irq ;
}
res_pool - > max_count = irq_count ;
res_pool - > free_count = irq_count ;
mc_bus - > irq_resources = irq_resources ;
return 0 ;
cleanup_msi_irqs :
fsl_mc_msi_domain_free_irqs ( & mc_bus_dev - > dev ) ;
return error ;
}
EXPORT_SYMBOL_GPL ( fsl_mc_populate_irq_pool ) ;
/**
2016-10-26 19:20:32 +03:00
* Teardown the interrupt pool associated with an fsl - mc bus .
2016-01-07 01:03:23 +03:00
* It frees the IRQs that were allocated to the pool , back to the GIC - ITS .
*/
void fsl_mc_cleanup_irq_pool ( struct fsl_mc_bus * mc_bus )
{
struct fsl_mc_device * mc_bus_dev = & mc_bus - > mc_dev ;
struct fsl_mc_resource_pool * res_pool =
& mc_bus - > resource_pools [ FSL_MC_POOL_IRQ ] ;
2017-11-17 16:38:32 +03:00
if ( ! mc_bus - > irq_resources )
2016-01-07 01:03:23 +03:00
return ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > max_count = = 0 )
2016-01-07 01:03:23 +03:00
return ;
2017-11-17 16:38:32 +03:00
if ( res_pool - > free_count ! = res_pool - > max_count )
2016-01-07 01:03:23 +03:00
return ;
INIT_LIST_HEAD ( & res_pool - > free_list ) ;
res_pool - > max_count = 0 ;
res_pool - > free_count = 0 ;
mc_bus - > irq_resources = NULL ;
fsl_mc_msi_domain_free_irqs ( & mc_bus_dev - > dev ) ;
}
EXPORT_SYMBOL_GPL ( fsl_mc_cleanup_irq_pool ) ;
/**
2016-10-26 19:20:32 +03:00
* Allocate the IRQs required by a given fsl - mc device .
2016-01-07 01:03:23 +03:00
*/
int __must_check fsl_mc_allocate_irqs ( struct fsl_mc_device * mc_dev )
{
int i ;
int irq_count ;
int res_allocated_count = 0 ;
int error = - EINVAL ;
struct fsl_mc_device_irq * * irqs = NULL ;
struct fsl_mc_bus * mc_bus ;
struct fsl_mc_resource_pool * res_pool ;
2017-11-17 16:38:32 +03:00
if ( mc_dev - > irqs )
2016-01-07 01:03:23 +03:00
return - EINVAL ;
irq_count = mc_dev - > obj_desc . irq_count ;
2017-11-17 16:38:32 +03:00
if ( irq_count = = 0 )
2016-01-07 01:03:23 +03:00
return - EINVAL ;
2017-11-17 16:38:34 +03:00
if ( is_fsl_mc_bus_dprc ( mc_dev ) )
2016-01-07 01:03:23 +03:00
mc_bus = to_fsl_mc_bus ( mc_dev ) ;
else
mc_bus = to_fsl_mc_bus ( to_fsl_mc_device ( mc_dev - > dev . parent ) ) ;
2017-11-17 16:38:32 +03:00
if ( ! mc_bus - > irq_resources )
2016-01-07 01:03:23 +03:00
return - EINVAL ;
res_pool = & mc_bus - > resource_pools [ FSL_MC_POOL_IRQ ] ;
if ( res_pool - > free_count < irq_count ) {
dev_err ( & mc_dev - > dev ,
" Not able to allocate %u irqs for device \n " , irq_count ) ;
return - ENOSPC ;
}
treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:
devm_kzalloc(handle, a * b, gfp)
with:
devm_kcalloc(handle, a * b, gfp)
as well as handling cases of:
devm_kzalloc(handle, a * b * c, gfp)
with:
devm_kzalloc(handle, array3_size(a, b, c), gfp)
as it's slightly less ugly than:
devm_kcalloc(handle, array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
devm_kzalloc(handle, 4 * 1024, gfp)
though any constants defined via macros get caught up in the conversion.
Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.
Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@
(
devm_kzalloc(HANDLE,
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
devm_kzalloc(HANDLE,
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@
(
devm_kzalloc(HANDLE,
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(char) * COUNT
+ COUNT
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
devm_kzalloc(HANDLE,
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@
(
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
devm_kzalloc(HANDLE,
- COUNT * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
)
// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE,
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
devm_kzalloc(HANDLE,
- E1 * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
)
// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * E2
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- (E1) * (E2)
+ E1, E2
, ...)
|
- devm_kzalloc
+ devm_kcalloc
(HANDLE,
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-13 00:07:58 +03:00
irqs = devm_kcalloc ( & mc_dev - > dev , irq_count , sizeof ( irqs [ 0 ] ) ,
2016-01-07 01:03:23 +03:00
GFP_KERNEL ) ;
if ( ! irqs )
return - ENOMEM ;
for ( i = 0 ; i < irq_count ; i + + ) {
struct fsl_mc_resource * resource ;
error = fsl_mc_resource_allocate ( mc_bus , FSL_MC_POOL_IRQ ,
& resource ) ;
if ( error < 0 )
goto error_resource_alloc ;
irqs [ i ] = to_fsl_mc_irq ( resource ) ;
res_allocated_count + + ;
irqs [ i ] - > mc_dev = mc_dev ;
irqs [ i ] - > dev_irq_index = i ;
}
mc_dev - > irqs = irqs ;
return 0 ;
error_resource_alloc :
for ( i = 0 ; i < res_allocated_count ; i + + ) {
irqs [ i ] - > mc_dev = NULL ;
fsl_mc_resource_free ( & irqs [ i ] - > resource ) ;
}
return error ;
}
EXPORT_SYMBOL_GPL ( fsl_mc_allocate_irqs ) ;
/*
2016-10-26 19:20:32 +03:00
* Frees the IRQs that were allocated for an fsl - mc device .
2016-01-07 01:03:23 +03:00
*/
void fsl_mc_free_irqs ( struct fsl_mc_device * mc_dev )
{
int i ;
int irq_count ;
struct fsl_mc_bus * mc_bus ;
struct fsl_mc_device_irq * * irqs = mc_dev - > irqs ;
2017-11-17 16:38:32 +03:00
if ( ! irqs )
2016-01-07 01:03:23 +03:00
return ;
irq_count = mc_dev - > obj_desc . irq_count ;
2017-11-17 16:38:34 +03:00
if ( is_fsl_mc_bus_dprc ( mc_dev ) )
2016-01-07 01:03:23 +03:00
mc_bus = to_fsl_mc_bus ( mc_dev ) ;
else
mc_bus = to_fsl_mc_bus ( to_fsl_mc_device ( mc_dev - > dev . parent ) ) ;
2017-11-17 16:38:32 +03:00
if ( ! mc_bus - > irq_resources )
2016-01-07 01:03:23 +03:00
return ;
for ( i = 0 ; i < irq_count ; i + + ) {
irqs [ i ] - > mc_dev = NULL ;
fsl_mc_resource_free ( & irqs [ i ] - > resource ) ;
}
mc_dev - > irqs = NULL ;
}
EXPORT_SYMBOL_GPL ( fsl_mc_free_irqs ) ;
2016-08-24 01:13:24 +03:00
void fsl_mc_init_all_resource_pools ( struct fsl_mc_device * mc_bus_dev )
{
int pool_type ;
struct fsl_mc_bus * mc_bus = to_fsl_mc_bus ( mc_bus_dev ) ;
for ( pool_type = 0 ; pool_type < FSL_MC_NUM_POOL_TYPES ; pool_type + + ) {
struct fsl_mc_resource_pool * res_pool =
& mc_bus - > resource_pools [ pool_type ] ;
res_pool - > type = pool_type ;
res_pool - > max_count = 0 ;
res_pool - > free_count = 0 ;
res_pool - > mc_bus = mc_bus ;
INIT_LIST_HEAD ( & res_pool - > free_list ) ;
mutex_init ( & res_pool - > mutex ) ;
}
}
static void fsl_mc_cleanup_resource_pool ( struct fsl_mc_device * mc_bus_dev ,
enum fsl_mc_pool_type pool_type )
{
struct fsl_mc_resource * resource ;
struct fsl_mc_resource * next ;
struct fsl_mc_bus * mc_bus = to_fsl_mc_bus ( mc_bus_dev ) ;
struct fsl_mc_resource_pool * res_pool =
& mc_bus - > resource_pools [ pool_type ] ;
int free_count = 0 ;
list_for_each_entry_safe ( resource , next , & res_pool - > free_list , node ) {
free_count + + ;
devm_kfree ( & mc_bus_dev - > dev , resource ) ;
}
}
void fsl_mc_cleanup_all_resource_pools ( struct fsl_mc_device * mc_bus_dev )
{
int pool_type ;
for ( pool_type = 0 ; pool_type < FSL_MC_NUM_POOL_TYPES ; pool_type + + )
fsl_mc_cleanup_resource_pool ( mc_bus_dev , pool_type ) ;
}
2015-03-06 04:35:25 +03:00
/**
* fsl_mc_allocator_probe - callback invoked when an allocatable device is
* being added to the system
*/
static int fsl_mc_allocator_probe ( struct fsl_mc_device * mc_dev )
{
enum fsl_mc_pool_type pool_type ;
struct fsl_mc_device * mc_bus_dev ;
struct fsl_mc_bus * mc_bus ;
2015-10-17 19:18:21 +03:00
int error ;
2015-03-06 04:35:25 +03:00
2017-11-17 16:38:34 +03:00
if ( ! fsl_mc_is_allocatable ( mc_dev ) )
2015-10-17 19:18:21 +03:00
return - EINVAL ;
2015-03-06 04:35:25 +03:00
mc_bus_dev = to_fsl_mc_device ( mc_dev - > dev . parent ) ;
2017-11-17 16:38:32 +03:00
if ( ! dev_is_fsl_mc ( & mc_bus_dev - > dev ) )
2015-10-17 19:18:21 +03:00
return - EINVAL ;
2015-03-06 04:35:25 +03:00
mc_bus = to_fsl_mc_bus ( mc_bus_dev ) ;
error = object_type_to_pool_type ( mc_dev - > obj_desc . type , & pool_type ) ;
if ( error < 0 )
2015-10-17 19:18:21 +03:00
return error ;
2015-03-06 04:35:25 +03:00
error = fsl_mc_resource_pool_add_device ( mc_bus , pool_type , mc_dev ) ;
if ( error < 0 )
2015-10-17 19:18:21 +03:00
return error ;
2015-03-06 04:35:25 +03:00
2015-10-17 19:18:16 +03:00
dev_dbg ( & mc_dev - > dev ,
2016-10-26 19:20:31 +03:00
" Allocatable fsl-mc device bound to fsl_mc_allocator driver " ) ;
2015-03-06 04:35:25 +03:00
return 0 ;
}
/**
* fsl_mc_allocator_remove - callback invoked when an allocatable device is
* being removed from the system
*/
static int fsl_mc_allocator_remove ( struct fsl_mc_device * mc_dev )
{
2015-10-17 19:18:21 +03:00
int error ;
2015-03-06 04:35:25 +03:00
2017-11-17 16:38:34 +03:00
if ( ! fsl_mc_is_allocatable ( mc_dev ) )
2015-10-17 19:18:21 +03:00
return - EINVAL ;
2015-03-06 04:35:25 +03:00
2015-10-17 19:18:20 +03:00
if ( mc_dev - > resource ) {
error = fsl_mc_resource_pool_remove_device ( mc_dev ) ;
if ( error < 0 )
2015-10-17 19:18:21 +03:00
return error ;
2015-10-17 19:18:20 +03:00
}
2015-03-06 04:35:25 +03:00
2015-10-17 19:18:16 +03:00
dev_dbg ( & mc_dev - > dev ,
2016-10-26 19:20:31 +03:00
" Allocatable fsl-mc device unbound from fsl_mc_allocator driver " ) ;
2015-10-17 19:18:21 +03:00
return 0 ;
2015-03-06 04:35:25 +03:00
}
2016-06-23 00:40:44 +03:00
static const struct fsl_mc_device_id match_id_table [ ] = {
2015-03-06 04:35:25 +03:00
{
. vendor = FSL_MC_VENDOR_FREESCALE ,
. obj_type = " dpbp " ,
} ,
{
. vendor = FSL_MC_VENDOR_FREESCALE ,
. obj_type = " dpmcp " ,
} ,
{
. vendor = FSL_MC_VENDOR_FREESCALE ,
. obj_type = " dpcon " ,
} ,
{ . vendor = 0x0 } ,
} ;
static struct fsl_mc_driver fsl_mc_allocator_driver = {
. driver = {
. name = " fsl_mc_allocator " ,
. pm = NULL ,
} ,
. match_id_table = match_id_table ,
. probe = fsl_mc_allocator_probe ,
. remove = fsl_mc_allocator_remove ,
} ;
2015-03-28 00:01:08 +03:00
int __init fsl_mc_allocator_driver_init ( void )
{
return fsl_mc_driver_register ( & fsl_mc_allocator_driver ) ;
}
2018-03-15 20:05:33 +03:00
void fsl_mc_allocator_driver_exit ( void )
{
fsl_mc_driver_unregister ( & fsl_mc_allocator_driver ) ;
}