2022-06-07 17:11:32 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2013-06-12 17:04:34 +04:00
/*
* OMAP DPLL clock support
*
* Copyright ( C ) 2013 Texas Instruments , Inc .
*
* Tero Kristo < t - kristo @ ti . com >
*/
2015-06-20 01:00:46 +03:00
# include <linux/clk.h>
2013-06-12 17:04:34 +04:00
# 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>
2015-01-29 23:24:28 +03:00
# include "clock.h"
2013-06-12 17:04:34 +04:00
# undef pr_fmt
# define pr_fmt(fmt) "%s: " fmt, __func__
# if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined ( CONFIG_SOC_DRA7XX )
static const struct clk_ops dpll_m4xen_ck_ops = {
. enable = & omap3_noncore_dpll_enable ,
. disable = & omap3_noncore_dpll_disable ,
. recalc_rate = & omap4_dpll_regm4xen_recalc ,
. round_rate = & omap4_dpll_regm4xen_round_rate ,
. set_rate = & omap3_noncore_dpll_set_rate ,
2014-10-03 17:57:14 +04:00
. set_parent = & omap3_noncore_dpll_set_parent ,
. set_rate_and_parent = & omap3_noncore_dpll_set_rate_and_parent ,
. determine_rate = & omap4_dpll_regm4xen_determine_rate ,
2013-06-12 17:04:34 +04:00
. get_parent = & omap2_init_dpll_parent ,
2018-09-04 09:49:37 +03:00
. save_context = & omap3_core_dpll_save_context ,
. restore_context = & omap3_core_dpll_restore_context ,
2013-06-12 17:04:34 +04:00
} ;
2014-02-21 19:36:21 +04:00
# else
static const struct clk_ops dpll_m4xen_ck_ops = { } ;
2013-06-12 17:04:34 +04:00
# endif
2014-02-21 19:36:21 +04:00
# if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) || \
defined ( CONFIG_SOC_OMAP5 ) | | defined ( CONFIG_SOC_DRA7XX ) | | \
defined ( CONFIG_SOC_AM33XX ) | | defined ( CONFIG_SOC_AM43XX )
2013-06-12 17:04:34 +04:00
static const struct clk_ops dpll_core_ck_ops = {
. recalc_rate = & omap3_dpll_recalc ,
. get_parent = & omap2_init_dpll_parent ,
} ;
static const struct clk_ops dpll_ck_ops = {
. enable = & omap3_noncore_dpll_enable ,
. disable = & omap3_noncore_dpll_disable ,
. recalc_rate = & omap3_dpll_recalc ,
. round_rate = & omap2_dpll_round_rate ,
. set_rate = & omap3_noncore_dpll_set_rate ,
2014-10-03 17:57:14 +04:00
. set_parent = & omap3_noncore_dpll_set_parent ,
. set_rate_and_parent = & omap3_noncore_dpll_set_rate_and_parent ,
. determine_rate = & omap3_noncore_dpll_determine_rate ,
2013-06-12 17:04:34 +04:00
. get_parent = & omap2_init_dpll_parent ,
2018-09-04 09:49:37 +03:00
. save_context = & omap3_noncore_dpll_save_context ,
. restore_context = & omap3_noncore_dpll_restore_context ,
2013-06-12 17:04:34 +04:00
} ;
static const struct clk_ops dpll_no_gate_ck_ops = {
. recalc_rate = & omap3_dpll_recalc ,
. get_parent = & omap2_init_dpll_parent ,
. round_rate = & omap2_dpll_round_rate ,
. set_rate = & omap3_noncore_dpll_set_rate ,
2014-10-03 17:57:14 +04:00
. set_parent = & omap3_noncore_dpll_set_parent ,
. set_rate_and_parent = & omap3_noncore_dpll_set_rate_and_parent ,
. determine_rate = & omap3_noncore_dpll_determine_rate ,
2018-09-04 09:49:37 +03:00
. save_context = & omap3_noncore_dpll_save_context ,
. restore_context = & omap3_noncore_dpll_restore_context
2013-06-12 17:04:34 +04:00
} ;
2014-02-21 19:36:21 +04:00
# else
static const struct clk_ops dpll_core_ck_ops = { } ;
static const struct clk_ops dpll_ck_ops = { } ;
static const struct clk_ops dpll_no_gate_ck_ops = { } ;
const struct clk_hw_omap_ops clkhwops_omap3_dpll = { } ;
# endif
# ifdef CONFIG_ARCH_OMAP2
static const struct clk_ops omap2_dpll_core_ck_ops = {
. get_parent = & omap2_init_dpll_parent ,
. recalc_rate = & omap2_dpllcore_recalc ,
. round_rate = & omap2_dpll_round_rate ,
. set_rate = & omap2_reprogram_dpllcore ,
} ;
# else
static const struct clk_ops omap2_dpll_core_ck_ops = { } ;
# endif
# ifdef CONFIG_ARCH_OMAP3
static const struct clk_ops omap3_dpll_core_ck_ops = {
. get_parent = & omap2_init_dpll_parent ,
. recalc_rate = & omap3_dpll_recalc ,
. round_rate = & omap2_dpll_round_rate ,
} ;
# else
static const struct clk_ops omap3_dpll_core_ck_ops = { } ;
# endif
2013-06-12 17:04:34 +04:00
# ifdef CONFIG_ARCH_OMAP3
static const struct clk_ops omap3_dpll_ck_ops = {
. enable = & omap3_noncore_dpll_enable ,
. disable = & omap3_noncore_dpll_disable ,
. get_parent = & omap2_init_dpll_parent ,
. recalc_rate = & omap3_dpll_recalc ,
. set_rate = & omap3_noncore_dpll_set_rate ,
2014-10-03 17:57:14 +04:00
. set_parent = & omap3_noncore_dpll_set_parent ,
. set_rate_and_parent = & omap3_noncore_dpll_set_rate_and_parent ,
. determine_rate = & omap3_noncore_dpll_determine_rate ,
2013-06-12 17:04:34 +04:00
. round_rate = & omap2_dpll_round_rate ,
} ;
2016-12-03 00:14:38 +03:00
static const struct clk_ops omap3_dpll5_ck_ops = {
. enable = & omap3_noncore_dpll_enable ,
. disable = & omap3_noncore_dpll_disable ,
. get_parent = & omap2_init_dpll_parent ,
. recalc_rate = & omap3_dpll_recalc ,
. set_rate = & omap3_dpll5_set_rate ,
. set_parent = & omap3_noncore_dpll_set_parent ,
. set_rate_and_parent = & omap3_noncore_dpll_set_rate_and_parent ,
. determine_rate = & omap3_noncore_dpll_determine_rate ,
. round_rate = & omap2_dpll_round_rate ,
} ;
2013-06-12 17:04:34 +04:00
static const struct clk_ops omap3_dpll_per_ck_ops = {
. enable = & omap3_noncore_dpll_enable ,
. disable = & omap3_noncore_dpll_disable ,
. get_parent = & omap2_init_dpll_parent ,
. recalc_rate = & omap3_dpll_recalc ,
. set_rate = & omap3_dpll4_set_rate ,
2014-10-03 17:57:14 +04:00
. set_parent = & omap3_noncore_dpll_set_parent ,
. set_rate_and_parent = & omap3_dpll4_set_rate_and_parent ,
. determine_rate = & omap3_noncore_dpll_determine_rate ,
2013-06-12 17:04:34 +04:00
. round_rate = & omap2_dpll_round_rate ,
} ;
# endif
static const struct clk_ops dpll_x2_ck_ops = {
. recalc_rate = & omap3_clkoutx2_recalc ,
} ;
/**
2015-01-29 23:24:28 +03:00
* _register_dpll - low level registration of a DPLL clock
2021-01-20 12:30:35 +03:00
* @ user : pointer to the hardware clock definition for the clock
2013-06-12 17:04:34 +04:00
* @ node : device node for the clock
*
* Finalizes DPLL registration process . In case a failure ( clk - ref or
* clk - bypass is missing ) , the clock is added to retry list and
* the initialization is retried on later stage .
*/
2017-11-06 10:43:16 +03:00
static void __init _register_dpll ( void * user ,
2015-01-29 23:24:28 +03:00
struct device_node * node )
2013-06-12 17:04:34 +04:00
{
2017-11-06 10:43:16 +03:00
struct clk_hw * hw = user ;
2013-06-12 17:04:34 +04:00
struct clk_hw_omap * clk_hw = to_clk_hw_omap ( hw ) ;
struct dpll_data * dd = clk_hw - > dpll_data ;
2022-02-04 10:14:48 +03:00
const char * name ;
2013-06-12 17:04:34 +04:00
struct clk * clk ;
2019-08-16 01:12:49 +03:00
const struct clk_init_data * init = hw - > init ;
2013-06-12 17:04:34 +04:00
2016-02-20 14:24:26 +03:00
clk = of_clk_get ( node , 0 ) ;
if ( IS_ERR ( clk ) ) {
2018-08-28 18:44:29 +03:00
pr_debug ( " clk-ref missing for %pOFn, retry later \n " ,
node ) ;
2016-02-20 14:24:26 +03:00
if ( ! ti_clk_retry_init ( node , hw , _register_dpll ) )
return ;
2013-06-12 17:04:34 +04:00
2016-02-20 14:24:26 +03:00
goto cleanup ;
}
dd - > clk_ref = __clk_get_hw ( clk ) ;
clk = of_clk_get ( node , 1 ) ;
if ( IS_ERR ( clk ) ) {
2018-08-28 18:44:29 +03:00
pr_debug ( " clk-bypass missing for %pOFn, retry later \n " ,
node ) ;
2015-01-29 23:24:28 +03:00
if ( ! ti_clk_retry_init ( node , hw , _register_dpll ) )
2013-06-12 17:04:34 +04:00
return ;
goto cleanup ;
}
2016-02-20 14:24:26 +03:00
dd - > clk_bypass = __clk_get_hw ( clk ) ;
2013-06-12 17:04:34 +04:00
/* register the clock */
2022-02-04 10:14:48 +03:00
name = ti_dt_clk_name ( node ) ;
2022-11-13 21:11:46 +03:00
clk = of_ti_clk_register_omap_hw ( node , & clk_hw - > hw , name ) ;
2013-06-12 17:04:34 +04:00
if ( ! IS_ERR ( clk ) ) {
of_clk_add_provider ( node , of_clk_src_simple_get , clk ) ;
2019-08-16 01:12:49 +03:00
kfree ( init - > parent_names ) ;
kfree ( init ) ;
2013-06-12 17:04:34 +04:00
return ;
}
cleanup :
kfree ( clk_hw - > dpll_data ) ;
2019-08-16 01:12:49 +03:00
kfree ( init - > parent_names ) ;
kfree ( init ) ;
2013-06-12 17:04:34 +04:00
kfree ( clk_hw ) ;
}
# if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
2014-06-17 18:03:24 +04:00
defined ( CONFIG_SOC_DRA7XX ) | | defined ( CONFIG_SOC_AM33XX ) | | \
defined ( CONFIG_SOC_AM43XX )
2013-06-12 17:04:34 +04:00
/**
2015-01-29 23:24:28 +03:00
* _register_dpll_x2 - Registers a DPLLx2 clock
2013-06-12 17:04:34 +04:00
* @ node : device node for this clock
* @ ops : clk_ops for this clock
* @ hw_ops : clk_hw_ops for this clock
*
* Initializes a DPLL x 2 clock from device tree data .
*/
2015-01-29 23:24:28 +03:00
static void _register_dpll_x2 ( struct device_node * node ,
const struct clk_ops * ops ,
const struct clk_hw_omap_ops * hw_ops )
2013-06-12 17:04:34 +04:00
{
struct clk * clk ;
struct clk_init_data init = { NULL } ;
struct clk_hw_omap * clk_hw ;
2022-02-04 10:14:48 +03:00
const char * name = ti_dt_clk_name ( node ) ;
2013-06-12 17:04:34 +04:00
const char * parent_name ;
parent_name = of_clk_get_parent_name ( node , 0 ) ;
if ( ! parent_name ) {
2018-08-28 18:44:29 +03:00
pr_err ( " %pOFn must have parent \n " , node ) ;
2013-06-12 17:04:34 +04:00
return ;
}
clk_hw = kzalloc ( sizeof ( * clk_hw ) , GFP_KERNEL ) ;
if ( ! clk_hw )
return ;
clk_hw - > ops = hw_ops ;
clk_hw - > hw . init = & init ;
init . name = name ;
init . ops = ops ;
init . parent_names = & parent_name ;
init . num_parents = 1 ;
2017-04-20 00:43:10 +03:00
# if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined ( CONFIG_SOC_DRA7XX )
2017-02-09 12:25:28 +03:00
if ( hw_ops = = & clkhwops_omap4_dpllmx ) {
2017-04-20 00:43:10 +03:00
int ret ;
2017-02-09 12:25:28 +03:00
/* Check if register defined, if not, drop hw-ops */
ret = of_property_count_elems_of_size ( node , " reg " , 1 ) ;
if ( ret < = 0 ) {
2017-04-20 00:43:10 +03:00
clk_hw - > ops = NULL ;
2017-02-09 12:24:37 +03:00
} else if ( ti_clk_get_reg_addr ( node , 0 , & clk_hw - > clksel_reg ) ) {
kfree ( clk_hw ) ;
return ;
2017-02-09 12:25:28 +03:00
}
}
2017-04-20 00:43:10 +03:00
# endif
2017-02-09 12:25:28 +03:00
2013-06-12 17:04:34 +04:00
/* register the clock */
2022-11-13 21:11:46 +03:00
clk = of_ti_clk_register_omap_hw ( node , & clk_hw - > hw , name ) ;
2013-06-12 17:04:34 +04:00
2019-01-15 12:15:15 +03:00
if ( IS_ERR ( clk ) )
2013-06-12 17:04:34 +04:00
kfree ( clk_hw ) ;
2019-01-15 12:15:15 +03:00
else
2013-06-12 17:04:34 +04:00
of_clk_add_provider ( node , of_clk_src_simple_get , clk ) ;
}
# endif
/**
* of_ti_dpll_setup - Setup function for OMAP DPLL clocks
* @ node : device node containing the DPLL info
* @ ops : ops for the DPLL
* @ ddt : DPLL data template to use
*
* Initializes a DPLL clock from device tree data .
*/
static void __init of_ti_dpll_setup ( struct device_node * node ,
const struct clk_ops * ops ,
2014-02-21 19:22:32 +04:00
const struct dpll_data * ddt )
2013-06-12 17:04:34 +04:00
{
struct clk_hw_omap * clk_hw = NULL ;
struct clk_init_data * init = NULL ;
const char * * parent_names = NULL ;
struct dpll_data * dd = NULL ;
2021-06-06 23:22:53 +03:00
int ssc_clk_index ;
2013-06-12 17:04:34 +04:00
u8 dpll_mode = 0 ;
2021-06-06 23:22:53 +03:00
u32 min_div ;
2013-06-12 17:04:34 +04:00
2019-07-03 19:27:00 +03:00
dd = kmemdup ( ddt , sizeof ( * dd ) , GFP_KERNEL ) ;
2013-06-12 17:04:34 +04:00
clk_hw = kzalloc ( sizeof ( * clk_hw ) , GFP_KERNEL ) ;
init = kzalloc ( sizeof ( * init ) , GFP_KERNEL ) ;
if ( ! dd | | ! clk_hw | | ! init )
goto cleanup ;
clk_hw - > dpll_data = dd ;
clk_hw - > ops = & clkhwops_omap3_dpll ;
clk_hw - > hw . init = init ;
2022-02-04 10:14:48 +03:00
init - > name = ti_dt_clk_name ( node ) ;
2013-06-12 17:04:34 +04:00
init - > ops = ops ;
init - > num_parents = of_clk_get_parent_count ( node ) ;
2016-02-20 04:49:23 +03:00
if ( ! init - > num_parents ) {
2018-08-28 18:44:29 +03:00
pr_err ( " %pOFn must have parent(s) \n " , node ) ;
2013-06-12 17:04:34 +04:00
goto cleanup ;
}
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-13 00:03:40 +03:00
parent_names = kcalloc ( init - > num_parents , sizeof ( char * ) , GFP_KERNEL ) ;
2013-06-12 17:04:34 +04:00
if ( ! parent_names )
goto cleanup ;
2015-07-07 06:59:06 +03:00
of_clk_parent_fill ( node , parent_names , init - > num_parents ) ;
2013-06-12 17:04:34 +04:00
init - > parent_names = parent_names ;
2017-02-09 12:24:37 +03:00
if ( ti_clk_get_reg_addr ( node , 0 , & dd - > control_reg ) )
goto cleanup ;
2013-06-12 17:04:34 +04:00
2014-02-21 19:36:21 +04:00
/*
* Special case for OMAP2 DPLL , register order is different due to
* missing idlest_reg , also clkhwops is different . Detected from
* missing idlest_mask .
*/
if ( ! dd - > idlest_mask ) {
2017-02-09 12:24:37 +03:00
if ( ti_clk_get_reg_addr ( node , 1 , & dd - > mult_div1_reg ) )
goto cleanup ;
2014-02-21 19:36:21 +04:00
# ifdef CONFIG_ARCH_OMAP2
clk_hw - > ops = & clkhwops_omap2xxx_dpll ;
omap2xxx_clkt_dpllcore_init ( & clk_hw - > hw ) ;
# endif
} else {
2017-02-09 12:24:37 +03:00
if ( ti_clk_get_reg_addr ( node , 1 , & dd - > idlest_reg ) )
2014-02-21 19:36:21 +04:00
goto cleanup ;
2017-02-09 12:24:37 +03:00
if ( ti_clk_get_reg_addr ( node , 2 , & dd - > mult_div1_reg ) )
goto cleanup ;
2014-02-21 19:36:21 +04:00
}
2014-02-21 19:22:32 +04:00
if ( dd - > autoidle_mask ) {
2017-02-09 12:24:37 +03:00
if ( ti_clk_get_reg_addr ( node , 3 , & dd - > autoidle_reg ) )
2013-06-12 17:04:34 +04:00
goto cleanup ;
2021-06-06 23:22:53 +03:00
ssc_clk_index = 4 ;
} else {
ssc_clk_index = 3 ;
}
if ( dd - > ssc_deltam_int_mask & & dd - > ssc_deltam_frac_mask & &
dd - > ssc_modfreq_mant_mask & & dd - > ssc_modfreq_exp_mask ) {
if ( ti_clk_get_reg_addr ( node , ssc_clk_index + + ,
& dd - > ssc_deltam_reg ) )
goto cleanup ;
if ( ti_clk_get_reg_addr ( node , ssc_clk_index + + ,
& dd - > ssc_modfreq_reg ) )
goto cleanup ;
of_property_read_u32 ( node , " ti,ssc-modfreq-hz " ,
& dd - > ssc_modfreq ) ;
of_property_read_u32 ( node , " ti,ssc-deltam " , & dd - > ssc_deltam ) ;
dd - > ssc_downspread =
of_property_read_bool ( node , " ti,ssc-downspread " ) ;
2013-06-12 17:04:34 +04:00
}
if ( of_property_read_bool ( node , " ti,low-power-stop " ) )
dpll_mode | = 1 < < DPLL_LOW_POWER_STOP ;
if ( of_property_read_bool ( node , " ti,low-power-bypass " ) )
dpll_mode | = 1 < < DPLL_LOW_POWER_BYPASS ;
if ( of_property_read_bool ( node , " ti,lock " ) )
dpll_mode | = 1 < < DPLL_LOCKED ;
2021-06-06 23:22:53 +03:00
if ( ! of_property_read_u32 ( node , " ti,min-div " , & min_div ) & &
min_div > dd - > min_divider )
dd - > min_divider = min_div ;
2013-06-12 17:04:34 +04:00
if ( dpll_mode )
dd - > modes = dpll_mode ;
2015-01-29 23:24:28 +03:00
_register_dpll ( & clk_hw - > hw , node ) ;
2013-06-12 17:04:34 +04:00
return ;
cleanup :
kfree ( dd ) ;
kfree ( parent_names ) ;
kfree ( init ) ;
kfree ( clk_hw ) ;
}
# if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined ( CONFIG_SOC_DRA7XX )
static void __init of_ti_omap4_dpll_x2_setup ( struct device_node * node )
{
2015-01-29 23:24:28 +03:00
_register_dpll_x2 ( node , & dpll_x2_ck_ops , & clkhwops_omap4_dpllmx ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap4_dpll_x2_clock , " ti,omap4-dpll-x2-clock " ,
of_ti_omap4_dpll_x2_setup ) ;
# endif
2014-06-17 18:03:24 +04:00
# if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
2013-06-12 17:04:34 +04:00
static void __init of_ti_am3_dpll_x2_setup ( struct device_node * node )
{
2015-01-29 23:24:28 +03:00
_register_dpll_x2 ( node , & dpll_x2_ck_ops , NULL ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_am3_dpll_x2_clock , " ti,am3-dpll-x2-clock " ,
of_ti_am3_dpll_x2_setup ) ;
# endif
# ifdef CONFIG_ARCH_OMAP3
static void __init of_ti_omap3_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
. freqsel_mask = 0xf0 ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2016-12-03 00:14:38 +03:00
if ( ( of_machine_is_compatible ( " ti,omap3630 " ) | |
of_machine_is_compatible ( " ti,omap36xx " ) ) & &
2018-12-05 22:50:21 +03:00
of_node_name_eq ( node , " dpll5_ck " ) )
2016-12-03 00:14:38 +03:00
of_ti_dpll_setup ( node , & omap3_dpll5_ck_ops , & dd ) ;
else
of_ti_dpll_setup ( node , & omap3_dpll_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap3_dpll_clock , " ti,omap3-dpll-clock " ,
of_ti_omap3_dpll_setup ) ;
static void __init of_ti_omap3_core_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0x7ff < < 16 ,
. div1_mask = 0x7f < < 8 ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
. freqsel_mask = 0xf0 ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & omap3_dpll_core_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap3_core_dpll_clock , " ti,omap3-dpll-core-clock " ,
of_ti_omap3_core_dpll_setup ) ;
static void __init of_ti_omap3_per_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 < < 1 ,
. enable_mask = 0x7 < < 16 ,
. autoidle_mask = 0x7 < < 3 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
. freqsel_mask = 0xf00000 ,
. modes = ( 1 < < DPLL_LOW_POWER_STOP ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & omap3_dpll_per_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap3_per_dpll_clock , " ti,omap3-dpll-per-clock " ,
of_ti_omap3_per_dpll_setup ) ;
static void __init of_ti_omap3_per_jtype_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 < < 1 ,
. enable_mask = 0x7 < < 16 ,
. autoidle_mask = 0x7 < < 3 ,
. mult_mask = 0xfff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 4095 ,
. max_divider = 128 ,
. min_divider = 1 ,
. sddiv_mask = 0xff < < 24 ,
. dco_mask = 0xe < < 20 ,
. flags = DPLL_J_TYPE ,
. modes = ( 1 < < DPLL_LOW_POWER_STOP ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & omap3_dpll_per_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap3_per_jtype_dpll_clock , " ti,omap3-dpll-per-j-type-clock " ,
of_ti_omap3_per_jtype_dpll_setup ) ;
# endif
static void __init of_ti_omap4_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap4_dpll_clock , " ti,omap4-dpll-clock " ,
of_ti_omap4_dpll_setup ) ;
2014-05-16 14:45:59 +04:00
static void __init of_ti_omap5_mpu_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. dcc_mask = BIT ( 22 ) ,
. dcc_rate = 1400000000 , /* DCC beyond 1.4GHz */
. min_divider = 1 ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
of_ti_dpll_setup ( node , & dpll_ck_ops , & dd ) ;
}
CLK_OF_DECLARE ( of_ti_omap5_mpu_dpll_clock , " ti,omap5-mpu-dpll-clock " ,
of_ti_omap5_mpu_dpll_setup ) ;
2013-06-12 17:04:34 +04:00
static void __init of_ti_omap4_core_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_core_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap4_core_dpll_clock , " ti,omap4-dpll-core-clock " ,
of_ti_omap4_core_dpll_setup ) ;
# if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined ( CONFIG_SOC_DRA7XX )
static void __init of_ti_omap4_m4xen_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
. m4xen_mask = 0x800 ,
. lpmode_mask = 1 < < 10 ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_m4xen_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap4_m4xen_dpll_clock , " ti,omap4-dpll-m4xen-clock " ,
of_ti_omap4_m4xen_dpll_setup ) ;
static void __init of_ti_omap4_jtype_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. autoidle_mask = 0x7 ,
. mult_mask = 0xfff < < 8 ,
. div1_mask = 0xff ,
. max_multiplier = 4095 ,
. max_divider = 256 ,
. min_divider = 1 ,
. sddiv_mask = 0xff < < 24 ,
. flags = DPLL_J_TYPE ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_m4xen_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_omap4_jtype_dpll_clock , " ti,omap4-dpll-j-type-clock " ,
of_ti_omap4_jtype_dpll_setup ) ;
# endif
static void __init of_ti_am3_no_gate_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
2021-06-06 23:22:53 +03:00
. ssc_enable_mask = 0x1 < < 12 ,
. ssc_downspread_mask = 0x1 < < 14 ,
2013-06-12 17:04:34 +04:00
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
2021-06-06 23:22:53 +03:00
. ssc_deltam_int_mask = 0x3 < < 18 ,
. ssc_deltam_frac_mask = 0x3ffff ,
. ssc_modfreq_mant_mask = 0x7f ,
. ssc_modfreq_exp_mask = 0x7 < < 8 ,
2013-06-12 17:04:34 +04:00
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
2016-03-16 22:54:56 +03:00
. max_rate = 1000000000 ,
2013-06-12 17:04:34 +04:00
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_no_gate_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_am3_no_gate_dpll_clock , " ti,am3-dpll-no-gate-clock " ,
of_ti_am3_no_gate_dpll_setup ) ;
static void __init of_ti_am3_jtype_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 4095 ,
. max_divider = 256 ,
. min_divider = 2 ,
. flags = DPLL_J_TYPE ,
2016-03-16 22:54:56 +03:00
. max_rate = 2000000000 ,
2013-06-12 17:04:34 +04:00
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_am3_jtype_dpll_clock , " ti,am3-dpll-j-type-clock " ,
of_ti_am3_jtype_dpll_setup ) ;
static void __init of_ti_am3_no_gate_jtype_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
2016-03-16 22:54:56 +03:00
. max_rate = 2000000000 ,
2013-06-12 17:04:34 +04:00
. flags = DPLL_J_TYPE ,
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_no_gate_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_am3_no_gate_jtype_dpll_clock ,
" ti,am3-dpll-no-gate-j-type-clock " ,
of_ti_am3_no_gate_jtype_dpll_setup ) ;
static void __init of_ti_am3_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
2021-06-06 23:22:53 +03:00
. ssc_enable_mask = 0x1 < < 12 ,
. ssc_downspread_mask = 0x1 < < 14 ,
2013-06-12 17:04:34 +04:00
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
2021-06-06 23:22:53 +03:00
. ssc_deltam_int_mask = 0x3 < < 18 ,
. ssc_deltam_frac_mask = 0x3ffff ,
. ssc_modfreq_mant_mask = 0x7f ,
. ssc_modfreq_exp_mask = 0x7 < < 8 ,
2013-06-12 17:04:34 +04:00
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
2016-03-16 22:54:56 +03:00
. max_rate = 1000000000 ,
2013-06-12 17:04:34 +04:00
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_am3_dpll_clock , " ti,am3-dpll-clock " , of_ti_am3_dpll_setup ) ;
static void __init of_ti_am3_core_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. idlest_mask = 0x1 ,
. enable_mask = 0x7 ,
. mult_mask = 0x7ff < < 8 ,
. div1_mask = 0x7f ,
. max_multiplier = 2047 ,
. max_divider = 128 ,
. min_divider = 1 ,
2016-03-16 22:54:56 +03:00
. max_rate = 1000000000 ,
2013-06-12 17:04:34 +04:00
. modes = ( 1 < < DPLL_LOW_POWER_BYPASS ) | ( 1 < < DPLL_LOCKED ) ,
} ;
2014-02-21 19:22:32 +04:00
of_ti_dpll_setup ( node , & dpll_core_ck_ops , & dd ) ;
2013-06-12 17:04:34 +04:00
}
CLK_OF_DECLARE ( ti_am3_core_dpll_clock , " ti,am3-dpll-core-clock " ,
of_ti_am3_core_dpll_setup ) ;
2014-02-21 19:36:21 +04:00
static void __init of_ti_omap2_core_dpll_setup ( struct device_node * node )
{
const struct dpll_data dd = {
. enable_mask = 0x3 ,
. mult_mask = 0x3ff < < 12 ,
. div1_mask = 0xf < < 8 ,
. max_divider = 16 ,
. min_divider = 1 ,
} ;
of_ti_dpll_setup ( node , & omap2_dpll_core_ck_ops , & dd ) ;
}
CLK_OF_DECLARE ( ti_omap2_core_dpll_clock , " ti,omap2-dpll-core-clock " ,
of_ti_omap2_core_dpll_setup ) ;