2014-02-19 18:56:40 +04:00
/*
* pbias - regulator . c
*
* Copyright ( C ) 2014 Texas Instruments Incorporated - http : //www.ti.com/
* Author : Balaji T K < balajitk @ ti . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed " as is " WITHOUT ANY WARRANTY of any
* kind , whether express or implied ; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# include <linux/err.h>
# include <linux/io.h>
# include <linux/module.h>
# include <linux/mfd/syscon.h>
# include <linux/platform_device.h>
# include <linux/regulator/driver.h>
# include <linux/regulator/machine.h>
# include <linux/regulator/of_regulator.h>
# include <linux/regmap.h>
# include <linux/slab.h>
# include <linux/of.h>
# include <linux/of_device.h>
struct pbias_reg_info {
u32 enable ;
u32 enable_mask ;
2015-07-27 14:24:10 +03:00
u32 disable_val ;
2014-02-19 18:56:40 +04:00
u32 vmode ;
unsigned int enable_time ;
char * name ;
2017-08-31 13:18:45 +03:00
const unsigned int * pbias_volt_table ;
int n_voltages ;
2014-02-19 18:56:40 +04:00
} ;
struct pbias_regulator_data {
struct regulator_desc desc ;
void __iomem * pbias_addr ;
struct regulator_dev * dev ;
struct regmap * syscon ;
const struct pbias_reg_info * info ;
int voltage ;
} ;
2015-09-03 09:50:37 +03:00
struct pbias_of_data {
unsigned int offset ;
} ;
2017-08-31 13:18:45 +03:00
static const unsigned int pbias_volt_table_3_0V [ ] = {
2014-03-08 07:56:47 +04:00
1800000 ,
3000000
} ;
2014-02-19 18:56:40 +04:00
2017-08-31 13:18:45 +03:00
static const unsigned int pbias_volt_table_3_3V [ ] = {
1800000 ,
3300000
} ;
2017-01-28 17:55:21 +03:00
static const struct regulator_ops pbias_regulator_voltage_ops = {
2014-03-08 07:56:47 +04:00
. list_voltage = regulator_list_voltage_table ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2014-04-15 08:02:08 +04:00
. enable = regulator_enable_regmap ,
2014-03-08 07:56:47 +04:00
. disable = regulator_disable_regmap ,
2014-04-15 08:02:08 +04:00
. is_enabled = regulator_is_enabled_regmap ,
2014-02-19 18:56:40 +04:00
} ;
static const struct pbias_reg_info pbias_mmc_omap2430 = {
. enable = BIT ( 1 ) ,
. enable_mask = BIT ( 1 ) ,
. vmode = BIT ( 0 ) ,
2015-07-27 14:24:10 +03:00
. disable_val = 0 ,
2014-02-19 18:56:40 +04:00
. enable_time = 100 ,
2017-08-31 13:18:45 +03:00
. pbias_volt_table = pbias_volt_table_3_0V ,
. n_voltages = 2 ,
2014-02-19 18:56:40 +04:00
. name = " pbias_mmc_omap2430 "
} ;
static const struct pbias_reg_info pbias_sim_omap3 = {
. enable = BIT ( 9 ) ,
. enable_mask = BIT ( 9 ) ,
. vmode = BIT ( 8 ) ,
. enable_time = 100 ,
2017-08-31 13:18:45 +03:00
. pbias_volt_table = pbias_volt_table_3_0V ,
. n_voltages = 2 ,
2014-02-19 18:56:40 +04:00
. name = " pbias_sim_omap3 "
} ;
static const struct pbias_reg_info pbias_mmc_omap4 = {
. enable = BIT ( 26 ) | BIT ( 22 ) ,
. enable_mask = BIT ( 26 ) | BIT ( 25 ) | BIT ( 22 ) ,
2015-07-27 14:24:10 +03:00
. disable_val = BIT ( 25 ) ,
2014-02-19 18:56:40 +04:00
. vmode = BIT ( 21 ) ,
. enable_time = 100 ,
2017-08-31 13:18:45 +03:00
. pbias_volt_table = pbias_volt_table_3_0V ,
. n_voltages = 2 ,
2014-02-19 18:56:40 +04:00
. name = " pbias_mmc_omap4 "
} ;
static const struct pbias_reg_info pbias_mmc_omap5 = {
. enable = BIT ( 27 ) | BIT ( 26 ) ,
. enable_mask = BIT ( 27 ) | BIT ( 25 ) | BIT ( 26 ) ,
2015-07-27 14:24:10 +03:00
. disable_val = BIT ( 25 ) ,
2014-02-19 18:56:40 +04:00
. vmode = BIT ( 21 ) ,
. enable_time = 100 ,
2017-08-31 13:18:45 +03:00
. pbias_volt_table = pbias_volt_table_3_3V ,
. n_voltages = 2 ,
2014-02-19 18:56:40 +04:00
. name = " pbias_mmc_omap5 "
} ;
static struct of_regulator_match pbias_matches [ ] = {
{ . name = " pbias_mmc_omap2430 " , . driver_data = ( void * ) & pbias_mmc_omap2430 } ,
{ . name = " pbias_sim_omap3 " , . driver_data = ( void * ) & pbias_sim_omap3 } ,
{ . name = " pbias_mmc_omap4 " , . driver_data = ( void * ) & pbias_mmc_omap4 } ,
{ . name = " pbias_mmc_omap5 " , . driver_data = ( void * ) & pbias_mmc_omap5 } ,
} ;
# define PBIAS_NUM_REGS ARRAY_SIZE(pbias_matches)
2015-09-03 09:50:37 +03:00
/* Offset from SCM general area (and syscon) base */
static const struct pbias_of_data pbias_of_data_omap2 = {
. offset = 0x230 ,
} ;
static const struct pbias_of_data pbias_of_data_omap3 = {
. offset = 0x2b0 ,
} ;
static const struct pbias_of_data pbias_of_data_omap4 = {
. offset = 0x60 ,
} ;
static const struct pbias_of_data pbias_of_data_omap5 = {
. offset = 0x60 ,
} ;
static const struct pbias_of_data pbias_of_data_dra7 = {
. offset = 0xe00 ,
} ;
2014-02-19 18:56:40 +04:00
static const struct of_device_id pbias_of_match [ ] = {
{ . compatible = " ti,pbias-omap " , } ,
2015-09-03 09:50:37 +03:00
{ . compatible = " ti,pbias-omap2 " , . data = & pbias_of_data_omap2 , } ,
{ . compatible = " ti,pbias-omap3 " , . data = & pbias_of_data_omap3 , } ,
{ . compatible = " ti,pbias-omap4 " , . data = & pbias_of_data_omap4 , } ,
{ . compatible = " ti,pbias-omap5 " , . data = & pbias_of_data_omap5 , } ,
{ . compatible = " ti,pbias-dra7 " , . data = & pbias_of_data_dra7 , } ,
2014-02-19 18:56:40 +04:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , pbias_of_match ) ;
static int pbias_regulator_probe ( struct platform_device * pdev )
{
struct device_node * np = pdev - > dev . of_node ;
struct pbias_regulator_data * drvdata ;
struct resource * res ;
struct regulator_config cfg = { } ;
struct regmap * syscon ;
const struct pbias_reg_info * info ;
int ret = 0 ;
int count , idx , data_idx = 0 ;
2015-09-03 09:50:37 +03:00
const struct of_device_id * match ;
const struct pbias_of_data * data ;
unsigned int offset ;
2014-02-19 18:56:40 +04:00
count = of_regulator_match ( & pdev - > dev , np , pbias_matches ,
PBIAS_NUM_REGS ) ;
if ( count < 0 )
return count ;
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
drvdata = devm_kcalloc ( & pdev - > dev ,
count , sizeof ( struct pbias_regulator_data ) ,
GFP_KERNEL ) ;
2014-06-02 10:30:44 +04:00
if ( ! drvdata )
2014-02-19 18:56:40 +04:00
return - ENOMEM ;
syscon = syscon_regmap_lookup_by_phandle ( np , " syscon " ) ;
if ( IS_ERR ( syscon ) )
return PTR_ERR ( syscon ) ;
2015-09-03 09:50:37 +03:00
match = of_match_device ( of_match_ptr ( pbias_of_match ) , & pdev - > dev ) ;
if ( match & & match - > data ) {
data = match - > data ;
offset = data - > offset ;
} else {
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
if ( ! res )
return - EINVAL ;
offset = res - > start ;
dev_WARN ( & pdev - > dev ,
" using legacy dt data for pbias offset \n " ) ;
}
2014-03-08 07:56:47 +04:00
cfg . regmap = syscon ;
2014-02-19 18:56:40 +04:00
cfg . dev = & pdev - > dev ;
for ( idx = 0 ; idx < PBIAS_NUM_REGS & & data_idx < count ; idx + + ) {
if ( ! pbias_matches [ idx ] . init_data | |
! pbias_matches [ idx ] . of_node )
continue ;
info = pbias_matches [ idx ] . driver_data ;
if ( ! info )
return - ENODEV ;
drvdata [ data_idx ] . syscon = syscon ;
drvdata [ data_idx ] . info = info ;
drvdata [ data_idx ] . desc . name = info - > name ;
drvdata [ data_idx ] . desc . owner = THIS_MODULE ;
drvdata [ data_idx ] . desc . type = REGULATOR_VOLTAGE ;
drvdata [ data_idx ] . desc . ops = & pbias_regulator_voltage_ops ;
2017-08-31 13:18:45 +03:00
drvdata [ data_idx ] . desc . volt_table = info - > pbias_volt_table ;
drvdata [ data_idx ] . desc . n_voltages = info - > n_voltages ;
2014-02-19 18:56:40 +04:00
drvdata [ data_idx ] . desc . enable_time = info - > enable_time ;
2015-09-03 09:50:37 +03:00
drvdata [ data_idx ] . desc . vsel_reg = offset ;
2014-03-08 07:56:47 +04:00
drvdata [ data_idx ] . desc . vsel_mask = info - > vmode ;
2015-09-03 09:50:37 +03:00
drvdata [ data_idx ] . desc . enable_reg = offset ;
2014-03-08 07:56:47 +04:00
drvdata [ data_idx ] . desc . enable_mask = info - > enable_mask ;
2014-04-15 08:02:08 +04:00
drvdata [ data_idx ] . desc . enable_val = info - > enable ;
2015-07-27 14:24:10 +03:00
drvdata [ data_idx ] . desc . disable_val = info - > disable_val ;
2014-02-19 18:56:40 +04:00
cfg . init_data = pbias_matches [ idx ] . init_data ;
cfg . driver_data = & drvdata [ data_idx ] ;
cfg . of_node = pbias_matches [ idx ] . of_node ;
drvdata [ data_idx ] . dev = devm_regulator_register ( & pdev - > dev ,
& drvdata [ data_idx ] . desc , & cfg ) ;
if ( IS_ERR ( drvdata [ data_idx ] . dev ) ) {
ret = PTR_ERR ( drvdata [ data_idx ] . dev ) ;
dev_err ( & pdev - > dev ,
" Failed to register regulator: %d \n " , ret ) ;
goto err_regulator ;
}
data_idx + + ;
}
platform_set_drvdata ( pdev , drvdata ) ;
err_regulator :
return ret ;
}
static struct platform_driver pbias_regulator_driver = {
. probe = pbias_regulator_probe ,
. driver = {
. name = " pbias-regulator " ,
. of_match_table = of_match_ptr ( pbias_of_match ) ,
} ,
} ;
module_platform_driver ( pbias_regulator_driver ) ;
MODULE_AUTHOR ( " Balaji T K <balajitk@ti.com> " ) ;
MODULE_DESCRIPTION ( " pbias voltage regulator " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " platform:pbias-regulator " ) ;