2019-05-31 11:09:32 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2013-12-06 06:18:43 +04:00
/*
* TI / National Semiconductor LP3943 PWM driver
*
* Copyright 2013 Texas Instruments
*
* Author : Milo Kim < milo . kim @ ti . com >
*/
# include <linux/err.h>
# include <linux/i2c.h>
# include <linux/mfd/lp3943.h>
# include <linux/module.h>
# include <linux/platform_device.h>
# include <linux/pwm.h>
# include <linux/slab.h>
# define LP3943_MAX_DUTY 255
# define LP3943_MIN_PERIOD 6250
# define LP3943_MAX_PERIOD 1600000
struct lp3943_pwm {
struct pwm_chip chip ;
struct lp3943 * lp3943 ;
struct lp3943_platform_data * pdata ;
} ;
static inline struct lp3943_pwm * to_lp3943_pwm ( struct pwm_chip * _chip )
{
return container_of ( _chip , struct lp3943_pwm , chip ) ;
}
static struct lp3943_pwm_map *
lp3943_pwm_request_map ( struct lp3943_pwm * lp3943_pwm , int hwpwm )
{
struct lp3943_platform_data * pdata = lp3943_pwm - > pdata ;
struct lp3943 * lp3943 = lp3943_pwm - > lp3943 ;
struct lp3943_pwm_map * pwm_map ;
int i , offset ;
pwm_map = kzalloc ( sizeof ( * pwm_map ) , GFP_KERNEL ) ;
if ( ! pwm_map )
return ERR_PTR ( - ENOMEM ) ;
pwm_map - > output = pdata - > pwms [ hwpwm ] - > output ;
pwm_map - > num_outputs = pdata - > pwms [ hwpwm ] - > num_outputs ;
for ( i = 0 ; i < pwm_map - > num_outputs ; i + + ) {
offset = pwm_map - > output [ i ] ;
/* Return an error if the pin is already assigned */
2014-01-24 01:32:20 +04:00
if ( test_and_set_bit ( offset , & lp3943 - > pin_used ) ) {
kfree ( pwm_map ) ;
2013-12-06 06:18:43 +04:00
return ERR_PTR ( - EBUSY ) ;
2014-01-24 01:32:20 +04:00
}
2013-12-06 06:18:43 +04:00
}
return pwm_map ;
}
static int lp3943_pwm_request ( struct pwm_chip * chip , struct pwm_device * pwm )
{
struct lp3943_pwm * lp3943_pwm = to_lp3943_pwm ( chip ) ;
struct lp3943_pwm_map * pwm_map ;
pwm_map = lp3943_pwm_request_map ( lp3943_pwm , pwm - > hwpwm ) ;
if ( IS_ERR ( pwm_map ) )
return PTR_ERR ( pwm_map ) ;
return pwm_set_chip_data ( pwm , pwm_map ) ;
}
static void lp3943_pwm_free_map ( struct lp3943_pwm * lp3943_pwm ,
struct lp3943_pwm_map * pwm_map )
{
struct lp3943 * lp3943 = lp3943_pwm - > lp3943 ;
int i , offset ;
for ( i = 0 ; i < pwm_map - > num_outputs ; i + + ) {
offset = pwm_map - > output [ i ] ;
clear_bit ( offset , & lp3943 - > pin_used ) ;
}
kfree ( pwm_map ) ;
}
static void lp3943_pwm_free ( struct pwm_chip * chip , struct pwm_device * pwm )
{
struct lp3943_pwm * lp3943_pwm = to_lp3943_pwm ( chip ) ;
struct lp3943_pwm_map * pwm_map = pwm_get_chip_data ( pwm ) ;
lp3943_pwm_free_map ( lp3943_pwm , pwm_map ) ;
}
static int lp3943_pwm_config ( struct pwm_chip * chip , struct pwm_device * pwm ,
int duty_ns , int period_ns )
{
struct lp3943_pwm * lp3943_pwm = to_lp3943_pwm ( chip ) ;
struct lp3943 * lp3943 = lp3943_pwm - > lp3943 ;
u8 val , reg_duty , reg_prescale ;
int err ;
/*
* How to configure the LP3943 PWMs
*
* 1 ) Period = 6250 ~ 1600000
* 2 ) Prescale = period / 6250 - 1
* 3 ) Duty = input duty
*
* Prescale and duty are register values
*/
if ( pwm - > hwpwm = = 0 ) {
reg_prescale = LP3943_REG_PRESCALE0 ;
reg_duty = LP3943_REG_PWM0 ;
} else {
reg_prescale = LP3943_REG_PRESCALE1 ;
reg_duty = LP3943_REG_PWM1 ;
}
period_ns = clamp ( period_ns , LP3943_MIN_PERIOD , LP3943_MAX_PERIOD ) ;
val = ( u8 ) ( period_ns / LP3943_MIN_PERIOD - 1 ) ;
err = lp3943_write_byte ( lp3943 , reg_prescale , val ) ;
if ( err )
return err ;
val = ( u8 ) ( duty_ns * LP3943_MAX_DUTY / period_ns ) ;
return lp3943_write_byte ( lp3943 , reg_duty , val ) ;
}
static int lp3943_pwm_set_mode ( struct lp3943_pwm * lp3943_pwm ,
struct lp3943_pwm_map * pwm_map ,
u8 val )
{
struct lp3943 * lp3943 = lp3943_pwm - > lp3943 ;
const struct lp3943_reg_cfg * mux = lp3943 - > mux_cfg ;
int i , index , err ;
for ( i = 0 ; i < pwm_map - > num_outputs ; i + + ) {
index = pwm_map - > output [ i ] ;
err = lp3943_update_bits ( lp3943 , mux [ index ] . reg ,
mux [ index ] . mask ,
val < < mux [ index ] . shift ) ;
if ( err )
return err ;
}
return 0 ;
}
static int lp3943_pwm_enable ( struct pwm_chip * chip , struct pwm_device * pwm )
{
struct lp3943_pwm * lp3943_pwm = to_lp3943_pwm ( chip ) ;
struct lp3943_pwm_map * pwm_map = pwm_get_chip_data ( pwm ) ;
u8 val ;
if ( pwm - > hwpwm = = 0 )
val = LP3943_DIM_PWM0 ;
else
val = LP3943_DIM_PWM1 ;
/*
* Each PWM generator is set to control any of outputs of LP3943 .
* To enable / disable the PWM , these output pins should be configured .
*/
return lp3943_pwm_set_mode ( lp3943_pwm , pwm_map , val ) ;
}
static void lp3943_pwm_disable ( struct pwm_chip * chip , struct pwm_device * pwm )
{
struct lp3943_pwm * lp3943_pwm = to_lp3943_pwm ( chip ) ;
struct lp3943_pwm_map * pwm_map = pwm_get_chip_data ( pwm ) ;
/*
* LP3943 outputs are open - drain , so the pin should be configured
* when the PWM is disabled .
*/
lp3943_pwm_set_mode ( lp3943_pwm , pwm_map , LP3943_GPIO_OUT_HIGH ) ;
}
static const struct pwm_ops lp3943_pwm_ops = {
. request = lp3943_pwm_request ,
. free = lp3943_pwm_free ,
. config = lp3943_pwm_config ,
. enable = lp3943_pwm_enable ,
. disable = lp3943_pwm_disable ,
. owner = THIS_MODULE ,
} ;
static int lp3943_pwm_parse_dt ( struct device * dev ,
struct lp3943_pwm * lp3943_pwm )
{
static const char * const name [ ] = { " ti,pwm0 " , " ti,pwm1 " , } ;
struct device_node * node = dev - > of_node ;
struct lp3943_platform_data * pdata ;
struct lp3943_pwm_map * pwm_map ;
enum lp3943_pwm_output * output ;
int i , err , proplen , count = 0 ;
u32 num_outputs ;
if ( ! node )
return - EINVAL ;
pdata = devm_kzalloc ( dev , sizeof ( * pdata ) , GFP_KERNEL ) ;
if ( ! pdata )
return - ENOMEM ;
/*
* Read the output map configuration from the device tree .
* Each of the two PWM generators can drive zero or more outputs .
*/
for ( i = 0 ; i < LP3943_NUM_PWMS ; i + + ) {
if ( ! of_get_property ( node , name [ i ] , & proplen ) )
continue ;
num_outputs = proplen / sizeof ( u32 ) ;
if ( num_outputs = = 0 )
continue ;
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
output = devm_kcalloc ( dev , num_outputs , sizeof ( * output ) ,
2013-12-06 06:18:43 +04:00
GFP_KERNEL ) ;
if ( ! output )
return - ENOMEM ;
err = of_property_read_u32_array ( node , name [ i ] , output ,
num_outputs ) ;
if ( err )
return err ;
pwm_map = devm_kzalloc ( dev , sizeof ( * pwm_map ) , GFP_KERNEL ) ;
if ( ! pwm_map )
return - ENOMEM ;
pwm_map - > output = output ;
pwm_map - > num_outputs = num_outputs ;
pdata - > pwms [ i ] = pwm_map ;
count + + ;
}
if ( count = = 0 )
return - ENODATA ;
lp3943_pwm - > pdata = pdata ;
return 0 ;
}
static int lp3943_pwm_probe ( struct platform_device * pdev )
{
struct lp3943 * lp3943 = dev_get_drvdata ( pdev - > dev . parent ) ;
struct lp3943_pwm * lp3943_pwm ;
int ret ;
lp3943_pwm = devm_kzalloc ( & pdev - > dev , sizeof ( * lp3943_pwm ) , GFP_KERNEL ) ;
if ( ! lp3943_pwm )
return - ENOMEM ;
lp3943_pwm - > pdata = lp3943 - > pdata ;
if ( ! lp3943_pwm - > pdata ) {
if ( IS_ENABLED ( CONFIG_OF ) )
ret = lp3943_pwm_parse_dt ( & pdev - > dev , lp3943_pwm ) ;
else
ret = - ENODEV ;
if ( ret )
return ret ;
}
lp3943_pwm - > lp3943 = lp3943 ;
lp3943_pwm - > chip . dev = & pdev - > dev ;
lp3943_pwm - > chip . ops = & lp3943_pwm_ops ;
lp3943_pwm - > chip . npwm = LP3943_NUM_PWMS ;
platform_set_drvdata ( pdev , lp3943_pwm ) ;
return pwmchip_add ( & lp3943_pwm - > chip ) ;
}
static int lp3943_pwm_remove ( struct platform_device * pdev )
{
struct lp3943_pwm * lp3943_pwm = platform_get_drvdata ( pdev ) ;
return pwmchip_remove ( & lp3943_pwm - > chip ) ;
}
# ifdef CONFIG_OF
static const struct of_device_id lp3943_pwm_of_match [ ] = {
{ . compatible = " ti,lp3943-pwm " , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , lp3943_pwm_of_match ) ;
# endif
static struct platform_driver lp3943_pwm_driver = {
. probe = lp3943_pwm_probe ,
. remove = lp3943_pwm_remove ,
. driver = {
. name = " lp3943-pwm " ,
. of_match_table = of_match_ptr ( lp3943_pwm_of_match ) ,
} ,
} ;
module_platform_driver ( lp3943_pwm_driver ) ;
MODULE_DESCRIPTION ( " LP3943 PWM driver " ) ;
MODULE_ALIAS ( " platform:lp3943-pwm " ) ;
MODULE_AUTHOR ( " Milo Kim " ) ;
MODULE_LICENSE ( " GPL " ) ;