2012-11-22 14:12:08 +04:00
/*
* AS3711 PMIC regulator driver , using DCDC Step Down and LDO supplies
*
* Copyright ( C ) 2012 Renesas Electronics Corporation
* Author : Guennadi Liakhovetski , < g . liakhovetski @ gmx . de >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the version 2 of the GNU General Public License as
* published by the Free Software Foundation
*/
# include <linux/err.h>
# include <linux/init.h>
# include <linux/mfd/as3711.h>
# include <linux/module.h>
2013-03-22 20:15:48 +04:00
# include <linux/of.h>
2012-11-22 14:12:08 +04:00
# include <linux/platform_device.h>
# include <linux/regmap.h>
# include <linux/regulator/driver.h>
2013-03-22 20:15:48 +04:00
# include <linux/regulator/of_regulator.h>
2012-11-22 14:12:08 +04:00
# include <linux/slab.h>
struct as3711_regulator_info {
struct regulator_desc desc ;
} ;
struct as3711_regulator {
struct as3711_regulator_info * reg_info ;
} ;
/*
* The regulator API supports 4 modes of operataion : FAST , NORMAL , IDLE and
* STANDBY . We map them in the following way to AS3711 SD1 - 4 DCDC modes :
* FAST : sdX_fast = 1
* NORMAL : low_noise = 1
* IDLE : low_noise = 0
*/
static int as3711_set_mode_sd ( struct regulator_dev * rdev , unsigned int mode )
{
unsigned int fast_bit = rdev - > desc - > enable_mask ,
low_noise_bit = fast_bit < < 4 ;
u8 val ;
switch ( mode ) {
case REGULATOR_MODE_FAST :
val = fast_bit | low_noise_bit ;
break ;
case REGULATOR_MODE_NORMAL :
val = low_noise_bit ;
break ;
case REGULATOR_MODE_IDLE :
val = 0 ;
break ;
default :
return - EINVAL ;
}
return regmap_update_bits ( rdev - > regmap , AS3711_SD_CONTROL_1 ,
low_noise_bit | fast_bit , val ) ;
}
static unsigned int as3711_get_mode_sd ( struct regulator_dev * rdev )
{
unsigned int fast_bit = rdev - > desc - > enable_mask ,
low_noise_bit = fast_bit < < 4 , mask = fast_bit | low_noise_bit ;
unsigned int val ;
int ret = regmap_read ( rdev - > regmap , AS3711_SD_CONTROL_1 , & val ) ;
if ( ret < 0 )
return ret ;
if ( ( val & mask ) = = mask )
return REGULATOR_MODE_FAST ;
if ( ( val & mask ) = = low_noise_bit )
return REGULATOR_MODE_NORMAL ;
if ( ! ( val & mask ) )
return REGULATOR_MODE_IDLE ;
return - EINVAL ;
}
2017-01-28 16:55:00 +03:00
static const struct regulator_ops as3711_sd_ops = {
2012-11-22 14:12:08 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2013-07-16 12:34:39 +04:00
. list_voltage = regulator_list_voltage_linear_range ,
. map_voltage = regulator_map_voltage_linear_range ,
2012-11-22 14:12:08 +04:00
. get_mode = as3711_get_mode_sd ,
. set_mode = as3711_set_mode_sd ,
} ;
2017-01-28 16:55:00 +03:00
static const struct regulator_ops as3711_aldo_ops = {
2012-11-22 14:12:08 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2013-07-16 12:34:39 +04:00
. list_voltage = regulator_list_voltage_linear_range ,
. map_voltage = regulator_map_voltage_linear_range ,
2012-11-22 14:12:08 +04:00
} ;
2017-01-28 16:55:00 +03:00
static const struct regulator_ops as3711_dldo_ops = {
2012-11-22 14:12:08 +04:00
. is_enabled = regulator_is_enabled_regmap ,
. enable = regulator_enable_regmap ,
. disable = regulator_disable_regmap ,
. get_voltage_sel = regulator_get_voltage_sel_regmap ,
. set_voltage_sel = regulator_set_voltage_sel_regmap ,
2013-07-16 12:34:39 +04:00
. list_voltage = regulator_list_voltage_linear_range ,
. map_voltage = regulator_map_voltage_linear_range ,
} ;
static const struct regulator_linear_range as3711_sd_ranges [ ] = {
2013-10-11 05:32:18 +04:00
REGULATOR_LINEAR_RANGE ( 612500 , 0x1 , 0x40 , 12500 ) ,
REGULATOR_LINEAR_RANGE ( 1425000 , 0x41 , 0x70 , 25000 ) ,
REGULATOR_LINEAR_RANGE ( 2650000 , 0x71 , 0x7f , 50000 ) ,
2013-07-16 12:34:39 +04:00
} ;
static const struct regulator_linear_range as3711_aldo_ranges [ ] = {
2013-10-11 05:32:18 +04:00
REGULATOR_LINEAR_RANGE ( 1200000 , 0 , 0xf , 50000 ) ,
REGULATOR_LINEAR_RANGE ( 1800000 , 0x10 , 0x1f , 100000 ) ,
2013-07-16 12:34:39 +04:00
} ;
static const struct regulator_linear_range as3711_dldo_ranges [ ] = {
2013-10-11 05:32:18 +04:00
REGULATOR_LINEAR_RANGE ( 900000 , 0 , 0x10 , 50000 ) ,
REGULATOR_LINEAR_RANGE ( 1750000 , 0x20 , 0x3f , 50000 ) ,
2012-11-22 14:12:08 +04:00
} ;
2014-09-07 14:34:51 +04:00
# define AS3711_REG(_id, _en_reg, _en_bit, _vmask, _sfx) \
[ AS3711_REGULATOR_ # # _id ] = { \
. desc = { \
. name = " as3711-regulator- " # _id , \
. id = AS3711_REGULATOR_ # # _id , \
. n_voltages = ( _vmask + 1 ) , \
. ops = & as3711_ # # _sfx # # _ops , \
. type = REGULATOR_VOLTAGE , \
. owner = THIS_MODULE , \
. vsel_reg = AS3711_ # # _id # # _VOLTAGE , \
. vsel_mask = _vmask , \
. enable_reg = AS3711_ # # _en_reg , \
. enable_mask = BIT ( _en_bit ) , \
. linear_ranges = as3711_ # # _sfx # # _ranges , \
. n_linear_ranges = ARRAY_SIZE ( as3711_ # # _sfx # # _ranges ) , \
} , \
2012-11-22 14:12:08 +04:00
}
static struct as3711_regulator_info as3711_reg_info [ ] = {
2014-09-07 14:34:51 +04:00
AS3711_REG ( SD_1 , SD_CONTROL , 0 , 0x7f , sd ) ,
AS3711_REG ( SD_2 , SD_CONTROL , 1 , 0x7f , sd ) ,
AS3711_REG ( SD_3 , SD_CONTROL , 2 , 0x7f , sd ) ,
AS3711_REG ( SD_4 , SD_CONTROL , 3 , 0x7f , sd ) ,
AS3711_REG ( LDO_1 , LDO_1_VOLTAGE , 7 , 0x1f , aldo ) ,
AS3711_REG ( LDO_2 , LDO_2_VOLTAGE , 7 , 0x1f , aldo ) ,
AS3711_REG ( LDO_3 , LDO_3_VOLTAGE , 7 , 0x3f , dldo ) ,
AS3711_REG ( LDO_4 , LDO_4_VOLTAGE , 7 , 0x3f , dldo ) ,
AS3711_REG ( LDO_5 , LDO_5_VOLTAGE , 7 , 0x3f , dldo ) ,
AS3711_REG ( LDO_6 , LDO_6_VOLTAGE , 7 , 0x3f , dldo ) ,
AS3711_REG ( LDO_7 , LDO_7_VOLTAGE , 7 , 0x3f , dldo ) ,
AS3711_REG ( LDO_8 , LDO_8_VOLTAGE , 7 , 0x3f , dldo ) ,
2012-11-22 14:12:08 +04:00
/* StepUp output voltage depends on supplying regulator */
} ;
# define AS3711_REGULATOR_NUM ARRAY_SIZE(as3711_reg_info)
2013-04-17 12:01:22 +04:00
static struct of_regulator_match
as3711_regulator_matches [ AS3711_REGULATOR_NUM ] = {
[ AS3711_REGULATOR_SD_1 ] = { . name = " sd1 " } ,
[ AS3711_REGULATOR_SD_2 ] = { . name = " sd2 " } ,
[ AS3711_REGULATOR_SD_3 ] = { . name = " sd3 " } ,
[ AS3711_REGULATOR_SD_4 ] = { . name = " sd4 " } ,
[ AS3711_REGULATOR_LDO_1 ] = { . name = " ldo1 " } ,
[ AS3711_REGULATOR_LDO_2 ] = { . name = " ldo2 " } ,
[ AS3711_REGULATOR_LDO_3 ] = { . name = " ldo3 " } ,
[ AS3711_REGULATOR_LDO_4 ] = { . name = " ldo4 " } ,
[ AS3711_REGULATOR_LDO_5 ] = { . name = " ldo5 " } ,
[ AS3711_REGULATOR_LDO_6 ] = { . name = " ldo6 " } ,
[ AS3711_REGULATOR_LDO_7 ] = { . name = " ldo7 " } ,
[ AS3711_REGULATOR_LDO_8 ] = { . name = " ldo8 " } ,
2013-03-22 20:15:48 +04:00
} ;
static int as3711_regulator_parse_dt ( struct device * dev ,
struct device_node * * of_node , const int count )
{
struct as3711_regulator_pdata * pdata = dev_get_platdata ( dev ) ;
struct device_node * regulators =
2014-02-14 15:49:55 +04:00
of_get_child_by_name ( dev - > parent - > of_node , " regulators " ) ;
2013-04-17 12:01:22 +04:00
struct of_regulator_match * match ;
2013-03-22 20:15:48 +04:00
int ret , i ;
if ( ! regulators ) {
dev_err ( dev , " regulator node not found \n " ) ;
return - ENODEV ;
}
2013-04-17 12:01:22 +04:00
ret = of_regulator_match ( dev - > parent , regulators ,
as3711_regulator_matches , count ) ;
2013-03-22 20:15:48 +04:00
of_node_put ( regulators ) ;
if ( ret < 0 ) {
dev_err ( dev , " Error parsing regulator init data: %d \n " , ret ) ;
return ret ;
}
2013-04-17 12:01:22 +04:00
for ( i = 0 , match = as3711_regulator_matches ; i < count ; i + + , match + + )
2013-03-22 20:15:48 +04:00
if ( match - > of_node ) {
pdata - > init_data [ i ] = match - > init_data ;
of_node [ i ] = match - > of_node ;
}
return 0 ;
}
2012-11-22 14:12:08 +04:00
static int as3711_regulator_probe ( struct platform_device * pdev )
{
struct as3711_regulator_pdata * pdata = dev_get_platdata ( & pdev - > dev ) ;
struct as3711 * as3711 = dev_get_drvdata ( pdev - > dev . parent ) ;
struct regulator_config config = { . dev = & pdev - > dev , } ;
struct as3711_regulator * reg = NULL ;
struct as3711_regulator * regs ;
2013-03-22 20:15:48 +04:00
struct device_node * of_node [ AS3711_REGULATOR_NUM ] = { } ;
2012-11-22 14:12:08 +04:00
struct regulator_dev * rdev ;
struct as3711_regulator_info * ri ;
int ret ;
int id ;
2013-03-22 20:15:48 +04:00
if ( ! pdata ) {
dev_err ( & pdev - > dev , " No platform data... \n " ) ;
return - ENODEV ;
}
if ( pdev - > dev . parent - > of_node ) {
ret = as3711_regulator_parse_dt ( & pdev - > dev , of_node , AS3711_REGULATOR_NUM ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " DT parsing failed: %d \n " , ret ) ;
return ret ;
}
}
2012-11-22 14:12:08 +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
regs = devm_kcalloc ( & pdev - > dev ,
AS3711_REGULATOR_NUM ,
sizeof ( struct as3711_regulator ) ,
GFP_KERNEL ) ;
2014-02-18 14:41:11 +04:00
if ( ! regs )
2012-11-22 14:12:08 +04:00
return - ENOMEM ;
for ( id = 0 , ri = as3711_reg_info ; id < AS3711_REGULATOR_NUM ; + + id , ri + + ) {
reg = & regs [ id ] ;
reg - > reg_info = ri ;
2014-02-06 10:47:41 +04:00
config . init_data = pdata - > init_data [ id ] ;
2012-11-22 14:12:08 +04:00
config . driver_data = reg ;
config . regmap = as3711 - > regmap ;
2013-03-22 20:15:48 +04:00
config . of_node = of_node [ id ] ;
2012-11-22 14:12:08 +04:00
2013-09-03 10:22:00 +04:00
rdev = devm_regulator_register ( & pdev - > dev , & ri - > desc , & config ) ;
2012-11-22 14:12:08 +04:00
if ( IS_ERR ( rdev ) ) {
dev_err ( & pdev - > dev , " Failed to register regulator %s \n " ,
ri - > desc . name ) ;
2013-09-03 10:22:00 +04:00
return PTR_ERR ( rdev ) ;
2012-11-22 14:12:08 +04:00
}
}
platform_set_drvdata ( pdev , regs ) ;
return 0 ;
}
static struct platform_driver as3711_regulator_driver = {
. driver = {
. name = " as3711-regulator " ,
} ,
. probe = as3711_regulator_probe ,
} ;
static int __init as3711_regulator_init ( void )
{
return platform_driver_register ( & as3711_regulator_driver ) ;
}
subsys_initcall ( as3711_regulator_init ) ;
static void __exit as3711_regulator_exit ( void )
{
platform_driver_unregister ( & as3711_regulator_driver ) ;
}
module_exit ( as3711_regulator_exit ) ;
MODULE_AUTHOR ( " Guennadi Liakhovetski <g.liakhovetski@gmx.de> " ) ;
MODULE_DESCRIPTION ( " AS3711 regulator driver " ) ;
MODULE_ALIAS ( " platform:as3711-regulator " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;