2019-05-28 10:10:04 -07:00
// SPDX-License-Identifier: GPL-2.0-only
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
/*
* Copyright ( c ) 2012 , NVIDIA CORPORATION . All rights reserved .
*/
2015-06-19 15:00:46 -07:00
# include <linux/clkdev.h>
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# include <linux/clk.h>
# include <linux/clk-provider.h>
2017-03-02 16:16:16 +02:00
# include <linux/delay.h>
2019-04-18 15:20:22 -07:00
# include <linux/io.h>
2013-01-11 13:16:26 +05:30
# include <linux/of.h>
2021-12-01 02:23:12 +03:00
# include <linux/of_device.h>
2013-01-11 13:16:26 +05:30
# include <linux/clk/tegra.h>
2021-12-01 02:23:12 +03:00
# include <linux/platform_device.h>
# include <linux/pm_runtime.h>
2013-11-05 17:33:17 -07:00
# include <linux/reset-controller.h>
2021-12-01 02:23:12 +03:00
# include <linux/string.h>
2014-07-17 13:17:24 +02:00
# include <soc/tegra/fuse.h>
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
# include "clk.h"
2013-01-11 13:16:26 +05:30
/* Global data of Tegra CPU CAR ops */
2021-12-01 02:23:12 +03:00
static struct device_node * tegra_car_np ;
2013-04-03 17:40:35 +03:00
static struct tegra_cpu_car_ops dummy_car_ops ;
struct tegra_cpu_car_ops * tegra_cpu_car_ops = & dummy_car_ops ;
2013-01-11 13:16:26 +05:30
2013-09-02 15:22:02 +03:00
int * periph_clk_enb_refcnt ;
2013-08-22 18:44:06 +03:00
static int periph_banks ;
2019-08-16 12:42:00 -07:00
static u32 * periph_state_ctx ;
2013-09-02 15:22:02 +03:00
static struct clk * * clks ;
static int clk_num ;
static struct clk_onecell_data clk_data ;
2013-08-22 18:44:06 +03:00
2015-05-20 09:27:05 +03:00
/* Handlers for SoC-specific reset lines */
static int ( * special_reset_assert ) ( unsigned long ) ;
static int ( * special_reset_deassert ) ( unsigned long ) ;
static unsigned int num_special_reset ;
2015-04-20 14:38:39 +02:00
static const struct tegra_clk_periph_regs periph_regs [ ] = {
2013-08-22 18:44:06 +03:00
[ 0 ] = {
. enb_reg = CLK_OUT_ENB_L ,
. enb_set_reg = CLK_OUT_ENB_SET_L ,
. enb_clr_reg = CLK_OUT_ENB_CLR_L ,
. rst_reg = RST_DEVICES_L ,
. rst_set_reg = RST_DEVICES_SET_L ,
. rst_clr_reg = RST_DEVICES_CLR_L ,
} ,
[ 1 ] = {
. enb_reg = CLK_OUT_ENB_H ,
. enb_set_reg = CLK_OUT_ENB_SET_H ,
. enb_clr_reg = CLK_OUT_ENB_CLR_H ,
. rst_reg = RST_DEVICES_H ,
. rst_set_reg = RST_DEVICES_SET_H ,
. rst_clr_reg = RST_DEVICES_CLR_H ,
} ,
[ 2 ] = {
. enb_reg = CLK_OUT_ENB_U ,
. enb_set_reg = CLK_OUT_ENB_SET_U ,
. enb_clr_reg = CLK_OUT_ENB_CLR_U ,
. rst_reg = RST_DEVICES_U ,
. rst_set_reg = RST_DEVICES_SET_U ,
. rst_clr_reg = RST_DEVICES_CLR_U ,
} ,
[ 3 ] = {
. enb_reg = CLK_OUT_ENB_V ,
. enb_set_reg = CLK_OUT_ENB_SET_V ,
. enb_clr_reg = CLK_OUT_ENB_CLR_V ,
. rst_reg = RST_DEVICES_V ,
. rst_set_reg = RST_DEVICES_SET_V ,
. rst_clr_reg = RST_DEVICES_CLR_V ,
} ,
[ 4 ] = {
. enb_reg = CLK_OUT_ENB_W ,
. enb_set_reg = CLK_OUT_ENB_SET_W ,
. enb_clr_reg = CLK_OUT_ENB_CLR_W ,
. rst_reg = RST_DEVICES_W ,
. rst_set_reg = RST_DEVICES_SET_W ,
. rst_clr_reg = RST_DEVICES_CLR_W ,
} ,
2013-09-11 17:57:37 +03:00
[ 5 ] = {
. enb_reg = CLK_OUT_ENB_X ,
. enb_set_reg = CLK_OUT_ENB_SET_X ,
. enb_clr_reg = CLK_OUT_ENB_CLR_X ,
. rst_reg = RST_DEVICES_X ,
. rst_set_reg = RST_DEVICES_SET_X ,
. rst_clr_reg = RST_DEVICES_CLR_X ,
} ,
2015-03-23 10:52:45 +01:00
[ 6 ] = {
. enb_reg = CLK_OUT_ENB_Y ,
. enb_set_reg = CLK_OUT_ENB_SET_Y ,
. enb_clr_reg = CLK_OUT_ENB_CLR_Y ,
. rst_reg = RST_DEVICES_Y ,
. rst_set_reg = RST_DEVICES_SET_Y ,
. rst_clr_reg = RST_DEVICES_CLR_Y ,
} ,
2013-08-22 18:44:06 +03:00
} ;
2013-11-05 17:33:17 -07:00
static void __iomem * clk_base ;
static int tegra_clk_rst_assert ( struct reset_controller_dev * rcdev ,
unsigned long id )
{
/*
* If peripheral is on the APB bus then we must read the APB bus to
* flush the write operation in apb bus . This will avoid peripheral
* access after disabling clock . Since the reset driver has no
* knowledge of which reset IDs represent which devices , simply do
* this all the time .
*/
tegra_read_chipid ( ) ;
2015-05-20 09:27:05 +03:00
if ( id < periph_banks * 32 ) {
writel_relaxed ( BIT ( id % 32 ) ,
clk_base + periph_regs [ id / 32 ] . rst_set_reg ) ;
return 0 ;
} else if ( id < periph_banks * 32 + num_special_reset ) {
return special_reset_assert ( id ) ;
}
2013-11-05 17:33:17 -07:00
2015-05-20 09:27:05 +03:00
return - EINVAL ;
2013-11-05 17:33:17 -07:00
}
static int tegra_clk_rst_deassert ( struct reset_controller_dev * rcdev ,
unsigned long id )
{
2015-05-20 09:27:05 +03:00
if ( id < periph_banks * 32 ) {
writel_relaxed ( BIT ( id % 32 ) ,
clk_base + periph_regs [ id / 32 ] . rst_clr_reg ) ;
return 0 ;
} else if ( id < periph_banks * 32 + num_special_reset ) {
return special_reset_deassert ( id ) ;
}
2013-11-05 17:33:17 -07:00
2015-05-20 09:27:05 +03:00
return - EINVAL ;
2013-11-05 17:33:17 -07:00
}
2017-03-02 16:16:16 +02:00
static int tegra_clk_rst_reset ( struct reset_controller_dev * rcdev ,
unsigned long id )
{
int err ;
err = tegra_clk_rst_assert ( rcdev , id ) ;
if ( err )
return err ;
udelay ( 1 ) ;
return tegra_clk_rst_deassert ( rcdev , id ) ;
}
2015-04-20 14:38:39 +02:00
const struct tegra_clk_periph_regs * get_reg_bank ( int clkid )
2013-08-22 18:44:06 +03:00
{
int reg_bank = clkid / 32 ;
if ( reg_bank < periph_banks )
return & periph_regs [ reg_bank ] ;
else {
WARN_ON ( 1 ) ;
return NULL ;
}
}
2019-08-16 12:41:54 -07:00
void tegra_clk_set_pllp_out_cpu ( bool enable )
{
u32 val ;
val = readl_relaxed ( clk_base + CLK_OUT_ENB_Y ) ;
if ( enable )
val | = CLK_ENB_PLLP_OUT_CPU ;
else
val & = ~ CLK_ENB_PLLP_OUT_CPU ;
writel_relaxed ( val , clk_base + CLK_OUT_ENB_Y ) ;
}
2019-08-16 12:42:00 -07:00
void tegra_clk_periph_suspend ( void )
{
unsigned int i , idx ;
idx = 0 ;
for ( i = 0 ; i < periph_banks ; i + + , idx + + )
periph_state_ctx [ idx ] =
readl_relaxed ( clk_base + periph_regs [ i ] . enb_reg ) ;
for ( i = 0 ; i < periph_banks ; i + + , idx + + )
periph_state_ctx [ idx ] =
readl_relaxed ( clk_base + periph_regs [ i ] . rst_reg ) ;
}
void tegra_clk_periph_resume ( void )
{
unsigned int i , idx ;
idx = 0 ;
for ( i = 0 ; i < periph_banks ; i + + , idx + + )
writel_relaxed ( periph_state_ctx [ idx ] ,
clk_base + periph_regs [ i ] . enb_reg ) ;
/*
* All non - boot peripherals will be in reset state on resume .
* Wait for 5u s of reset propagation delay before de - asserting
* the peripherals based on the saved context .
*/
fence_udelay ( 5 , clk_base ) ;
for ( i = 0 ; i < periph_banks ; i + + , idx + + )
writel_relaxed ( periph_state_ctx [ idx ] ,
clk_base + periph_regs [ i ] . rst_reg ) ;
fence_udelay ( 2 , clk_base ) ;
}
static int tegra_clk_periph_ctx_init ( int banks )
{
periph_state_ctx = kcalloc ( 2 * banks , sizeof ( * periph_state_ctx ) ,
GFP_KERNEL ) ;
if ( ! periph_state_ctx )
return - ENOMEM ;
return 0 ;
}
2013-11-05 17:33:17 -07:00
struct clk * * __init tegra_clk_init ( void __iomem * regs , int num , int banks )
2013-08-22 18:44:06 +03:00
{
2013-11-05 17:33:17 -07:00
clk_base = regs ;
2013-09-02 15:22:02 +03:00
if ( WARN_ON ( banks > ARRAY_SIZE ( periph_regs ) ) )
return NULL ;
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
periph_clk_enb_refcnt = kcalloc ( 32 * banks ,
sizeof ( * periph_clk_enb_refcnt ) ,
GFP_KERNEL ) ;
2013-09-02 15:22:02 +03:00
if ( ! periph_clk_enb_refcnt )
return NULL ;
2013-08-22 18:44:06 +03:00
2013-09-02 15:22:02 +03:00
periph_banks = banks ;
2013-08-22 18:44:06 +03:00
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
clks = kcalloc ( num , sizeof ( struct clk * ) , GFP_KERNEL ) ;
2019-12-10 05:05:12 +03:00
if ( ! clks ) {
2013-09-02 15:22:02 +03:00
kfree ( periph_clk_enb_refcnt ) ;
2019-12-10 05:05:12 +03:00
return NULL ;
}
2013-09-02 15:22:02 +03:00
clk_num = num ;
2019-08-16 12:42:00 -07:00
if ( IS_ENABLED ( CONFIG_PM_SLEEP ) ) {
if ( tegra_clk_periph_ctx_init ( banks ) ) {
kfree ( periph_clk_enb_refcnt ) ;
kfree ( clks ) ;
return NULL ;
}
}
2013-09-02 15:22:02 +03:00
return clks ;
2013-08-22 18:44:06 +03:00
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
void __init tegra_init_dup_clks ( struct tegra_clk_duplicate * dup_list ,
struct clk * clks [ ] , int clk_max )
{
struct clk * clk ;
for ( ; dup_list - > clk_id < clk_max ; dup_list + + ) {
clk = clks [ dup_list - > clk_id ] ;
dup_list - > lookup . clk = clk ;
clkdev_add ( & dup_list - > lookup ) ;
}
}
2021-12-01 02:23:12 +03:00
void tegra_init_from_table ( struct tegra_clk_init_table * tbl ,
struct clk * clks [ ] , int clk_max )
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
{
struct clk * clk ;
for ( ; tbl - > clk_id < clk_max ; tbl + + ) {
clk = clks [ tbl - > clk_id ] ;
2014-09-17 11:34:17 +02:00
if ( IS_ERR_OR_NULL ( clk ) ) {
pr_err ( " %s: invalid entry %ld in clks array for id %d \n " ,
__func__ , PTR_ERR ( clk ) , tbl - > clk_id ) ;
WARN_ON ( 1 ) ;
continue ;
}
clk: tegra: add Tegra specific clocks
Add Tegra specific clocks, pll, pll_out, peripheral, frac_divider, super.
Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com>
[swarren: alloc sizeof(*foo) not sizeof(struct foo), add comments re:
storing pointers to stack variables, make a timeout loop more idiomatic,
use _clk_pll_disable() not clk_disable_pll() from _program_pll() to
avoid redundant lock operations, unified tegra_clk_periph() and
tegra_clk_periph_nodiv(), unified tegra_clk_pll{,e}, rename all clock
registration functions so they don't have the same name as the clock
structs, return -EINVAL from clk_plle_enable when matching table rate
not found, pass ops to _tegra_clk_register_pll rather than a bool.]
Acked-by: Mike Turquette <mturquette@linaro.org>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
2013-01-11 13:16:20 +05:30
if ( tbl - > parent_id < clk_max ) {
struct clk * parent = clks [ tbl - > parent_id ] ;
if ( clk_set_parent ( clk , parent ) ) {
pr_err ( " %s: Failed to set parent %s of %s \n " ,
__func__ , __clk_get_name ( parent ) ,
__clk_get_name ( clk ) ) ;
WARN_ON ( 1 ) ;
}
}
if ( tbl - > rate )
if ( clk_set_rate ( clk , tbl - > rate ) ) {
pr_err ( " %s: Failed to set rate %lu of %s \n " ,
__func__ , tbl - > rate ,
__clk_get_name ( clk ) ) ;
WARN_ON ( 1 ) ;
}
if ( tbl - > state )
if ( clk_prepare_enable ( clk ) ) {
pr_err ( " %s: Failed to enable %s \n " , __func__ ,
__clk_get_name ( clk ) ) ;
WARN_ON ( 1 ) ;
}
}
}
2013-01-11 13:16:26 +05:30
2016-02-25 10:45:11 +01:00
static const struct reset_control_ops rst_ops = {
2013-11-05 17:33:17 -07:00
. assert = tegra_clk_rst_assert ,
. deassert = tegra_clk_rst_deassert ,
2017-03-02 16:16:16 +02:00
. reset = tegra_clk_rst_reset ,
2013-11-05 17:33:17 -07:00
} ;
static struct reset_controller_dev rst_ctlr = {
. ops = & rst_ops ,
. owner = THIS_MODULE ,
. of_reset_n_cells = 1 ,
} ;
2018-05-08 19:26:06 +03:00
void __init tegra_add_of_provider ( struct device_node * np ,
void * clk_src_onecell_get )
2013-09-02 15:22:02 +03:00
{
int i ;
2021-12-01 02:23:12 +03:00
tegra_car_np = np ;
2013-09-02 15:22:02 +03:00
for ( i = 0 ; i < clk_num ; i + + ) {
if ( IS_ERR ( clks [ i ] ) ) {
pr_err
( " Tegra clk %d: register failed with %ld \n " ,
i , PTR_ERR ( clks [ i ] ) ) ;
}
if ( ! clks [ i ] )
clks [ i ] = ERR_PTR ( - EINVAL ) ;
}
clk_data . clks = clks ;
clk_data . clk_num = clk_num ;
2018-05-08 19:26:06 +03:00
of_clk_add_provider ( np , clk_src_onecell_get , & clk_data ) ;
2013-11-05 17:33:17 -07:00
rst_ctlr . of_node = np ;
2015-05-20 09:27:05 +03:00
rst_ctlr . nr_resets = periph_banks * 32 + num_special_reset ;
2013-11-05 17:33:17 -07:00
reset_controller_register ( & rst_ctlr ) ;
2013-09-02 15:22:02 +03:00
}
2015-05-20 09:27:05 +03:00
void __init tegra_init_special_resets ( unsigned int num ,
int ( * assert ) ( unsigned long ) ,
int ( * deassert ) ( unsigned long ) )
{
num_special_reset = num ;
special_reset_assert = assert ;
special_reset_deassert = deassert ;
}
2021-12-01 02:23:12 +03:00
void tegra_register_devclks ( struct tegra_devclk * dev_clks , int num )
2013-10-09 14:47:57 +03:00
{
int i ;
for ( i = 0 ; i < num ; i + + , dev_clks + + )
clk_register_clkdev ( clks [ dev_clks - > dt_id ] , dev_clks - > con_id ,
dev_clks - > dev_id ) ;
2014-06-26 18:36:13 +03:00
for ( i = 0 ; i < clk_num ; i + + ) {
if ( ! IS_ERR_OR_NULL ( clks [ i ] ) )
clk_register_clkdev ( clks [ i ] , __clk_get_name ( clks [ i ] ) ,
" tegra-clk-debug " ) ;
}
2013-10-09 14:47:57 +03:00
}
2013-10-14 16:47:37 +03:00
struct clk * * __init tegra_lookup_dt_id ( int clk_id ,
struct tegra_clk * tegra_clk )
{
if ( tegra_clk [ clk_id ] . present )
return & clks [ tegra_clk [ clk_id ] . dt_id ] ;
else
return NULL ;
}
2021-12-01 02:23:12 +03:00
static struct device_node * tegra_clk_get_of_node ( struct clk_hw * hw )
{
struct device_node * np ;
char * node_name ;
node_name = kstrdup ( hw - > init - > name , GFP_KERNEL ) ;
if ( ! node_name )
return NULL ;
strreplace ( node_name , ' _ ' , ' - ' ) ;
for_each_child_of_node ( tegra_car_np , np ) {
if ( ! strcmp ( np - > name , node_name ) )
break ;
}
kfree ( node_name ) ;
return np ;
}
struct clk * tegra_clk_dev_register ( struct clk_hw * hw )
{
struct platform_device * pdev , * parent ;
const char * dev_name = NULL ;
struct device * dev = NULL ;
struct device_node * np ;
np = tegra_clk_get_of_node ( hw ) ;
if ( ! of_device_is_available ( np ) )
goto put_node ;
dev_name = kasprintf ( GFP_KERNEL , " tegra_clk_%s " , hw - > init - > name ) ;
if ( ! dev_name )
goto put_node ;
parent = of_find_device_by_node ( tegra_car_np ) ;
if ( parent ) {
pdev = of_platform_device_create ( np , dev_name , & parent - > dev ) ;
put_device ( & parent - > dev ) ;
if ( ! pdev ) {
pr_err ( " %s: failed to create device for %pOF \n " ,
__func__ , np ) ;
goto free_name ;
}
dev = & pdev - > dev ;
pm_runtime_enable ( dev ) ;
} else {
WARN ( 1 , " failed to find device for %pOF \n " , tegra_car_np ) ;
}
free_name :
kfree ( dev_name ) ;
put_node :
of_node_put ( np ) ;
return clk_register ( dev , hw ) ;
}
2013-03-25 13:22:24 -06:00
tegra_clk_apply_init_table_func tegra_clk_apply_init_table ;
2014-12-16 12:38:27 -08:00
static int __init tegra_clocks_apply_init_table ( void )
2013-03-25 13:22:24 -06:00
{
if ( ! tegra_clk_apply_init_table )
2014-12-16 12:38:27 -08:00
return 0 ;
2013-03-25 13:22:24 -06:00
tegra_clk_apply_init_table ( ) ;
2014-12-16 12:38:27 -08:00
return 0 ;
2013-03-25 13:22:24 -06:00
}
2014-12-16 12:38:27 -08:00
arch_initcall ( tegra_clocks_apply_init_table ) ;