2019-05-27 09:55:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2014-02-28 19:47:50 +04:00
/*
* Keystone accumulator queue manager
*
* Copyright ( C ) 2014 Texas Instruments Incorporated - http : //www.ti.com
* Author : Sandeep Nair < sandeep_n @ ti . com >
* Cyril Chemparathy < cyril @ ti . com >
* Santosh Shilimkar < santosh . shilimkar @ ti . com >
*/
2017-01-06 22:05:45 +03:00
# include <linux/dma-mapping.h>
2014-02-28 19:47:50 +04:00
# include <linux/io.h>
# include <linux/interrupt.h>
2017-01-06 22:05:45 +03:00
# include <linux/module.h>
2014-02-28 19:47:50 +04:00
# include <linux/of_address.h>
2017-01-06 22:05:45 +03:00
# include <linux/soc/ti/knav_qmss.h>
2014-02-28 19:47:50 +04:00
# include "knav_qmss.h"
# define knav_range_offset_to_inst(kdev, range, q) \
( range - > queue_base_inst + ( q < < kdev - > inst_shift ) )
static void __knav_acc_notify ( struct knav_range_info * range ,
struct knav_acc_channel * acc )
{
struct knav_device * kdev = range - > kdev ;
struct knav_queue_inst * inst ;
int range_base , queue ;
range_base = kdev - > base_id + range - > queue_base ;
if ( range - > flags & RANGE_MULTI_QUEUE ) {
for ( queue = 0 ; queue < range - > num_queues ; queue + + ) {
inst = knav_range_offset_to_inst ( kdev , range ,
queue ) ;
if ( inst - > notify_needed ) {
inst - > notify_needed = 0 ;
dev_dbg ( kdev - > dev , " acc-irq: notifying %d \n " ,
range_base + queue ) ;
knav_queue_notify ( inst ) ;
}
}
} else {
queue = acc - > channel - range - > acc_info . start_channel ;
inst = knav_range_offset_to_inst ( kdev , range , queue ) ;
dev_dbg ( kdev - > dev , " acc-irq: notifying %d \n " ,
range_base + queue ) ;
knav_queue_notify ( inst ) ;
}
}
static int knav_acc_set_notify ( struct knav_range_info * range ,
struct knav_queue_inst * kq ,
bool enabled )
{
struct knav_pdsp_info * pdsp = range - > acc_info . pdsp ;
struct knav_device * kdev = range - > kdev ;
u32 mask , offset ;
/*
* when enabling , we need to re - trigger an interrupt if we
* have descriptors pending
*/
if ( ! enabled | | atomic_read ( & kq - > desc_count ) < = 0 )
return 0 ;
kq - > notify_needed = 1 ;
atomic_inc ( & kq - > acc - > retrigger_count ) ;
mask = BIT ( kq - > acc - > channel % 32 ) ;
offset = ACC_INTD_OFFSET_STATUS ( kq - > acc - > channel ) ;
dev_dbg ( kdev - > dev , " setup-notify: re-triggering irq for %s \n " ,
kq - > acc - > name ) ;
writel_relaxed ( mask , pdsp - > intd + offset ) ;
return 0 ;
}
static irqreturn_t knav_acc_int_handler ( int irq , void * _instdata )
{
struct knav_acc_channel * acc ;
struct knav_queue_inst * kq = NULL ;
struct knav_range_info * range ;
struct knav_pdsp_info * pdsp ;
struct knav_acc_info * info ;
struct knav_device * kdev ;
u32 * list , * list_cpu , val , idx , notifies ;
int range_base , channel , queue = 0 ;
dma_addr_t list_dma ;
range = _instdata ;
info = & range - > acc_info ;
kdev = range - > kdev ;
pdsp = range - > acc_info . pdsp ;
acc = range - > acc ;
range_base = kdev - > base_id + range - > queue_base ;
if ( ( range - > flags & RANGE_MULTI_QUEUE ) = = 0 ) {
for ( queue = 0 ; queue < range - > num_irqs ; queue + + )
if ( range - > irqs [ queue ] . irq = = irq )
break ;
kq = knav_range_offset_to_inst ( kdev , range , queue ) ;
acc + = queue ;
}
channel = acc - > channel ;
list_dma = acc - > list_dma [ acc - > list_index ] ;
list_cpu = acc - > list_cpu [ acc - > list_index ] ;
2015-12-07 17:46:59 +03:00
dev_dbg ( kdev - > dev , " acc-irq: channel %d, list %d, virt %p, dma %pad \n " ,
channel , acc - > list_index , list_cpu , & list_dma ) ;
2014-02-28 19:47:50 +04:00
if ( atomic_read ( & acc - > retrigger_count ) ) {
atomic_dec ( & acc - > retrigger_count ) ;
__knav_acc_notify ( range , acc ) ;
writel_relaxed ( 1 , pdsp - > intd + ACC_INTD_OFFSET_COUNT ( channel ) ) ;
/* ack the interrupt */
writel_relaxed ( ACC_CHANNEL_INT_BASE + channel ,
pdsp - > intd + ACC_INTD_OFFSET_EOI ) ;
return IRQ_HANDLED ;
}
notifies = readl_relaxed ( pdsp - > intd + ACC_INTD_OFFSET_COUNT ( channel ) ) ;
WARN_ON ( ! notifies ) ;
dma_sync_single_for_cpu ( kdev - > dev , list_dma , info - > list_size ,
DMA_FROM_DEVICE ) ;
for ( list = list_cpu ; list < list_cpu + ( info - > list_size / sizeof ( u32 ) ) ;
list + = ACC_LIST_ENTRY_WORDS ) {
if ( ACC_LIST_ENTRY_WORDS = = 1 ) {
dev_dbg ( kdev - > dev ,
" acc-irq: list %d, entry @%p, %08x \n " ,
acc - > list_index , list , list [ 0 ] ) ;
} else if ( ACC_LIST_ENTRY_WORDS = = 2 ) {
dev_dbg ( kdev - > dev ,
" acc-irq: list %d, entry @%p, %08x %08x \n " ,
acc - > list_index , list , list [ 0 ] , list [ 1 ] ) ;
} else if ( ACC_LIST_ENTRY_WORDS = = 4 ) {
dev_dbg ( kdev - > dev ,
" acc-irq: list %d, entry @%p, %08x %08x %08x %08x \n " ,
acc - > list_index , list , list [ 0 ] , list [ 1 ] ,
list [ 2 ] , list [ 3 ] ) ;
}
val = list [ ACC_LIST_ENTRY_DESC_IDX ] ;
if ( ! val )
break ;
if ( range - > flags & RANGE_MULTI_QUEUE ) {
queue = list [ ACC_LIST_ENTRY_QUEUE_IDX ] > > 16 ;
if ( queue < range_base | |
queue > = range_base + range - > num_queues ) {
dev_err ( kdev - > dev ,
" bad queue %d, expecting %d-%d \n " ,
queue , range_base ,
range_base + range - > num_queues ) ;
break ;
}
queue - = range_base ;
kq = knav_range_offset_to_inst ( kdev , range ,
queue ) ;
}
if ( atomic_inc_return ( & kq - > desc_count ) > = ACC_DESCS_MAX ) {
atomic_dec ( & kq - > desc_count ) ;
dev_err ( kdev - > dev ,
" acc-irq: queue %d full, entry dropped \n " ,
queue + range_base ) ;
continue ;
}
idx = atomic_inc_return ( & kq - > desc_tail ) & ACC_DESCS_MASK ;
kq - > descs [ idx ] = val ;
kq - > notify_needed = 1 ;
dev_dbg ( kdev - > dev , " acc-irq: enqueue %08x at %d, queue %d \n " ,
val , idx , queue + range_base ) ;
}
__knav_acc_notify ( range , acc ) ;
memset ( list_cpu , 0 , info - > list_size ) ;
dma_sync_single_for_device ( kdev - > dev , list_dma , info - > list_size ,
DMA_TO_DEVICE ) ;
/* flip to the other list */
acc - > list_index ^ = 1 ;
/* reset the interrupt counter */
writel_relaxed ( 1 , pdsp - > intd + ACC_INTD_OFFSET_COUNT ( channel ) ) ;
/* ack the interrupt */
writel_relaxed ( ACC_CHANNEL_INT_BASE + channel ,
pdsp - > intd + ACC_INTD_OFFSET_EOI ) ;
return IRQ_HANDLED ;
}
2015-01-30 00:23:51 +03:00
static int knav_range_setup_acc_irq ( struct knav_range_info * range ,
2014-02-28 19:47:50 +04:00
int queue , bool enabled )
{
struct knav_device * kdev = range - > kdev ;
struct knav_acc_channel * acc ;
2018-10-31 11:41:34 +03:00
struct cpumask * cpu_mask ;
2014-02-28 19:47:50 +04:00
int ret = 0 , irq ;
u32 old , new ;
if ( range - > flags & RANGE_MULTI_QUEUE ) {
acc = range - > acc ;
irq = range - > irqs [ 0 ] . irq ;
2018-10-31 11:41:34 +03:00
cpu_mask = range - > irqs [ 0 ] . cpu_mask ;
2014-02-28 19:47:50 +04:00
} else {
acc = range - > acc + queue ;
irq = range - > irqs [ queue ] . irq ;
2018-10-31 11:41:34 +03:00
cpu_mask = range - > irqs [ queue ] . cpu_mask ;
2014-02-28 19:47:50 +04:00
}
old = acc - > open_mask ;
if ( enabled )
new = old | BIT ( queue ) ;
else
new = old & ~ BIT ( queue ) ;
acc - > open_mask = new ;
dev_dbg ( kdev - > dev ,
" setup-acc-irq: open mask old %08x, new %08x, channel %s \n " ,
old , new , acc - > name ) ;
if ( likely ( new = = old ) )
return 0 ;
if ( new & & ! old ) {
dev_dbg ( kdev - > dev ,
" setup-acc-irq: requesting %s for channel %s \n " ,
acc - > name , acc - > name ) ;
ret = request_irq ( irq , knav_acc_int_handler , 0 , acc - > name ,
range ) ;
2018-10-31 11:41:34 +03:00
if ( ! ret & & cpu_mask ) {
ret = irq_set_affinity_hint ( irq , cpu_mask ) ;
2014-02-28 19:47:50 +04:00
if ( ret ) {
dev_warn ( range - > kdev - > dev ,
" Failed to set IRQ affinity \n " ) ;
return ret ;
}
}
}
if ( old & & ! new ) {
dev_dbg ( kdev - > dev , " setup-acc-irq: freeing %s for channel %s \n " ,
acc - > name , acc - > name ) ;
2015-09-17 19:02:14 +03:00
ret = irq_set_affinity_hint ( irq , NULL ) ;
if ( ret )
dev_warn ( range - > kdev - > dev ,
" Failed to set IRQ affinity \n " ) ;
2014-02-28 19:47:50 +04:00
free_irq ( irq , range ) ;
}
return ret ;
}
static const char * knav_acc_result_str ( enum knav_acc_result result )
{
static const char * const result_str [ ] = {
[ ACC_RET_IDLE ] = " idle " ,
[ ACC_RET_SUCCESS ] = " success " ,
[ ACC_RET_INVALID_COMMAND ] = " invalid command " ,
[ ACC_RET_INVALID_CHANNEL ] = " invalid channel " ,
[ ACC_RET_INACTIVE_CHANNEL ] = " inactive channel " ,
[ ACC_RET_ACTIVE_CHANNEL ] = " active channel " ,
[ ACC_RET_INVALID_QUEUE ] = " invalid queue " ,
[ ACC_RET_INVALID_RET ] = " invalid return code " ,
} ;
if ( result > = ARRAY_SIZE ( result_str ) )
return result_str [ ACC_RET_INVALID_RET ] ;
else
return result_str [ result ] ;
}
static enum knav_acc_result
knav_acc_write ( struct knav_device * kdev , struct knav_pdsp_info * pdsp ,
struct knav_reg_acc_command * cmd )
{
u32 result ;
dev_dbg ( kdev - > dev , " acc command %08x %08x %08x %08x %08x \n " ,
2015-12-07 17:46:59 +03:00
cmd - > command , cmd - > queue_mask , cmd - > list_dma ,
2014-02-28 19:47:50 +04:00
cmd - > queue_num , cmd - > timer_config ) ;
writel_relaxed ( cmd - > timer_config , & pdsp - > acc_command - > timer_config ) ;
writel_relaxed ( cmd - > queue_num , & pdsp - > acc_command - > queue_num ) ;
2015-12-07 17:46:59 +03:00
writel_relaxed ( cmd - > list_dma , & pdsp - > acc_command - > list_dma ) ;
2014-02-28 19:47:50 +04:00
writel_relaxed ( cmd - > queue_mask , & pdsp - > acc_command - > queue_mask ) ;
writel_relaxed ( cmd - > command , & pdsp - > acc_command - > command ) ;
/* wait for the command to clear */
do {
result = readl_relaxed ( & pdsp - > acc_command - > command ) ;
} while ( ( result > > 8 ) & 0xff ) ;
return ( result > > 24 ) & 0xff ;
}
static void knav_acc_setup_cmd ( struct knav_device * kdev ,
struct knav_range_info * range ,
struct knav_reg_acc_command * cmd ,
int queue )
{
struct knav_acc_info * info = & range - > acc_info ;
struct knav_acc_channel * acc ;
int queue_base ;
u32 queue_mask ;
if ( range - > flags & RANGE_MULTI_QUEUE ) {
acc = range - > acc ;
queue_base = range - > queue_base ;
queue_mask = BIT ( range - > num_queues ) - 1 ;
} else {
acc = range - > acc + queue ;
queue_base = range - > queue_base + queue ;
queue_mask = 0 ;
}
memset ( cmd , 0 , sizeof ( * cmd ) ) ;
cmd - > command = acc - > channel ;
cmd - > queue_mask = queue_mask ;
2015-12-07 17:46:59 +03:00
cmd - > list_dma = ( u32 ) acc - > list_dma [ 0 ] ;
2014-02-28 19:47:50 +04:00
cmd - > queue_num = info - > list_entries < < 16 ;
cmd - > queue_num | = queue_base ;
cmd - > timer_config = ACC_LIST_ENTRY_TYPE < < 18 ;
if ( range - > flags & RANGE_MULTI_QUEUE )
cmd - > timer_config | = ACC_CFG_MULTI_QUEUE ;
cmd - > timer_config | = info - > pacing_mode < < 16 ;
cmd - > timer_config | = info - > timer_count ;
}
static void knav_acc_stop ( struct knav_device * kdev ,
struct knav_range_info * range ,
int queue )
{
struct knav_reg_acc_command cmd ;
struct knav_acc_channel * acc ;
enum knav_acc_result result ;
acc = range - > acc + queue ;
knav_acc_setup_cmd ( kdev , range , & cmd , queue ) ;
cmd . command | = ACC_CMD_DISABLE_CHANNEL < < 8 ;
result = knav_acc_write ( kdev , range - > acc_info . pdsp , & cmd ) ;
dev_dbg ( kdev - > dev , " stopped acc channel %s, result %s \n " ,
acc - > name , knav_acc_result_str ( result ) ) ;
}
static enum knav_acc_result knav_acc_start ( struct knav_device * kdev ,
struct knav_range_info * range ,
int queue )
{
struct knav_reg_acc_command cmd ;
struct knav_acc_channel * acc ;
enum knav_acc_result result ;
acc = range - > acc + queue ;
knav_acc_setup_cmd ( kdev , range , & cmd , queue ) ;
cmd . command | = ACC_CMD_ENABLE_CHANNEL < < 8 ;
result = knav_acc_write ( kdev , range - > acc_info . pdsp , & cmd ) ;
dev_dbg ( kdev - > dev , " started acc channel %s, result %s \n " ,
acc - > name , knav_acc_result_str ( result ) ) ;
return result ;
}
static int knav_acc_init_range ( struct knav_range_info * range )
{
struct knav_device * kdev = range - > kdev ;
struct knav_acc_channel * acc ;
enum knav_acc_result result ;
int queue ;
for ( queue = 0 ; queue < range - > num_queues ; queue + + ) {
acc = range - > acc + queue ;
knav_acc_stop ( kdev , range , queue ) ;
acc - > list_index = 0 ;
result = knav_acc_start ( kdev , range , queue ) ;
if ( result ! = ACC_RET_SUCCESS )
return - EIO ;
if ( range - > flags & RANGE_MULTI_QUEUE )
return 0 ;
}
return 0 ;
}
static int knav_acc_init_queue ( struct knav_range_info * range ,
struct knav_queue_inst * kq )
{
unsigned id = kq - > id - range - > queue_base ;
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
kq - > descs = devm_kcalloc ( range - > kdev - > dev ,
ACC_DESCS_MAX , sizeof ( u32 ) , GFP_KERNEL ) ;
2014-02-28 19:47:50 +04:00
if ( ! kq - > descs )
return - ENOMEM ;
kq - > acc = range - > acc ;
if ( ( range - > flags & RANGE_MULTI_QUEUE ) = = 0 )
kq - > acc + = id ;
return 0 ;
}
static int knav_acc_open_queue ( struct knav_range_info * range ,
struct knav_queue_inst * inst , unsigned flags )
{
unsigned id = inst - > id - range - > queue_base ;
return knav_range_setup_acc_irq ( range , id , true ) ;
}
static int knav_acc_close_queue ( struct knav_range_info * range ,
struct knav_queue_inst * inst )
{
unsigned id = inst - > id - range - > queue_base ;
return knav_range_setup_acc_irq ( range , id , false ) ;
}
static int knav_acc_free_range ( struct knav_range_info * range )
{
struct knav_device * kdev = range - > kdev ;
struct knav_acc_channel * acc ;
struct knav_acc_info * info ;
int channel , channels ;
info = & range - > acc_info ;
if ( range - > flags & RANGE_MULTI_QUEUE )
channels = 1 ;
else
channels = range - > num_queues ;
for ( channel = 0 ; channel < channels ; channel + + ) {
acc = range - > acc + channel ;
if ( ! acc - > list_cpu [ 0 ] )
continue ;
dma_unmap_single ( kdev - > dev , acc - > list_dma [ 0 ] ,
info - > mem_size , DMA_BIDIRECTIONAL ) ;
free_pages_exact ( acc - > list_cpu [ 0 ] , info - > mem_size ) ;
}
devm_kfree ( range - > kdev - > dev , range - > acc ) ;
return 0 ;
}
2020-07-25 00:47:10 +03:00
static struct knav_range_ops knav_acc_range_ops = {
2014-02-28 19:47:50 +04:00
. set_notify = knav_acc_set_notify ,
. init_queue = knav_acc_init_queue ,
. open_queue = knav_acc_open_queue ,
. close_queue = knav_acc_close_queue ,
. init_range = knav_acc_init_range ,
. free_range = knav_acc_free_range ,
} ;
/**
* knav_init_acc_range : Initialise accumulator ranges
*
* @ kdev : qmss device
* @ node : device node
* @ range : qmms range information
*
* Return 0 on success or error
*/
int knav_init_acc_range ( struct knav_device * kdev ,
2015-10-13 23:49:04 +03:00
struct device_node * node ,
struct knav_range_info * range )
2014-02-28 19:47:50 +04:00
{
struct knav_acc_channel * acc ;
struct knav_pdsp_info * pdsp ;
struct knav_acc_info * info ;
int ret , channel , channels ;
int list_size , mem_size ;
dma_addr_t list_dma ;
void * list_mem ;
u32 config [ 5 ] ;
range - > flags | = RANGE_HAS_ACCUMULATOR ;
info = & range - > acc_info ;
ret = of_property_read_u32_array ( node , " accumulator " , config , 5 ) ;
if ( ret )
return ret ;
info - > pdsp_id = config [ 0 ] ;
info - > start_channel = config [ 1 ] ;
info - > list_entries = config [ 2 ] ;
info - > pacing_mode = config [ 3 ] ;
info - > timer_count = config [ 4 ] / ACC_DEFAULT_PERIOD ;
if ( info - > start_channel > ACC_MAX_CHANNEL ) {
dev_err ( kdev - > dev , " channel %d invalid for range %s \n " ,
info - > start_channel , range - > name ) ;
return - EINVAL ;
}
if ( info - > pacing_mode > 3 ) {
dev_err ( kdev - > dev , " pacing mode %d invalid for range %s \n " ,
info - > pacing_mode , range - > name ) ;
return - EINVAL ;
}
pdsp = knav_find_pdsp ( kdev , info - > pdsp_id ) ;
if ( ! pdsp ) {
dev_err ( kdev - > dev , " pdsp id %d not found for range %s \n " ,
info - > pdsp_id , range - > name ) ;
return - EINVAL ;
}
2015-10-13 23:49:04 +03:00
if ( ! pdsp - > started ) {
dev_err ( kdev - > dev , " pdsp id %d not started for range %s \n " ,
info - > pdsp_id , range - > name ) ;
return - ENODEV ;
}
2014-02-28 19:47:50 +04:00
info - > pdsp = pdsp ;
channels = range - > num_queues ;
2023-03-10 17:47:25 +03:00
if ( of_property_read_bool ( node , " multi-queue " ) ) {
2014-02-28 19:47:50 +04:00
range - > flags | = RANGE_MULTI_QUEUE ;
channels = 1 ;
if ( range - > queue_base & ( 32 - 1 ) ) {
dev_err ( kdev - > dev ,
" misaligned multi-queue accumulator range %s \n " ,
range - > name ) ;
return - EINVAL ;
}
if ( range - > num_queues > 32 ) {
dev_err ( kdev - > dev ,
" too many queues in accumulator range %s \n " ,
range - > name ) ;
return - EINVAL ;
}
}
/* figure out list size */
list_size = info - > list_entries ;
list_size * = ACC_LIST_ENTRY_WORDS * sizeof ( u32 ) ;
info - > list_size = list_size ;
mem_size = PAGE_ALIGN ( list_size * 2 ) ;
info - > mem_size = mem_size ;
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
range - > acc = devm_kcalloc ( kdev - > dev , channels , sizeof ( * range - > acc ) ,
2014-02-28 19:47:50 +04:00
GFP_KERNEL ) ;
if ( ! range - > acc )
return - ENOMEM ;
for ( channel = 0 ; channel < channels ; channel + + ) {
acc = range - > acc + channel ;
acc - > channel = info - > start_channel + channel ;
/* allocate memory for the two lists */
list_mem = alloc_pages_exact ( mem_size , GFP_KERNEL | GFP_DMA ) ;
if ( ! list_mem )
return - ENOMEM ;
list_dma = dma_map_single ( kdev - > dev , list_mem , mem_size ,
DMA_BIDIRECTIONAL ) ;
if ( dma_mapping_error ( kdev - > dev , list_dma ) ) {
free_pages_exact ( list_mem , mem_size ) ;
return - ENOMEM ;
}
memset ( list_mem , 0 , mem_size ) ;
dma_sync_single_for_device ( kdev - > dev , list_dma , mem_size ,
DMA_TO_DEVICE ) ;
scnprintf ( acc - > name , sizeof ( acc - > name ) , " hwqueue-acc-%d " ,
acc - > channel ) ;
acc - > list_cpu [ 0 ] = list_mem ;
acc - > list_cpu [ 1 ] = list_mem + list_size ;
acc - > list_dma [ 0 ] = list_dma ;
acc - > list_dma [ 1 ] = list_dma + list_size ;
2015-12-07 17:46:59 +03:00
dev_dbg ( kdev - > dev , " %s: channel %d, dma %pad, virt %8p \n " ,
acc - > name , acc - > channel , & list_dma , list_mem ) ;
2014-02-28 19:47:50 +04:00
}
range - > ops = & knav_acc_range_ops ;
return 0 ;
}
EXPORT_SYMBOL_GPL ( knav_init_acc_range ) ;