2018-05-23 22:17:38 +03:00
// SPDX-License-Identifier: GPL-2.0
//
// Regulator Driver for Freescale MC13xxx PMIC
//
// Copyright 2010 Yong Shen <yong.shen@linaro.org>
//
// Based on mc13783 regulator driver :
// Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
// Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
//
// Regs infos taken from mc13xxx drivers from freescale and mc13xxx.pdf file
// from freescale
2010-12-14 09:00:54 +03:00
# include <linux/mfd/mc13xxx.h>
# include <linux/regulator/machine.h>
# include <linux/regulator/driver.h>
2011-12-21 19:00:46 +04:00
# include <linux/regulator/of_regulator.h>
2010-12-14 09:00:54 +03:00
# include <linux/platform_device.h>
# include <linux/kernel.h>
# include <linux/slab.h>
# include <linux/init.h>
# include <linux/err.h>
2011-07-18 00:28:23 +04:00
# include <linux/module.h>
2011-12-21 19:00:46 +04:00
# include <linux/of.h>
2010-12-14 09:00:54 +03:00
# include "mc13xxx.h"
static int mc13xxx_regulator_enable ( struct regulator_dev * rdev )
{
struct mc13xxx_regulator_priv * priv = rdev_get_drvdata ( rdev ) ;
struct mc13xxx_regulator * mc13xxx_regulators = priv - > mc13xxx_regulators ;
int id = rdev_get_id ( rdev ) ;
dev_dbg ( rdev_get_dev ( rdev ) , " %s id: %d \n " , __func__ , id ) ;
2014-06-08 15:26:29 +04:00
return mc13xxx_reg_rmw ( priv - > mc13xxx , mc13xxx_regulators [ id ] . reg ,
mc13xxx_regulators [ id ] . enable_bit ,
mc13xxx_regulators [ id ] . enable_bit ) ;
2010-12-14 09:00:54 +03:00
}
static int mc13xxx_regulator_disable ( struct regulator_dev * rdev )
{
struct mc13xxx_regulator_priv * priv = rdev_get_drvdata ( rdev ) ;
struct mc13xxx_regulator * mc13xxx_regulators = priv - > mc13xxx_regulators ;
int id = rdev_get_id ( rdev ) ;
dev_dbg ( rdev_get_dev ( rdev ) , " %s id: %d \n " , __func__ , id ) ;
2014-06-08 15:26:29 +04:00
return mc13xxx_reg_rmw ( priv - > mc13xxx , mc13xxx_regulators [ id ] . reg ,
mc13xxx_regulators [ id ] . enable_bit , 0 ) ;
2010-12-14 09:00:54 +03:00
}
static int mc13xxx_regulator_is_enabled ( struct regulator_dev * rdev )
{
struct mc13xxx_regulator_priv * priv = rdev_get_drvdata ( rdev ) ;
struct mc13xxx_regulator * mc13xxx_regulators = priv - > mc13xxx_regulators ;
int ret , id = rdev_get_id ( rdev ) ;
unsigned int val ;
ret = mc13xxx_reg_read ( priv - > mc13xxx , mc13xxx_regulators [ id ] . reg , & val ) ;
if ( ret )
return ret ;
return ( val & mc13xxx_regulators [ id ] . enable_bit ) ! = 0 ;
}
2012-03-20 06:46:35 +04:00
static int mc13xxx_regulator_set_voltage_sel ( struct regulator_dev * rdev ,
unsigned selector )
2010-12-14 09:00:54 +03:00
{
struct mc13xxx_regulator_priv * priv = rdev_get_drvdata ( rdev ) ;
struct mc13xxx_regulator * mc13xxx_regulators = priv - > mc13xxx_regulators ;
2012-03-20 06:46:35 +04:00
int id = rdev_get_id ( rdev ) ;
2010-12-14 09:00:54 +03:00
2014-06-08 15:26:29 +04:00
return mc13xxx_reg_rmw ( priv - > mc13xxx , mc13xxx_regulators [ id ] . vsel_reg ,
mc13xxx_regulators [ id ] . vsel_mask ,
selector < < mc13xxx_regulators [ id ] . vsel_shift ) ;
2010-12-14 09:00:54 +03:00
}
static int mc13xxx_regulator_get_voltage ( struct regulator_dev * rdev )
{
struct mc13xxx_regulator_priv * priv = rdev_get_drvdata ( rdev ) ;
struct mc13xxx_regulator * mc13xxx_regulators = priv - > mc13xxx_regulators ;
int ret , id = rdev_get_id ( rdev ) ;
unsigned int val ;
dev_dbg ( rdev_get_dev ( rdev ) , " %s id: %d \n " , __func__ , id ) ;
ret = mc13xxx_reg_read ( priv - > mc13xxx ,
mc13xxx_regulators [ id ] . vsel_reg , & val ) ;
if ( ret )
return ret ;
val = ( val & mc13xxx_regulators [ id ] . vsel_mask )
> > mc13xxx_regulators [ id ] . vsel_shift ;
dev_dbg ( rdev_get_dev ( rdev ) , " %s id: %d val: %d \n " , __func__ , id , val ) ;
2011-05-18 16:56:45 +04:00
BUG_ON ( val > = mc13xxx_regulators [ id ] . desc . n_voltages ) ;
2010-12-14 09:00:54 +03:00
2012-06-08 11:41:48 +04:00
return rdev - > desc - > volt_table [ val ] ;
2010-12-14 09:00:54 +03:00
}
struct regulator_ops mc13xxx_regulator_ops = {
. enable = mc13xxx_regulator_enable ,
. disable = mc13xxx_regulator_disable ,
. is_enabled = mc13xxx_regulator_is_enabled ,
2012-06-08 11:41:48 +04:00
. list_voltage = regulator_list_voltage_table ,
2012-03-20 06:46:35 +04:00
. set_voltage_sel = mc13xxx_regulator_set_voltage_sel ,
2010-12-14 09:00:54 +03:00
. get_voltage = mc13xxx_regulator_get_voltage ,
} ;
2010-12-15 17:10:25 +03:00
EXPORT_SYMBOL_GPL ( mc13xxx_regulator_ops ) ;
2010-12-14 09:00:54 +03:00
int mc13xxx_fixed_regulator_set_voltage ( struct regulator_dev * rdev , int min_uV ,
int max_uV , unsigned * selector )
{
int id = rdev_get_id ( rdev ) ;
dev_dbg ( rdev_get_dev ( rdev ) , " %s id: %d min_uV: %d max_uV: %d \n " ,
__func__ , id , min_uV , max_uV ) ;
2012-06-08 11:41:48 +04:00
if ( min_uV < = rdev - > desc - > volt_table [ 0 ] & &
2012-07-13 19:01:14 +04:00
rdev - > desc - > volt_table [ 0 ] < = max_uV ) {
* selector = 0 ;
2010-12-14 09:00:54 +03:00
return 0 ;
2012-07-13 19:01:14 +04:00
} else {
2010-12-14 09:00:54 +03:00
return - EINVAL ;
2012-07-13 19:01:14 +04:00
}
2010-12-14 09:00:54 +03:00
}
2010-12-15 17:10:25 +03:00
EXPORT_SYMBOL_GPL ( mc13xxx_fixed_regulator_set_voltage ) ;
2010-12-14 09:00:54 +03:00
struct regulator_ops mc13xxx_fixed_regulator_ops = {
. enable = mc13xxx_regulator_enable ,
. disable = mc13xxx_regulator_disable ,
. is_enabled = mc13xxx_regulator_is_enabled ,
2012-06-08 11:41:48 +04:00
. list_voltage = regulator_list_voltage_table ,
2010-12-14 09:00:54 +03:00
. set_voltage = mc13xxx_fixed_regulator_set_voltage ,
} ;
2010-12-15 17:10:25 +03:00
EXPORT_SYMBOL_GPL ( mc13xxx_fixed_regulator_ops ) ;
2010-12-14 09:00:54 +03:00
2011-12-21 19:00:46 +04:00
# ifdef CONFIG_OF
2012-11-19 22:22:22 +04:00
int mc13xxx_get_num_regulators_dt ( struct platform_device * pdev )
2011-12-21 19:00:46 +04:00
{
2013-01-30 16:54:49 +04:00
struct device_node * parent ;
int num ;
2011-12-21 19:00:46 +04:00
2014-03-02 11:44:35 +04:00
if ( ! pdev - > dev . parent - > of_node )
2014-02-25 15:19:27 +04:00
return - ENODEV ;
2014-03-02 11:44:35 +04:00
parent = of_get_child_by_name ( pdev - > dev . parent - > of_node , " regulators " ) ;
2011-12-21 19:00:46 +04:00
if ( ! parent )
return - ENODEV ;
2013-01-30 16:54:49 +04:00
num = of_get_child_count ( parent ) ;
2013-01-27 17:16:56 +04:00
of_node_put ( parent ) ;
2011-12-21 19:00:46 +04:00
return num ;
}
2012-02-10 01:43:01 +04:00
EXPORT_SYMBOL_GPL ( mc13xxx_get_num_regulators_dt ) ;
2011-12-21 19:00:46 +04:00
2012-11-19 22:22:22 +04:00
struct mc13xxx_regulator_init_data * mc13xxx_parse_regulators_dt (
2011-12-21 19:00:46 +04:00
struct platform_device * pdev , struct mc13xxx_regulator * regulators ,
2013-04-27 10:29:24 +04:00
int num_regulators )
2011-12-21 19:00:46 +04:00
{
struct mc13xxx_regulator_priv * priv = platform_get_drvdata ( pdev ) ;
struct mc13xxx_regulator_init_data * data , * p ;
struct device_node * parent , * child ;
2013-01-21 22:25:45 +04:00
int i , parsed = 0 ;
2014-03-02 11:44:35 +04:00
if ( ! pdev - > dev . parent - > of_node )
2014-02-25 15:19:27 +04:00
return NULL ;
2014-03-02 11:44:35 +04:00
parent = of_get_child_by_name ( pdev - > dev . parent - > of_node , " regulators " ) ;
2011-12-21 19:00:46 +04:00
if ( ! parent )
return NULL ;
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
data = devm_kcalloc ( & pdev - > dev , priv - > num_regulators , sizeof ( * data ) ,
2011-12-21 19:00:46 +04:00
GFP_KERNEL ) ;
2013-01-27 17:16:56 +04:00
if ( ! data ) {
of_node_put ( parent ) ;
2011-12-21 19:00:46 +04:00
return NULL ;
2013-01-27 17:16:56 +04:00
}
2011-12-21 19:00:46 +04:00
p = data ;
for_each_child_of_node ( parent , child ) {
2013-04-27 10:29:24 +04:00
int found = 0 ;
2011-12-21 19:00:46 +04:00
for ( i = 0 ; i < num_regulators ; i + + ) {
2013-04-27 10:29:24 +04:00
if ( ! regulators [ i ] . desc . name )
continue ;
2011-12-21 19:00:46 +04:00
if ( ! of_node_cmp ( child - > name ,
regulators [ i ] . desc . name ) ) {
p - > id = i ;
p - > init_data = of_get_regulator_init_data (
2014-11-10 16:43:53 +03:00
& pdev - > dev , child ,
& regulators [ i ] . desc ) ;
2011-12-21 19:00:46 +04:00
p - > node = child ;
p + + ;
2013-01-21 22:25:45 +04:00
parsed + + ;
2013-04-27 10:29:24 +04:00
found = 1 ;
2011-12-21 19:00:46 +04:00
break ;
}
}
2013-04-27 10:29:24 +04:00
if ( ! found )
dev_warn ( & pdev - > dev ,
2018-08-28 04:52:42 +03:00
" Unknown regulator: %pOFn \n " , child ) ;
2011-12-21 19:00:46 +04:00
}
2013-01-27 17:16:56 +04:00
of_node_put ( parent ) ;
2011-12-21 19:00:46 +04:00
2013-04-27 10:29:24 +04:00
priv - > num_regulators = parsed ;
2011-12-21 19:00:46 +04:00
return data ;
}
2012-02-10 01:43:01 +04:00
EXPORT_SYMBOL_GPL ( mc13xxx_parse_regulators_dt ) ;
2011-12-21 19:00:46 +04:00
# endif
2010-12-14 09:00:54 +03:00
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_AUTHOR ( " Yong Shen <yong.shen@linaro.org> " ) ;
MODULE_DESCRIPTION ( " Regulator Driver for Freescale MC13xxx PMIC " ) ;
MODULE_ALIAS ( " mc13xxx-regulator-core " ) ;