2019-05-27 08:55:05 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-06-11 18:04:39 +08:00
/*
* linux / sound / soc / pxa / mmp - sspa . c
* Base on pxa2xx - ssp . c
*
* Copyright ( C ) 2011 Marvell International Ltd .
*/
# include <linux/init.h>
# include <linux/module.h>
# include <linux/platform_device.h>
# include <linux/delay.h>
# include <linux/clk.h>
# include <linux/slab.h>
# include <linux/pxa2xx_ssp.h>
# include <linux/io.h>
2013-08-12 10:42:39 +02:00
# include <linux/dmaengine.h>
2012-06-11 18:04:39 +08:00
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/initval.h>
# include <sound/pcm_params.h>
# include <sound/soc.h>
# include <sound/pxa2xx-lib.h>
2013-08-12 10:42:39 +02:00
# include <sound/dmaengine_pcm.h>
2012-06-11 18:04:39 +08:00
# include "mmp-sspa.h"
/*
* SSPA audio private data
*/
struct sspa_priv {
struct ssp_device * sspa ;
2013-08-12 10:42:39 +02:00
struct snd_dmaengine_dai_dma_data * dma_params ;
2012-06-11 18:04:39 +08:00
struct clk * audio_clk ;
struct clk * sysclk ;
int dai_fmt ;
int running_cnt ;
} ;
static void mmp_sspa_write_reg ( struct ssp_device * sspa , u32 reg , u32 val )
{
__raw_writel ( val , sspa - > mmio_base + reg ) ;
}
static u32 mmp_sspa_read_reg ( struct ssp_device * sspa , u32 reg )
{
return __raw_readl ( sspa - > mmio_base + reg ) ;
}
static void mmp_sspa_tx_enable ( struct ssp_device * sspa )
{
unsigned int sspa_sp ;
sspa_sp = mmp_sspa_read_reg ( sspa , SSPA_TXSP ) ;
sspa_sp | = SSPA_SP_S_EN ;
sspa_sp | = SSPA_SP_WEN ;
mmp_sspa_write_reg ( sspa , SSPA_TXSP , sspa_sp ) ;
}
static void mmp_sspa_tx_disable ( struct ssp_device * sspa )
{
unsigned int sspa_sp ;
sspa_sp = mmp_sspa_read_reg ( sspa , SSPA_TXSP ) ;
sspa_sp & = ~ SSPA_SP_S_EN ;
sspa_sp | = SSPA_SP_WEN ;
mmp_sspa_write_reg ( sspa , SSPA_TXSP , sspa_sp ) ;
}
static void mmp_sspa_rx_enable ( struct ssp_device * sspa )
{
unsigned int sspa_sp ;
sspa_sp = mmp_sspa_read_reg ( sspa , SSPA_RXSP ) ;
sspa_sp | = SSPA_SP_S_EN ;
sspa_sp | = SSPA_SP_WEN ;
mmp_sspa_write_reg ( sspa , SSPA_RXSP , sspa_sp ) ;
}
static void mmp_sspa_rx_disable ( struct ssp_device * sspa )
{
unsigned int sspa_sp ;
sspa_sp = mmp_sspa_read_reg ( sspa , SSPA_RXSP ) ;
sspa_sp & = ~ SSPA_SP_S_EN ;
sspa_sp | = SSPA_SP_WEN ;
mmp_sspa_write_reg ( sspa , SSPA_RXSP , sspa_sp ) ;
}
static int mmp_sspa_startup ( struct snd_pcm_substream * substream ,
struct snd_soc_dai * dai )
{
struct sspa_priv * priv = snd_soc_dai_get_drvdata ( dai ) ;
clk_enable ( priv - > sysclk ) ;
clk_enable ( priv - > sspa - > clk ) ;
return 0 ;
}
static void mmp_sspa_shutdown ( struct snd_pcm_substream * substream ,
struct snd_soc_dai * dai )
{
struct sspa_priv * priv = snd_soc_dai_get_drvdata ( dai ) ;
clk_disable ( priv - > sspa - > clk ) ;
clk_disable ( priv - > sysclk ) ;
}
/*
* Set the SSP ports SYSCLK .
*/
static int mmp_sspa_set_dai_sysclk ( struct snd_soc_dai * cpu_dai ,
int clk_id , unsigned int freq , int dir )
{
struct sspa_priv * priv = snd_soc_dai_get_drvdata ( cpu_dai ) ;
int ret = 0 ;
switch ( clk_id ) {
case MMP_SSPA_CLK_AUDIO :
ret = clk_set_rate ( priv - > audio_clk , freq ) ;
if ( ret )
return ret ;
break ;
case MMP_SSPA_CLK_PLL :
case MMP_SSPA_CLK_VCXO :
/* not support yet */
return - EINVAL ;
default :
return - EINVAL ;
}
return 0 ;
}
static int mmp_sspa_set_dai_pll ( struct snd_soc_dai * cpu_dai , int pll_id ,
int source , unsigned int freq_in ,
unsigned int freq_out )
{
struct sspa_priv * priv = snd_soc_dai_get_drvdata ( cpu_dai ) ;
int ret = 0 ;
switch ( pll_id ) {
case MMP_SYSCLK :
ret = clk_set_rate ( priv - > sysclk , freq_out ) ;
if ( ret )
return ret ;
break ;
case MMP_SSPA_CLK :
ret = clk_set_rate ( priv - > sspa - > clk , freq_out ) ;
if ( ret )
return ret ;
break ;
default :
return - ENODEV ;
}
return 0 ;
}
/*
* Set up the sspa dai format . The sspa port must be inactive
* before calling this function as the physical
* interface format is changed .
*/
static int mmp_sspa_set_dai_fmt ( struct snd_soc_dai * cpu_dai ,
unsigned int fmt )
{
struct sspa_priv * sspa_priv = snd_soc_dai_get_drvdata ( cpu_dai ) ;
struct ssp_device * sspa = sspa_priv - > sspa ;
u32 sspa_sp , sspa_ctrl ;
/* check if we need to change anything at all */
if ( sspa_priv - > dai_fmt = = fmt )
return 0 ;
/* we can only change the settings if the port is not in use */
if ( ( mmp_sspa_read_reg ( sspa , SSPA_TXSP ) & SSPA_SP_S_EN ) | |
( mmp_sspa_read_reg ( sspa , SSPA_RXSP ) & SSPA_SP_S_EN ) ) {
2019-10-18 13:54:25 +03:00
dev_err ( sspa - > dev ,
2012-06-11 18:04:39 +08:00
" can't change hardware dai format: stream is in use \n " ) ;
return - EINVAL ;
}
/* reset port settings */
sspa_sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH ;
sspa_ctrl = 0 ;
switch ( fmt & SND_SOC_DAIFMT_MASTER_MASK ) {
case SND_SOC_DAIFMT_CBS_CFS :
sspa_sp | = SSPA_SP_MSL ;
break ;
case SND_SOC_DAIFMT_CBM_CFM :
break ;
default :
return - EINVAL ;
}
switch ( fmt & SND_SOC_DAIFMT_INV_MASK ) {
case SND_SOC_DAIFMT_NB_NF :
sspa_sp | = SSPA_SP_FSP ;
break ;
default :
return - EINVAL ;
}
switch ( fmt & SND_SOC_DAIFMT_FORMAT_MASK ) {
case SND_SOC_DAIFMT_I2S :
sspa_sp | = SSPA_TXSP_FPER ( 63 ) ;
sspa_sp | = SSPA_SP_FWID ( 31 ) ;
sspa_ctrl | = SSPA_CTL_XDATDLY ( 1 ) ;
break ;
default :
return - EINVAL ;
}
mmp_sspa_write_reg ( sspa , SSPA_TXSP , sspa_sp ) ;
mmp_sspa_write_reg ( sspa , SSPA_RXSP , sspa_sp ) ;
sspa_sp & = ~ ( SSPA_SP_S_RST | SSPA_SP_FFLUSH ) ;
mmp_sspa_write_reg ( sspa , SSPA_TXSP , sspa_sp ) ;
mmp_sspa_write_reg ( sspa , SSPA_RXSP , sspa_sp ) ;
/*
* FIXME : hw issue , for the tx serial port ,
* can not config the master / slave mode ;
* so must clean this bit .
* The master / slave mode has been set in the
* rx port .
*/
sspa_sp & = ~ SSPA_SP_MSL ;
mmp_sspa_write_reg ( sspa , SSPA_TXSP , sspa_sp ) ;
mmp_sspa_write_reg ( sspa , SSPA_TXCTL , sspa_ctrl ) ;
mmp_sspa_write_reg ( sspa , SSPA_RXCTL , sspa_ctrl ) ;
/* Since we are configuring the timings for the format by hand
* we have to defer some things until hw_params ( ) where we
* know parameters like the sample size .
*/
sspa_priv - > dai_fmt = fmt ;
return 0 ;
}
/*
* Set the SSPA audio DMA parameters and sample size .
* Can be called multiple times by oss emulation .
*/
static int mmp_sspa_hw_params ( struct snd_pcm_substream * substream ,
struct snd_pcm_hw_params * params ,
struct snd_soc_dai * dai )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
2020-03-23 14:19:49 +09:00
struct snd_soc_dai * cpu_dai = asoc_rtd_to_cpu ( rtd , 0 ) ;
2012-06-11 18:04:39 +08:00
struct sspa_priv * sspa_priv = snd_soc_dai_get_drvdata ( dai ) ;
struct ssp_device * sspa = sspa_priv - > sspa ;
2013-08-12 10:42:39 +02:00
struct snd_dmaengine_dai_dma_data * dma_params ;
2012-06-11 18:04:39 +08:00
u32 sspa_ctrl ;
if ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK )
sspa_ctrl = mmp_sspa_read_reg ( sspa , SSPA_TXCTL ) ;
else
sspa_ctrl = mmp_sspa_read_reg ( sspa , SSPA_RXCTL ) ;
sspa_ctrl & = ~ SSPA_CTL_XFRLEN1_MASK ;
sspa_ctrl | = SSPA_CTL_XFRLEN1 ( params_channels ( params ) - 1 ) ;
sspa_ctrl & = ~ SSPA_CTL_XWDLEN1_MASK ;
sspa_ctrl | = SSPA_CTL_XWDLEN1 ( SSPA_CTL_32_BITS ) ;
sspa_ctrl & = ~ SSPA_CTL_XSSZ1_MASK ;
switch ( params_format ( params ) ) {
case SNDRV_PCM_FORMAT_S8 :
sspa_ctrl | = SSPA_CTL_XSSZ1 ( SSPA_CTL_8_BITS ) ;
break ;
case SNDRV_PCM_FORMAT_S16_LE :
sspa_ctrl | = SSPA_CTL_XSSZ1 ( SSPA_CTL_16_BITS ) ;
break ;
case SNDRV_PCM_FORMAT_S20_3LE :
sspa_ctrl | = SSPA_CTL_XSSZ1 ( SSPA_CTL_20_BITS ) ;
break ;
case SNDRV_PCM_FORMAT_S24_3LE :
sspa_ctrl | = SSPA_CTL_XSSZ1 ( SSPA_CTL_24_BITS ) ;
break ;
case SNDRV_PCM_FORMAT_S32_LE :
sspa_ctrl | = SSPA_CTL_XSSZ1 ( SSPA_CTL_32_BITS ) ;
break ;
default :
return - EINVAL ;
}
if ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ) {
mmp_sspa_write_reg ( sspa , SSPA_TXCTL , sspa_ctrl ) ;
mmp_sspa_write_reg ( sspa , SSPA_TXFIFO_LL , 0x1 ) ;
} else {
mmp_sspa_write_reg ( sspa , SSPA_RXCTL , sspa_ctrl ) ;
mmp_sspa_write_reg ( sspa , SSPA_RXFIFO_UL , 0x0 ) ;
}
dma_params = & sspa_priv - > dma_params [ substream - > stream ] ;
2013-08-12 10:42:39 +02:00
dma_params - > addr = substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ?
2012-06-11 18:04:39 +08:00
( sspa - > phys_base + SSPA_TXD ) :
( sspa - > phys_base + SSPA_RXD ) ;
snd_soc_dai_set_dma_data ( cpu_dai , substream , dma_params ) ;
return 0 ;
}
static int mmp_sspa_trigger ( struct snd_pcm_substream * substream , int cmd ,
struct snd_soc_dai * dai )
{
struct sspa_priv * sspa_priv = snd_soc_dai_get_drvdata ( dai ) ;
struct ssp_device * sspa = sspa_priv - > sspa ;
int ret = 0 ;
switch ( cmd ) {
case SNDRV_PCM_TRIGGER_START :
case SNDRV_PCM_TRIGGER_RESUME :
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
/*
* whatever playback or capture , must enable rx .
* this is a hw issue , so need check if rx has been
* enabled or not ; if has been enabled by another
* stream , do not enable again .
*/
if ( ! sspa_priv - > running_cnt )
mmp_sspa_rx_enable ( sspa ) ;
if ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK )
mmp_sspa_tx_enable ( sspa ) ;
sspa_priv - > running_cnt + + ;
break ;
case SNDRV_PCM_TRIGGER_STOP :
case SNDRV_PCM_TRIGGER_SUSPEND :
case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
sspa_priv - > running_cnt - - ;
if ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK )
mmp_sspa_tx_disable ( sspa ) ;
/* have no capture stream, disable rx port */
if ( ! sspa_priv - > running_cnt )
mmp_sspa_rx_disable ( sspa ) ;
break ;
default :
ret = - EINVAL ;
}
return ret ;
}
static int mmp_sspa_probe ( struct snd_soc_dai * dai )
{
struct sspa_priv * priv = dev_get_drvdata ( dai - > dev ) ;
snd_soc_dai_set_drvdata ( dai , priv ) ;
return 0 ;
}
# define MMP_SSPA_RATES SNDRV_PCM_RATE_8000_192000
# define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE )
2017-07-13 01:05:08 -05:00
static const struct snd_soc_dai_ops mmp_sspa_dai_ops = {
2012-06-11 18:04:39 +08:00
. startup = mmp_sspa_startup ,
. shutdown = mmp_sspa_shutdown ,
. trigger = mmp_sspa_trigger ,
. hw_params = mmp_sspa_hw_params ,
. set_sysclk = mmp_sspa_set_dai_sysclk ,
. set_pll = mmp_sspa_set_dai_pll ,
. set_fmt = mmp_sspa_set_dai_fmt ,
} ;
2013-05-14 22:19:52 +02:00
static struct snd_soc_dai_driver mmp_sspa_dai = {
2012-06-11 18:04:39 +08:00
. probe = mmp_sspa_probe ,
. playback = {
. channels_min = 1 ,
. channels_max = 128 ,
. rates = MMP_SSPA_RATES ,
. formats = MMP_SSPA_FORMATS ,
} ,
. capture = {
. channels_min = 1 ,
. channels_max = 2 ,
. rates = MMP_SSPA_RATES ,
. formats = MMP_SSPA_FORMATS ,
} ,
. ops = & mmp_sspa_dai_ops ,
} ;
2013-03-21 03:34:48 -07:00
static const struct snd_soc_component_driver mmp_sspa_component = {
. name = " mmp-sspa " ,
} ;
2012-12-07 09:26:17 -05:00
static int asoc_mmp_sspa_probe ( struct platform_device * pdev )
2012-06-11 18:04:39 +08:00
{
struct sspa_priv * priv ;
priv = devm_kzalloc ( & pdev - > dev ,
sizeof ( struct sspa_priv ) , GFP_KERNEL ) ;
if ( ! priv )
return - ENOMEM ;
priv - > sspa = devm_kzalloc ( & pdev - > dev ,
sizeof ( struct ssp_device ) , GFP_KERNEL ) ;
if ( priv - > sspa = = NULL )
return - ENOMEM ;
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-12 14:07:58 -07:00
priv - > dma_params = devm_kcalloc ( & pdev - > dev ,
2 , sizeof ( struct snd_dmaengine_dai_dma_data ) ,
2013-08-12 10:42:39 +02:00
GFP_KERNEL ) ;
2012-06-11 18:04:39 +08:00
if ( priv - > dma_params = = NULL )
return - ENOMEM ;
2019-07-27 23:07:22 +08:00
priv - > sspa - > mmio_base = devm_platform_ioremap_resource ( pdev , 0 ) ;
2013-01-21 11:09:26 +01:00
if ( IS_ERR ( priv - > sspa - > mmio_base ) )
return PTR_ERR ( priv - > sspa - > mmio_base ) ;
2012-06-11 18:04:39 +08:00
priv - > sspa - > clk = devm_clk_get ( & pdev - > dev , NULL ) ;
if ( IS_ERR ( priv - > sspa - > clk ) )
return PTR_ERR ( priv - > sspa - > clk ) ;
priv - > audio_clk = clk_get ( NULL , " mmp-audio " ) ;
if ( IS_ERR ( priv - > audio_clk ) )
return PTR_ERR ( priv - > audio_clk ) ;
priv - > sysclk = clk_get ( NULL , " mmp-sysclk " ) ;
if ( IS_ERR ( priv - > sysclk ) ) {
clk_put ( priv - > audio_clk ) ;
return PTR_ERR ( priv - > sysclk ) ;
}
clk_enable ( priv - > audio_clk ) ;
priv - > dai_fmt = ( unsigned int ) - 1 ;
platform_set_drvdata ( pdev , priv ) ;
2013-09-17 10:32:48 +05:30
return devm_snd_soc_register_component ( & pdev - > dev , & mmp_sspa_component ,
& mmp_sspa_dai , 1 ) ;
2012-06-11 18:04:39 +08:00
}
2012-12-07 09:26:17 -05:00
static int asoc_mmp_sspa_remove ( struct platform_device * pdev )
2012-06-11 18:04:39 +08:00
{
struct sspa_priv * priv = platform_get_drvdata ( pdev ) ;
clk_disable ( priv - > audio_clk ) ;
clk_put ( priv - > audio_clk ) ;
clk_put ( priv - > sysclk ) ;
return 0 ;
}
static struct platform_driver asoc_mmp_sspa_driver = {
. driver = {
. name = " mmp-sspa-dai " ,
} ,
. probe = asoc_mmp_sspa_probe ,
2012-12-07 09:26:17 -05:00
. remove = asoc_mmp_sspa_remove ,
2012-06-11 18:04:39 +08:00
} ;
module_platform_driver ( asoc_mmp_sspa_driver ) ;
MODULE_AUTHOR ( " Leo Yan <leoy@marvell.com> " ) ;
MODULE_DESCRIPTION ( " MMP SSPA SoC Interface " ) ;
MODULE_LICENSE ( " GPL " ) ;
2016-05-06 17:27:34 +02:00
MODULE_ALIAS ( " platform:mmp-sspa-dai " ) ;