2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2008-07-09 18:27:56 +04:00
/*
* Au12x0 / Au1550 PSC ALSA ASoC audio support .
*
* ( c ) 2007 - 2008 MSC Vertriebsges . m . b . H . ,
2009-10-31 22:15:08 +03:00
* Manuel Lauss < manuel . lauss @ gmail . com >
2008-07-09 18:27:56 +04:00
*
* DMA glue for Au1x - PSC audio .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <linux/dma-mapping.h>
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/pcm_params.h>
# include <sound/soc.h>
# include <asm/mach-au1x00/au1000.h>
# include <asm/mach-au1x00/au1xxx_dbdma.h>
# include <asm/mach-au1x00/au1xxx_psc.h>
# include "psc.h"
/*#define PCM_DEBUG*/
2018-01-29 05:50:37 +03:00
# define DRV_NAME "dbdma2"
2008-07-09 18:27:56 +04:00
# define MSG(x...) printk(KERN_INFO "au1xpsc_pcm: " x)
# ifdef PCM_DEBUG
# define DBG MSG
# else
# define DBG(x...) do {} while (0)
# endif
struct au1xpsc_audio_dmadata {
/* DDMA control data */
unsigned int ddma_id ; /* DDMA direction ID for this PSC */
u32 ddma_chan ; /* DDMA context */
/* PCM context (for irq handlers) */
struct snd_pcm_substream * substream ;
unsigned long curr_period ; /* current segment DDMA is working on */
unsigned long q_period ; /* queue period(s) */
2009-10-13 22:22:35 +04:00
dma_addr_t dma_area ; /* address of queued DMA area */
dma_addr_t dma_area_s ; /* start address of DMA area */
2008-07-09 18:27:56 +04:00
unsigned long pos ; /* current byte position being played */
unsigned long periods ; /* number of SG segments in total */
unsigned long period_bytes ; /* size in bytes of one SG segment */
/* runtime data */
int msbits ;
} ;
/*
* These settings are somewhat okay , at least on my machine audio plays
* almost skip - free . Especially the 64 kB buffer seems to help a LOT .
*/
# define AU1XPSC_PERIOD_MIN_BYTES 1024
# define AU1XPSC_BUFFER_MIN_BYTES 65536
/* PCM hardware DMA capabilities - platform specific */
static const struct snd_pcm_hardware au1xpsc_pcm_hardware = {
. info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
2009-04-28 14:25:59 +04:00
SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH ,
2008-07-09 18:27:56 +04:00
. period_bytes_min = AU1XPSC_PERIOD_MIN_BYTES ,
. period_bytes_max = 4096 * 1024 - 1 ,
. periods_min = 2 ,
. periods_max = 4096 , /* 2 to as-much-as-you-like */
. buffer_bytes_max = 4096 * 1024 - 1 ,
. fifo_size = 16 , /* fifo entries of AC97/I2S PSC */
} ;
static void au1x_pcm_queue_tx ( struct au1xpsc_audio_dmadata * cd )
{
2009-10-13 22:22:35 +04:00
au1xxx_dbdma_put_source ( cd - > ddma_chan , cd - > dma_area ,
2008-07-09 18:27:56 +04:00
cd - > period_bytes , DDMA_FLAGS_IE ) ;
/* update next-to-queue period */
+ + cd - > q_period ;
cd - > dma_area + = cd - > period_bytes ;
if ( cd - > q_period > = cd - > periods ) {
cd - > q_period = 0 ;
cd - > dma_area = cd - > dma_area_s ;
}
}
static void au1x_pcm_queue_rx ( struct au1xpsc_audio_dmadata * cd )
{
2009-10-13 22:22:35 +04:00
au1xxx_dbdma_put_dest ( cd - > ddma_chan , cd - > dma_area ,
2009-10-13 22:22:34 +04:00
cd - > period_bytes , DDMA_FLAGS_IE ) ;
2008-07-09 18:27:56 +04:00
/* update next-to-queue period */
+ + cd - > q_period ;
cd - > dma_area + = cd - > period_bytes ;
if ( cd - > q_period > = cd - > periods ) {
cd - > q_period = 0 ;
cd - > dma_area = cd - > dma_area_s ;
}
}
static void au1x_pcm_dmatx_cb ( int irq , void * dev_id )
{
struct au1xpsc_audio_dmadata * cd = dev_id ;
cd - > pos + = cd - > period_bytes ;
if ( + + cd - > curr_period > = cd - > periods ) {
cd - > pos = 0 ;
cd - > curr_period = 0 ;
}
snd_pcm_period_elapsed ( cd - > substream ) ;
au1x_pcm_queue_tx ( cd ) ;
}
static void au1x_pcm_dmarx_cb ( int irq , void * dev_id )
{
struct au1xpsc_audio_dmadata * cd = dev_id ;
cd - > pos + = cd - > period_bytes ;
if ( + + cd - > curr_period > = cd - > periods ) {
cd - > pos = 0 ;
cd - > curr_period = 0 ;
}
snd_pcm_period_elapsed ( cd - > substream ) ;
au1x_pcm_queue_rx ( cd ) ;
}
static void au1x_pcm_dbdma_free ( struct au1xpsc_audio_dmadata * pcd )
{
if ( pcd - > ddma_chan ) {
au1xxx_dbdma_stop ( pcd - > ddma_chan ) ;
au1xxx_dbdma_reset ( pcd - > ddma_chan ) ;
au1xxx_dbdma_chan_free ( pcd - > ddma_chan ) ;
pcd - > ddma_chan = 0 ;
pcd - > msbits = 0 ;
}
}
/* in case of missing DMA ring or changed TX-source / RX-dest bit widths,
* allocate ( or reallocate ) a 2 - descriptor DMA ring with bit depth according
* to ALSA - supplied sample depth . This is due to limitations in the dbdma api
* ( cannot adjust source / dest widths of already allocated descriptor ring ) .
*/
static int au1x_pcm_dbdma_realloc ( struct au1xpsc_audio_dmadata * pcd ,
int stype , int msbits )
{
/* DMA only in 8/16/32 bit widths */
if ( msbits = = 24 )
msbits = 32 ;
/* check current config: correct bits and descriptors allocated? */
if ( ( pcd - > ddma_chan ) & & ( msbits = = pcd - > msbits ) )
goto out ; /* all ok! */
au1x_pcm_dbdma_free ( pcd ) ;
2011-07-25 15:45:04 +04:00
if ( stype = = SNDRV_PCM_STREAM_CAPTURE )
2008-07-09 18:27:56 +04:00
pcd - > ddma_chan = au1xxx_dbdma_chan_alloc ( pcd - > ddma_id ,
DSCR_CMD0_ALWAYS ,
au1x_pcm_dmarx_cb , ( void * ) pcd ) ;
else
pcd - > ddma_chan = au1xxx_dbdma_chan_alloc ( DSCR_CMD0_ALWAYS ,
pcd - > ddma_id ,
au1x_pcm_dmatx_cb , ( void * ) pcd ) ;
if ( ! pcd - > ddma_chan )
2009-01-08 05:09:08 +03:00
return - ENOMEM ;
2008-07-09 18:27:56 +04:00
au1xxx_dbdma_set_devwidth ( pcd - > ddma_chan , msbits ) ;
au1xxx_dbdma_ring_alloc ( pcd - > ddma_chan , 2 ) ;
pcd - > msbits = msbits ;
au1xxx_dbdma_stop ( pcd - > ddma_chan ) ;
au1xxx_dbdma_reset ( pcd - > ddma_chan ) ;
out :
return 0 ;
}
2019-10-02 08:32:07 +03:00
static inline struct au1xpsc_audio_dmadata * to_dmadata ( struct snd_pcm_substream * ss ,
struct snd_soc_component * component )
2010-08-26 16:53:51 +04:00
{
2018-01-29 05:50:37 +03:00
struct au1xpsc_audio_dmadata * pcd = snd_soc_component_get_drvdata ( component ) ;
2011-07-25 15:45:04 +04:00
return & pcd [ ss - > stream ] ;
2010-08-26 16:53:51 +04:00
}
2019-10-02 08:32:07 +03:00
static int au1xpsc_pcm_hw_params ( struct snd_soc_component * component ,
struct snd_pcm_substream * substream ,
2008-07-09 18:27:56 +04:00
struct snd_pcm_hw_params * params )
{
struct snd_pcm_runtime * runtime = substream - > runtime ;
struct au1xpsc_audio_dmadata * pcd ;
int stype , ret ;
2011-07-25 15:45:04 +04:00
stype = substream - > stream ;
2019-10-02 08:32:07 +03:00
pcd = to_dmadata ( substream , component ) ;
2008-07-09 18:27:56 +04:00
2016-04-13 02:54:01 +03:00
DBG ( " runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %zu "
" runtime->min_align %lu \n " ,
2008-07-09 18:27:56 +04:00
( unsigned long ) runtime - > dma_area ,
( unsigned long ) runtime - > dma_addr , runtime - > dma_bytes ,
runtime - > min_align ) ;
DBG ( " bits %d frags %d frag_bytes %d is_rx %d \n " , params - > msbits ,
params_periods ( params ) , params_period_bytes ( params ) , stype ) ;
ret = au1x_pcm_dbdma_realloc ( pcd , stype , params - > msbits ) ;
if ( ret ) {
MSG ( " DDMA channel (re)alloc failed! \n " ) ;
goto out ;
}
pcd - > substream = substream ;
pcd - > period_bytes = params_period_bytes ( params ) ;
pcd - > periods = params_periods ( params ) ;
2009-10-13 22:22:35 +04:00
pcd - > dma_area_s = pcd - > dma_area = runtime - > dma_addr ;
2008-07-09 18:27:56 +04:00
pcd - > q_period = 0 ;
pcd - > curr_period = 0 ;
pcd - > pos = 0 ;
ret = 0 ;
out :
return ret ;
}
2019-10-02 08:32:07 +03:00
static int au1xpsc_pcm_prepare ( struct snd_soc_component * component ,
struct snd_pcm_substream * substream )
2008-07-09 18:27:56 +04:00
{
2019-10-02 08:32:07 +03:00
struct au1xpsc_audio_dmadata * pcd = to_dmadata ( substream , component ) ;
2008-07-09 18:27:56 +04:00
au1xxx_dbdma_reset ( pcd - > ddma_chan ) ;
2011-07-25 15:45:04 +04:00
if ( substream - > stream = = SNDRV_PCM_STREAM_CAPTURE ) {
2008-07-09 18:27:56 +04:00
au1x_pcm_queue_rx ( pcd ) ;
au1x_pcm_queue_rx ( pcd ) ;
} else {
au1x_pcm_queue_tx ( pcd ) ;
au1x_pcm_queue_tx ( pcd ) ;
}
return 0 ;
}
2019-10-02 08:32:07 +03:00
static int au1xpsc_pcm_trigger ( struct snd_soc_component * component ,
struct snd_pcm_substream * substream , int cmd )
2008-07-09 18:27:56 +04:00
{
2019-10-02 08:32:07 +03:00
u32 c = to_dmadata ( substream , component ) - > ddma_chan ;
2008-07-09 18:27:56 +04:00
switch ( cmd ) {
case SNDRV_PCM_TRIGGER_START :
case SNDRV_PCM_TRIGGER_RESUME :
au1xxx_dbdma_start ( c ) ;
break ;
case SNDRV_PCM_TRIGGER_STOP :
case SNDRV_PCM_TRIGGER_SUSPEND :
au1xxx_dbdma_stop ( c ) ;
break ;
default :
return - EINVAL ;
}
return 0 ;
}
static snd_pcm_uframes_t
2019-10-02 08:32:07 +03:00
au1xpsc_pcm_pointer ( struct snd_soc_component * component ,
struct snd_pcm_substream * substream )
2008-07-09 18:27:56 +04:00
{
2019-10-02 08:32:07 +03:00
return bytes_to_frames ( substream - > runtime ,
to_dmadata ( substream , component ) - > pos ) ;
2008-07-09 18:27:56 +04:00
}
2019-10-02 08:32:07 +03:00
static int au1xpsc_pcm_open ( struct snd_soc_component * component ,
struct snd_pcm_substream * substream )
2008-07-09 18:27:56 +04:00
{
2019-10-02 08:32:07 +03:00
struct au1xpsc_audio_dmadata * pcd = to_dmadata ( substream , component ) ;
2020-07-20 04:19:19 +03:00
struct snd_soc_pcm_runtime * rtd = asoc_substream_to_rtd ( substream ) ;
2011-07-25 15:45:04 +04:00
int stype = substream - > stream , * dmaids ;
2011-07-25 15:45:02 +04:00
2020-03-23 08:17:47 +03:00
dmaids = snd_soc_dai_get_dma_data ( asoc_rtd_to_cpu ( rtd , 0 ) , substream ) ;
2011-07-25 15:45:02 +04:00
if ( ! dmaids )
return - ENODEV ; /* whoa, has ordering changed? */
pcd - > ddma_id = dmaids [ stype ] ;
2008-07-09 18:27:56 +04:00
snd_soc_set_runtime_hwparams ( substream , & au1xpsc_pcm_hardware ) ;
return 0 ;
}
2019-10-02 08:32:07 +03:00
static int au1xpsc_pcm_close ( struct snd_soc_component * component ,
struct snd_pcm_substream * substream )
2008-07-09 18:27:56 +04:00
{
2019-10-02 08:32:07 +03:00
au1x_pcm_dbdma_free ( to_dmadata ( substream , component ) ) ;
2008-07-09 18:27:56 +04:00
return 0 ;
}
2019-10-02 08:32:07 +03:00
static int au1xpsc_pcm_new ( struct snd_soc_component * component ,
struct snd_soc_pcm_runtime * rtd )
2008-07-09 18:27:56 +04:00
{
2011-06-07 19:08:33 +04:00
struct snd_card * card = rtd - > card - > snd_card ;
struct snd_pcm * pcm = rtd - > pcm ;
2019-12-10 17:25:53 +03:00
snd_pcm_set_managed_buffer_all ( pcm , SNDRV_DMA_TYPE_DEV ,
2008-07-09 18:27:56 +04:00
card - > dev , AU1XPSC_BUFFER_MIN_BYTES , ( 4096 * 1024 ) - 1 ) ;
return 0 ;
}
2009-10-31 22:15:08 +03:00
/* au1xpsc audio platform */
2018-01-29 05:50:37 +03:00
static struct snd_soc_component_driver au1xpsc_soc_component = {
. name = DRV_NAME ,
2019-10-02 08:32:07 +03:00
. open = au1xpsc_pcm_open ,
. close = au1xpsc_pcm_close ,
. hw_params = au1xpsc_pcm_hw_params ,
. prepare = au1xpsc_pcm_prepare ,
. trigger = au1xpsc_pcm_trigger ,
. pointer = au1xpsc_pcm_pointer ,
. pcm_construct = au1xpsc_pcm_new ,
2009-10-31 22:15:08 +03:00
} ;
2012-12-07 18:26:22 +04:00
static int au1xpsc_pcm_drvprobe ( struct platform_device * pdev )
2008-07-09 18:27:56 +04:00
{
2010-08-26 16:53:51 +04:00
struct au1xpsc_audio_dmadata * dmadata ;
2008-07-09 18:27:56 +04:00
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
dmadata = devm_kcalloc ( & pdev - > dev ,
2 , sizeof ( struct au1xpsc_audio_dmadata ) ,
2011-12-29 20:51:28 +04:00
GFP_KERNEL ) ;
2010-08-26 16:53:51 +04:00
if ( ! dmadata )
2008-07-09 18:27:56 +04:00
return - ENOMEM ;
2010-08-26 16:53:51 +04:00
platform_set_drvdata ( pdev , dmadata ) ;
2008-07-09 18:27:56 +04:00
2018-01-29 05:50:37 +03:00
return devm_snd_soc_register_component ( & pdev - > dev ,
& au1xpsc_soc_component , NULL , 0 ) ;
2008-07-09 18:27:56 +04:00
}
2009-10-31 22:15:08 +03:00
static struct platform_driver au1xpsc_pcm_driver = {
. driver = {
2010-08-26 16:53:51 +04:00
. name = " au1xpsc-pcm " ,
2009-10-31 22:15:08 +03:00
} ,
. probe = au1xpsc_pcm_drvprobe ,
2008-07-09 18:27:56 +04:00
} ;
2011-11-25 06:06:59 +04:00
module_platform_driver ( au1xpsc_pcm_driver ) ;
2009-10-31 22:15:08 +03:00
2008-07-09 18:27:56 +04:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " Au12x0/Au1550 PSC Audio DMA driver " ) ;
2009-10-31 22:15:08 +03:00
MODULE_AUTHOR ( " Manuel Lauss " ) ;