2013-09-13 12:02:15 +03:00
/*
* TI Divider Clock
*
* Copyright ( C ) 2013 Texas Instruments , Inc .
*
* Tero Kristo < t - kristo @ ti . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* 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/clk-provider.h>
# include <linux/slab.h>
# include <linux/err.h>
# include <linux/of.h>
# include <linux/of_address.h>
# include <linux/clk/ti.h>
2014-12-16 18:20:50 +02:00
# include "clock.h"
2013-09-13 12:02:15 +03:00
# undef pr_fmt
# define pr_fmt(fmt) "%s: " fmt, __func__
# define div_mask(d) ((1 << ((d)->width)) - 1)
static unsigned int _get_table_maxdiv ( const struct clk_div_table * table )
{
unsigned int maxdiv = 0 ;
const struct clk_div_table * clkt ;
for ( clkt = table ; clkt - > div ; clkt + + )
if ( clkt - > div > maxdiv )
maxdiv = clkt - > div ;
return maxdiv ;
}
2017-02-09 14:45:45 +02:00
static unsigned int _get_maxdiv ( struct clk_omap_divider * divider )
2013-09-13 12:02:15 +03:00
{
if ( divider - > flags & CLK_DIVIDER_ONE_BASED )
return div_mask ( divider ) ;
if ( divider - > flags & CLK_DIVIDER_POWER_OF_TWO )
return 1 < < div_mask ( divider ) ;
if ( divider - > table )
return _get_table_maxdiv ( divider - > table ) ;
return div_mask ( divider ) + 1 ;
}
static unsigned int _get_table_div ( const struct clk_div_table * table ,
unsigned int val )
{
const struct clk_div_table * clkt ;
for ( clkt = table ; clkt - > div ; clkt + + )
if ( clkt - > val = = val )
return clkt - > div ;
return 0 ;
}
2017-02-09 14:45:45 +02:00
static unsigned int _get_div ( struct clk_omap_divider * divider , unsigned int val )
2013-09-13 12:02:15 +03:00
{
if ( divider - > flags & CLK_DIVIDER_ONE_BASED )
return val ;
if ( divider - > flags & CLK_DIVIDER_POWER_OF_TWO )
return 1 < < val ;
if ( divider - > table )
return _get_table_div ( divider - > table , val ) ;
return val + 1 ;
}
static unsigned int _get_table_val ( const struct clk_div_table * table ,
unsigned int div )
{
const struct clk_div_table * clkt ;
for ( clkt = table ; clkt - > div ; clkt + + )
if ( clkt - > div = = div )
return clkt - > val ;
return 0 ;
}
2017-02-09 14:45:45 +02:00
static unsigned int _get_val ( struct clk_omap_divider * divider , u8 div )
2013-09-13 12:02:15 +03:00
{
if ( divider - > flags & CLK_DIVIDER_ONE_BASED )
return div ;
if ( divider - > flags & CLK_DIVIDER_POWER_OF_TWO )
return __ffs ( div ) ;
if ( divider - > table )
return _get_table_val ( divider - > table , div ) ;
return div - 1 ;
}
static unsigned long ti_clk_divider_recalc_rate ( struct clk_hw * hw ,
unsigned long parent_rate )
{
2017-02-09 14:45:45 +02:00
struct clk_omap_divider * divider = to_clk_omap_divider ( hw ) ;
2013-09-13 12:02:15 +03:00
unsigned int div , val ;
2017-02-09 11:24:37 +02:00
val = ti_clk_ll_ops - > clk_readl ( & divider - > reg ) > > divider - > shift ;
2013-09-13 12:02:15 +03:00
val & = div_mask ( divider ) ;
div = _get_div ( divider , val ) ;
if ( ! div ) {
WARN ( ! ( divider - > flags & CLK_DIVIDER_ALLOW_ZERO ) ,
" %s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set \n " ,
2015-07-30 17:20:57 -07:00
clk_hw_get_name ( hw ) ) ;
2013-09-13 12:02:15 +03:00
return parent_rate ;
}
2014-02-13 12:04:00 +02:00
return DIV_ROUND_UP ( parent_rate , div ) ;
2013-09-13 12:02:15 +03:00
}
/*
* The reverse of DIV_ROUND_UP : The maximum number which
* divided by m is r
*/
# define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
static bool _is_valid_table_div ( const struct clk_div_table * table ,
unsigned int div )
{
const struct clk_div_table * clkt ;
for ( clkt = table ; clkt - > div ; clkt + + )
if ( clkt - > div = = div )
return true ;
return false ;
}
2017-02-09 14:45:45 +02:00
static bool _is_valid_div ( struct clk_omap_divider * divider , unsigned int div )
2013-09-13 12:02:15 +03:00
{
if ( divider - > flags & CLK_DIVIDER_POWER_OF_TWO )
return is_power_of_2 ( div ) ;
if ( divider - > table )
return _is_valid_table_div ( divider - > table , div ) ;
return true ;
}
2016-12-02 14:35:43 +05:30
static int _div_round_up ( const struct clk_div_table * table ,
unsigned long parent_rate , unsigned long rate )
{
const struct clk_div_table * clkt ;
int up = INT_MAX ;
int div = DIV_ROUND_UP_ULL ( ( u64 ) parent_rate , rate ) ;
for ( clkt = table ; clkt - > div ; clkt + + ) {
if ( clkt - > div = = div )
return clkt - > div ;
else if ( clkt - > div < div )
continue ;
if ( ( clkt - > div - div ) < ( up - div ) )
up = clkt - > div ;
}
return up ;
}
static int _div_round ( const struct clk_div_table * table ,
unsigned long parent_rate , unsigned long rate )
{
if ( ! table )
return DIV_ROUND_UP ( parent_rate , rate ) ;
return _div_round_up ( table , parent_rate , rate ) ;
}
2013-09-13 12:02:15 +03:00
static int ti_clk_divider_bestdiv ( struct clk_hw * hw , unsigned long rate ,
unsigned long * best_parent_rate )
{
2017-02-09 14:45:45 +02:00
struct clk_omap_divider * divider = to_clk_omap_divider ( hw ) ;
2013-09-13 12:02:15 +03:00
int i , bestdiv = 0 ;
unsigned long parent_rate , best = 0 , now , maxdiv ;
unsigned long parent_rate_saved = * best_parent_rate ;
if ( ! rate )
rate = 1 ;
maxdiv = _get_maxdiv ( divider ) ;
2015-06-29 16:56:30 -07:00
if ( ! ( clk_hw_get_flags ( hw ) & CLK_SET_RATE_PARENT ) ) {
2013-09-13 12:02:15 +03:00
parent_rate = * best_parent_rate ;
2016-12-02 14:35:43 +05:30
bestdiv = _div_round ( divider - > table , parent_rate , rate ) ;
2013-09-13 12:02:15 +03:00
bestdiv = bestdiv = = 0 ? 1 : bestdiv ;
bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv ;
return bestdiv ;
}
/*
* The maximum divider we can use without overflowing
* unsigned long in rate * i below
*/
maxdiv = min ( ULONG_MAX / rate , maxdiv ) ;
for ( i = 1 ; i < = maxdiv ; i + + ) {
if ( ! _is_valid_div ( divider , i ) )
continue ;
if ( rate * i = = parent_rate_saved ) {
/*
* It ' s the most ideal case if the requested rate can be
* divided from parent clock without needing to change
* parent rate , so return the divider immediately .
*/
* best_parent_rate = parent_rate_saved ;
return i ;
}
2015-07-30 17:20:57 -07:00
parent_rate = clk_hw_round_rate ( clk_hw_get_parent ( hw ) ,
2013-09-13 12:02:15 +03:00
MULT_ROUND_UP ( rate , i ) ) ;
2014-02-13 12:04:00 +02:00
now = DIV_ROUND_UP ( parent_rate , i ) ;
2013-09-13 12:02:15 +03:00
if ( now < = rate & & now > best ) {
bestdiv = i ;
best = now ;
* best_parent_rate = parent_rate ;
}
}
if ( ! bestdiv ) {
bestdiv = _get_maxdiv ( divider ) ;
* best_parent_rate =
2015-07-30 17:20:57 -07:00
clk_hw_round_rate ( clk_hw_get_parent ( hw ) , 1 ) ;
2013-09-13 12:02:15 +03:00
}
return bestdiv ;
}
static long ti_clk_divider_round_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long * prate )
{
int div ;
div = ti_clk_divider_bestdiv ( hw , rate , prate ) ;
2014-02-13 12:04:00 +02:00
return DIV_ROUND_UP ( * prate , div ) ;
2013-09-13 12:02:15 +03:00
}
static int ti_clk_divider_set_rate ( struct clk_hw * hw , unsigned long rate ,
unsigned long parent_rate )
{
2017-02-09 14:45:45 +02:00
struct clk_omap_divider * divider ;
2013-09-13 12:02:15 +03:00
unsigned int div , value ;
u32 val ;
2014-08-18 11:56:54 -05:00
if ( ! hw | | ! rate )
return - EINVAL ;
2017-02-09 14:45:45 +02:00
divider = to_clk_omap_divider ( hw ) ;
2014-08-18 11:56:54 -05:00
2014-02-13 12:04:00 +02:00
div = DIV_ROUND_UP ( parent_rate , rate ) ;
2013-09-13 12:02:15 +03:00
value = _get_val ( divider , div ) ;
if ( value > div_mask ( divider ) )
value = div_mask ( divider ) ;
if ( divider - > flags & CLK_DIVIDER_HIWORD_MASK ) {
val = div_mask ( divider ) < < ( divider - > shift + 16 ) ;
} else {
2017-02-09 11:24:37 +02:00
val = ti_clk_ll_ops - > clk_readl ( & divider - > reg ) ;
2013-09-13 12:02:15 +03:00
val & = ~ ( div_mask ( divider ) < < divider - > shift ) ;
}
val | = value < < divider - > shift ;
2017-02-09 11:24:37 +02:00
ti_clk_ll_ops - > clk_writel ( val , & divider - > reg ) ;
2013-09-13 12:02:15 +03:00
2018-02-15 09:49:27 +02:00
ti_clk_latch ( & divider - > reg , divider - > latch ) ;
2013-09-13 12:02:15 +03:00
return 0 ;
}
2018-09-04 12:19:37 +05:30
/**
* clk_divider_save_context - Save the divider value
* @ hw : pointer struct clk_hw
*
* Save the divider value
*/
static int clk_divider_save_context ( struct clk_hw * hw )
{
struct clk_omap_divider * divider = to_clk_omap_divider ( hw ) ;
u32 val ;
val = ti_clk_ll_ops - > clk_readl ( & divider - > reg ) > > divider - > shift ;
divider - > context = val & div_mask ( divider ) ;
return 0 ;
}
/**
* clk_divider_restore_context - restore the saved the divider value
* @ hw : pointer struct clk_hw
*
* Restore the saved the divider value
*/
static void clk_divider_restore_context ( struct clk_hw * hw )
{
struct clk_omap_divider * divider = to_clk_omap_divider ( hw ) ;
u32 val ;
val = ti_clk_ll_ops - > clk_readl ( & divider - > reg ) ;
val & = ~ ( div_mask ( divider ) < < divider - > shift ) ;
val | = divider - > context < < divider - > shift ;
ti_clk_ll_ops - > clk_writel ( val , & divider - > reg ) ;
}
2013-09-13 12:02:15 +03:00
const struct clk_ops ti_clk_divider_ops = {
. recalc_rate = ti_clk_divider_recalc_rate ,
. round_rate = ti_clk_divider_round_rate ,
. set_rate = ti_clk_divider_set_rate ,
2018-09-04 12:19:37 +05:30
. save_context = clk_divider_save_context ,
. restore_context = clk_divider_restore_context ,
2013-09-13 12:02:15 +03:00
} ;
static struct clk * _register_divider ( struct device * dev , const char * name ,
const char * parent_name ,
2017-02-09 11:24:37 +02:00
unsigned long flags ,
struct clk_omap_reg * reg ,
2018-02-15 09:49:27 +02:00
u8 shift , u8 width , s8 latch ,
u8 clk_divider_flags ,
2015-10-01 14:20:37 -05:00
const struct clk_div_table * table )
2013-09-13 12:02:15 +03:00
{
2017-02-09 14:45:45 +02:00
struct clk_omap_divider * div ;
2013-09-13 12:02:15 +03:00
struct clk * clk ;
struct clk_init_data init ;
if ( clk_divider_flags & CLK_DIVIDER_HIWORD_MASK ) {
if ( width + shift > 16 ) {
pr_warn ( " divider value exceeds LOWORD field \n " ) ;
return ERR_PTR ( - EINVAL ) ;
}
}
/* allocate the divider */
div = kzalloc ( sizeof ( * div ) , GFP_KERNEL ) ;
2017-09-27 19:14:01 +02:00
if ( ! div )
2013-09-13 12:02:15 +03:00
return ERR_PTR ( - ENOMEM ) ;
init . name = name ;
init . ops = & ti_clk_divider_ops ;
init . flags = flags | CLK_IS_BASIC ;
init . parent_names = ( parent_name ? & parent_name : NULL ) ;
init . num_parents = ( parent_name ? 1 : 0 ) ;
/* struct clk_divider assignments */
2017-02-09 11:24:37 +02:00
memcpy ( & div - > reg , reg , sizeof ( * reg ) ) ;
2013-09-13 12:02:15 +03:00
div - > shift = shift ;
div - > width = width ;
2018-02-15 09:49:27 +02:00
div - > latch = latch ;
2013-09-13 12:02:15 +03:00
div - > flags = clk_divider_flags ;
div - > hw . init = & init ;
div - > table = table ;
/* register the clock */
2016-09-29 12:06:40 +03:00
clk = ti_clk_register ( dev , & div - > hw , name ) ;
2013-09-13 12:02:15 +03:00
if ( IS_ERR ( clk ) )
kfree ( div ) ;
return clk ;
}
2017-02-09 14:46:53 +02:00
int ti_clk_parse_divider_data ( int * div_table , int num_dividers , int max_div ,
u8 flags , u8 * width ,
const struct clk_div_table * * table )
2014-12-16 18:20:50 +02:00
{
int valid_div = 0 ;
u32 val ;
2017-02-09 14:46:53 +02:00
int div ;
int i ;
struct clk_div_table * tmp ;
2014-12-16 18:20:50 +02:00
2017-02-09 14:46:53 +02:00
if ( ! div_table ) {
2014-12-16 18:20:50 +02:00
if ( flags & CLKF_INDEX_STARTS_AT_ONE )
val = 1 ;
else
val = 0 ;
div = 1 ;
2017-02-09 14:46:53 +02:00
while ( div < max_div ) {
2014-12-16 18:20:50 +02:00
if ( flags & CLKF_INDEX_POWER_OF_TWO )
div < < = 1 ;
else
div + + ;
val + + ;
}
* width = fls ( val ) ;
2017-02-09 14:46:53 +02:00
* table = NULL ;
2014-12-16 18:20:50 +02:00
2017-02-09 14:46:53 +02:00
return 0 ;
2014-12-16 18:20:50 +02:00
}
2017-02-09 14:46:53 +02:00
i = 0 ;
while ( ! num_dividers | | i < num_dividers ) {
if ( div_table [ i ] = = - 1 )
break ;
if ( div_table [ i ] )
2014-12-16 18:20:50 +02:00
valid_div + + ;
2017-02-09 14:46:53 +02:00
i + + ;
}
2014-12-16 18:20:50 +02:00
2017-02-09 14:46:53 +02:00
num_dividers = i ;
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(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.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- 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 E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- 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 THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 14:03:40 -07:00
tmp = kcalloc ( valid_div + 1 , sizeof ( * tmp ) , GFP_KERNEL ) ;
2017-02-09 14:46:53 +02:00
if ( ! tmp )
return - ENOMEM ;
2014-12-16 18:20:50 +02:00
valid_div = 0 ;
* width = 0 ;
2017-02-09 14:46:53 +02:00
for ( i = 0 ; i < num_dividers ; i + + )
if ( div_table [ i ] > 0 ) {
tmp [ valid_div ] . div = div_table [ i ] ;
tmp [ valid_div ] . val = i ;
2014-12-16 18:20:50 +02:00
valid_div + + ;
* width = i ;
}
* width = fls ( * width ) ;
2017-02-09 14:46:53 +02:00
* table = tmp ;
return 0 ;
}
static const struct clk_div_table *
_get_div_table_from_setup ( struct ti_clk_divider * setup , u8 * width )
{
const struct clk_div_table * table = NULL ;
ti_clk_parse_divider_data ( setup - > dividers , setup - > num_dividers ,
setup - > max_div , setup - > flags , width ,
& table ) ;
2014-12-16 18:20:50 +02:00
return table ;
}
struct clk_hw * ti_clk_build_component_div ( struct ti_clk_divider * setup )
{
2017-02-09 14:45:45 +02:00
struct clk_omap_divider * div ;
2014-12-16 18:20:50 +02:00
struct clk_omap_reg * reg ;
if ( ! setup )
return NULL ;
div = kzalloc ( sizeof ( * div ) , GFP_KERNEL ) ;
if ( ! div )
return ERR_PTR ( - ENOMEM ) ;
reg = ( struct clk_omap_reg * ) & div - > reg ;
reg - > index = setup - > module ;
reg - > offset = setup - > reg ;
if ( setup - > flags & CLKF_INDEX_STARTS_AT_ONE )
div - > flags | = CLK_DIVIDER_ONE_BASED ;
if ( setup - > flags & CLKF_INDEX_POWER_OF_TWO )
div - > flags | = CLK_DIVIDER_POWER_OF_TWO ;
div - > table = _get_div_table_from_setup ( setup , & div - > width ) ;
div - > shift = setup - > bit_shift ;
2018-02-15 09:49:27 +02:00
div - > latch = - EINVAL ;
2014-12-16 18:20:50 +02:00
return & div - > hw ;
}
struct clk * ti_clk_register_divider ( struct ti_clk * setup )
{
2017-04-19 19:44:55 +02:00
struct ti_clk_divider * div = setup - > data ;
struct clk_omap_reg reg = {
. index = div - > module ,
. offset = div - > reg ,
} ;
2014-12-16 18:20:50 +02:00
u8 width ;
u32 flags = 0 ;
u8 div_flags = 0 ;
2017-02-09 14:46:53 +02:00
const struct clk_div_table * table ;
2014-12-16 18:20:50 +02:00
struct clk * clk ;
if ( div - > flags & CLKF_INDEX_STARTS_AT_ONE )
div_flags | = CLK_DIVIDER_ONE_BASED ;
if ( div - > flags & CLKF_INDEX_POWER_OF_TWO )
div_flags | = CLK_DIVIDER_POWER_OF_TWO ;
if ( div - > flags & CLKF_SET_RATE_PARENT )
flags | = CLK_SET_RATE_PARENT ;
table = _get_div_table_from_setup ( div , & width ) ;
if ( IS_ERR ( table ) )
return ( struct clk * ) table ;
clk = _register_divider ( NULL , setup - > name , div - > parent ,
2017-04-19 19:44:55 +02:00
flags , & reg , div - > bit_shift ,
2018-02-15 09:49:27 +02:00
width , - EINVAL , div_flags , table ) ;
2014-12-16 18:20:50 +02:00
if ( IS_ERR ( clk ) )
kfree ( table ) ;
return clk ;
}
2014-09-26 17:31:48 -07:00
static struct clk_div_table *
__init ti_clk_get_div_table ( struct device_node * node )
2013-09-13 12:02:15 +03:00
{
struct clk_div_table * table ;
const __be32 * divspec ;
u32 val ;
u32 num_div ;
u32 valid_div ;
int i ;
divspec = of_get_property ( node , " ti,dividers " , & num_div ) ;
if ( ! divspec )
return NULL ;
num_div / = 4 ;
valid_div = 0 ;
/* Determine required size for divider table */
for ( i = 0 ; i < num_div ; i + + ) {
of_property_read_u32_index ( node , " ti,dividers " , i , & val ) ;
if ( val )
valid_div + + ;
}
if ( ! valid_div ) {
2018-08-28 10:44:29 -05:00
pr_err ( " no valid dividers for %pOFn table \n " , node ) ;
2013-09-13 12:02:15 +03:00
return ERR_PTR ( - EINVAL ) ;
}
treewide: kzalloc() -> kcalloc()
The kzalloc() function has a 2-factor argument form, kcalloc(). This
patch replaces cases of:
kzalloc(a * b, gfp)
with:
kcalloc(a * b, gfp)
as well as handling cases of:
kzalloc(a * b * c, gfp)
with:
kzalloc(array3_size(a, b, c), gfp)
as it's slightly less ugly than:
kzalloc_array(array_size(a, b), c, gfp)
This does, however, attempt to ignore constant size factors like:
kzalloc(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.
The Coccinelle script used for this was:
// Fix redundant parens around sizeof().
@@
type TYPE;
expression THING, E;
@@
(
kzalloc(
- (sizeof(TYPE)) * E
+ sizeof(TYPE) * E
, ...)
|
kzalloc(
- (sizeof(THING)) * E
+ sizeof(THING) * E
, ...)
)
// Drop single-byte sizes and redundant parens.
@@
expression COUNT;
typedef u8;
typedef __u8;
@@
(
kzalloc(
- sizeof(u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * (COUNT)
+ COUNT
, ...)
|
kzalloc(
- sizeof(u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(__u8) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(char) * COUNT
+ COUNT
, ...)
|
kzalloc(
- sizeof(unsigned char) * COUNT
+ COUNT
, ...)
)
// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@
(
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_ID)
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_ID
+ COUNT_ID, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (COUNT_CONST)
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * COUNT_CONST
+ COUNT_CONST, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_ID)
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_ID
+ COUNT_ID, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (COUNT_CONST)
+ COUNT_CONST, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * COUNT_CONST
+ COUNT_CONST, sizeof(THING)
, ...)
)
// 2-factor product, only identifiers.
@@
identifier SIZE, COUNT;
@@
- kzalloc
+ kcalloc
(
- SIZE * COUNT
+ COUNT, SIZE
, ...)
// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@
(
kzalloc(
- sizeof(TYPE) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(TYPE) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(TYPE))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * (COUNT) * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * (STRIDE)
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
|
kzalloc(
- sizeof(THING) * COUNT * STRIDE
+ array3_size(COUNT, STRIDE, sizeof(THING))
, ...)
)
// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@
(
kzalloc(
- sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(THING1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(THING1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * COUNT
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
|
kzalloc(
- sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+ array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
, ...)
)
// 3-factor product, only identifiers, with redundant parens removed.
@@
identifier STRIDE, SIZE, COUNT;
@@
(
kzalloc(
- (COUNT) * STRIDE * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * SIZE
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- COUNT * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * STRIDE * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- (COUNT) * (STRIDE) * (SIZE)
+ array3_size(COUNT, STRIDE, SIZE)
, ...)
|
kzalloc(
- 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 E1, E2, E3;
constant C1, C2, C3;
@@
(
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(
- (E1) * E2 * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * E3
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- (E1) * (E2) * (E3)
+ array3_size(E1, E2, E3)
, ...)
|
kzalloc(
- 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 THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@
(
kzalloc(sizeof(THING) * C2, ...)
|
kzalloc(sizeof(TYPE) * C2, ...)
|
kzalloc(C1 * C2 * C3, ...)
|
kzalloc(C1 * C2, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * (E2)
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(TYPE) * E2
+ E2, sizeof(TYPE)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * (E2)
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- sizeof(THING) * E2
+ E2, sizeof(THING)
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * E2
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- (E1) * (E2)
+ E1, E2
, ...)
|
- kzalloc
+ kcalloc
(
- E1 * E2
+ E1, E2
, ...)
)
Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 14:03:40 -07:00
table = kcalloc ( valid_div + 1 , sizeof ( * table ) , GFP_KERNEL ) ;
2013-09-13 12:02:15 +03:00
if ( ! table )
return ERR_PTR ( - ENOMEM ) ;
valid_div = 0 ;
for ( i = 0 ; i < num_div ; i + + ) {
of_property_read_u32_index ( node , " ti,dividers " , i , & val ) ;
if ( val ) {
table [ valid_div ] . div = val ;
table [ valid_div ] . val = i ;
valid_div + + ;
}
}
return table ;
}
static int _get_divider_width ( struct device_node * node ,
const struct clk_div_table * table ,
u8 flags )
{
u32 min_div ;
u32 max_div ;
u32 val = 0 ;
u32 div ;
if ( ! table ) {
/* Clk divider table not provided, determine min/max divs */
if ( of_property_read_u32 ( node , " ti,min-div " , & min_div ) )
min_div = 1 ;
if ( of_property_read_u32 ( node , " ti,max-div " , & max_div ) ) {
2018-08-28 10:44:29 -05:00
pr_err ( " no max-div for %pOFn! \n " , node ) ;
2013-09-13 12:02:15 +03:00
return - EINVAL ;
}
/* Determine bit width for the field */
if ( flags & CLK_DIVIDER_ONE_BASED )
val = 1 ;
div = min_div ;
while ( div < max_div ) {
if ( flags & CLK_DIVIDER_POWER_OF_TWO )
div < < = 1 ;
else
div + + ;
val + + ;
}
} else {
div = 0 ;
while ( table [ div ] . div ) {
val = table [ div ] . val ;
div + + ;
}
}
return fls ( val ) ;
}
static int __init ti_clk_divider_populate ( struct device_node * node ,
2017-02-09 11:24:37 +02:00
struct clk_omap_reg * reg , const struct clk_div_table * * table ,
2018-02-15 09:49:27 +02:00
u32 * flags , u8 * div_flags , u8 * width , u8 * shift , s8 * latch )
2013-09-13 12:02:15 +03:00
{
u32 val ;
2017-02-09 11:24:37 +02:00
int ret ;
2013-09-13 12:02:15 +03:00
2017-02-09 11:24:37 +02:00
ret = ti_clk_get_reg_addr ( node , 0 , reg ) ;
if ( ret )
return ret ;
2013-09-13 12:02:15 +03:00
if ( ! of_property_read_u32 ( node , " ti,bit-shift " , & val ) )
* shift = val ;
else
* shift = 0 ;
2018-02-15 09:49:27 +02:00
if ( latch ) {
if ( ! of_property_read_u32 ( node , " ti,latch-bit " , & val ) )
* latch = val ;
else
* latch = - EINVAL ;
}
2013-09-13 12:02:15 +03:00
* flags = 0 ;
* div_flags = 0 ;
if ( of_property_read_bool ( node , " ti,index-starts-at-one " ) )
* div_flags | = CLK_DIVIDER_ONE_BASED ;
if ( of_property_read_bool ( node , " ti,index-power-of-two " ) )
* div_flags | = CLK_DIVIDER_POWER_OF_TWO ;
if ( of_property_read_bool ( node , " ti,set-rate-parent " ) )
* flags | = CLK_SET_RATE_PARENT ;
* table = ti_clk_get_div_table ( node ) ;
if ( IS_ERR ( * table ) )
return PTR_ERR ( * table ) ;
* width = _get_divider_width ( node , * table , * div_flags ) ;
return 0 ;
}
/**
* of_ti_divider_clk_setup - Setup function for simple div rate clock
* @ node : device node for this clock
*
* Sets up a basic divider clock .
*/
static void __init of_ti_divider_clk_setup ( struct device_node * node )
{
struct clk * clk ;
const char * parent_name ;
2017-02-09 11:24:37 +02:00
struct clk_omap_reg reg ;
2013-09-13 12:02:15 +03:00
u8 clk_divider_flags = 0 ;
u8 width = 0 ;
u8 shift = 0 ;
2018-02-15 09:49:27 +02:00
s8 latch = - EINVAL ;
2013-09-13 12:02:15 +03:00
const struct clk_div_table * table = NULL ;
u32 flags = 0 ;
parent_name = of_clk_get_parent_name ( node , 0 ) ;
if ( ti_clk_divider_populate ( node , & reg , & table , & flags ,
2018-02-15 09:49:27 +02:00
& clk_divider_flags , & width , & shift , & latch ) )
2013-09-13 12:02:15 +03:00
goto cleanup ;
2017-02-09 11:24:37 +02:00
clk = _register_divider ( NULL , node - > name , parent_name , flags , & reg ,
2018-02-15 09:49:27 +02:00
shift , width , latch , clk_divider_flags , table ) ;
2013-09-13 12:02:15 +03:00
if ( ! IS_ERR ( clk ) ) {
of_clk_add_provider ( node , of_clk_src_simple_get , clk ) ;
of_ti_clk_autoidle_setup ( node ) ;
return ;
}
cleanup :
kfree ( table ) ;
}
CLK_OF_DECLARE ( divider_clk , " ti,divider-clock " , of_ti_divider_clk_setup ) ;
static void __init of_ti_composite_divider_clk_setup ( struct device_node * node )
{
2017-02-09 14:45:45 +02:00
struct clk_omap_divider * div ;
2013-09-13 12:02:15 +03:00
u32 val ;
div = kzalloc ( sizeof ( * div ) , GFP_KERNEL ) ;
if ( ! div )
return ;
if ( ti_clk_divider_populate ( node , & div - > reg , & div - > table , & val ,
2018-02-15 09:49:27 +02:00
& div - > flags , & div - > width , & div - > shift ,
NULL ) < 0 )
2013-09-13 12:02:15 +03:00
goto cleanup ;
if ( ! ti_clk_add_component ( node , & div - > hw , CLK_COMPONENT_TYPE_DIVIDER ) )
return ;
cleanup :
kfree ( div - > table ) ;
kfree ( div ) ;
}
CLK_OF_DECLARE ( ti_composite_divider_clk , " ti,composite-divider-clock " ,
of_ti_composite_divider_clk_setup ) ;