From 2852bfbf4f168fec27049ad9ed20941fc9e84b95 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 9 Aug 2018 01:19:52 +0800 Subject: [PATCH 001/836] clk: sunxi-ng: h6: fix bus clocks' divider position The bus clocks (AHB/APB) on Allwinner H6 have their second divider start at bit 8, according to the user manual and the BSP code. However, currently the divider offset is incorrectly set to 16, thus the divider is not correctly read and the clock frequency is not correctly calculated. Fix this bit offset on all affected bus clocks in ccu-sun50i-h6. Cc: stable@vger.kernel.org # v4.17.y Signed-off-by: Icenowy Zheng Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index bdbfe78fe133..0f7a0ffd3f70 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -224,7 +224,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2", psi_ahb1_ahb2_parents, 0x510, 0, 5, /* M */ - 16, 2, /* P */ + 8, 2, /* P */ 24, 2, /* mux */ 0); @@ -233,19 +233,19 @@ static const char * const ahb3_apb1_apb2_parents[] = { "osc24M", "osc32k", "pll-periph0" }; static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, 0, 5, /* M */ - 16, 2, /* P */ + 8, 2, /* P */ 24, 2, /* mux */ 0); static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, 0, 5, /* M */ - 16, 2, /* P */ + 8, 2, /* P */ 24, 2, /* mux */ 0); static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, 0, 5, /* M */ - 16, 2, /* P */ + 8, 2, /* P */ 24, 2, /* mux */ 0); From 58c0f79887d5e425fe6a9fd542778e50df69e9c6 Mon Sep 17 00:00:00 2001 From: Rongyi Chen Date: Fri, 10 Aug 2018 23:16:38 +0800 Subject: [PATCH 002/836] clk: sunxi-ng: h6: fix PWM gate/reset offset Currently the register offset of the PWM bus gate in Allwinner H6 clock driver is wrong. Fix this issue. Fixes: 542353ea ("clk: sunxi-ng: add support for the Allwinner H6 CCU") Signed-off-by: Rongyi Chen [Icenowy: refactor commit message] Signed-off-by: Icenowy Zheng Signed-off-by: Chen-Yu Tsai --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index 0f7a0ffd3f70..d425b47cef17 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -352,7 +352,7 @@ static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "psi-ahb1-ahb2", static SUNXI_CCU_GATE(bus_psi_clk, "bus-psi", "psi-ahb1-ahb2", 0x79c, BIT(0), 0); -static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x79c, BIT(0), 0); +static SUNXI_CCU_GATE(bus_pwm_clk, "bus-pwm", "apb1", 0x7ac, BIT(0), 0); static SUNXI_CCU_GATE(bus_iommu_clk, "bus-iommu", "apb1", 0x7bc, BIT(0), 0); From cb54fbd21a8fd97c2a82a069e8c80abdedbeb530 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 9 Aug 2018 18:52:13 +0200 Subject: [PATCH 003/836] clk: sunxi-ng: Add maximum rate constraint to NM PLLs On some NM PLLs, frequency can be set above PLL working range. Add a constraint for maximum supported rate. This way, drivers can specify which is maximum allowed rate for PLL. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nm.c | 7 +++++++ drivers/clk/sunxi-ng/ccu_nm.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c index 4e2073307f34..6fe3c14f7b2d 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.c +++ b/drivers/clk/sunxi-ng/ccu_nm.c @@ -124,6 +124,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate, return rate; } + if (nm->max_rate && rate > nm->max_rate) { + rate = nm->max_rate; + if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate /= nm->fixed_post_div; + return rate; + } + if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV) rate /= nm->fixed_post_div; diff --git a/drivers/clk/sunxi-ng/ccu_nm.h b/drivers/clk/sunxi-ng/ccu_nm.h index 1d8b459c50b7..de232f2199a6 100644 --- a/drivers/clk/sunxi-ng/ccu_nm.h +++ b/drivers/clk/sunxi-ng/ccu_nm.h @@ -38,6 +38,7 @@ struct ccu_nm { unsigned int fixed_post_div; unsigned int min_rate; + unsigned int max_rate; struct ccu_common common; }; @@ -115,6 +116,35 @@ struct ccu_nm { }, \ } +#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(_struct, _name, \ + _parent, _reg, \ + _min_rate, _max_rate, \ + _nshift, _nwidth, \ + _mshift, _mwidth, \ + _frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1, \ + _gate, _lock, _flags) \ + struct ccu_nm _struct = { \ + .enable = _gate, \ + .lock = _lock, \ + .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \ + .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ + .frac = _SUNXI_CCU_FRAC(_frac_en, _frac_sel, \ + _frac_rate_0, \ + _frac_rate_1), \ + .min_rate = _min_rate, \ + .max_rate = _max_rate, \ + .common = { \ + .reg = _reg, \ + .features = CCU_FEATURE_FRACTIONAL, \ + .hw.init = CLK_HW_INIT(_name, \ + _parent, \ + &ccu_nm_ops, \ + _flags), \ + }, \ + } + #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ _nshift, _nwidth, \ _mshift, _mwidth, \ From 02d7901695afd1dcbec7182d878927893c07174e Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 9 Aug 2018 18:52:14 +0200 Subject: [PATCH 004/836] clk: sunxi-ng: h3/h5: Add max. rate constraint to pll-video As it turns out, pll-video can be set to higher rate that it is really supported by HW. For example, one monitor requested 185.58 MHz pixel clock. Clock framework calculated that minimum rate error would be when pll-video is set to 2040 MHz. This is clearly out of specs. Both H3 and H5 user manuals specify 600 MHz as maximum supported rate. However, BSP clock drivers allow up to 912 MHz and 1008 MHz respectively. Here 912 MHz is chosen because user manuals were already proven wrong once for lower limits. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c index 77ed0b0ba681..eb5c608428fa 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -69,18 +69,19 @@ static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", BIT(28), /* lock */ CLK_SET_RATE_UNGATE); -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video_clk, "pll-video", - "osc24M", 0x0010, - 192000000, /* Minimum rate */ - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video_clk, "pll-video", + "osc24M", 0x0010, + 192000000, /* Minimum rate */ + 912000000, /* Maximum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", "osc24M", 0x0018, From b16fb66915fcfc6b1a7eb48225b6b30b69bb721b Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 9 Aug 2018 18:52:15 +0200 Subject: [PATCH 005/836] clk: sunxi-ng: r40: Add max. rate constraint to video PLLs Video PLLs on R40 can be set to higher rate that it is actually supported by HW. Limit maximum rate to 1008 MHz. This is the maximum allowed rate by BSP clock driver. Interestengly, user manual specifies maximum frequency to be 600 MHz. Historically, this data was wrong in some user manuals for other SoCs, so more faith is put in BSP clock driver. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 52 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c index 0f388f6944d5..582ebd41d20d 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c @@ -65,19 +65,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", BIT(28), /* lock */ CLK_SET_RATE_UNGATE); -/* TODO: The result of N/M is required to be in [8, 25] range. */ -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", - "osc24M", 0x0010, - 192000000, /* Minimum rate */ - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", + "osc24M", 0x0010, + 192000000, /* Minimum rate */ + 1008000000, /* Maximum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); /* TODO: The result of N/M is required to be in [8, 25] range. */ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", @@ -152,19 +152,19 @@ static struct ccu_nk pll_periph1_clk = { }, }; -/* TODO: The result of N/M is required to be in [8, 25] range. */ -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", - "osc24M", 0x030, - 192000000, /* Minimum rate */ - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1", + "osc24M", 0x030, + 192000000, /* Minimum rate */ + 1008000000, /* Maximum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static struct ccu_nkm pll_sata_clk = { .enable = BIT(31), From a8e5433cdc500290b52d26a05056e02c448a413c Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 9 Aug 2018 18:52:16 +0200 Subject: [PATCH 006/836] clk: sunxi-ng: nkmp: Add constraint for maximum rate Some, if not most, NKMP PLLs can be set to higher rate that is really supported by HW. Implement support for maximum frequency constrain for NKMP PLLs. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu_nkmp.c | 7 +++++++ drivers/clk/sunxi-ng/ccu_nkmp.h | 1 + 2 files changed, 8 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c index ebd9436d2c7c..9b49adb20d07 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.c +++ b/drivers/clk/sunxi-ng/ccu_nkmp.c @@ -137,6 +137,13 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate, if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) rate *= nkmp->fixed_post_div; + if (nkmp->max_rate && rate > nkmp->max_rate) { + rate = nkmp->max_rate; + if (nkmp->common.features & CCU_FEATURE_FIXED_POSTDIV) + rate /= nkmp->fixed_post_div; + return rate; + } + _nkmp.min_n = nkmp->n.min ?: 1; _nkmp.max_n = nkmp->n.max ?: 1 << nkmp->n.width; _nkmp.min_k = nkmp->k.min ?: 1; diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h index 6940503e7fc4..a9f8c116a745 100644 --- a/drivers/clk/sunxi-ng/ccu_nkmp.h +++ b/drivers/clk/sunxi-ng/ccu_nkmp.h @@ -35,6 +35,7 @@ struct ccu_nkmp { struct ccu_div_internal p; unsigned int fixed_post_div; + unsigned int max_rate; struct ccu_common common; }; From a528872dbb87faefda3056023eaaf83f14fdafdf Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Thu, 9 Aug 2018 18:52:17 +0200 Subject: [PATCH 007/836] clk: sunxi-ng: a83t: Add max. rate constraint to video PLLs It may happen that clock framework finds optimal video PLL rate above that which is really supported by HW. User manual doesn't really say what is upper limit for video PLLs on A83T. Because of that, use the maximum rate defined in BSP clk driver which is 3 GHz. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c index 7d08015b980d..2d6555d73170 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-a83t.c @@ -108,6 +108,7 @@ static struct ccu_nkmp pll_video0_clk = { .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ .p = _SUNXI_CCU_DIV(0, 2), /* output divider */ + .max_rate = 3000000000UL, .common = { .reg = 0x010, .lock_reg = CCU_SUN8I_A83T_LOCK_REG, @@ -220,6 +221,7 @@ static struct ccu_nkmp pll_video1_clk = { .n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0), .m = _SUNXI_CCU_DIV(16, 1), /* input divider */ .p = _SUNXI_CCU_DIV(0, 2), /* external divider p */ + .max_rate = 3000000000UL, .common = { .reg = 0x04c, .lock_reg = CCU_SUN8I_A83T_LOCK_REG, From fdb78a8c35bce065272d71ac7eb64d6d7512db99 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 23 Jul 2018 15:21:52 +0200 Subject: [PATCH 008/836] clk: renesas: rcar-gen3: Rename rint to .r All other internal clock names have a period prepended. Hence rename the internal RCLK from "rint" to ".r", and move it to the section where all other internal clocks are defined. Signed-off-by: Geert Uytterhoeven Acked-by: Stephen Boyd Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 3 ++- drivers/clk/renesas/r8a7796-cpg-mssr.c | 3 ++- drivers/clk/renesas/r8a77965-cpg-mssr.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index a85dd50e8911..ccaea9e1849d 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -73,6 +73,8 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + /* Core Clock Outputs */ DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_BASE("z2", R8A7795_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), @@ -112,7 +114,6 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV4, 0x250), DEF_DIV6_RO("osc", R8A7795_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), - DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index dfb267a92f2a..6a4ef3d04aa0 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -73,6 +73,8 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + /* Core Clock Outputs */ DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_BASE("z2", R8A7796_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), @@ -111,7 +113,6 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_DIV6P1("hdmi", R8A7796_CLK_HDMI, CLK_PLL1_DIV4, 0x250), DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), - DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), DEF_BASE("r", R8A7796_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index 8fae5e9c4a77..7a7eb9658058 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -68,6 +68,8 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + /* Core Clock Outputs */ DEF_BASE("z", R8A77965_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), DEF_FIXED("ztr", R8A77965_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), @@ -105,7 +107,6 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_DIV6P1("hdmi", R8A77965_CLK_HDMI, CLK_PLL1_DIV4, 0x250), DEF_DIV6_RO("osc", R8A77965_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), - DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), DEF_BASE("r", R8A77965_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; From 38c79e2899a66096583f3377c64b35f30584f1b4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:14:44 +0200 Subject: [PATCH 009/836] clk: renesas: rcar-gen3: Add support for OSC EXTAL predivider Add a clock type and macro for defining clocks using the OSC EXTAL predivider combined with a fixed divider. On most R-Car Gen3 SoCs, the predivider value depends on mode pins, and thus must be specified in the configuration structure. Inspired by a patch in the BSP by Takeshi Kihara . Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/rcar-gen3-cpg.c | 7 +++++++ drivers/clk/renesas/rcar-gen3-cpg.h | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 628b63b85d3f..7533a51c679b 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -563,6 +563,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, return cpg_z_clk_register(core->name, __clk_get_name(parent), base, CPG_FRQCRC_Z2FC_MASK); + case CLK_TYPE_GEN3_OSC: + /* + * Clock combining OSC EXTAL predivider and a fixed divider + */ + div = cpg_pll_config->osc_prediv * core->div; + break; + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index ea4f8fc3c4c9..d7d84d9e4a1c 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -23,6 +23,7 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_PE, CLK_TYPE_GEN3_Z, CLK_TYPE_GEN3_Z2, + CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ @@ -33,6 +34,8 @@ enum rcar_gen3_clk_types { DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE, \ (_parent_sscg) << 16 | (_parent_clean), \ .div = (_div_sscg) << 16 | (_div_clean)) +#define DEF_GEN3_OSC(_name, _id, _parent, _div) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_OSC, _parent, .div = _div) struct rcar_gen3_cpg_pll_config { u8 extal_div; @@ -40,6 +43,7 @@ struct rcar_gen3_cpg_pll_config { u8 pll1_div; u8 pll3_mult; u8 pll3_div; + u8 osc_prediv; }; #define CPG_RCKCR 0x240 From f23b866e20210d2ca8e6aa8506ff727dd9d03d03 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:28:44 +0200 Subject: [PATCH 010/836] clk: renesas: r8a7795: Add OSC EXTAL predivider configuration R-Car Gen3 Hardware Manual Rev.0.52 documents the relation between the MD13 and MD14 mode pins, and the OSC EXTAL predivider, as used by the OSC and RINT RCLK clocks. Hence augment the configuration structure with all documented predivider values. According to R-Car Gen3 Hardware Manual Rev.0.53, the CPG_RCKCR register was removed in R-Car H3 ES2.0. Change the OSC and RINT clock definitions to use the OSC EXTAL predivider instead, which is supported on all R-Car H3 SoC revisions. Inspired by a patch in the BSP by Takeshi Kihara . Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a7795-cpg-mssr.c | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index ccaea9e1849d..ca8cb0eed950 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -73,7 +73,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), - DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), /* Core Clock Outputs */ DEF_BASE("z", R8A7795_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), @@ -113,7 +113,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = { DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV4, 0x250), - DEF_DIV6_RO("osc", R8A7795_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + DEF_GEN3_OSC("osc", R8A7795_CLK_OSC, CLK_EXTAL, 8), DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; @@ -284,25 +284,25 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { */ /* - * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC * 14 13 19 17 (MHz) - *------------------------------------------------------------------- - * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 - * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 * 0 0 1 0 Prohibited setting - * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 - * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 - * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 * 0 1 1 0 Prohibited setting - * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 - * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 - * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 * 1 0 1 0 Prohibited setting - * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 - * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 - * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 * 1 1 1 0 Prohibited setting - * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 */ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ (((md) & BIT(13)) >> 11) | \ @@ -310,23 +310,23 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { (((md) & BIT(17)) >> 17)) static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { - /* EXTAL div PLL1 mult/div PLL3 mult/div */ - { 1, 192, 1, 192, 1, }, - { 1, 192, 1, 128, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 192, 1, 192, 1, }, - { 1, 160, 1, 160, 1, }, - { 1, 160, 1, 106, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 160, 1, 160, 1, }, - { 1, 128, 1, 128, 1, }, - { 1, 128, 1, 84, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 128, 1, 128, 1, }, - { 2, 192, 1, 192, 1, }, - { 2, 192, 1, 128, 1, }, - { 0, /* Prohibited setting */ }, - { 2, 192, 1, 192, 1, }, + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, }; static const struct soc_device_attribute r8a7795es1[] __initconst = { From 7b8b9a4131221b5e9c460c0bbc107b8b018b05ca Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:39:29 +0200 Subject: [PATCH 011/836] clk: renesas: r8a7796: Add OSC EXTAL predivider configuration R-Car Gen3 Hardware Manual Rev.0.52 documents the relation between the MD13 and MD14 mode pins, and the OSC EXTAL predivider, as used by the OSC and RINT RCLK clocks. Hence augment the configuration structure with all documented predivider values. According to R-Car Gen3 Hardware Manual Rev.0.53, the CPG_RCKCR register was removed in R-Car M3-W ES1.1. Change the OSC and RINT clock definitions to use the OSC EXTAL predivider instead, which is supported on all R-Car M3-W SoC revisions. Inspired by a patch in the BSP by Takeshi Kihara . Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a7796-cpg-mssr.c | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index 6a4ef3d04aa0..7e98fb8b1074 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -73,7 +73,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), - DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), /* Core Clock Outputs */ DEF_BASE("z", R8A7796_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), @@ -112,7 +112,7 @@ static const struct cpg_core_clk r8a7796_core_clks[] __initconst = { DEF_DIV6P1("mso", R8A7796_CLK_MSO, CLK_PLL1_DIV4, 0x014), DEF_DIV6P1("hdmi", R8A7796_CLK_HDMI, CLK_PLL1_DIV4, 0x250), - DEF_DIV6_RO("osc", R8A7796_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + DEF_GEN3_OSC("osc", R8A7796_CLK_OSC, CLK_EXTAL, 8), DEF_BASE("r", R8A7796_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; @@ -256,25 +256,25 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = { */ /* - * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC * 14 13 19 17 (MHz) - *------------------------------------------------------------------- - * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 - * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 * 0 0 1 0 Prohibited setting - * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 - * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 - * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 * 0 1 1 0 Prohibited setting - * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 - * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 - * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 * 1 0 1 0 Prohibited setting - * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 - * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 - * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 * 1 1 1 0 Prohibited setting - * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 */ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ (((md) & BIT(13)) >> 11) | \ @@ -282,23 +282,23 @@ static const unsigned int r8a7796_crit_mod_clks[] __initconst = { (((md) & BIT(17)) >> 17)) static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { - /* EXTAL div PLL1 mult/div PLL3 mult/div */ - { 1, 192, 1, 192, 1, }, - { 1, 192, 1, 128, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 192, 1, 192, 1, }, - { 1, 160, 1, 160, 1, }, - { 1, 160, 1, 106, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 160, 1, 160, 1, }, - { 1, 128, 1, 128, 1, }, - { 1, 128, 1, 84, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 128, 1, 128, 1, }, - { 2, 192, 1, 192, 1, }, - { 2, 192, 1, 128, 1, }, - { 0, /* Prohibited setting */ }, - { 2, 192, 1, 192, 1, }, + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, }; static int __init r8a7796_cpg_mssr_init(struct device *dev) From 979a2298a55a5b93d47b9479f7fbc977324f091f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:41:25 +0200 Subject: [PATCH 012/836] clk: renesas: r8a77965: Add OSC EXTAL predivider configuration R-Car Gen3 Hardware Manual Rev.0.52 documents the relation between the MD13 and MD14 mode pins, and the OSC EXTAL predivider, as used by the OSC and RINT RCLK clocks. Hence augment the configuration structure with all documented predivider values. According to R-Car Gen3 Hardware Manual Rev.1.00, R-Car M3-N does not have the CPG_RCKCR register. Change the OSC and RINT clock definitions to use the OSC EXTAL predivider instead, which is supported on all R-Car M3-N SoC revisions. Inspired by a patch in the BSP by Takeshi Kihara . Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77965-cpg-mssr.c | 66 ++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index 7a7eb9658058..c596e2afaeeb 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -68,7 +68,7 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), - DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), /* Core Clock Outputs */ DEF_BASE("z", R8A77965_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), @@ -106,7 +106,7 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { DEF_DIV6P1("mso", R8A77965_CLK_MSO, CLK_PLL1_DIV4, 0x014), DEF_DIV6P1("hdmi", R8A77965_CLK_HDMI, CLK_PLL1_DIV4, 0x250), - DEF_DIV6_RO("osc", R8A77965_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + DEF_GEN3_OSC("osc", R8A77965_CLK_OSC, CLK_EXTAL, 8), DEF_BASE("r", R8A77965_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), }; @@ -253,25 +253,25 @@ static const unsigned int r8a77965_crit_mod_clks[] __initconst = { */ /* - * MD EXTAL PLL0 PLL1 PLL3 PLL4 + * MD EXTAL PLL0 PLL1 PLL3 PLL4 OSC * 14 13 19 17 (MHz) - *----------------------------------------------------------- - * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 - * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 + *----------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x128 x144 /16 * 0 0 1 0 Prohibited setting - * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 - * 0 1 0 0 20 x 1 x150 x160 x160 x120 - * 0 1 0 1 20 x 1 x150 x160 x106 x120 + * 0 0 1 1 16.66 x 1 x180 x192 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x106 x120 /19 * 0 1 1 0 Prohibited setting - * 0 1 1 1 20 x 1 x150 x160 x160 x120 - * 1 0 0 0 25 x 1 x120 x128 x128 x96 - * 1 0 0 1 25 x 1 x120 x128 x84 x96 + * 0 1 1 1 20 x 1 x150 x160 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x84 x96 /24 * 1 0 1 0 Prohibited setting - * 1 0 1 1 25 x 1 x120 x128 x128 x96 - * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 - * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 + * 1 0 1 1 25 x 1 x120 x128 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x128 x144 /32 * 1 1 1 0 Prohibited setting - * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 + * 1 1 1 1 33.33 / 2 x180 x192 x192 x144 /32 */ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ (((md) & BIT(13)) >> 11) | \ @@ -279,23 +279,23 @@ static const unsigned int r8a77965_crit_mod_clks[] __initconst = { (((md) & BIT(17)) >> 17)) static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { - /* EXTAL div PLL1 mult/div PLL3 mult/div */ - { 1, 192, 1, 192, 1, }, - { 1, 192, 1, 128, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 192, 1, 192, 1, }, - { 1, 160, 1, 160, 1, }, - { 1, 160, 1, 106, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 160, 1, 160, 1, }, - { 1, 128, 1, 128, 1, }, - { 1, 128, 1, 84, 1, }, - { 0, /* Prohibited setting */ }, - { 1, 128, 1, 128, 1, }, - { 2, 192, 1, 192, 1, }, - { 2, 192, 1, 128, 1, }, - { 0, /* Prohibited setting */ }, - { 2, 192, 1, 192, 1, }, + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, }; static int __init r8a77965_cpg_mssr_init(struct device *dev) From 3a251270e6c877092baded767eba07e9abb1e00d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 14:16:40 +0200 Subject: [PATCH 013/836] clk: renesas: r8a77980: Add OSC predivider configuration and clock R-Car Gen3 Hardware Manual Rev.0.54 documents the relation between the MD13 and MD14 mode pins, and the OSC EXTAL predivider, as used by the OSC clock. Hence augment the configuration structure with all documented predivider values. Add the OSC clock using the configured predivider. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77980-cpg-mssr.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c index d7ebd9ec0059..a8b8d8613b46 100644 --- a/drivers/clk/renesas/r8a77980-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -96,6 +96,8 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = { DEF_DIV6P1("canfd", R8A77980_CLK_CANFD, CLK_PLL1_DIV4, 0x244), DEF_DIV6P1("csi0", R8A77980_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), DEF_DIV6P1("mso", R8A77980_CLK_MSO, CLK_PLL1_DIV4, 0x014), + + DEF_GEN3_OSC("osc", R8A77980_CLK_OSC, CLK_EXTAL, 8), }; static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = { @@ -171,23 +173,23 @@ static const unsigned int r8a77980_crit_mod_clks[] __initconst = { */ /* - * MD EXTAL PLL2 PLL1 PLL3 + * MD EXTAL PLL2 PLL1 PLL3 OSC * 14 13 (MHz) - * -------------------------------------------------- - * 0 0 16.66 x 1 x240 x192 x192 - * 0 1 20 x 1 x200 x160 x160 - * 1 0 27 x 1 x148 x118 x118 - * 1 1 33.33 / 2 x240 x192 x192 + * -------------------------------------------------------- + * 0 0 16.66 x 1 x240 x192 x192 /16 + * 0 1 20 x 1 x200 x160 x160 /19 + * 1 0 27 x 1 x148 x118 x118 /26 + * 1 1 33.33 / 2 x240 x192 x192 /32 */ #define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \ (((md) & BIT(13)) >> 13)) static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[4] __initconst = { - /* EXTAL div PLL1 mult/div PLL3 mult/div */ - { 1, 192, 1, 192, 1, }, - { 1, 160, 1, 160, 1, }, - { 1, 118, 1, 118, 1, }, - { 2, 192, 1, 192, 1, }, + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 118, 1, 118, 1, 26, }, + { 2, 192, 1, 192, 1, 32, }, }; static int __init r8a77980_cpg_mssr_init(struct device *dev) From 0d2602d750152f9fcf3d9af9466f3d67b60aa646 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:47:28 +0200 Subject: [PATCH 014/836] clk: renesas: cpg-mssr: Add support for fixed rate clocks Add support for defining fixed rate clocks, to be used for on-chip oscillators. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/renesas-cpg-mssr.c | 5 +++++ drivers/clk/renesas/renesas-cpg-mssr.h | 3 +++ 2 files changed, 8 insertions(+) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index f4b013e9352d..e04338932786 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -313,6 +313,11 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, } break; + case CLK_TYPE_FR: + clk = clk_register_fixed_rate(NULL, core->name, NULL, 0, + core->mult); + break; + default: if (info->cpg_clk_register) clk = info->cpg_clk_register(dev, core, info, diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 642f720b9b05..87bb8f368d4e 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -38,6 +38,7 @@ enum clk_types { CLK_TYPE_FF, /* Fixed Factor Clock */ CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */ CLK_TYPE_DIV6_RO, /* DIV6 Clock read only with extra divisor */ + CLK_TYPE_FR, /* Fixed Rate Clock */ /* Custom definitions start here */ CLK_TYPE_CUSTOM, @@ -56,6 +57,8 @@ enum clk_types { DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) #define DEF_DIV6_RO(_name, _id, _parent, _offset, _div) \ DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1) +#define DEF_RATE(_name, _id, _rate) \ + DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate) /* * Definitions of Module Clocks From b9d0b84b3db8552f033d5051393b90852b977a76 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:54:30 +0200 Subject: [PATCH 015/836] clk: renesas: rcar-gen3: Add support for RCKSEL clock selection Add a clock type and macro for defining clocks where the parent and divider are selected based on the value of the RCKCR.CKSEL bit. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/rcar-gen3-cpg.c | 23 ++++++++++++++++++++--- drivers/clk/renesas/rcar-gen3-cpg.h | 7 ++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 7533a51c679b..19a77822757d 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -1,7 +1,7 @@ /* * R-Car Gen3 Clock Pulse Generator * - * Copyright (C) 2015-2016 Glider bvba + * Copyright (C) 2015-2018 Glider bvba * * Based on clk-rcar-gen3.c * @@ -31,6 +31,8 @@ #define CPG_PLL2CR 0x002c #define CPG_PLL4CR 0x01f4 +#define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ + struct cpg_simple_notifier { struct notifier_block nb; void __iomem *reg; @@ -444,7 +446,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, unsigned int div = 1; u32 value; - parent = clks[core->parent & 0xffff]; /* CLK_TYPE_PE uses high bits */ + parent = clks[core->parent & 0xffff]; /* some types use high bits */ if (IS_ERR(parent)) return ERR_CAST(parent); @@ -524,7 +526,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, if (clk_get_rate(clks[cpg_clk_extalr])) { parent = clks[cpg_clk_extalr]; - value |= BIT(15); + value |= CPG_RCKCR_CKSEL; } writel(value, csn->reg); @@ -570,6 +572,21 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, div = cpg_pll_config->osc_prediv * core->div; break; + case CLK_TYPE_GEN3_RCKSEL: + /* + * Clock selectable between two parents and two fixed dividers + * using RCKCR.CKSEL + */ + if (readl(base + CPG_RCKCR) & CPG_RCKCR_CKSEL) { + div = core->div & 0xffff; + } else { + parent = clks[core->parent >> 16]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + div = core->div >> 16; + } + break; + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index d7d84d9e4a1c..7c49aebf9dd1 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -1,7 +1,7 @@ /* * R-Car Gen3 Clock Pulse Generator * - * Copyright (C) 2015-2016 Glider bvba + * Copyright (C) 2015-2018 Glider bvba * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_Z, CLK_TYPE_GEN3_Z2, CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ + CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */ }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ @@ -37,6 +38,10 @@ enum rcar_gen3_clk_types { #define DEF_GEN3_OSC(_name, _id, _parent, _div) \ DEF_BASE(_name, _id, CLK_TYPE_GEN3_OSC, _parent, .div = _div) +#define DEF_GEN3_RCKSEL(_name, _id, _parent0, _div0, _parent1, _div1) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_RCKSEL, \ + (_parent0) << 16 | (_parent1), .div = (_div0) << 16 | (_div1)) + struct rcar_gen3_cpg_pll_config { u8 extal_div; u8 pll1_mult; From dc643a843b5d510c04b2e222a1a4bd735d387f50 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 14:04:51 +0200 Subject: [PATCH 016/836] clk: renesas: r8a77990: Correct RCLK handling According to R-Car Gen3 Hardware Manual Rev.1.00, R-Car E3 has the RCLK Frequency Control Register (RCKCR), which determines the OSC and RINT predivider values, and selection of the RCLK clock source between RINT and the On-Chip Oscillator. Hence change the OSC and RINT clock definitions to use the RCKCR divider, and add the missing On-Chip Oscillator and RCLK clock source switching logic. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77990-cpg-mssr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index 9e14f1486fbb..9437219efdd9 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -44,6 +44,8 @@ enum clk_ids { CLK_S2, CLK_S3, CLK_SDSRC, + CLK_RINT, + CLK_OCO, /* Module Clocks */ MOD_CLK_BASE @@ -72,6 +74,10 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), + /* Core Clock Outputs */ DEF_FIXED("za2", R8A77990_CLK_ZA2, CLK_PLL0D24, 1, 1), DEF_FIXED("za8", R8A77990_CLK_ZA8, CLK_PLL0D8, 1, 1), @@ -100,8 +106,8 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = { DEF_FIXED("cl", R8A77990_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("cp", R8A77990_CLK_CP, CLK_EXTAL, 2, 1), DEF_FIXED("cpex", R8A77990_CLK_CPEX, CLK_EXTAL, 4, 1), - DEF_FIXED("osc", R8A77990_CLK_OSC, CLK_EXTAL, 384, 1), - DEF_FIXED("r", R8A77990_CLK_R, CLK_EXTAL, 1536, 1), + + DEF_DIV6_RO("osc", R8A77990_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), DEF_GEN3_PE("s0d6c", R8A77990_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2), DEF_GEN3_PE("s3d1c", R8A77990_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), @@ -111,6 +117,8 @@ static const struct cpg_core_clk r8a77990_core_clks[] __initconst = { DEF_DIV6P1("canfd", R8A77990_CLK_CANFD, CLK_PLL0D6, 0x244), DEF_DIV6P1("csi0", R8A77990_CLK_CSI0, CLK_PLL1D2, 0x00c), DEF_DIV6P1("mso", R8A77990_CLK_MSO, CLK_PLL1D2, 0x014), + + DEF_GEN3_RCKSEL("r", R8A77990_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4), }; static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = { From 4f57998d647772280a6442bbc746249e5bfee572 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 14:12:19 +0200 Subject: [PATCH 017/836] clk: renesas: r8a77995: Correct RCLK handling According to R-Car Gen3 Hardware Manual Rev.1.00, R-Car D3 has the RCLK Frequency Control Register (RCKCR), which determines the OSC and RINT predivider values, and selection of the RCLK clock source between RINT and the On-Chip Oscillator. Hence change the OSC and RINT clock definitions to use the RCKCR divider, and add the missing On-Chip Oscillator and RCLK clock source switching logic. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77995-cpg-mssr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index ea4cafbe6e85..49e6a0de5491 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -46,6 +46,8 @@ enum clk_ids { CLK_S3, CLK_SDSRC, CLK_SSPSRC, + CLK_RINT, + CLK_OCO, /* Module Clocks */ MOD_CLK_BASE @@ -72,6 +74,10 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), + /* Core Clock Outputs */ DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), @@ -90,8 +96,8 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1), DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1), - DEF_FIXED("osc", R8A77995_CLK_OSC, CLK_EXTAL, 384, 1), - DEF_FIXED("r", R8A77995_CLK_R, CLK_EXTAL, 1536, 1), + + DEF_DIV6_RO("osc", R8A77995_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), DEF_GEN3_PE("s1d4c", R8A77995_CLK_S1D4C, CLK_S1, 4, CLK_PE, 2), DEF_GEN3_PE("s3d1c", R8A77995_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), @@ -102,6 +108,8 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244), DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014), + + DEF_GEN3_RCKSEL("r", R8A77995_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4), }; static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = { From cd51e427e050f6a3d3bc3e0e38ad30974a52cb44 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 14:19:47 +0200 Subject: [PATCH 018/836] clk: renesas: rcar-gen3: Add support for mode pin clock selection Make the existing support for selecting between clean and SSCG clocks using MD12 more generic, to allow using other mode pins for arbitrary clock selection. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/rcar-gen3-cpg.c | 10 ++++------ drivers/clk/renesas/rcar-gen3-cpg.h | 13 +++++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 19a77822757d..4346fdeef01b 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -539,16 +539,14 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, parent = clks[cpg_clk_extalr]; break; - case CLK_TYPE_GEN3_PE: + case CLK_TYPE_GEN3_MDSEL: /* - * Peripheral clock with a fixed divider, selectable between - * clean and spread spectrum parents using MD12 + * Clock selectable between two parents and two fixed dividers + * using a mode pin */ - if (cpg_mode & BIT(12)) { - /* Clean */ + if (cpg_mode & BIT(core->offset)) { div = core->div & 0xffff; } else { - /* SCCG */ parent = clks[core->parent >> 16]; if (IS_ERR(parent)) return ERR_CAST(parent); diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 7c49aebf9dd1..04dc45d15874 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -20,7 +20,7 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_PLL4, CLK_TYPE_GEN3_SD, CLK_TYPE_GEN3_R, - CLK_TYPE_GEN3_PE, + CLK_TYPE_GEN3_MDSEL, /* Select parent/divider using mode pin */ CLK_TYPE_GEN3_Z, CLK_TYPE_GEN3_Z2, CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ @@ -30,11 +30,16 @@ enum rcar_gen3_clk_types { #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) +#define DEF_GEN3_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_MDSEL, \ + (_parent0) << 16 | (_parent1), \ + .div = (_div0) << 16 | (_div1), .offset = _md) + #define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \ _div_clean) \ - DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE, \ - (_parent_sscg) << 16 | (_parent_clean), \ - .div = (_div_sscg) << 16 | (_div_clean)) + DEF_GEN3_MDSEL(_name, _id, 12, _parent_sscg, _div_sscg, \ + _parent_clean, _div_clean) + #define DEF_GEN3_OSC(_name, _id, _parent, _div) \ DEF_BASE(_name, _id, CLK_TYPE_GEN3_OSC, _parent, .div = _div) From f3824deb46332d1f037f9a26c8f01e3143e64c7e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 14:25:07 +0200 Subject: [PATCH 019/836] clk: renesas: r8a77980: Add RCLK for watchdog timer On R-Car V3H, RCLK can be switched between EXTALR and the On-Chip Oscillator using mode pin MD19. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77980-cpg-mssr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c index a8b8d8613b46..acf2b4dded4c 100644 --- a/drivers/clk/renesas/r8a77980-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -41,6 +41,7 @@ enum clk_ids { CLK_S2, CLK_S3, CLK_SDSRC, + CLK_OCO, /* Module Clocks */ MOD_CLK_BASE @@ -64,6 +65,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = { DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + DEF_RATE(".oco", CLK_OCO, 32768), /* Core Clock Outputs */ DEF_FIXED("ztr", R8A77980_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), @@ -98,6 +100,7 @@ static const struct cpg_core_clk r8a77980_core_clks[] __initconst = { DEF_DIV6P1("mso", R8A77980_CLK_MSO, CLK_PLL1_DIV4, 0x014), DEF_GEN3_OSC("osc", R8A77980_CLK_OSC, CLK_EXTAL, 8), + DEF_GEN3_MDSEL("r", R8A77980_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), }; static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = { @@ -119,6 +122,7 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = { DEF_MOD("tpu0", 304, R8A77980_CLK_S3D4), DEF_MOD("sdif", 314, R8A77980_CLK_SD0), DEF_MOD("pciec0", 319, R8A77980_CLK_S2D2), + DEF_MOD("rwdt", 402, R8A77980_CLK_R), DEF_MOD("intc-ex", 407, R8A77980_CLK_CP), DEF_MOD("intc-ap", 408, R8A77980_CLK_S0D3), DEF_MOD("hscif3", 517, R8A77980_CLK_S3D1), From e59bb7be47af31d293d6f94d2fad11188d2ba0e7 Mon Sep 17 00:00:00 2001 From: Takeshi Kihara Date: Wed, 25 Jul 2018 21:14:17 +0200 Subject: [PATCH 020/836] clk: renesas: r8a77965: Add SATA clock This patch adds SATA clock to the R8A77965 SoC. Signed-off-by: Takeshi Kihara [wsa: rebased to upstream base] Signed-off-by: Wolfram Sang Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77965-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index c596e2afaeeb..312f9fe738e3 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -193,6 +193,7 @@ static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { DEF_MOD("vin1", 810, R8A77965_CLK_S0D2), DEF_MOD("vin0", 811, R8A77965_CLK_S0D2), DEF_MOD("etheravb", 812, R8A77965_CLK_S0D6), + DEF_MOD("sata0", 815, R8A77965_CLK_S3D2), DEF_MOD("imr1", 822, R8A77965_CLK_S0D2), DEF_MOD("imr0", 823, R8A77965_CLK_S0D2), From 62f32dde334302d7ebb2b3c150f404a61cfcf55e Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 2 Aug 2018 15:56:34 +0100 Subject: [PATCH 021/836] clk: renesas: Add r8a774a1 CPG Core Clock Definitions Add all RZ/G2M Clock Pulse Generator Core Clock Outputs, as listed in Table 8.2b ("List of Clocks [RZ/G2M]") of the RZ/G2M Hardware User's Manual. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r8a774a1-cpg-mssr.h | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 include/dt-bindings/clock/r8a774a1-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a774a1-cpg-mssr.h b/include/dt-bindings/clock/r8a774a1-cpg-mssr.h new file mode 100644 index 000000000000..9bc5d45ff4b5 --- /dev/null +++ b/include/dt-bindings/clock/r8a774a1-cpg-mssr.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__ + +#include + +/* r8a774a1 CPG Core Clocks */ +#define R8A774A1_CLK_Z 0 +#define R8A774A1_CLK_Z2 1 +#define R8A774A1_CLK_ZG 2 +#define R8A774A1_CLK_ZTR 3 +#define R8A774A1_CLK_ZTRD2 4 +#define R8A774A1_CLK_ZT 5 +#define R8A774A1_CLK_ZX 6 +#define R8A774A1_CLK_S0D1 7 +#define R8A774A1_CLK_S0D2 8 +#define R8A774A1_CLK_S0D3 9 +#define R8A774A1_CLK_S0D4 10 +#define R8A774A1_CLK_S0D6 11 +#define R8A774A1_CLK_S0D8 12 +#define R8A774A1_CLK_S0D12 13 +#define R8A774A1_CLK_S1D2 14 +#define R8A774A1_CLK_S1D4 15 +#define R8A774A1_CLK_S2D1 16 +#define R8A774A1_CLK_S2D2 17 +#define R8A774A1_CLK_S2D4 18 +#define R8A774A1_CLK_S3D1 19 +#define R8A774A1_CLK_S3D2 20 +#define R8A774A1_CLK_S3D4 21 +#define R8A774A1_CLK_LB 22 +#define R8A774A1_CLK_CL 23 +#define R8A774A1_CLK_ZB3 24 +#define R8A774A1_CLK_ZB3D2 25 +#define R8A774A1_CLK_ZB3D4 26 +#define R8A774A1_CLK_CR 27 +#define R8A774A1_CLK_CRD2 28 +#define R8A774A1_CLK_SD0H 29 +#define R8A774A1_CLK_SD0 30 +#define R8A774A1_CLK_SD1H 31 +#define R8A774A1_CLK_SD1 32 +#define R8A774A1_CLK_SD2H 33 +#define R8A774A1_CLK_SD2 34 +#define R8A774A1_CLK_SD3H 35 +#define R8A774A1_CLK_SD3 36 +#define R8A774A1_CLK_RPC 37 +#define R8A774A1_CLK_RPCD2 38 +#define R8A774A1_CLK_MSO 39 +#define R8A774A1_CLK_HDMI 40 +#define R8A774A1_CLK_CSI0 41 +#define R8A774A1_CLK_CP 42 +#define R8A774A1_CLK_CPEX 43 +#define R8A774A1_CLK_R 44 +#define R8A774A1_CLK_OSC 45 + +#endif /* __DT_BINDINGS_CLOCK_R8A774A1_CPG_MSSR_H__ */ From 331a53e05b67b40a107e7e2597d22b4f8a2ca0d2 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 2 Aug 2018 15:57:51 +0100 Subject: [PATCH 022/836] clk: renesas: cpg-mssr: Add r8a774a1 support Add RZ/G2M (R8A774A1) Clock Pulse Generator / Module Standby and Software Reset support. Based on the Table 8.2b of "RZ/G Series, 2nd Generation User's Manual: Hardware ((Rev. 0.61, June 12, 2018)". Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Signed-off-by: Geert Uytterhoeven --- .../bindings/clock/renesas,cpg-mssr.txt | 9 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a774a1-cpg-mssr.c | 323 ++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 6 files changed, 341 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/renesas/r8a774a1-cpg-mssr.c diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index db542abadb75..42d0f83d812b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -16,6 +16,7 @@ Required Properties: - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) + - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H) @@ -35,10 +36,10 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7792, - r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, - r8a77980, r8a77990, r8a77995) - - "extalr" (r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) + - "extal" (r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, r8a7791, + r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, + r8a77970, r8a77980, r8a77990, r8a77995) + - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 9022bbe1297e..f998a7333acb 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -8,6 +8,7 @@ config CLK_RENESAS select CLK_R8A7743 if ARCH_R8A7743 select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 + select CLK_R8A774A1 if ARCH_R8A774A1 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 select CLK_R8A7790 if ARCH_R8A7790 @@ -67,6 +68,10 @@ config CLK_R8A77470 bool "RZ/G1C clock support" if COMPILE_TEST select CLK_RCAR_GEN2_CPG +config CLK_R8A774A1 + bool "RZ/G2M clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A7778 bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index e4aa3d6143d2..71d4cafe15c0 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c new file mode 100644 index 000000000000..b0da34217bdf --- /dev/null +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774a1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774A1_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_BASE("z", R8A774A1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A774A1_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), + DEF_FIXED("ztr", R8A774A1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774A1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774A1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774A1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774A1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774A1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774A1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774A1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774A1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774A1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774A1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774A1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774A1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774A1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774A1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774A1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774A1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774A1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774A1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("csi0", R8A774A1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774A1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774A1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774A1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774A1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { + DEF_MOD("fdp1-0", 119, R8A774A1_CLK_S0D1), + DEF_MOD("scif5", 202, R8A774A1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774A1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774A1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774A1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774A1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774A1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774A1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774A1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774A1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774A1_CLK_S0D3), + DEF_MOD("sys-dmac1", 218, R8A774A1_CLK_S0D3), + DEF_MOD("sys-dmac0", 219, R8A774A1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774A1_CLK_R), + DEF_MOD("cmt2", 301, R8A774A1_CLK_R), + DEF_MOD("cmt1", 302, R8A774A1_CLK_R), + DEF_MOD("cmt0", 303, R8A774A1_CLK_R), + DEF_MOD("scif2", 310, R8A774A1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774A1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774A1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774A1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774A1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774A1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774A1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774A1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774A1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774A1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774A1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774A1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774A1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774A1_CLK_S0D3), + DEF_MOD("audmac0", 502, R8A774A1_CLK_S0D3), + DEF_MOD("hscif4", 516, R8A774A1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774A1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774A1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774A1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774A1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774A1_CLK_CP), + DEF_MOD("pwm", 523, R8A774A1_CLK_S0D12), + DEF_MOD("fcpvd2", 601, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvd1", 602, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A774A1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774A1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774A1_CLK_S0D1), + DEF_MOD("fcpci0", 617, R8A774A1_CLK_S0D2), + DEF_MOD("fcpcs", 619, R8A774A1_CLK_S0D2), + DEF_MOD("vspd2", 621, R8A774A1_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A774A1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774A1_CLK_S0D2), + DEF_MOD("vspb", 626, R8A774A1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774A1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774A1_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A774A1_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A774A1_CLK_S3D4), + DEF_MOD("csi20", 714, R8A774A1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774A1_CLK_CSI0), + DEF_MOD("du2", 722, R8A774A1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774A1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774A1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774A1_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A774A1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774A1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774A1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774A1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774A1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774A1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774A1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774A1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774A1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774A1_CLK_S0D6), + DEF_MOD("gpio7", 905, R8A774A1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774A1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774A1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774A1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774A1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774A1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774A1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774A1_CLK_S3D4), + DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774A1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774A1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774A1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774A1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774A1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774A1_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774A1_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a774a1_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +static int __init r8a774a1_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a774a1_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774a1_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774a1_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774a1_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774a1_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774a1_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774a1_crit_mod_clks), + + /* Callbacks */ + .init = r8a774a1_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index e04338932786..f90b0d0ba46a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -664,6 +664,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a77470_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774A1 + { + .compatible = "renesas,r8a774a1-cpg-mssr", + .data = &r8a774a1_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7790 { .compatible = "renesas,r8a7790-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 87bb8f368d4e..2e1730bc5ef2 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -137,6 +137,7 @@ struct cpg_mssr_info { extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; From cc4f6944d0e333ed57a2f300afd7c8cb6df228d5 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 11 Aug 2018 07:23:55 +0530 Subject: [PATCH 023/836] clk: qcom: Add support for RCG to register for DFS Dynamic Frequency switch is a feature of clock controller by which request from peripherals allows automatic switching frequency of input clock without SW intervention. There are various performance levels associated with a root clock. When the input performance state changes, the source clocks and division ratios of the new performance state are loaded on to RCG via HW and the RCG switches to new clock frequency when the RCG is in DFS HW enabled mode. Register the root clock generators(RCG) to switch to use the dfs clock ops in the cases where DFS is enabled. The clk_round_rate() called by the clock consumer would invoke the dfs determine clock ops and would read the DFS performance level registers to identify all the frequencies supported and update the frequency table. The DFS clock consumers would maintain these frequency mapping and request the desired performance levels. Signed-off-by: Taniya Das [sboyd@kernel.org: Rework registration logic to stop copying, change recalc_rate() to index directly into the table if possible and fallback to calculating on the fly with an assumed correct parent] Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rcg.h | 11 ++ drivers/clk/qcom/clk-rcg2.c | 194 ++++++++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index dbd5a9e83554..e5eca8a1abe4 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -163,4 +163,15 @@ extern const struct clk_ops clk_pixel_ops; extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +struct clk_rcg_dfs_data { + struct clk_rcg2 *rcg; + struct clk_init_data *init; +}; + +#define DEFINE_RCG_DFS(r) \ + { .rcg = &r##_src, .init = &r##_init } + +extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, + const struct clk_rcg_dfs_data *rcgs, + size_t len); #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4165f4..d5d77f9ad170 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -40,6 +41,14 @@ #define N_REG 0xc #define D_REG 0x10 +/* Dynamic Frequency Scaling */ +#define MAX_PERF_LEVEL 8 +#define SE_CMD_DFSR_OFFSET 0x14 +#define SE_CMD_DFS_EN BIT(0) +#define SE_PERF_DFSR(level) (0x1c + 0x4 * (level)) +#define SE_PERF_M_DFSR(level) (0x5c + 0x4 * (level)) +#define SE_PERF_N_DFSR(level) (0x9c + 0x4 * (level)) + enum freq_policy { FLOOR, CEIL, @@ -929,3 +938,188 @@ const struct clk_ops clk_rcg2_shared_ops = { .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +/* Common APIs to be used for DFS based RCGR */ +static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l, + struct freq_tbl *f) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct clk_hw *p; + unsigned long prate = 0; + u32 val, mask, cfg, mode; + int i, num_parents; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg); + + mask = BIT(rcg->hid_width) - 1; + f->pre_div = 1; + if (cfg & mask) + f->pre_div = cfg & mask; + + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + num_parents = clk_hw_get_num_parents(hw); + for (i = 0; i < num_parents; i++) { + if (cfg == rcg->parent_map[i].cfg) { + f->src = rcg->parent_map[i].src; + p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i); + prate = clk_hw_get_rate(p); + } + } + + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + if (mode) { + mask = BIT(rcg->mnd_width) - 1; + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_M_DFSR(l), + &val); + val &= mask; + f->m = val; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_N_DFSR(l), + &val); + val = ~val; + val &= mask; + val += f->m; + f->n = val; + } + + f->freq = calc_rate(prate, f->m, f->n, mode, f->pre_div); +} + +static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg) +{ + struct freq_tbl *freq_tbl; + int i; + + freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(*freq_tbl), GFP_KERNEL); + if (!freq_tbl) + return -ENOMEM; + rcg->freq_tbl = freq_tbl; + + for (i = 0; i < MAX_PERF_LEVEL; i++) + clk_rcg2_dfs_populate_freq(&rcg->clkr.hw, i, freq_tbl + i); + + return 0; +} + +static int clk_rcg2_dfs_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + int ret; + + if (!rcg->freq_tbl) { + ret = clk_rcg2_dfs_populate_freq_table(rcg); + if (ret) { + pr_err("Failed to update DFS tables for %s\n", + clk_hw_get_name(hw)); + return ret; + } + } + + return clk_rcg2_determine_rate(hw, req); +} + +static unsigned long +clk_rcg2_dfs_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 level, mask, cfg, m = 0, n = 0, mode, pre_div; + + regmap_read(rcg->clkr.regmap, + rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &level); + level &= GENMASK(4, 1); + level >>= 1; + + if (rcg->freq_tbl) + return rcg->freq_tbl[level].freq; + + /* + * Assume that parent_rate is actually the parent because + * we can't do any better at figuring it out when the table + * hasn't been populated yet. We only populate the table + * in determine_rate because we can't guarantee the parents + * will be registered with the framework until then. + */ + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(level), + &cfg); + + mask = BIT(rcg->hid_width) - 1; + pre_div = 1; + if (cfg & mask) + pre_div = cfg & mask; + + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + if (mode) { + mask = BIT(rcg->mnd_width) - 1; + regmap_read(rcg->clkr.regmap, + rcg->cmd_rcgr + SE_PERF_M_DFSR(level), &m); + m &= mask; + + regmap_read(rcg->clkr.regmap, + rcg->cmd_rcgr + SE_PERF_N_DFSR(level), &n); + n = ~n; + n &= mask; + n += m; + } + + return calc_rate(parent_rate, m, n, mode, pre_div); +} + +static const struct clk_ops clk_rcg2_dfs_ops = { + .is_enabled = clk_rcg2_is_enabled, + .get_parent = clk_rcg2_get_parent, + .determine_rate = clk_rcg2_dfs_determine_rate, + .recalc_rate = clk_rcg2_dfs_recalc_rate, +}; + +static int clk_rcg2_enable_dfs(const struct clk_rcg_dfs_data *data, + struct regmap *regmap) +{ + struct clk_rcg2 *rcg = data->rcg; + struct clk_init_data *init = data->init; + u32 val; + int ret; + + ret = regmap_read(regmap, rcg->cmd_rcgr + SE_CMD_DFSR_OFFSET, &val); + if (ret) + return -EINVAL; + + if (!(val & SE_CMD_DFS_EN)) + return 0; + + /* + * Rate changes with consumer writing a register in + * their own I/O region + */ + init->flags |= CLK_GET_RATE_NOCACHE; + init->ops = &clk_rcg2_dfs_ops; + + rcg->freq_tbl = NULL; + + pr_debug("DFS registered for clk %s\n", init->name); + + return 0; +} + +int qcom_cc_register_rcg_dfs(struct regmap *regmap, + const struct clk_rcg_dfs_data *rcgs, size_t len) +{ + int i, ret; + + for (i = 0; i < len; i++) { + ret = clk_rcg2_enable_dfs(&rcgs[i], regmap); + if (ret) { + const char *name = rcgs[i].init->name; + + pr_err("DFS register failed for clk %s\n", name); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs); From 8b69c6dba2300b616737bbfc28685d86d786b11d Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Sat, 11 Aug 2018 07:23:56 +0530 Subject: [PATCH 024/836] clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845 QUPv3 clocks support DFS and thus register the RCGs which require support for the same. Signed-off-by: Taniya Das [sboyd@kernel.org: Use new macro, split out init structures so they don't have to be copied] Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-sdm845.c | 249 +++++++++++++++++++++------------- 1 file changed, 153 insertions(+), 96 deletions(-) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index fa1a196350f1..42ab01d33b52 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -396,18 +396,27 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { { } }; +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, +}; + static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { .cmd_rcgr = 0x17034, .mnd_width = 16, .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s0_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { @@ -416,12 +425,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s1_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { @@ -430,12 +441,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s2_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { @@ -444,12 +457,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s3_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { @@ -458,12 +473,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s4_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { @@ -472,12 +489,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s5_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = { + .name = "gcc_qupv3_wrap0_s6_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { @@ -486,12 +505,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s6_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = { + .name = "gcc_qupv3_wrap0_s7_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { @@ -500,12 +521,14 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap0_s7_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { @@ -514,12 +537,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s0_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { @@ -528,12 +553,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s1_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { @@ -542,12 +569,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s2_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { @@ -556,12 +585,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s3_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { @@ -570,12 +601,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s4_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { @@ -584,12 +617,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s5_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { @@ -598,12 +633,14 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s6_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { @@ -612,12 +649,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { .hid_width = 5, .parent_map = gcc_parent_map_0, .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, - .clkr.hw.init = &(struct clk_init_data){ - .name = "gcc_qupv3_wrap1_s7_clk_src", - .parent_names = gcc_parent_names_0, - .num_parents = 4, - .ops = &clk_rcg2_shared_ops, - }, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_init, }; static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { @@ -3458,9 +3490,29 @@ static const struct of_device_id gcc_sdm845_match_table[] = { }; MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk), +}; + static int gcc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; regmap = qcom_cc_map(pdev, &gcc_sdm845_desc); if (IS_ERR(regmap)) @@ -3470,6 +3522,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap); } From f300168a3a012a4e49ef550d69bd4dbcfc97a23f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 7 Aug 2018 18:17:11 +0200 Subject: [PATCH 025/836] clk: max77686: Add SPDX license identifiers Replace GPL v2.0 and v2.0+ license statements with SPDX license identifiers. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Stephen Boyd --- drivers/clk/clk-max77686.c | 27 +++++----------------- include/dt-bindings/clock/maxim,max77686.h | 5 +--- include/dt-bindings/clock/maxim,max77802.h | 5 +--- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index eb953d3b0b69..02551fe4b87c 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -1,24 +1,9 @@ -/* - * clk-max77686.c - Clock driver for Maxim 77686/MAX77802 - * - * Copyright (C) 2012 Samsung Electornics - * Jonghwa Lee - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// clk-max77686.c - Clock driver for Maxim 77686/MAX77802 +// +// Copyright (C) 2012 Samsung Electornics +// Jonghwa Lee #include #include diff --git a/include/dt-bindings/clock/maxim,max77686.h b/include/dt-bindings/clock/maxim,max77686.h index 7b28b0905869..af8261dcace1 100644 --- a/include/dt-bindings/clock/maxim,max77686.h +++ b/include/dt-bindings/clock/maxim,max77686.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2014 Google, Inc * - * 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. - * * Device Tree binding constants clocks for the Maxim 77686 PMIC. */ diff --git a/include/dt-bindings/clock/maxim,max77802.h b/include/dt-bindings/clock/maxim,max77802.h index 997312edcbb5..51adcbaed697 100644 --- a/include/dt-bindings/clock/maxim,max77802.h +++ b/include/dt-bindings/clock/maxim,max77802.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2014 Google, Inc * - * 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. - * * Device Tree binding constants clocks for the Maxim 77802 PMIC. */ From 94047d979574dda95a92a0e696189afb9b284ede Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 7 Aug 2018 18:17:12 +0200 Subject: [PATCH 026/836] clk: s2mps11,s3c64xx: Add SPDX license identifiers Replace GPL v2.0 and v2.0+ license statements with SPDX license identifiers. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/clk-s2mps11.c | 21 +++++-------------- include/dt-bindings/clock/samsung,s2mps11.h | 5 +---- .../dt-bindings/clock/samsung,s3c64xx-clock.h | 7 ++----- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index d44e0eea31ec..ebf9115dad1d 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -1,19 +1,8 @@ -/* - * clk-s2mps11.c - Clock driver for S2MPS11. - * - * Copyright (C) 2013,2014 Samsung Electornics - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// clk-s2mps11.c - Clock driver for S2MPS11. +// +// Copyright (C) 2013,2014 Samsung Electornics #include #include diff --git a/include/dt-bindings/clock/samsung,s2mps11.h b/include/dt-bindings/clock/samsung,s2mps11.h index b903d7de27c9..5ece35d429ff 100644 --- a/include/dt-bindings/clock/samsung,s2mps11.h +++ b/include/dt-bindings/clock/samsung,s2mps11.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2015 Markus Reichl * - * 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. - * * Device Tree binding constants clocks for the Samsung S2MPS11 PMIC. */ diff --git a/include/dt-bindings/clock/samsung,s3c64xx-clock.h b/include/dt-bindings/clock/samsung,s3c64xx-clock.h index ad95c7f50090..19d233f37e2f 100644 --- a/include/dt-bindings/clock/samsung,s3c64xx-clock.h +++ b/include/dt-bindings/clock/samsung,s3c64xx-clock.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Tomasz Figa * - * 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. - * * Device Tree binding constants for Samsung S3C64xx clock controller. -*/ + */ #ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H #define _DT_BINDINGS_CLOCK_SAMSUNG_S3C64XX_CLOCK_H From 8748b4a786a9e3973f6e6521edff7b266cafef48 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 7 Aug 2018 18:17:13 +0200 Subject: [PATCH 027/836] clk: s2mps11: Use existing defines from bindings for clock IDs The clock IDs must match between DeviceTree bindings and the driver. There is already a header file used by DeviceTree sources so include it in the driver to remove duplicated symbols. Signed-off-by: Krzysztof Kozlowski Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/clk-s2mps11.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index d44e0eea31ec..7c961bf2bfc7 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -28,12 +28,7 @@ #include #include -enum { - S2MPS11_CLK_AP = 0, - S2MPS11_CLK_CP, - S2MPS11_CLK_BT, - S2MPS11_CLKS_NUM, -}; +#include struct s2mps11_clk { struct sec_pmic_dev *iodev; From bc7133cef81283d48a426604ef4af1507e2b20d9 Mon Sep 17 00:00:00 2001 From: Hoan Nguyen An Date: Fri, 24 Aug 2018 13:52:29 +0900 Subject: [PATCH 028/836] clk: renesas: r8a77965: Add FDP clock This patch adds FDP1-0 clock to the R8A77965 SoC. Signed-off-by: Hoan Nguyen An Reviewed-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77965-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index 312f9fe738e3..1fcc411502da 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -112,6 +112,7 @@ static const struct cpg_core_clk r8a77965_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a77965_mod_clks[] __initconst = { + DEF_MOD("fdp1-0", 119, R8A77965_CLK_S0D1), DEF_MOD("scif5", 202, R8A77965_CLK_S3D4), DEF_MOD("scif4", 203, R8A77965_CLK_S3D4), DEF_MOD("scif3", 204, R8A77965_CLK_S3D4), From b567752144e39a6bc621d56b8f09daba041c7806 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 9 Aug 2018 15:01:19 -0700 Subject: [PATCH 029/836] clk: qcom: Add some missing gcc clks for msm8996 Add a few missing gcc clks for msm8996 Signed-off-by: Rajendra Nayak [bjorn: omit aggre0_noc_qosgen_extref_clk] Signed-off-by: Bjorn Andersson Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-msm8996.c | 152 +++++++++++++++++++ include/dt-bindings/clock/qcom,gcc-msm8996.h | 9 ++ 2 files changed, 161 insertions(+) diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 9a3290fdd01b..9d136172c27c 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -260,6 +260,36 @@ static struct clk_alpha_pll_postdiv gpll0 = { }, }; +static struct clk_branch gcc_mmss_gpll0_div_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mmss_gpll0_div_clk", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_gpll0_div_clk = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_gpll0_div_clk", + .parent_names = (const char *[]){ "gpll0" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops + }, + }, +}; + static struct clk_alpha_pll gpll4_early = { .offset = 0x77000, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], @@ -2951,6 +2981,20 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { }, }; +static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { + .halt_reg = 0x82014, + .clkr = { + .enable_reg = 0x82014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre1_pnoc_ahb_clk", + .parent_names = (const char *[]){ "periph_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_aggre2_ufs_axi_clk = { .halt_reg = 0x83014, .clkr = { @@ -2981,6 +3025,34 @@ static struct clk_branch gcc_aggre2_usb3_axi_clk = { }, }; +static struct clk_branch gcc_dcc_ahb_clk = { + .halt_reg = 0x84004, + .clkr = { + .enable_reg = 0x84004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcc_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = { + .halt_reg = 0x85000, + .clkr = { + .enable_reg = 0x85000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_qspi_ahb_clk = { .halt_reg = 0x8b004, .clkr = { @@ -3039,6 +3111,20 @@ static struct clk_branch gcc_hdmi_clkref_clk = { }, }; +static struct clk_branch gcc_edp_clkref_clk = { + .halt_reg = 0x88004, + .clkr = { + .enable_reg = 0x88004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_edp_clkref_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_ufs_clkref_clk = { .halt_reg = 0x88008, .clkr = { @@ -3095,6 +3181,62 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = { }, }; +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x8a000, + .clkr = { + .enable_reg = 0x8a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .parent_names = (const char *[]){ "config_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { + .halt_reg = 0x8a004, + .clkr = { + .enable_reg = 0x8a004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_mnoc_bimc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_snoc_axi_clk = { + .halt_reg = 0x8a024, + .clkr = { + .enable_reg = 0x8a024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_snoc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x8a028, + .clkr = { + .enable_reg = 0x8a028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .parent_names = (const char *[]){ "system_noc_clk_src" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_hw *gcc_msm8996_hws[] = { &xo.hw, &gpll0_early_div.hw, @@ -3355,6 +3497,7 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, + [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, @@ -3365,6 +3508,15 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr, [GCC_RX2_USB2_CLKREF_CLK] = &gcc_rx2_usb2_clkref_clk.clkr, [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, + [GCC_EDP_CLKREF_CLK] = &gcc_edp_clkref_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, + [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, + [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr, + [GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK] = &gcc_aggre0_noc_mpu_cfg_ahb_clk.clkr, + [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr, + [GCC_MSS_GPLL0_DIV_CLK] = &gcc_mss_gpll0_div_clk.clkr, }; static struct gdsc *gcc_msm8996_gdscs[] = { diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index 75b07cf5eed0..db80f2ee571b 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h @@ -235,6 +235,15 @@ #define GCC_RX1_USB2_CLKREF_CLK 218 #define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 219 #define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 220 +#define GCC_EDP_CLKREF_CLK 221 +#define GCC_MSS_CFG_AHB_CLK 222 +#define GCC_MSS_Q6_BIMC_AXI_CLK 223 +#define GCC_MSS_SNOC_AXI_CLK 224 +#define GCC_MSS_MNOC_BIMC_AXI_CLK 225 +#define GCC_DCC_AHB_CLK 226 +#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK 227 +#define GCC_MMSS_GPLL0_DIV_CLK 228 +#define GCC_MSS_GPLL0_DIV_CLK 229 #define GCC_SYSTEM_NOC_BCR 0 #define GCC_CONFIG_NOC_BCR 1 From 48735597f7bd4421fe1e9392899ae9654c263315 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 24 Jul 2018 10:45:12 -0700 Subject: [PATCH 030/836] clk: qcom: Add qspi (Quad SPI) clock defines for sdm845 to header These clocks will need to be defined in the clock driver and referenced in device tree files. Signed-off-by: Douglas Anderson Acked-by: Rob Herring Reviewed-by: Taniya Das Signed-off-by: Stephen Boyd --- include/dt-bindings/clock/qcom,gcc-sdm845.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/dt-bindings/clock/qcom,gcc-sdm845.h b/include/dt-bindings/clock/qcom,gcc-sdm845.h index f96fc2dbf60e..b8eae5a76503 100644 --- a/include/dt-bindings/clock/qcom,gcc-sdm845.h +++ b/include/dt-bindings/clock/qcom,gcc-sdm845.h @@ -194,6 +194,9 @@ #define GPLL4 184 #define GCC_CPUSS_DVM_BUS_CLK 185 #define GCC_CPUSS_GNOC_CLK 186 +#define GCC_QSPI_CORE_CLK_SRC 187 +#define GCC_QSPI_CORE_CLK 188 +#define GCC_QSPI_CNOC_PERIPH_AHB_CLK 189 /* GCC Resets */ #define GCC_MMSS_BCR 0 From 4f83d9b848f67f85df04e69740bf8d70cb4a72b6 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 24 Jul 2018 10:45:13 -0700 Subject: [PATCH 031/836] clk: qcom: Add qspi (Quad SPI) clocks for sdm845 Add both the interface and core clock. Signed-off-by: Douglas Anderson Reviewed-by: Taniya Das Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gcc-sdm845.c | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index fa1a196350f1..5d8fbf34886b 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -356,6 +356,28 @@ static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qspi_core_clk_src = { + .cmd_rcgr = 0x4b008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qspi_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk_src", + .parent_names = gcc_parent_names_0, + .num_parents = 4, + .ops = &clk_rcg2_floor_ops, + }, +}; + static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { F(9600000, P_BI_TCXO, 2, 0, 0), F(19200000, P_BI_TCXO, 1, 0, 0), @@ -1933,6 +1955,37 @@ static struct clk_branch gcc_qmip_video_ahb_clk = { }, }; +static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = { + .halt_reg = 0x4b000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_cnoc_periph_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qspi_core_clk = { + .halt_reg = 0x4b004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4b004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qspi_core_clk", + .parent_names = (const char *[]){ + "gcc_qspi_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_qupv3_wrap0_s0_clk = { .halt_reg = 0x17030, .halt_check = BRANCH_HALT_VOTED, @@ -3381,6 +3434,9 @@ static struct clk_regmap *gcc_sdm845_clocks[] = { [GPLL4] = &gpll4.clkr, [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, + [GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr, + [GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr, + [GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr, }; static const struct qcom_reset_map gcc_sdm845_resets[] = { From e665f029a283aff4f36f0c5388f7c708be67470e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 28 Aug 2018 10:44:29 -0500 Subject: [PATCH 032/836] clk: Convert to using %pOFn instead of device_node.name In preparation to remove the node name pointer from struct device_node, convert printf users to use the %pOFn format specifier. Cc: Eugeniy Paltsev Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-clk@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Cc: linux-renesas-soc@vger.kernel.org Cc: linux-omap@vger.kernel.org Signed-off-by: Rob Herring Signed-off-by: Stephen Boyd --- drivers/clk/axs10x/pll_clock.c | 4 ++-- drivers/clk/bcm/clk-kona-setup.c | 22 +++++++++++----------- drivers/clk/clk-asm9260.c | 4 ++-- drivers/clk/clk-cdce925.c | 10 +++++----- drivers/clk/clk-fixed-factor.c | 8 ++++---- drivers/clk/clk-gpio.c | 8 ++++---- drivers/clk/clk-hsdk-pll.c | 4 ++-- drivers/clk/clk-nomadik.c | 4 ++-- drivers/clk/clk-npcm7xx.c | 2 +- drivers/clk/clk-palmas.c | 4 ++-- drivers/clk/clk-qoriq.c | 14 +++++++------- drivers/clk/clk-scmi.c | 2 +- drivers/clk/clk-scpi.c | 6 +++--- drivers/clk/clk-si5351.c | 4 ++-- drivers/clk/clk-stm32f4.c | 2 +- drivers/clk/clk-stm32h7.c | 2 +- drivers/clk/clk-stm32mp1.c | 2 +- drivers/clk/clk-tango4.c | 10 +++++----- drivers/clk/keystone/gate.c | 2 +- drivers/clk/keystone/pll.c | 2 +- drivers/clk/renesas/clk-div6.c | 12 ++++++------ drivers/clk/renesas/clk-emev2.c | 8 ++++---- drivers/clk/renesas/clk-mstp.c | 8 ++++---- drivers/clk/renesas/clk-r8a73a4.c | 4 ++-- drivers/clk/renesas/clk-r8a7740.c | 4 ++-- drivers/clk/renesas/clk-r8a7778.c | 4 ++-- drivers/clk/renesas/clk-r8a7779.c | 4 ++-- drivers/clk/renesas/clk-rcar-gen2.c | 4 ++-- drivers/clk/renesas/clk-rz.c | 4 ++-- drivers/clk/renesas/clk-sh73a0.c | 4 ++-- drivers/clk/st/clkgen-fsyn.c | 2 +- drivers/clk/sunxi/clk-mod0.c | 6 +++--- drivers/clk/sunxi/clk-sun9i-core.c | 20 ++++++++++---------- drivers/clk/sunxi/clk-sunxi.c | 4 ++-- drivers/clk/ti/apll.c | 18 +++++++++--------- drivers/clk/ti/clk-dra7-atl.c | 4 ++-- drivers/clk/ti/clk.c | 10 +++++----- drivers/clk/ti/clkctrl.c | 14 ++++++-------- drivers/clk/ti/composite.c | 14 +++++++------- drivers/clk/ti/divider.c | 4 ++-- drivers/clk/ti/dpll.c | 12 ++++++------ drivers/clk/ti/fapll.c | 8 ++++---- drivers/clk/ti/fixed-factor.c | 4 ++-- drivers/clk/ti/gate.c | 2 +- drivers/clk/ti/interface.c | 2 +- drivers/clk/ti/mux.c | 4 ++-- drivers/clk/zynq/clkc.c | 4 ++-- 47 files changed, 151 insertions(+), 153 deletions(-) diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c index 25d8c240ddfb..c68dada97316 100644 --- a/drivers/clk/axs10x/pll_clock.c +++ b/drivers/clk/axs10x/pll_clock.c @@ -301,13 +301,13 @@ static void __init of_axs10x_pll_clk_setup(struct device_node *node) ret = clk_hw_register(NULL, &pll_clk->hw); if (ret) { - pr_err("failed to register %s clock\n", node->name); + pr_err("failed to register %pOFn clock\n", node); goto err_unmap_lock; } ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); if (ret) { - pr_err("failed to add hw provider for %s clock\n", node->name); + pr_err("failed to add hw provider for %pOFn clock\n", node); goto err_unregister_clk; } diff --git a/drivers/clk/bcm/clk-kona-setup.c b/drivers/clk/bcm/clk-kona-setup.c index 281f4322355c..e65eeef9cbaf 100644 --- a/drivers/clk/bcm/clk-kona-setup.c +++ b/drivers/clk/bcm/clk-kona-setup.c @@ -808,29 +808,29 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, ret = of_address_to_resource(node, 0, &res); if (ret) { - pr_err("%s: no valid CCU registers found for %s\n", __func__, - node->name); + pr_err("%s: no valid CCU registers found for %pOFn\n", __func__, + node); goto out_err; } range = resource_size(&res); if (range > (resource_size_t)U32_MAX) { - pr_err("%s: address range too large for %s\n", __func__, - node->name); + pr_err("%s: address range too large for %pOFn\n", __func__, + node); goto out_err; } ccu->range = (u32)range; if (!ccu_data_valid(ccu)) { - pr_err("%s: ccu data not valid for %s\n", __func__, node->name); + pr_err("%s: ccu data not valid for %pOFn\n", __func__, node); goto out_err; } ccu->base = ioremap(res.start, ccu->range); if (!ccu->base) { - pr_err("%s: unable to map CCU registers for %s\n", __func__, - node->name); + pr_err("%s: unable to map CCU registers for %pOFn\n", __func__, + node); goto out_err; } ccu->node = of_node_get(node); @@ -848,16 +848,16 @@ void __init kona_dt_ccu_setup(struct ccu_data *ccu, ret = of_clk_add_hw_provider(node, of_clk_kona_onecell_get, ccu); if (ret) { - pr_err("%s: error adding ccu %s as provider (%d)\n", __func__, - node->name, ret); + pr_err("%s: error adding ccu %pOFn as provider (%d)\n", __func__, + node, ret); goto out_err; } if (!kona_ccu_init(ccu)) - pr_err("Broadcom %s initialization had errors\n", node->name); + pr_err("Broadcom %pOFn initialization had errors\n", node); return; out_err: kona_ccu_teardown(ccu); - pr_err("Broadcom %s setup aborted\n", node->name); + pr_err("Broadcom %pOFn setup aborted\n", node); } diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index 44b544157121..d571a00b5282 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c @@ -281,7 +281,7 @@ static void __init asm9260_acc_init(struct device_node *np) base = of_io_request_and_map(np, 0, np->name); if (IS_ERR(base)) - panic("%s: unable to map resource", np->name); + panic("%pOFn: unable to map resource", np); /* register pll */ rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000; @@ -292,7 +292,7 @@ static void __init asm9260_acc_init(struct device_node *np) ref_clk, 0, rate, accuracy); if (IS_ERR(hw)) - panic("%s: can't register REFCLK. Check DT!", np->name); + panic("%pOFn: can't register REFCLK. Check DT!", np); for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) { const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n]; diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 0a7e7d5a7506..49531a2a5436 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -669,8 +669,8 @@ static int cdce925_probe(struct i2c_client *client, /* Register PLL clocks */ for (i = 0; i < data->chip_info->num_plls; ++i) { - pll_clk_name[i] = kasprintf(GFP_KERNEL, "%s.pll%d", - client->dev.of_node->name, i); + pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", + client->dev.of_node, i); init.name = pll_clk_name[i]; data->pll[i].chip = data; data->pll[i].hw.init = &init; @@ -710,7 +710,7 @@ static int cdce925_probe(struct i2c_client *client, init.flags = 0; init.num_parents = 1; init.parent_names = &parent_name; /* Mux Y1 to input */ - init.name = kasprintf(GFP_KERNEL, "%s.Y1", client->dev.of_node->name); + init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); data->clk[0].chip = data; data->clk[0].hw.init = &init; data->clk[0].index = 0; @@ -727,8 +727,8 @@ static int cdce925_probe(struct i2c_client *client, init.flags = CLK_SET_RATE_PARENT; init.num_parents = 1; for (i = 1; i < data->chip_info->num_outputs; ++i) { - init.name = kasprintf(GFP_KERNEL, "%s.Y%d", - client->dev.of_node->name, i+1); + init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", + client->dev.of_node, i+1); data->clk[i].chip = data; data->clk[i].hw.init = &init; data->clk[i].index = i; diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 20724abd38bd..ef0ca9414f37 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -158,14 +158,14 @@ static struct clk *_of_fixed_factor_clk_setup(struct device_node *node) int ret; if (of_property_read_u32(node, "clock-div", &div)) { - pr_err("%s Fixed factor clock <%s> must have a clock-div property\n", - __func__, node->name); + pr_err("%s Fixed factor clock <%pOFn> must have a clock-div property\n", + __func__, node); return ERR_PTR(-EIO); } if (of_property_read_u32(node, "clock-mult", &mult)) { - pr_err("%s Fixed factor clock <%s> must have a clock-mult property\n", - __func__, node->name); + pr_err("%s Fixed factor clock <%pOFn> must have a clock-mult property\n", + __func__, node); return ERR_PTR(-EIO); } diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 40af4fbab4d2..6a43ce420492 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -233,11 +233,11 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) if (IS_ERR(gpiod)) { ret = PTR_ERR(gpiod); if (ret == -EPROBE_DEFER) - pr_debug("%s: %s: GPIOs not yet available, retry later\n", - node->name, __func__); + pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n", + node, __func__); else - pr_err("%s: %s: Can't get '%s' named GPIO property\n", - node->name, __func__, + pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n", + node, __func__, gpio_name); return ret; } diff --git a/drivers/clk/clk-hsdk-pll.c b/drivers/clk/clk-hsdk-pll.c index c4ee280f454d..a47c2b600f20 100644 --- a/drivers/clk/clk-hsdk-pll.c +++ b/drivers/clk/clk-hsdk-pll.c @@ -390,13 +390,13 @@ static void __init of_hsdk_pll_clk_setup(struct device_node *node) ret = clk_hw_register(NULL, &pll_clk->hw); if (ret) { - pr_err("failed to register %s clock\n", node->name); + pr_err("failed to register %pOFn clock\n", node); goto err_unmap_spec_regs; } ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); if (ret) { - pr_err("failed to add hw provider for %s clock\n", node->name); + pr_err("failed to add hw provider for %pOFn clock\n", node); goto err_unmap_spec_regs; } diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c index 13ad6d1e5090..84a24875c629 100644 --- a/drivers/clk/clk-nomadik.c +++ b/drivers/clk/clk-nomadik.c @@ -97,8 +97,8 @@ static void __init nomadik_src_init(void) } src_base = of_iomap(np, 0); if (!src_base) { - pr_err("%s: must have src parent node with REGS (%s)\n", - __func__, np->name); + pr_err("%s: must have src parent node with REGS (%pOFn)\n", + __func__, np); return; } diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c index 740af90a9508..afb0eb106953 100644 --- a/drivers/clk/clk-npcm7xx.c +++ b/drivers/clk/clk-npcm7xx.c @@ -549,7 +549,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np) ret = of_address_to_resource(clk_np, 0, &res); if (ret) { - pr_err("%s: failed to get resource, ret %d\n", clk_np->name, + pr_err("%pOFn: failed to get resource, ret %d\n", clk_np, ret); return; } diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 7f51c01085ab..e9612e7068e9 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -195,8 +195,8 @@ static void palmas_clks_get_clk_data(struct platform_device *pdev, prop = PALMAS_EXT_CONTROL_NSLEEP; break; default: - dev_warn(&pdev->dev, "%s: Invalid ext control option: %u\n", - node->name, prop); + dev_warn(&pdev->dev, "%pOFn: Invalid ext control option: %u\n", + node, prop); prop = 0; break; } diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 3a1812f65e5d..4c30b6e799ed 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -945,8 +945,8 @@ static void __init core_mux_init(struct device_node *np) rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); if (rc) { - pr_err("%s: Couldn't register clk provider for node %s: %d\n", - __func__, np->name, rc); + pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n", + __func__, np, rc); return; } } @@ -1199,8 +1199,8 @@ static void __init legacy_pll_init(struct device_node *np, int idx) rc = of_clk_add_provider(np, of_clk_src_onecell_get, onecell_data); if (rc) { - pr_err("%s: Couldn't register clk provider for node %s: %d\n", - __func__, np->name, rc); + pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n", + __func__, np, rc); goto err_cell; } @@ -1360,7 +1360,7 @@ static void __init clockgen_init(struct device_node *np) is_old_ls1021a = true; } if (!clockgen.regs) { - pr_err("%s(): %s: of_iomap() failed\n", __func__, np->name); + pr_err("%s(): %pOFn: of_iomap() failed\n", __func__, np); return; } @@ -1406,8 +1406,8 @@ static void __init clockgen_init(struct device_node *np) ret = of_clk_add_provider(np, clockgen_clk_get, &clockgen); if (ret) { - pr_err("%s: Couldn't register clk provider for node %s: %d\n", - __func__, np->name, ret); + pr_err("%s: Couldn't register clk provider for node %pOFn: %d\n", + __func__, np, ret); } return; diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index a985bf5e1ac6..a2287c770d5c 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -132,7 +132,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev) count = handle->clk_ops->count_get(handle); if (count < 0) { - dev_err(dev, "%s: invalid clock output count\n", np->name); + dev_err(dev, "%pOFn: invalid clock output count\n", np); return -EINVAL; } diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 25854722810e..d3ccc1cfccd5 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -207,7 +207,7 @@ static int scpi_clk_add(struct device *dev, struct device_node *np, count = of_property_count_strings(np, "clock-output-names"); if (count < 0) { - dev_err(dev, "%s: invalid clock output count\n", np->name); + dev_err(dev, "%pOFn: invalid clock output count\n", np); return -EINVAL; } @@ -232,13 +232,13 @@ static int scpi_clk_add(struct device *dev, struct device_node *np, if (of_property_read_string_index(np, "clock-output-names", idx, &name)) { - dev_err(dev, "invalid clock name @ %s\n", np->name); + dev_err(dev, "invalid clock name @ %pOFn\n", np); return -EINVAL; } if (of_property_read_u32_index(np, "clock-indices", idx, &val)) { - dev_err(dev, "invalid clock index @ %s\n", np->name); + dev_err(dev, "invalid clock index @ %pOFn\n", np); return -EINVAL; } diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 50e7c341e97e..8bdf91b56012 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1215,8 +1215,8 @@ static int si5351_dt_parse(struct i2c_client *client, /* per clkout properties */ for_each_child_of_node(np, child) { if (of_property_read_u32(child, "reg", &num)) { - dev_err(&client->dev, "missing reg property of %s\n", - child->name); + dev_err(&client->dev, "missing reg property of %pOFn\n", + child); goto put_child; } diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 294850bdc195..cdaa567c8042 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -1433,7 +1433,7 @@ static void __init stm32f4_rcc_init(struct device_node *np) base = of_iomap(np, 0); if (!base) { - pr_err("%s: unable to map resource\n", np->name); + pr_err("%pOFn: unable to map resource\n", np); return; } diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c index d3271eca3779..0ea7261d15e0 100644 --- a/drivers/clk/clk-stm32h7.c +++ b/drivers/clk/clk-stm32h7.c @@ -1216,7 +1216,7 @@ static void __init stm32h7_rcc_init(struct device_node *np) /* get RCC base @ from DT */ base = of_iomap(np, 0); if (!base) { - pr_err("%s: unable to map resource", np->name); + pr_err("%pOFn: unable to map resource", np); goto err_free_clks; } diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index a907555b2a3d..4f48342bc280 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -2088,7 +2088,7 @@ static void stm32mp1_rcc_init(struct device_node *np) base = of_iomap(np, 0); if (!base) { - pr_err("%s: unable to map resource", np->name); + pr_err("%pOFn: unable to map resource", np); of_node_put(np); return; } diff --git a/drivers/clk/clk-tango4.c b/drivers/clk/clk-tango4.c index 34b22b7930fb..fe12a43f7a40 100644 --- a/drivers/clk/clk-tango4.c +++ b/drivers/clk/clk-tango4.c @@ -54,13 +54,13 @@ static void __init tango4_clkgen_setup(struct device_node *np) const char *parent = of_clk_get_parent_name(np, 0); if (!base) - panic("%s: invalid address\n", np->name); + panic("%pOFn: invalid address\n", np); if (readl(base + CPUCLK_DIV) & DIV_BYPASS) - panic("%s: unsupported cpuclk setup\n", np->name); + panic("%pOFn: unsupported cpuclk setup\n", np); if (readl(base + SYSCLK_DIV) & DIV_BYPASS) - panic("%s: unsupported sysclk setup\n", np->name); + panic("%pOFn: unsupported sysclk setup\n", np); writel(0x100, base + CPUCLK_DIV); /* disable frequency ramping */ @@ -77,9 +77,9 @@ static void __init tango4_clkgen_setup(struct device_node *np) pp[3] = clk_register_fixed_factor(NULL, "sdio_clk", "cd6", 0, 1, 2); if (IS_ERR(pp[0]) || IS_ERR(pp[1]) || IS_ERR(pp[2]) || IS_ERR(pp[3])) - panic("%s: clk registration failed\n", np->name); + panic("%pOFn: clk registration failed\n", np); if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) - panic("%s: clk provider registration failed\n", np->name); + panic("%pOFn: clk provider registration failed\n", np); } CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup); diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c index aed5af23895b..def15db4eef0 100644 --- a/drivers/clk/keystone/gate.c +++ b/drivers/clk/keystone/gate.c @@ -245,7 +245,7 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock) return; } - pr_err("%s: error registering clk %s\n", __func__, node->name); + pr_err("%s: error registering clk %pOFn\n", __func__, node); unmap_domain: iounmap(data->domain_base); diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c index e7e840fb74ea..2b871fc91d56 100644 --- a/drivers/clk/keystone/pll.c +++ b/drivers/clk/keystone/pll.c @@ -219,7 +219,7 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) } out: - pr_err("%s: error initializing pll %s\n", __func__, node->name); + pr_err("%s: error initializing pll %pOFn\n", __func__, node); kfree(pll_data); } diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 9febbf42c3df..3ca4a047edc7 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -312,8 +312,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) num_parents = of_clk_get_parent_count(np); if (num_parents < 1) { - pr_err("%s: no parent found for %s DIV6 clock\n", - __func__, np->name); + pr_err("%s: no parent found for %pOFn DIV6 clock\n", + __func__, np); return; } @@ -324,8 +324,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) reg = of_iomap(np, 0); if (reg == NULL) { - pr_err("%s: failed to map %s DIV6 clock register\n", - __func__, np->name); + pr_err("%s: failed to map %pOFn DIV6 clock register\n", + __func__, np); goto error; } @@ -337,8 +337,8 @@ static void __init cpg_div6_clock_init(struct device_node *np) clk = cpg_div6_register(clk_name, num_parents, parent_names, reg, NULL); if (IS_ERR(clk)) { - pr_err("%s: failed to register %s DIV6 clock (%ld)\n", - __func__, np->name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn DIV6 clock (%ld)\n", + __func__, np, PTR_ERR(clk)); goto error; } diff --git a/drivers/clk/renesas/clk-emev2.c b/drivers/clk/renesas/clk-emev2.c index a91825471c79..a587f63378b3 100644 --- a/drivers/clk/renesas/clk-emev2.c +++ b/drivers/clk/renesas/clk-emev2.c @@ -86,8 +86,8 @@ static void __init emev2_smu_clkdiv_init(struct device_node *np) clk = clk_register_divider(NULL, np->name, parent_name, 0, smu_base + reg[0], reg[1], 8, 0, &lock); of_clk_add_provider(np, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, np->name, NULL); - pr_debug("## %s %s %p\n", __func__, np->name, clk); + clk_register_clkdev(clk, np->full_name, NULL); + pr_debug("## %s %pOFn %p\n", __func__, np, clk); } CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv", emev2_smu_clkdiv_init); @@ -104,7 +104,7 @@ static void __init emev2_smu_gclk_init(struct device_node *np) clk = clk_register_gate(NULL, np->name, parent_name, 0, smu_base + reg[0], reg[1], 0, &lock); of_clk_add_provider(np, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, np->name, NULL); - pr_debug("## %s %s %p\n", __func__, np->name, clk); + clk_register_clkdev(clk, np->full_name, NULL); + pr_debug("## %s %pOFn %p\n", __func__, np, clk); } CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init); diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index e82adcb16a52..b72c7344effa 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -239,8 +239,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) break; if (clkidx >= MSTP_MAX_CLOCKS) { - pr_err("%s: invalid clock %s %s index %u\n", - __func__, np->name, name, clkidx); + pr_err("%s: invalid clock %pOFn %s index %u\n", + __func__, np, name, clkidx); continue; } @@ -259,8 +259,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) */ clk_register_clkdev(clks[clkidx], name, NULL); } else { - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clks[clkidx])); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clks[clkidx])); } } diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c index 7b903ce4c901..48e9f1e816ad 100644 --- a/drivers/clk/renesas/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -228,8 +228,8 @@ static void __init r8a73a4_cpg_clocks_init(struct device_node *np) clk = r8a73a4_cpg_register_clock(np, cpg, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index a7a30d2eca41..da781640f88f 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -187,8 +187,8 @@ static void __init r8a7740_cpg_clocks_init(struct device_node *np) clk = r8a7740_cpg_register_clock(np, cpg, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/renesas/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c index 886a8380e912..9b964611e5b6 100644 --- a/drivers/clk/renesas/clk-r8a7778.c +++ b/drivers/clk/renesas/clk-r8a7778.c @@ -130,8 +130,8 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np) clk = r8a7778_cpg_register_clock(np, cpg, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c index 5adcca4656c3..10019145a912 100644 --- a/drivers/clk/renesas/clk-r8a7779.c +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -164,8 +164,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np) clk = r8a7779_cpg_register_clock(np, cpg, config, plla_mult, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index bccd62f2cb09..06c015d43167 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -445,8 +445,8 @@ static void __init rcar_gen2_cpg_clocks_init(struct device_node *np) clk = rcar_gen2_cpg_register_clock(np, cpg, config, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c index ac2f86d626b6..8ac904912439 100644 --- a/drivers/clk/renesas/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -113,8 +113,8 @@ static void __init rz_cpg_clocks_init(struct device_node *np) clk = rz_cpg_register_clock(np, cpg, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index bab33610eb6c..2f44e0dd7afa 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -206,8 +206,8 @@ static void __init sh73a0_cpg_clocks_init(struct device_node *np) clk = sh73a0_cpg_register_clock(np, cpg, name); if (IS_ERR(clk)) - pr_err("%s: failed to register %s %s clock (%ld)\n", - __func__, np->name, name, PTR_ERR(clk)); + pr_err("%s: failed to register %pOFn %s clock (%ld)\n", + __func__, np, name, PTR_ERR(clk)); else cpg->data.clks[i] = clk; } diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index a79d81985c4e..cfa000007622 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -936,7 +936,7 @@ static void __init st_of_quadfs_setup(struct device_node *np, if (!clk_parent_name) return; - pll_name = kasprintf(GFP_KERNEL, "%s.pll", np->name); + pll_name = kasprintf(GFP_KERNEL, "%pOFn.pll", np); if (!pll_name) return; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index a27c264cc9b4..fc0278a1acc7 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -140,8 +140,8 @@ static void __init sun9i_a80_mod0_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Could not get registers for mod0-clk: %s\n", - node->name); + pr_err("Could not get registers for mod0-clk: %pOFn\n", + node); return; } @@ -306,7 +306,7 @@ static void __init sunxi_mmc_setup(struct device_node *node, reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Couldn't map the %s clock registers\n", node->name); + pr_err("Couldn't map the %pOFn clock registers\n", node); return; } diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index e9295c286d5d..7e21b2b10c94 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -88,8 +88,8 @@ static void __init sun9i_a80_pll4_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Could not get registers for a80-pll4-clk: %s\n", - node->name); + pr_err("Could not get registers for a80-pll4-clk: %pOFn\n", + node); return; } @@ -142,8 +142,8 @@ static void __init sun9i_a80_gt_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Could not get registers for a80-gt-clk: %s\n", - node->name); + pr_err("Could not get registers for a80-gt-clk: %pOFn\n", + node); return; } @@ -197,8 +197,8 @@ static void __init sun9i_a80_ahb_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Could not get registers for a80-ahb-clk: %s\n", - node->name); + pr_err("Could not get registers for a80-ahb-clk: %pOFn\n", + node); return; } @@ -223,8 +223,8 @@ static void __init sun9i_a80_apb0_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Could not get registers for a80-apb0-clk: %s\n", - node->name); + pr_err("Could not get registers for a80-apb0-clk: %pOFn\n", + node); return; } @@ -280,8 +280,8 @@ static void __init sun9i_a80_apb1_setup(struct device_node *node) reg = of_io_request_and_map(node, 0, of_node_full_name(node)); if (IS_ERR(reg)) { - pr_err("Could not get registers for a80-apb1-clk: %s\n", - node->name); + pr_err("Could not get registers for a80-apb1-clk: %pOFn\n", + node); return; } diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 012714d94b42..892c29030b7b 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -568,8 +568,8 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, reg = of_iomap(node, 0); if (!reg) { - pr_err("Could not get registers for factors-clk: %s\n", - node->name); + pr_err("Could not get registers for factors-clk: %pOFn\n", + node); return NULL; } diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index 61c126a5d26a..222f68bc3f2a 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -143,8 +143,8 @@ static void __init omap_clk_register_apll(void *user, clk = of_clk_get(node, 0); if (IS_ERR(clk)) { - pr_debug("clk-ref for %s not ready, retry\n", - node->name); + pr_debug("clk-ref for %pOFn not ready, retry\n", + node); if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) return; @@ -155,8 +155,8 @@ static void __init omap_clk_register_apll(void *user, clk = of_clk_get(node, 1); if (IS_ERR(clk)) { - pr_debug("clk-bypass for %s not ready, retry\n", - node->name); + pr_debug("clk-bypass for %pOFn not ready, retry\n", + node); if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) return; @@ -202,7 +202,7 @@ static void __init of_dra7_apll_setup(struct device_node *node) init->num_parents = of_clk_get_parent_count(node); if (init->num_parents < 1) { - pr_err("dra7 apll %s must have parent(s)\n", node->name); + pr_err("dra7 apll %pOFn must have parent(s)\n", node); goto cleanup; } @@ -366,7 +366,7 @@ static void __init of_omap2_apll_setup(struct device_node *node) init->num_parents = of_clk_get_parent_count(node); if (init->num_parents != 1) { - pr_err("%s must have one parent\n", node->name); + pr_err("%pOFn must have one parent\n", node); goto cleanup; } @@ -374,13 +374,13 @@ static void __init of_omap2_apll_setup(struct device_node *node) init->parent_names = &parent_name; if (of_property_read_u32(node, "ti,clock-frequency", &val)) { - pr_err("%s missing clock-frequency\n", node->name); + pr_err("%pOFn missing clock-frequency\n", node); goto cleanup; } clk_hw->fixed_rate = val; if (of_property_read_u32(node, "ti,bit-shift", &val)) { - pr_err("%s missing bit-shift\n", node->name); + pr_err("%pOFn missing bit-shift\n", node); goto cleanup; } @@ -389,7 +389,7 @@ static void __init of_omap2_apll_setup(struct device_node *node) ad->autoidle_mask = 0x3 << val; if (of_property_read_u32(node, "ti,idlest-shift", &val)) { - pr_err("%s missing idlest-shift\n", node->name); + pr_err("%pOFn missing idlest-shift\n", node); goto cleanup; } diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c index 148815470431..a01ca9395179 100644 --- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -190,8 +190,8 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node) init.num_parents = of_clk_get_parent_count(node); if (init.num_parents != 1) { - pr_err("%s: atl clock %s must have 1 parent\n", __func__, - node->name); + pr_err("%s: atl clock %pOFn must have 1 parent\n", __func__, + node); goto cleanup; } diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 7d22e1af2247..be04214970cf 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -223,7 +223,7 @@ int __init ti_clk_retry_init(struct device_node *node, void *user, { struct clk_init_item *retry; - pr_debug("%s: adding to retry list...\n", node->name); + pr_debug("%pOFn: adding to retry list...\n", node); retry = kzalloc(sizeof(*retry), GFP_KERNEL); if (!retry) return -ENOMEM; @@ -258,14 +258,14 @@ int ti_clk_get_reg_addr(struct device_node *node, int index, } if (i == CLK_MAX_MEMMAPS) { - pr_err("clk-provider not found for %s!\n", node->name); + pr_err("clk-provider not found for %pOFn!\n", node); return -ENOENT; } reg->index = i; if (of_property_read_u32_index(node, "reg", index, &val)) { - pr_err("%s must have reg[%d]!\n", node->name, index); + pr_err("%pOFn must have reg[%d]!\n", node, index); return -EINVAL; } @@ -312,7 +312,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index, /* get clocks for this parent */ clocks = of_get_child_by_name(parent, "clocks"); if (!clocks) { - pr_err("%s missing 'clocks' child node.\n", parent->name); + pr_err("%pOFn missing 'clocks' child node.\n", parent); return -EINVAL; } @@ -365,7 +365,7 @@ void ti_dt_clk_init_retry_clks(void) while (!list_empty(&retry_list) && retries) { list_for_each_entry_safe(retry, tmp, &retry_list, link) { - pr_debug("retry-init: %s\n", retry->node->name); + pr_debug("retry-init: %pOFn\n", retry->node); retry->func(retry->user, retry->node); list_del(&retry->link); kfree(retry); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 421b05392220..240e911a3db9 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -259,8 +259,8 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, struct omap_clkctrl_clk *clkctrl_clk; int ret = 0; - init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name, - node->name, offset, bit); + init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d", node->parent, + node, offset, bit); clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); if (!init.name || !clkctrl_clk) { ret = -ENOMEM; @@ -492,8 +492,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) provider->base = of_iomap(node, 0); - provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3, - GFP_KERNEL); + provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent); if (!provider->clkdm_name) { kfree(provider); return; @@ -503,8 +502,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) * Create default clkdm name, replace _cm from end of parent node * name with _clkdm */ - strcpy(provider->clkdm_name, node->parent->name); - provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0; + provider->clkdm_name[strlen(provider->clkdm_name) - 5] = 0; strcat(provider->clkdm_name, "clkdm"); INIT_LIST_HEAD(&provider->clocks); @@ -539,8 +537,8 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) init.flags = 0; if (reg_data->flags & CLKF_SET_RATE_PARENT) init.flags |= CLK_SET_RATE_PARENT; - init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", - node->parent->name, node->name, + init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d", + node->parent, node, reg_data->offset, 0); clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); if (!init.name || !clkctrl_clk) diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index 030e8b2c1050..6a89936ba03a 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -135,8 +135,8 @@ static void __init _register_composite(void *user, comp = _lookup_component(cclk->comp_nodes[i]); if (!comp) { - pr_debug("component %s not ready for %s, retry\n", - cclk->comp_nodes[i]->name, node->name); + pr_debug("component %s not ready for %pOFn, retry\n", + cclk->comp_nodes[i]->name, node); if (!ti_clk_retry_init(node, hw, _register_composite)) return; @@ -144,8 +144,8 @@ static void __init _register_composite(void *user, goto cleanup; } if (cclk->comp_clks[comp->type] != NULL) { - pr_err("duplicate component types for %s (%s)!\n", - node->name, component_clk_types[comp->type]); + pr_err("duplicate component types for %pOFn (%s)!\n", + node, component_clk_types[comp->type]); goto cleanup; } @@ -168,7 +168,7 @@ static void __init _register_composite(void *user, } if (!num_parents) { - pr_err("%s: no parents found for %s!\n", __func__, node->name); + pr_err("%s: no parents found for %pOFn!\n", __func__, node); goto cleanup; } @@ -212,7 +212,7 @@ static void __init of_ti_composite_clk_setup(struct device_node *node) num_clks = of_clk_get_parent_count(node); if (!num_clks) { - pr_err("composite clk %s must have component(s)\n", node->name); + pr_err("composite clk %pOFn must have component(s)\n", node); return; } @@ -248,7 +248,7 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, num_parents = of_clk_get_parent_count(node); if (!num_parents) { - pr_err("component-clock %s must have parent(s)\n", node->name); + pr_err("component-clock %pOFn must have parent(s)\n", node); return -EINVAL; } diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index ccfb4d9a152a..4fcb337a6d1c 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -492,7 +492,7 @@ __init ti_clk_get_div_table(struct device_node *node) } if (!valid_div) { - pr_err("no valid dividers for %s table\n", node->name); + pr_err("no valid dividers for %pOFn table\n", node); return ERR_PTR(-EINVAL); } @@ -530,7 +530,7 @@ static int _get_divider_width(struct device_node *node, min_div = 1; if (of_property_read_u32(node, "ti,max-div", &max_div)) { - pr_err("no max-div for %s!\n", node->name); + pr_err("no max-div for %pOFn!\n", node); return -EINVAL; } diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index dc86d07d0921..2e80c5ead74a 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -162,8 +162,8 @@ static void __init _register_dpll(void *user, clk = of_clk_get(node, 0); if (IS_ERR(clk)) { - pr_debug("clk-ref missing for %s, retry later\n", - node->name); + pr_debug("clk-ref missing for %pOFn, retry later\n", + node); if (!ti_clk_retry_init(node, hw, _register_dpll)) return; @@ -175,8 +175,8 @@ static void __init _register_dpll(void *user, clk = of_clk_get(node, 1); if (IS_ERR(clk)) { - pr_debug("clk-bypass missing for %s, retry later\n", - node->name); + pr_debug("clk-bypass missing for %pOFn, retry later\n", + node); if (!ti_clk_retry_init(node, hw, _register_dpll)) return; @@ -226,7 +226,7 @@ static void _register_dpll_x2(struct device_node *node, parent_name = of_clk_get_parent_name(node, 0); if (!parent_name) { - pr_err("%s must have parent\n", node->name); + pr_err("%pOFn must have parent\n", node); return; } @@ -305,7 +305,7 @@ static void __init of_ti_dpll_setup(struct device_node *node, init->num_parents = of_clk_get_parent_count(node); if (!init->num_parents) { - pr_err("%s must have parent(s)\n", node->name); + pr_err("%pOFn must have parent(s)\n", node); goto cleanup; } diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index 071af44b1ba8..ed24f20f63c7 100644 --- a/drivers/clk/ti/fapll.c +++ b/drivers/clk/ti/fapll.c @@ -555,7 +555,7 @@ static void __init ti_fapll_setup(struct device_node *node) init->num_parents = of_clk_get_parent_count(node); if (init->num_parents != 2) { - pr_err("%s must have two parents\n", node->name); + pr_err("%pOFn must have two parents\n", node); goto free; } @@ -564,19 +564,19 @@ static void __init ti_fapll_setup(struct device_node *node) fd->clk_ref = of_clk_get(node, 0); if (IS_ERR(fd->clk_ref)) { - pr_err("%s could not get clk_ref\n", node->name); + pr_err("%pOFn could not get clk_ref\n", node); goto free; } fd->clk_bypass = of_clk_get(node, 1); if (IS_ERR(fd->clk_bypass)) { - pr_err("%s could not get clk_bypass\n", node->name); + pr_err("%pOFn could not get clk_bypass\n", node); goto free; } fd->base = of_iomap(node, 0); if (!fd->base) { - pr_err("%s could not get IO base\n", node->name); + pr_err("%pOFn could not get IO base\n", node); goto free; } diff --git a/drivers/clk/ti/fixed-factor.c b/drivers/clk/ti/fixed-factor.c index 0174a51a4ba6..7cbe896db071 100644 --- a/drivers/clk/ti/fixed-factor.c +++ b/drivers/clk/ti/fixed-factor.c @@ -42,12 +42,12 @@ static void __init of_ti_fixed_factor_clk_setup(struct device_node *node) u32 flags = 0; if (of_property_read_u32(node, "ti,clock-div", &div)) { - pr_err("%s must have a clock-div property\n", node->name); + pr_err("%pOFn must have a clock-div property\n", node); return; } if (of_property_read_u32(node, "ti,clock-mult", &mult)) { - pr_err("%s must have a clock-mult property\n", node->name); + pr_err("%pOFn must have a clock-mult property\n", node); return; } diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 935b2de5fb88..d4b5638e8b99 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -179,7 +179,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node, } if (of_clk_get_parent_count(node) != 1) { - pr_err("%s must have 1 parent\n", node->name); + pr_err("%pOFn must have 1 parent\n", node); return; } diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c index 41ae7021670e..87e00c2ee957 100644 --- a/drivers/clk/ti/interface.c +++ b/drivers/clk/ti/interface.c @@ -84,7 +84,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node, parent_name = of_clk_get_parent_name(node, 0); if (!parent_name) { - pr_err("%s must have a parent\n", node->name); + pr_err("%pOFn must have a parent\n", node); return; } diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index 69a4308a5a98..18be7eb51546 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -186,7 +186,7 @@ static void of_mux_clk_setup(struct device_node *node) num_parents = of_clk_get_parent_count(node); if (num_parents < 2) { - pr_err("mux-clock %s must have parents\n", node->name); + pr_err("mux-clock %pOFn must have parents\n", node); return; } parent_names = kzalloc((sizeof(char *) * num_parents), GFP_KERNEL); @@ -278,7 +278,7 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node) num_parents = of_clk_get_parent_count(node); if (num_parents < 2) { - pr_err("%s must have parents\n", node->name); + pr_err("%pOFn must have parents\n", node); goto cleanup; } diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 88a2cab37f62..d7b53ac8ad11 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -602,7 +602,7 @@ void __init zynq_clock_init(void) } if (of_address_to_resource(np, 0, &res)) { - pr_err("%s: failed to get resource\n", np->name); + pr_err("%pOFn: failed to get resource\n", np); goto np_err; } @@ -611,7 +611,7 @@ void __init zynq_clock_init(void) if (slcr->data) { zynq_clkc_base = (__force void __iomem *)slcr->data + res.start; } else { - pr_err("%s: Unable to get I/O memory\n", np->name); + pr_err("%pOFn: Unable to get I/O memory\n", np); of_node_put(slcr); goto np_err; } From 00a461cc32ec27fa7bd9c874a7b36b0c6c542c12 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 22 Aug 2018 11:03:19 +0200 Subject: [PATCH 033/836] clk: ti: fix OF child-node lookup Fix child-node lookup which by using the wrong OF helper was searching the whole tree depth-first, something which could end up matching an unrelated node. Also fix the related node-reference leaks. Fixes: 5b385a45e001 ("clk: ti: add support for clkctrl aliases") Signed-off-by: Johan Hovold Acked-by: Tero Kristo Signed-off-by: Stephen Boyd --- drivers/clk/ti/clk.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 7d22e1af2247..27e0979b3158 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -129,7 +129,7 @@ int ti_clk_setup_ll_ops(struct ti_clk_ll_ops *ops) void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) { struct ti_dt_clk *c; - struct device_node *node; + struct device_node *node, *parent; struct clk *clk; struct of_phandle_args clkspec; char buf[64]; @@ -164,8 +164,12 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) continue; node = of_find_node_by_name(NULL, buf); - if (num_args) - node = of_find_node_by_name(node, "clk"); + if (num_args) { + parent = node; + node = of_get_child_by_name(parent, "clk"); + of_node_put(parent); + } + clkspec.np = node; clkspec.args_count = num_args; for (i = 0; i < num_args; i++) { @@ -173,11 +177,12 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) if (ret) { pr_warn("Bad tag in %s at %d: %s\n", c->node_name, i, tags[i]); + of_node_put(node); return; } } clk = of_clk_get_from_provider(&clkspec); - + of_node_put(node); if (!IS_ERR(clk)) { c->lk.clk = clk; clkdev_add(&c->lk); From 2bdb2a1cca8669cfe15be62b8f1ed966e374585b Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Thu, 30 Aug 2018 10:34:37 -0700 Subject: [PATCH 034/836] clk: qcom: Allocate space for NULL terimation in DFS table The table allocated in clk_rcg2_dfs_populate_freq_table() is eventually iterated over by qcom_find_freq() which assumes that the table is NULL terminated. Allocate one extra space in the array for the NULL termination. Initting of the NULL termination is implicit due to kcalloc(). Fixes: cc4f6944d0e3 ("clk: qcom: Add support for RCG to register for DFS") Signed-off-by: Douglas Anderson Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-rcg2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index d5d77f9ad170..6e3bd195d012 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -993,7 +993,8 @@ static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg) struct freq_tbl *freq_tbl; int i; - freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(*freq_tbl), GFP_KERNEL); + /* Allocate space for 1 extra since table is NULL terminated */ + freq_tbl = kcalloc(MAX_PERF_LEVEL + 1, sizeof(*freq_tbl), GFP_KERNEL); if (!freq_tbl) return -ENOMEM; rcg->freq_tbl = freq_tbl; From 681cd4a890e394b91b0b5df0d7f6095d3ae83193 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Sat, 4 Aug 2018 19:22:22 -0500 Subject: [PATCH 035/836] clk: qcom: clk-branch: Use true and false for boolean values Return statements in functions returning bool should use true or false instead of an integer value. This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Signed-off-by: Stephen Boyd --- drivers/clk/qcom/clk-branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index bc2205c450b6..99446bf630aa 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -18,7 +18,7 @@ static bool clk_branch_in_hwcg_mode(const struct clk_branch *br) u32 val; if (!br->hwcg_reg) - return 0; + return false; regmap_read(br->clkr.regmap, br->hwcg_reg, &val); From 0b85de7cef013eeaf5cc873f0fd127ccfc2413be Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Wed, 22 Aug 2018 00:05:32 +0300 Subject: [PATCH 036/836] clk: cdce925: release child device nodes of_get_child_by_name() returns device node with refcount incremented, but there is no decrement in cdce925_probe(). The patch adds one. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: Stephen Boyd --- drivers/clk/clk-cdce925.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/clk-cdce925.c b/drivers/clk/clk-cdce925.c index 0a7e7d5a7506..e9c3ffad4ac3 100644 --- a/drivers/clk/clk-cdce925.c +++ b/drivers/clk/clk-cdce925.c @@ -703,6 +703,7 @@ static int cdce925_probe(struct i2c_client *client, 0x12 + (i*CDCE925_OFFSET_PLL), 0x07, value & 0x07); } + of_node_put(np_output); } /* Register output clock Y1 */ From e848c2ea117f222b62715d5c4e1714ec4e0aa647 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 22 Aug 2018 00:02:14 +0200 Subject: [PATCH 037/836] clk: renesas: use SPDX identifier for Renesas drivers Signed-off-by: Wolfram Sang Reviewed-by: Simon Horman Reviewed-by: Geert Uytterhoeven Signed-off-by: Stephen Boyd --- drivers/clk/renesas/clk-div6.c | 5 +---- drivers/clk/renesas/r8a7795-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a7796-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a77995-cpg-mssr.c | 5 +---- drivers/clk/renesas/rcar-gen3-cpg.c | 5 +---- drivers/clk/renesas/rcar-usb2-clock-sel.c | 5 +---- drivers/clk/renesas/renesas-cpg-mssr.c | 5 +---- drivers/clk/renesas/renesas-cpg-mssr.h | 5 +---- 8 files changed, 8 insertions(+), 32 deletions(-) diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 9febbf42c3df..6643733952a6 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7790 Common Clock Framework support * * Copyright (C) 2013 Renesas Solutions Corp. * * Contact: Laurent Pinchart - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index a85dd50e8911..846a4f984c8d 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7795 Clock Pulse Generator / Module Standby and Software Reset * @@ -6,10 +7,6 @@ * Based on clk-rcar-gen3.c * * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index dfb267a92f2a..9476ffeebb7b 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7796 Clock Pulse Generator / Module Standby and Software Reset * @@ -7,10 +8,6 @@ * * Copyright (C) 2015 Glider bvba * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index ea4cafbe6e85..334b3c141dad 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a77995 Clock Pulse Generator / Module Standby and Software Reset * @@ -7,10 +8,6 @@ * * Copyright (C) 2015 Glider bvba * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index 628b63b85d3f..07fabc6475c5 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R-Car Gen3 Clock Pulse Generator * @@ -6,10 +7,6 @@ * Based on clk-rcar-gen3.c * * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c index 6cd030a58964..b241f9ca3d71 100644 --- a/drivers/clk/renesas/rcar-usb2-clock-sel.c +++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Renesas R-Car USB2.0 clock selector * @@ -6,10 +7,6 @@ * Based on renesas-cpg-mssr.c * * Copyright (C) 2015 Glider bvba - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index f4b013e9352d..a9c4f67b94b5 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Renesas Clock Pulse Generator / Module Standby and Software Reset * @@ -7,10 +8,6 @@ * * Copyright (C) 2013 Ideas On Board SPRL * Copyright (C) 2015 Renesas Electronics Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 642f720b9b05..59b1b30c1dba 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Renesas Clock Pulse Generator / Module Standby and Software Reset * * Copyright (C) 2015 Glider bvba - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #ifndef __CLK_RENESAS_CPG_MSSR_H__ From f40c467523cb5dd352e669a8bab2411b31db089e Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Mon, 23 Jul 2018 16:56:32 +0530 Subject: [PATCH 038/836] dt-bindings: clock: Introduce QCOM Camera clock bindings Add device tree bindings for camera clock controller for Qualcomm Technology Inc's SDM845 SoCs. Signed-off-by: Amit Nischal Signed-off-by: Stephen Boyd --- .../devicetree/bindings/clock/qcom,camcc.txt | 18 +++ include/dt-bindings/clock/qcom,camcc-sdm845.h | 116 ++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/qcom,camcc.txt create mode 100644 include/dt-bindings/clock/qcom,camcc-sdm845.h diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc.txt b/Documentation/devicetree/bindings/clock/qcom,camcc.txt new file mode 100644 index 000000000000..c5eb6694fda9 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,camcc.txt @@ -0,0 +1,18 @@ +Qualcomm Camera Clock & Reset Controller Binding +------------------------------------------------ + +Required properties : +- compatible : shall contain "qcom,sdm845-camcc". +- reg : shall contain base register location and length. +- #clock-cells : from common clock binding, shall contain 1. +- #reset-cells : from common reset binding, shall contain 1. +- #power-domain-cells : from generic power domain binding, shall contain 1. + +Example: + camcc: clock-controller@ad00000 { + compatible = "qcom,sdm845-camcc"; + reg = <0xad00000 0x10000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; diff --git a/include/dt-bindings/clock/qcom,camcc-sdm845.h b/include/dt-bindings/clock/qcom,camcc-sdm845.h new file mode 100644 index 000000000000..4f7a2d2320bf --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sdm845.h @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H +#define _DT_BINDINGS_CLK_SDM_CAM_CC_SDM845_H + +/* CAM_CC clock registers */ +#define CAM_CC_BPS_AHB_CLK 0 +#define CAM_CC_BPS_AREG_CLK 1 +#define CAM_CC_BPS_AXI_CLK 2 +#define CAM_CC_BPS_CLK 3 +#define CAM_CC_BPS_CLK_SRC 4 +#define CAM_CC_CAMNOC_ATB_CLK 5 +#define CAM_CC_CAMNOC_AXI_CLK 6 +#define CAM_CC_CCI_CLK 7 +#define CAM_CC_CCI_CLK_SRC 8 +#define CAM_CC_CPAS_AHB_CLK 9 +#define CAM_CC_CPHY_RX_CLK_SRC 10 +#define CAM_CC_CSI0PHYTIMER_CLK 11 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 12 +#define CAM_CC_CSI1PHYTIMER_CLK 13 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 14 +#define CAM_CC_CSI2PHYTIMER_CLK 15 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 16 +#define CAM_CC_CSI3PHYTIMER_CLK 17 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 18 +#define CAM_CC_CSIPHY0_CLK 19 +#define CAM_CC_CSIPHY1_CLK 20 +#define CAM_CC_CSIPHY2_CLK 21 +#define CAM_CC_CSIPHY3_CLK 22 +#define CAM_CC_FAST_AHB_CLK_SRC 23 +#define CAM_CC_FD_CORE_CLK 24 +#define CAM_CC_FD_CORE_CLK_SRC 25 +#define CAM_CC_FD_CORE_UAR_CLK 26 +#define CAM_CC_ICP_APB_CLK 27 +#define CAM_CC_ICP_ATB_CLK 28 +#define CAM_CC_ICP_CLK 29 +#define CAM_CC_ICP_CLK_SRC 30 +#define CAM_CC_ICP_CTI_CLK 31 +#define CAM_CC_ICP_TS_CLK 32 +#define CAM_CC_IFE_0_AXI_CLK 33 +#define CAM_CC_IFE_0_CLK 34 +#define CAM_CC_IFE_0_CLK_SRC 35 +#define CAM_CC_IFE_0_CPHY_RX_CLK 36 +#define CAM_CC_IFE_0_CSID_CLK 37 +#define CAM_CC_IFE_0_CSID_CLK_SRC 38 +#define CAM_CC_IFE_0_DSP_CLK 39 +#define CAM_CC_IFE_1_AXI_CLK 40 +#define CAM_CC_IFE_1_CLK 41 +#define CAM_CC_IFE_1_CLK_SRC 42 +#define CAM_CC_IFE_1_CPHY_RX_CLK 43 +#define CAM_CC_IFE_1_CSID_CLK 44 +#define CAM_CC_IFE_1_CSID_CLK_SRC 45 +#define CAM_CC_IFE_1_DSP_CLK 46 +#define CAM_CC_IFE_LITE_CLK 47 +#define CAM_CC_IFE_LITE_CLK_SRC 48 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 49 +#define CAM_CC_IFE_LITE_CSID_CLK 50 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 51 +#define CAM_CC_IPE_0_AHB_CLK 52 +#define CAM_CC_IPE_0_AREG_CLK 53 +#define CAM_CC_IPE_0_AXI_CLK 54 +#define CAM_CC_IPE_0_CLK 55 +#define CAM_CC_IPE_0_CLK_SRC 56 +#define CAM_CC_IPE_1_AHB_CLK 57 +#define CAM_CC_IPE_1_AREG_CLK 58 +#define CAM_CC_IPE_1_AXI_CLK 59 +#define CAM_CC_IPE_1_CLK 60 +#define CAM_CC_IPE_1_CLK_SRC 61 +#define CAM_CC_JPEG_CLK 62 +#define CAM_CC_JPEG_CLK_SRC 63 +#define CAM_CC_LRME_CLK 64 +#define CAM_CC_LRME_CLK_SRC 65 +#define CAM_CC_MCLK0_CLK 66 +#define CAM_CC_MCLK0_CLK_SRC 67 +#define CAM_CC_MCLK1_CLK 68 +#define CAM_CC_MCLK1_CLK_SRC 69 +#define CAM_CC_MCLK2_CLK 70 +#define CAM_CC_MCLK2_CLK_SRC 71 +#define CAM_CC_MCLK3_CLK 72 +#define CAM_CC_MCLK3_CLK_SRC 73 +#define CAM_CC_PLL0 74 +#define CAM_CC_PLL0_OUT_EVEN 75 +#define CAM_CC_PLL1 76 +#define CAM_CC_PLL1_OUT_EVEN 77 +#define CAM_CC_PLL2 78 +#define CAM_CC_PLL2_OUT_EVEN 79 +#define CAM_CC_PLL3 80 +#define CAM_CC_PLL3_OUT_EVEN 81 +#define CAM_CC_SLOW_AHB_CLK_SRC 82 +#define CAM_CC_SOC_AHB_CLK 83 +#define CAM_CC_SYS_TMR_CLK 84 + +/* CAM_CC Resets */ +#define TITAN_CAM_CC_CCI_BCR 0 +#define TITAN_CAM_CC_CPAS_BCR 1 +#define TITAN_CAM_CC_CSI0PHY_BCR 2 +#define TITAN_CAM_CC_CSI1PHY_BCR 3 +#define TITAN_CAM_CC_CSI2PHY_BCR 4 +#define TITAN_CAM_CC_MCLK0_BCR 5 +#define TITAN_CAM_CC_MCLK1_BCR 6 +#define TITAN_CAM_CC_MCLK2_BCR 7 +#define TITAN_CAM_CC_MCLK3_BCR 8 +#define TITAN_CAM_CC_TITAN_TOP_BCR 9 + +/* CAM_CC GDSCRs */ +#define BPS_GDSC 0 +#define IPE_0_GDSC 1 +#define IPE_1_GDSC 2 +#define IFE_0_GDSC 3 +#define IFE_1_GDSC 4 +#define TITAN_TOP_GDSC 5 + +#endif From 78412c262004be21d1104ffad3232bb1c2e14a25 Mon Sep 17 00:00:00 2001 From: Amit Nischal Date: Wed, 8 Aug 2018 16:17:19 +0530 Subject: [PATCH 039/836] clk: qcom: Add camera clock controller driver for SDM845 Add support for the camera clock controller found on SDM845 based devices. This would allow camera drivers to probe and control their clocks. Signed-off-by: Amit Nischal Signed-off-by: Stephen Boyd --- drivers/clk/qcom/Kconfig | 8 + drivers/clk/qcom/Makefile | 1 + drivers/clk/qcom/camcc-sdm845.c | 1745 +++++++++++++++++++++++++++++++ 3 files changed, 1754 insertions(+) create mode 100644 drivers/clk/qcom/camcc-sdm845.c diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 064768699fe7..5b181b182f40 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -235,6 +235,14 @@ config MSM_GCC_8998 Say Y if you want to use peripheral devices such as UART, SPI, i2c, USB, UFS, SD/eMMC, PCIe, etc. +config SDM_CAMCC_845 + tristate "SDM845 Camera Clock Controller" + depends on COMMON_CLK_QCOM + select SDM_GCC_845 + help + Support for the camera clock controller on SDM845 devices. + Say Y if you want to support camera devices and camera functionality. + config SDM_GCC_845 tristate "SDM845 Global Clock Controller" select QCOM_GDSC diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 21a45035930d..935f142bc155 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o diff --git a/drivers/clk/qcom/camcc-sdm845.c b/drivers/clk/qcom/camcc-sdm845.c new file mode 100644 index 000000000000..1b2cefef7431 --- /dev/null +++ b/drivers/clk/qcom/camcc-sdm845.c @@ -0,0 +1,1745 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "gdsc.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CORE_BI_PLL_TEST_SE, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 1 }, + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, + { P_CAM_CC_PLL3_OUT_EVEN, 5 }, + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, + { P_CORE_BI_PLL_TEST_SE, 7 }, +}; + +static const char * const cam_cc_parent_names_0[] = { + "bi_tcxo", + "cam_cc_pll2_out_even", + "cam_cc_pll1_out_even", + "cam_cc_pll3_out_even", + "cam_cc_pll0_out_even", + "core_bi_pll_test_se", +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_fabia_even[] = { + { 0x0, 1 }, + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_names = (const char *[]){ "cam_cc_pll0" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1_out_even", + .parent_names = (const char *[]){ "cam_cc_pll1" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2_out_even", + .parent_names = (const char *[]){ "cam_cc_pll2" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll3", + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .ops = &clk_alpha_pll_fabia_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 8, + .post_div_table = post_div_table_fabia_even, + .num_post_div = ARRAY_SIZE(post_div_table_fabia_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll3_out_even", + .parent_names = (const char *[]){ "cam_cc_pll3" }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_fabia_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +/* + * As per HW design, some of the CAMCC RCGs needs to + * move to XO clock during their clock disable so using + * clk_rcg2_shared_ops for such RCGs. This is required + * to power down the camera memories gracefully. + * Also, use CLK_SET_RATE_PARENT flag for the RCGs which + * have CAM_CC_PLL2_OUT_EVEN PLL as parent in frequency + * table and requires reconfiguration of the PLL frequency. + */ +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x600c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_clk_src = { + .cmd_rcgr = 0xb0d8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x9060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_cphy_rx_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(240000000, P_CAM_CC_PLL2_OUT_EVEN, 2, 0, 0), + F(269333333, P_CAM_CC_PLL1_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x5004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi0phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x5028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi1phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x504c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi2phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x5070, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi3phytimer_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x6038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_fast_ahb_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fd_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fd_core_clk_src = { + .cmd_rcgr = 0xb0b0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fd_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_clk_src = { + .cmd_rcgr = 0xb088, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0), + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .cmd_rcgr = 0x900c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(384000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { + .cmd_rcgr = 0x9038, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_csid_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_1_clk_src = { + .cmd_rcgr = 0xa00c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { + .cmd_rcgr = 0xa030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_csid_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0xb004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0xb024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0), + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(538666667, P_CAM_CC_PLL1_OUT_EVEN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_0_clk_src = { + .cmd_rcgr = 0x700c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ipe_1_clk_src = { + .cmd_rcgr = 0x800c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0xb04c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_jpeg_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_lrme_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(269333333, P_CAM_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(320000000, P_CAM_CC_PLL2_OUT_EVEN, 1.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_lrme_clk_src = { + .cmd_rcgr = 0xb0f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_lrme_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_lrme_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_CC_PLL2_OUT_EVEN, 10, 1, 2), + F(33333333, P_CAM_CC_PLL0_OUT_EVEN, 2, 1, 9), + F(34285714, P_CAM_CC_PLL2_OUT_EVEN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk0_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .cmd_rcgr = 0x4024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk1_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4044, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk2_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4064, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk3_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_CAM_CC_PLL0_OUT_EVEN, 10, 0, 0), + F(66666667, P_CAM_CC_PLL0_OUT_EVEN, 9, 0, 0), + F(73846154, P_CAM_CC_PLL2_OUT_EVEN, 6.5, 0, 0), + F(80000000, P_CAM_CC_PLL2_OUT_EVEN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x6054, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_slow_ahb_clk_src", + .parent_names = cam_cc_parent_names_0, + .num_parents = 6, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch cam_cc_bps_ahb_clk = { + .halt_reg = 0x606c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x606c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_areg_clk = { + .halt_reg = 0x6050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_areg_clk", + .parent_names = (const char *[]){ + "cam_cc_fast_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_axi_clk = { + .halt_reg = 0x6034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_clk = { + .halt_reg = 0x6024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_clk", + .parent_names = (const char *[]){ + "cam_cc_bps_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_atb_clk = { + .halt_reg = 0xb12c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb12c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_clk = { + .halt_reg = 0xb124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb124, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_clk = { + .halt_reg = 0xb0f0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0f0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_clk", + .parent_names = (const char *[]){ + "cam_cc_cci_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ahb_clk = { + .halt_reg = 0xb11c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb11c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cpas_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi0phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi0phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x5040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi1phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi1phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x5064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi2phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi2phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x5088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi3phytimer_clk", + .parent_names = (const char *[]){ + "cam_cc_csi3phytimer_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x5020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy0_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x5044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy1_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x5068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5068, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy2_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x508c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x508c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy3_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_fd_core_clk = { + .halt_reg = 0xb0c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0c8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_clk", + .parent_names = (const char *[]){ + "cam_cc_fd_core_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_fd_core_uar_clk = { + .halt_reg = 0xb0d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0d0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_uar_clk", + .parent_names = (const char *[]){ + "cam_cc_fd_core_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_apb_clk = { + .halt_reg = 0xb084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_apb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_atb_clk = { + .halt_reg = 0xb078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_atb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_clk = { + .halt_reg = 0xb0a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0a0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_clk", + .parent_names = (const char *[]){ + "cam_cc_icp_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_cti_clk = { + .halt_reg = 0xb07c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb07c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_cti_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_ts_clk = { + .halt_reg = 0xb080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_ts_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_axi_clk = { + .halt_reg = 0x907c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x907c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_clk = { + .halt_reg = 0x9024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_cphy_rx_clk = { + .halt_reg = 0x9078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_cphy_rx_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_csid_clk = { + .halt_reg = 0x9050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_csid_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_0_csid_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_dsp_clk = { + .halt_reg = 0x9034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_dsp_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_0_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_axi_clk = { + .halt_reg = 0xa054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_cphy_rx_clk = { + .halt_reg = 0xa050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_cphy_rx_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_csid_clk = { + .halt_reg = 0xa048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_csid_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_1_csid_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_dsp_clk = { + .halt_reg = 0xa02c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa02c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_dsp_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0xb01c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb01c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_lite_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0xb044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_names = (const char *[]){ + "cam_cc_cphy_rx_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0xb03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_csid_clk", + .parent_names = (const char *[]){ + "cam_cc_ife_lite_csid_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_ahb_clk = { + .halt_reg = 0x703c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x703c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_areg_clk = { + .halt_reg = 0x7038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_areg_clk", + .parent_names = (const char *[]){ + "cam_cc_fast_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_axi_clk = { + .halt_reg = 0x7034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_clk = { + .halt_reg = 0x7024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_clk", + .parent_names = (const char *[]){ + "cam_cc_ipe_0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_ahb_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_ahb_clk", + .parent_names = (const char *[]){ + "cam_cc_slow_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_areg_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_areg_clk", + .parent_names = (const char *[]){ + "cam_cc_fast_ahb_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_axi_clk = { + .halt_reg = 0x8034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_1_clk = { + .halt_reg = 0x8024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_1_clk", + .parent_names = (const char *[]){ + "cam_cc_ipe_1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0xb064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_jpeg_clk", + .parent_names = (const char *[]){ + "cam_cc_jpeg_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_lrme_clk = { + .halt_reg = 0xb110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb110, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_lrme_clk", + .parent_names = (const char *[]){ + "cam_cc_lrme_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk0_clk = { + .halt_reg = 0x401c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk0_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk0_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk1_clk = { + .halt_reg = 0x403c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x403c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk1_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk1_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk2_clk = { + .halt_reg = 0x405c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x405c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk2_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk2_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk3_clk = { + .halt_reg = 0x407c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x407c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk3_clk", + .parent_names = (const char *[]){ + "cam_cc_mclk3_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_soc_ahb_clk = { + .halt_reg = 0xb13c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb13c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_soc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sys_tmr_clk = { + .halt_reg = 0xb0a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb0a8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sys_tmr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc bps_gdsc = { + .gdscr = 0x6004, + .pd = { + .name = "bps_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ipe_0_gdsc = { + .gdscr = 0x7004, + .pd = { + .name = "ipe_0_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ipe_1_gdsc = { + .gdscr = 0x8004, + .pd = { + .name = "ipe_1_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ife_0_gdsc = { + .gdscr = 0x9004, + .pd = { + .name = "ife_0_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ife_1_gdsc = { + .gdscr = 0xa004, + .pd = { + .name = "ife_1_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc titan_top_gdsc = { + .gdscr = 0xb134, + .pd = { + .name = "titan_top_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *cam_cc_sdm845_clocks[] = { + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, + [CAM_CC_BPS_AREG_CLK] = &cam_cc_bps_areg_clk.clkr, + [CAM_CC_BPS_AXI_CLK] = &cam_cc_bps_axi_clk.clkr, + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, + [CAM_CC_CAMNOC_ATB_CLK] = &cam_cc_camnoc_atb_clk.clkr, + [CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr, + [CAM_CC_CCI_CLK] = &cam_cc_cci_clk.clkr, + [CAM_CC_CCI_CLK_SRC] = &cam_cc_cci_clk_src.clkr, + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_FD_CORE_CLK] = &cam_cc_fd_core_clk.clkr, + [CAM_CC_FD_CORE_CLK_SRC] = &cam_cc_fd_core_clk_src.clkr, + [CAM_CC_FD_CORE_UAR_CLK] = &cam_cc_fd_core_uar_clk.clkr, + [CAM_CC_ICP_APB_CLK] = &cam_cc_icp_apb_clk.clkr, + [CAM_CC_ICP_ATB_CLK] = &cam_cc_icp_atb_clk.clkr, + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, + [CAM_CC_ICP_CTI_CLK] = &cam_cc_icp_cti_clk.clkr, + [CAM_CC_ICP_TS_CLK] = &cam_cc_icp_ts_clk.clkr, + [CAM_CC_IFE_0_AXI_CLK] = &cam_cc_ife_0_axi_clk.clkr, + [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr, + [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr, + [CAM_CC_IFE_0_CPHY_RX_CLK] = &cam_cc_ife_0_cphy_rx_clk.clkr, + [CAM_CC_IFE_0_CSID_CLK] = &cam_cc_ife_0_csid_clk.clkr, + [CAM_CC_IFE_0_CSID_CLK_SRC] = &cam_cc_ife_0_csid_clk_src.clkr, + [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr, + [CAM_CC_IFE_1_AXI_CLK] = &cam_cc_ife_1_axi_clk.clkr, + [CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr, + [CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr, + [CAM_CC_IFE_1_CPHY_RX_CLK] = &cam_cc_ife_1_cphy_rx_clk.clkr, + [CAM_CC_IFE_1_CSID_CLK] = &cam_cc_ife_1_csid_clk.clkr, + [CAM_CC_IFE_1_CSID_CLK_SRC] = &cam_cc_ife_1_csid_clk_src.clkr, + [CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr, + [CAM_CC_IPE_0_AREG_CLK] = &cam_cc_ipe_0_areg_clk.clkr, + [CAM_CC_IPE_0_AXI_CLK] = &cam_cc_ipe_0_axi_clk.clkr, + [CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr, + [CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr, + [CAM_CC_IPE_1_AHB_CLK] = &cam_cc_ipe_1_ahb_clk.clkr, + [CAM_CC_IPE_1_AREG_CLK] = &cam_cc_ipe_1_areg_clk.clkr, + [CAM_CC_IPE_1_AXI_CLK] = &cam_cc_ipe_1_axi_clk.clkr, + [CAM_CC_IPE_1_CLK] = &cam_cc_ipe_1_clk.clkr, + [CAM_CC_IPE_1_CLK_SRC] = &cam_cc_ipe_1_clk_src.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_LRME_CLK] = &cam_cc_lrme_clk.clkr, + [CAM_CC_LRME_CLK_SRC] = &cam_cc_lrme_clk_src.clkr, + [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr, + [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr, + [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr, + [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr, + [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr, + [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr, + [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr, + [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_SOC_AHB_CLK] = &cam_cc_soc_ahb_clk.clkr, + [CAM_CC_SYS_TMR_CLK] = &cam_cc_sys_tmr_clk.clkr, +}; + +static struct gdsc *cam_cc_sdm845_gdscs[] = { + [BPS_GDSC] = &bps_gdsc, + [IPE_0_GDSC] = &ipe_0_gdsc, + [IPE_1_GDSC] = &ipe_1_gdsc, + [IFE_0_GDSC] = &ife_0_gdsc, + [IFE_1_GDSC] = &ife_1_gdsc, + [TITAN_TOP_GDSC] = &titan_top_gdsc, +}; + +static const struct regmap_config cam_cc_sdm845_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xd004, + .fast_io = true, +}; + +static const struct qcom_cc_desc cam_cc_sdm845_desc = { + .config = &cam_cc_sdm845_regmap_config, + .clks = cam_cc_sdm845_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sdm845_clocks), + .gdscs = cam_cc_sdm845_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sdm845_gdscs), +}; + +static const struct of_device_id cam_cc_sdm845_match_table[] = { + { .compatible = "qcom,sdm845-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sdm845_match_table); + +static int cam_cc_sdm845_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + struct alpha_pll_config cam_cc_pll_config = { }; + + regmap = qcom_cc_map(pdev, &cam_cc_sdm845_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + cam_cc_pll_config.l = 0x1f; + cam_cc_pll_config.alpha = 0x4000; + clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll_config); + + cam_cc_pll_config.l = 0x2a; + cam_cc_pll_config.alpha = 0x1556; + clk_fabia_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll_config); + + cam_cc_pll_config.l = 0x32; + cam_cc_pll_config.alpha = 0x0; + clk_fabia_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll_config); + + cam_cc_pll_config.l = 0x14; + clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll_config); + + return qcom_cc_really_probe(pdev, &cam_cc_sdm845_desc, regmap); +} + +static struct platform_driver cam_cc_sdm845_driver = { + .probe = cam_cc_sdm845_probe, + .driver = { + .name = "sdm845-camcc", + .of_match_table = cam_cc_sdm845_match_table, + }, +}; + +static int __init cam_cc_sdm845_init(void) +{ + return platform_driver_register(&cam_cc_sdm845_driver); +} +subsys_initcall(cam_cc_sdm845_init); + +static void __exit cam_cc_sdm845_exit(void) +{ + platform_driver_unregister(&cam_cc_sdm845_driver); +} +module_exit(cam_cc_sdm845_exit); + +MODULE_DESCRIPTION("QTI CAM_CC SDM845 Driver"); +MODULE_LICENSE("GPL v2"); From 1adb0a9faabb44cd76c668f12d8b51de869c38b5 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Mon, 6 Aug 2018 14:44:02 +0100 Subject: [PATCH 040/836] clk: mediatek: remove unused array audio_parents Array audio_parents is declared but never used, hence it is redundant and can be removed. Cleans up clang warning: warning: 'audio_parents' defined but not used [-Wunused-const-variable=] Signed-off-by: Colin Ian King Signed-off-by: Stephen Boyd --- drivers/clk/mediatek/clk-mt2701.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c index 4dda8988b2f0..ab6ab07f53e6 100644 --- a/drivers/clk/mediatek/clk-mt2701.c +++ b/drivers/clk/mediatek/clk-mt2701.c @@ -249,11 +249,6 @@ static const char * const msdc30_parents[] = { "univpll2_d4" }; -static const char * const audio_parents[] = { - "clk26m", - "syspll1_d16" -}; - static const char * const aud_intbus_parents[] = { "clk26m", "syspll1_d4", From c14d28e86d3c70720622e1d517968c1721f23214 Mon Sep 17 00:00:00 2001 From: Urja Rannikko Date: Tue, 28 Aug 2018 18:55:07 +0000 Subject: [PATCH 041/836] clk: rockchip: improve rk3288 pll rates for better hdmi output Add and correct PLL rates for better hdmi output. This includes minimizing jitter on 213 MHz for better 71 MHz, 250.5 MHz for better 83.5 MHz, 428 MHz for better 25.175 Mhz, low jitter 273 MHz for better 68.25 mhz, 356 MHz for better 118.68 Mhz and 300MHz. Increase the used Fvco for 308, 324 MHz, 292.5 MHz, 273.6 MHz, 238 MHz and 216 MHz. And add some additional rates allowing to reach better hdmi-related rates in general. These match the rates used by ChromeOS, so have been quite widely tested. Signed-off-by: Urja Rannikko Signed-off-by: Heiko Stuebner --- drivers/clk/rockchip/clk-rk3288.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 450de24a1b42..5a67b7869960 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -83,22 +83,43 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = { RK3066_PLL_RATE( 768000000, 1, 64, 2), RK3066_PLL_RATE( 742500000, 8, 495, 2), RK3066_PLL_RATE( 696000000, 1, 58, 2), + RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1), RK3066_PLL_RATE( 600000000, 1, 50, 2), RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1), RK3066_PLL_RATE( 552000000, 1, 46, 2), RK3066_PLL_RATE( 504000000, 1, 84, 4), RK3066_PLL_RATE( 500000000, 3, 125, 2), RK3066_PLL_RATE( 456000000, 1, 76, 4), + RK3066_PLL_RATE( 428000000, 1, 107, 6), RK3066_PLL_RATE( 408000000, 1, 68, 4), RK3066_PLL_RATE( 400000000, 3, 100, 2), + RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1), RK3066_PLL_RATE( 384000000, 2, 128, 4), RK3066_PLL_RATE( 360000000, 1, 60, 4), + RK3066_PLL_RATE_NB( 356000000, 1, 178, 12, 1), + RK3066_PLL_RATE_NB( 324000000, 1, 189, 14, 1), RK3066_PLL_RATE( 312000000, 1, 52, 4), - RK3066_PLL_RATE( 300000000, 1, 50, 4), - RK3066_PLL_RATE( 297000000, 2, 198, 8), + RK3066_PLL_RATE_NB( 308000000, 1, 154, 12, 1), + RK3066_PLL_RATE_NB( 303000000, 1, 202, 16, 1), + RK3066_PLL_RATE( 300000000, 1, 75, 6), + RK3066_PLL_RATE_NB( 297750000, 2, 397, 16, 1), + RK3066_PLL_RATE_NB( 293250000, 2, 391, 16, 1), + RK3066_PLL_RATE_NB( 292500000, 1, 195, 16, 1), + RK3066_PLL_RATE( 273600000, 1, 114, 10), + RK3066_PLL_RATE_NB( 273000000, 1, 182, 16, 1), + RK3066_PLL_RATE_NB( 270000000, 1, 180, 16, 1), + RK3066_PLL_RATE_NB( 266250000, 2, 355, 16, 1), + RK3066_PLL_RATE_NB( 256500000, 1, 171, 16, 1), RK3066_PLL_RATE( 252000000, 1, 84, 8), - RK3066_PLL_RATE( 216000000, 1, 72, 8), - RK3066_PLL_RATE( 148500000, 2, 99, 8), + RK3066_PLL_RATE_NB( 250500000, 1, 167, 16, 1), + RK3066_PLL_RATE_NB( 243428571, 1, 142, 14, 1), + RK3066_PLL_RATE( 238000000, 1, 119, 12), + RK3066_PLL_RATE_NB( 219750000, 2, 293, 16, 1), + RK3066_PLL_RATE_NB( 216000000, 1, 144, 16, 1), + RK3066_PLL_RATE_NB( 213000000, 1, 142, 16, 1), + RK3066_PLL_RATE( 195428571, 1, 114, 14), + RK3066_PLL_RATE( 160000000, 1, 80, 12), + RK3066_PLL_RATE( 157500000, 1, 105, 16), RK3066_PLL_RATE( 126000000, 1, 84, 16), RK3066_PLL_RATE( 48000000, 1, 64, 32), { /* sentinel */ }, From b30c862f2a72002c06df23d05c2ca6b49148c4d4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 30 Aug 2018 17:21:26 +0200 Subject: [PATCH 042/836] clk: renesas: r8a77990: Add missing I2C7 clock When trying to use I2C7 on R-Car E3: renesas-cpg-mssr e6150000.clock-controller: Cannot get module clock 1003: -2 i2c-rcar e6690000.i2c: failed to add to PM domain always-on: -2 i2c-rcar: probe of e6690000.i2c failed with error -2 Unlike other R-Car Gen3 SoCs, R-Car E3 has more than 7 I2C bus interfaces. Add the forgotten module clock for the 8th instance to fix this. Signed-off-by: Geert Uytterhoeven Reviewed-by: Stephen Boyd --- drivers/clk/renesas/r8a77990-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index 9437219efdd9..7e000d070589 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -210,6 +210,7 @@ static const struct mssr_mod_clk r8a77990_mod_clks[] __initconst = { DEF_MOD("i2c1", 930, R8A77990_CLK_S3D2), DEF_MOD("i2c0", 931, R8A77990_CLK_S3D2), + DEF_MOD("i2c7", 1003, R8A77990_CLK_S3D2), DEF_MOD("ssi-all", 1005, R8A77990_CLK_S3D4), DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), From e9a2310fb689151166df7fd9971093362d34bd79 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 25 Jul 2018 19:47:19 -0500 Subject: [PATCH 043/836] reset: hisilicon: fix potential NULL pointer dereference There is a potential execution path in which function platform_get_resource() returns NULL. If this happens, we will end up having a NULL pointer dereference. Fix this by replacing devm_ioremap with devm_ioremap_resource, which has the NULL check and the memory region request. This code was detected with the help of Coccinelle. Cc: stable@vger.kernel.org Fixes: 97b7129cd2af ("reset: hisilicon: change the definition of hisi_reset_init") Signed-off-by: Gustavo A. R. Silva Signed-off-by: Stephen Boyd --- drivers/clk/hisilicon/reset.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c index 2a5015c736ce..43e82fa64422 100644 --- a/drivers/clk/hisilicon/reset.c +++ b/drivers/clk/hisilicon/reset.c @@ -109,9 +109,8 @@ struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev) return NULL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - rstc->membase = devm_ioremap(&pdev->dev, - res->start, resource_size(res)); - if (!rstc->membase) + rstc->membase = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rstc->membase)) return NULL; spin_lock_init(&rstc->lock); From d9d95e78cff80c3fe43e757ba90644cd766302ac Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 13 Jul 2018 15:44:45 +0200 Subject: [PATCH 044/836] clk: mvebu: armada-37xx-periph: save the IP base address in the driver data Prepare the introduction of suspend/resume hooks by having an easy way to access all the registers in one go just from a device: add the IP base address in the driver data. Signed-off-by: Miquel Raynal Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 499f5962c8b0..78048c2e3774 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -56,6 +56,7 @@ struct clk_periph_driver_data { struct clk_hw_onecell_data *hw_data; spinlock_t lock; + void __iomem *reg; }; struct clk_double_div { @@ -680,7 +681,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int num_periph = 0, i, ret; struct resource *res; - void __iomem *reg; data = of_device_get_match_data(dev); if (!data) @@ -689,11 +689,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) while (data[num_periph].name) num_periph++; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg = devm_ioremap_resource(dev, res); - if (IS_ERR(reg)) - return PTR_ERR(reg); - driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL); if (!driver_data) return -ENOMEM; @@ -706,12 +701,16 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) return -ENOMEM; driver_data->hw_data->num = num_periph; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + driver_data->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(driver_data->reg)) + return PTR_ERR(driver_data->reg); + spin_lock_init(&driver_data->lock); for (i = 0; i < num_periph; i++) { struct clk_hw **hw = &driver_data->hw_data->hws[i]; - - if (armada_3700_add_composite_clk(&data[i], reg, + if (armada_3700_add_composite_clk(&data[i], driver_data->reg, &driver_data->lock, dev, hw)) dev_err(dev, "Can't register periph clock %s\n", data[i].name); From 5beb1e60dba973e0b9cfb54d9735d5d4385b9d90 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 13 Jul 2018 15:44:46 +0200 Subject: [PATCH 045/836] clk: mvebu: armada-37xx-periph: add suspend/resume support Add suspend/resume hooks in Armada 37xx peripheral clocks driver to handle S2RAM operations. One can think that these hooks are useless by comparing the register values before and after a suspend/resume cycle: they will look the same anyway. This is because of some scripts executed by the Cortex-M3 core during ATF operations to init both the clocks and the DDR. These values could be modified by the BL33 stage or by Linux itself and should be preserved. Signed-off-by: Miquel Raynal Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 78048c2e3774..1f1cff428d78 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -57,6 +57,14 @@ struct clk_periph_driver_data { struct clk_hw_onecell_data *hw_data; spinlock_t lock; void __iomem *reg; + + /* Storage registers for suspend/resume operations */ + u32 tbg_sel; + u32 div_sel0; + u32 div_sel1; + u32 div_sel2; + u32 clk_sel; + u32 clk_dis; }; struct clk_double_div { @@ -673,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data, return PTR_ERR_OR_ZERO(*hw); } +static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev) +{ + struct clk_periph_driver_data *data = dev_get_drvdata(dev); + + data->tbg_sel = readl(data->reg + TBG_SEL); + data->div_sel0 = readl(data->reg + DIV_SEL0); + data->div_sel1 = readl(data->reg + DIV_SEL1); + data->div_sel2 = readl(data->reg + DIV_SEL2); + data->clk_sel = readl(data->reg + CLK_SEL); + data->clk_dis = readl(data->reg + CLK_DIS); + + return 0; +} + +static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev) +{ + struct clk_periph_driver_data *data = dev_get_drvdata(dev); + + /* Follow the same order than what the Cortex-M3 does (ATF code) */ + writel(data->clk_dis, data->reg + CLK_DIS); + writel(data->div_sel0, data->reg + DIV_SEL0); + writel(data->div_sel1, data->reg + DIV_SEL1); + writel(data->div_sel2, data->reg + DIV_SEL2); + writel(data->tbg_sel, data->reg + TBG_SEL); + writel(data->clk_sel, data->reg + CLK_SEL); + + return 0; +} + +static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, + armada_3700_periph_clock_resume) +}; + static int armada_3700_periph_clock_probe(struct platform_device *pdev) { struct clk_periph_driver_data *driver_data; @@ -748,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = { .driver = { .name = "marvell-armada-3700-periph-clock", .of_match_table = armada_3700_periph_clock_of_match, + .pm = &armada_3700_periph_clock_pm_ops, }, }; From f4661d293eb2d01dfc742982761a36fafe456d46 Mon Sep 17 00:00:00 2001 From: Jacek Tomaka Date: Sat, 25 Aug 2018 11:50:39 +0800 Subject: [PATCH 046/836] x86/microcode: Make revision and processor flags world-readable The microcode revision is already readable for non-root users via /proc/cpuinfo. Thus, there's no reason to keep the same information readable by root only in /sys/devices/system/cpu/cpuX/microcode/. Make .../processor_flags world-readable too, while at it. Reported-by: Tim Burgess Signed-off-by: Jacek Tomaka Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Link: http://lkml.kernel.org/r/20180825035039.14409-1-jacekt@dugeo.com --- arch/x86/kernel/cpu/microcode/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index b9bc8a1a584e..2637ff09d6a0 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -666,8 +666,8 @@ static ssize_t pf_show(struct device *dev, } static DEVICE_ATTR_WO(reload); -static DEVICE_ATTR(version, 0400, version_show, NULL); -static DEVICE_ATTR(processor_flags, 0400, pf_show, NULL); +static DEVICE_ATTR(version, 0444, version_show, NULL); +static DEVICE_ATTR(processor_flags, 0444, pf_show, NULL); static struct attribute *mc_default_attrs[] = { &dev_attr_version.attr, From 0a87bf6cd5297d8ae99f3560a7969a0b141f7350 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 1 Sep 2018 21:54:27 +0300 Subject: [PATCH 047/836] clk: renesas: r8a77980: Add CMT clocks Now that RCLK has been added by Geert, we can add the CMT module clocks. Based on the original (and large) patch by Vladimir Barinov. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77980-cpg-mssr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c index acf2b4dded4c..25a3083b6764 100644 --- a/drivers/clk/renesas/r8a77980-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -119,6 +119,10 @@ static const struct mssr_mod_clk r8a77980_mod_clks[] __initconst = { DEF_MOD("msiof0", 211, R8A77980_CLK_MSO), DEF_MOD("sys-dmac2", 217, R8A77980_CLK_S0D3), DEF_MOD("sys-dmac1", 218, R8A77980_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A77980_CLK_R), + DEF_MOD("cmt2", 301, R8A77980_CLK_R), + DEF_MOD("cmt1", 302, R8A77980_CLK_R), + DEF_MOD("cmt0", 303, R8A77980_CLK_R), DEF_MOD("tpu0", 304, R8A77980_CLK_S3D4), DEF_MOD("sdif", 314, R8A77980_CLK_SD0), DEF_MOD("pciec0", 319, R8A77980_CLK_S2D2), From 381081ffc2948e1e1a7cbbafe3b91631530a1936 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 1 Sep 2018 23:12:28 +0300 Subject: [PATCH 048/836] clk: renesas: r8a77970: Add SD0H/SD0 clocks for SDHI On R-Car V3M (AKA R8A77970), the SD0CKCR is laid out differently than on the other R-Car gen3 SoCs. In fact, the layout is the same as on R-Car gen2 SoCs, so we'll need to copy the divisor tables from the R-Car gen2 driver. We'll also need to support the SoC specific clock types, thus we're adding CLK_TYPE_GEN3_SOC_BASE at the end of 'enum rcar_gen3_clk_types', declare SD0H/SDH clocks in 'enum r8a77970_clk_types', and handle those clocks in the overridden cpg_clk_register() method; then, finally, add the SD-IF module clock (derived from the SD0 clock). Signed-off-by: Sergei Shtylyov Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77970-cpg-mssr.c | 66 ++++++++++++++++++++++++- drivers/clk/renesas/rcar-gen3-cpg.h | 3 ++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index f55842917e8d..07d0ddc1eefa 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -1,7 +1,7 @@ /* * r8a77970 Clock Pulse Generator / Module Standby and Software Reset * - * Copyright (C) 2017 Cogent Embedded Inc. + * Copyright (C) 2017-2018 Cogent Embedded Inc. * * Based on r8a7795-cpg-mssr.c * @@ -12,6 +12,7 @@ * the Free Software Foundation; version 2 of the License. */ +#include #include #include #include @@ -22,6 +23,13 @@ #include "renesas-cpg-mssr.h" #include "rcar-gen3-cpg.h" +#define CPG_SD0CKCR 0x0074 + +enum r8a77970_clk_types { + CLK_TYPE_R8A77970_SD0H = CLK_TYPE_GEN3_SOC_BASE, + CLK_TYPE_R8A77970_SD0, +}; + enum clk_ids { /* Core Clock Outputs exported to DT */ LAST_DT_CORE_CLK = R8A77970_CLK_OSC, @@ -42,6 +50,20 @@ enum clk_ids { MOD_CLK_BASE }; +static spinlock_t cpg_lock; + +static const struct clk_div_table cpg_sd0h_div_table[] = { + { 0, 2 }, { 1, 3 }, { 2, 4 }, { 3, 6 }, + { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, + { 8, 24 }, { 10, 36 }, { 11, 48 }, { 0, 0 }, +}; + +static const struct clk_div_table cpg_sd0_div_table[] = { + { 4, 8 }, { 5, 12 }, { 6, 16 }, { 7, 18 }, + { 8, 24 }, { 10, 36 }, { 11, 48 }, { 12, 10 }, + { 0, 0 }, +}; + static const struct cpg_core_clk r8a77970_core_clks[] __initconst = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), @@ -68,6 +90,10 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = { DEF_FIXED("s2d2", R8A77970_CLK_S2D2, CLK_PLL1_DIV2, 12, 1), DEF_FIXED("s2d4", R8A77970_CLK_S2D4, CLK_PLL1_DIV2, 24, 1), + DEF_BASE("sd0h", R8A77970_CLK_SD0H, CLK_TYPE_R8A77970_SD0H, + CLK_PLL1_DIV2), + DEF_BASE("sd0", R8A77970_CLK_SD0, CLK_TYPE_R8A77970_SD0, CLK_PLL1_DIV2), + DEF_FIXED("cl", R8A77970_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A77970_CLK_CP, CLK_EXTAL, 2, 1), @@ -92,6 +118,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = { DEF_MOD("mfis", 213, R8A77970_CLK_S2D2), DEF_MOD("sys-dmac2", 217, R8A77970_CLK_S2D1), DEF_MOD("sys-dmac1", 218, R8A77970_CLK_S2D1), + DEF_MOD("sd-if", 314, R8A77970_CLK_SD0), DEF_MOD("rwdt", 402, R8A77970_CLK_R), DEF_MOD("intc-ex", 407, R8A77970_CLK_CP), DEF_MOD("intc-ap", 408, R8A77970_CLK_S2D1), @@ -173,11 +200,46 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev) if (error) return error; + spin_lock_init(&cpg_lock); + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); } +static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base, + struct raw_notifier_head *notifiers) +{ + const struct clk_div_table *table; + const struct clk *parent; + unsigned int shift; + + switch (core->type) { + case CLK_TYPE_R8A77970_SD0H: + table = cpg_sd0h_div_table; + shift = 8; + break; + case CLK_TYPE_R8A77970_SD0: + table = cpg_sd0_div_table; + shift = 4; + break; + default: + return rcar_gen3_cpg_clk_register(dev, core, info, clks, base, + notifiers); + } + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + return clk_register_divider_table(NULL, core->name, + __clk_get_name(parent), 0, + base + CPG_SD0CKCR, + shift, 4, 0, table, &cpg_lock); +} + const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = { /* Core Clocks */ .core_clks = r8a77970_core_clks, @@ -196,5 +258,5 @@ const struct cpg_mssr_info r8a77970_cpg_mssr_info __initconst = { /* Callbacks */ .init = r8a77970_cpg_mssr_init, - .cpg_clk_register = rcar_gen3_cpg_clk_register, + .cpg_clk_register = r8a77970_cpg_clk_register, }; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index 04dc45d15874..ba4e4f1946a9 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -25,6 +25,9 @@ enum rcar_gen3_clk_types { CLK_TYPE_GEN3_Z2, CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */ + + /* SoC specific definitions start here */ + CLK_TYPE_GEN3_SOC_BASE, }; #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ From afaef01c001537fa97a25092d7f54d764dc7d8c1 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:16:58 +0300 Subject: [PATCH 049/836] x86/entry: Add STACKLEAK erasing the kernel stack at the end of syscalls The STACKLEAK feature (initially developed by PaX Team) has the following benefits: 1. Reduces the information that can be revealed through kernel stack leak bugs. The idea of erasing the thread stack at the end of syscalls is similar to CONFIG_PAGE_POISONING and memzero_explicit() in kernel crypto, which all comply with FDP_RIP.2 (Full Residual Information Protection) of the Common Criteria standard. 2. Blocks some uninitialized stack variable attacks (e.g. CVE-2017-17712, CVE-2010-2963). That kind of bugs should be killed by improving C compilers in future, which might take a long time. This commit introduces the code filling the used part of the kernel stack with a poison value before returning to userspace. Full STACKLEAK feature also contains the gcc plugin which comes in a separate commit. The STACKLEAK feature is ported from grsecurity/PaX. More information at: https://grsecurity.net/ https://pax.grsecurity.net/ This code is modified from Brad Spengler/PaX Team's code in the last public patch of grsecurity/PaX based on our understanding of the code. Changes or omissions from the original code are ours and don't reflect the original grsecurity/PaX code. Performance impact: Hardware: Intel Core i7-4770, 16 GB RAM Test #1: building the Linux kernel on a single core 0.91% slowdown Test #2: hackbench -s 4096 -l 2000 -g 15 -f 25 -P 4.2% slowdown So the STACKLEAK description in Kconfig includes: "The tradeoff is the performance impact: on a single CPU system kernel compilation sees a 1% slowdown, other systems and workloads may vary and you are advised to test this feature on your expected workload before deploying it". Signed-off-by: Alexander Popov Acked-by: Thomas Gleixner Reviewed-by: Dave Hansen Acked-by: Ingo Molnar Signed-off-by: Kees Cook --- Documentation/x86/x86_64/mm.txt | 2 ++ arch/Kconfig | 7 ++++ arch/x86/Kconfig | 1 + arch/x86/entry/calling.h | 14 ++++++++ arch/x86/entry/entry_32.S | 7 ++++ arch/x86/entry/entry_64.S | 3 ++ arch/x86/entry/entry_64_compat.S | 5 +++ include/linux/sched.h | 4 +++ include/linux/stackleak.h | 26 ++++++++++++++ kernel/Makefile | 4 +++ kernel/fork.c | 3 ++ kernel/stackleak.c | 62 ++++++++++++++++++++++++++++++++ scripts/gcc-plugins/Kconfig | 19 ++++++++++ 13 files changed, 157 insertions(+) create mode 100644 include/linux/stackleak.h create mode 100644 kernel/stackleak.c diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index 5432a96d31ff..600bc2afa27d 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt @@ -24,6 +24,7 @@ ffffffffa0000000 - fffffffffeffffff (1520 MB) module mapping space [fixmap start] - ffffffffff5fffff kernel-internal fixmap range ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole +STACKLEAK_POISON value in this last hole: ffffffffffff4111 Virtual memory map with 5 level page tables: @@ -50,6 +51,7 @@ ffffffffa0000000 - fffffffffeffffff (1520 MB) module mapping space [fixmap start] - ffffffffff5fffff kernel-internal fixmap range ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole +STACKLEAK_POISON value in this last hole: ffffffffffff4111 Architecture defines a 64-bit virtual address. Implementations can support less. Currently supported are 48- and 57-bit virtual addresses. Bits 63 diff --git a/arch/Kconfig b/arch/Kconfig index 6801123932a5..ee79ff56faab 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -419,6 +419,13 @@ config SECCOMP_FILTER See Documentation/userspace-api/seccomp_filter.rst for details. +config HAVE_ARCH_STACKLEAK + bool + help + An architecture should select this if it has the code which + fills the used part of the kernel stack with the STACKLEAK_POISON + value before returning from system calls. + config HAVE_STACKPROTECTOR bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 1a0be022f91d..662cb2cc9630 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -127,6 +127,7 @@ config X86 select HAVE_ARCH_PREL32_RELOCATIONS select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_THREAD_STRUCT_WHITELIST + select HAVE_ARCH_STACKLEAK select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD if X86_64 diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h index 352e70cd33e8..20d0885b00fb 100644 --- a/arch/x86/entry/calling.h +++ b/arch/x86/entry/calling.h @@ -329,8 +329,22 @@ For 32-bit we have the following conventions - kernel is built with #endif +.macro STACKLEAK_ERASE_NOCLOBBER +#ifdef CONFIG_GCC_PLUGIN_STACKLEAK + PUSH_AND_CLEAR_REGS + call stackleak_erase + POP_REGS +#endif +.endm + #endif /* CONFIG_X86_64 */ +.macro STACKLEAK_ERASE +#ifdef CONFIG_GCC_PLUGIN_STACKLEAK + call stackleak_erase +#endif +.endm + /* * This does 'call enter_from_user_mode' unless we can avoid it based on * kernel config or using the static jump infrastructure. diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index 2767c625a52c..dfb975b4c981 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -46,6 +46,8 @@ #include #include +#include "calling.h" + .section .entry.text, "ax" /* @@ -711,6 +713,7 @@ ENTRY(ret_from_fork) /* When we fork, we trace the syscall return in the child, too. */ movl %esp, %eax call syscall_return_slowpath + STACKLEAK_ERASE jmp restore_all /* kernel thread */ @@ -885,6 +888,8 @@ ENTRY(entry_SYSENTER_32) ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \ "jmp .Lsyscall_32_done", X86_FEATURE_XENPV + STACKLEAK_ERASE + /* Opportunistic SYSEXIT */ TRACE_IRQS_ON /* User mode traces as IRQs on. */ @@ -996,6 +1001,8 @@ ENTRY(entry_INT80_32) call do_int80_syscall_32 .Lsyscall_32_done: + STACKLEAK_ERASE + restore_all: TRACE_IRQS_IRET SWITCH_TO_ENTRY_STACK diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 957dfb693ecc..a5dd28093020 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -329,6 +329,8 @@ syscall_return_via_sysret: * We are on the trampoline stack. All regs except RDI are live. * We can do future final exit work right here. */ + STACKLEAK_ERASE_NOCLOBBER + SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi popq %rdi @@ -688,6 +690,7 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode) * We are on the trampoline stack. All regs except RDI are live. * We can do future final exit work right here. */ + STACKLEAK_ERASE_NOCLOBBER SWITCH_TO_USER_CR3_STACK scratch_reg=%rdi diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index 7d0df78db727..8eaf8952c408 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -261,6 +261,11 @@ GLOBAL(entry_SYSCALL_compat_after_hwframe) /* Opportunistic SYSRET */ sysret32_from_system_call: + /* + * We are not going to return to userspace from the trampoline + * stack. So let's erase the thread stack right now. + */ + STACKLEAK_ERASE TRACE_IRQS_ON /* User mode traces as IRQs on. */ movq RBX(%rsp), %rbx /* pt_regs->rbx */ movq RBP(%rsp), %rbp /* pt_regs->rbp */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 977cb57d7bc9..c1a23acd24e7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1192,6 +1192,10 @@ struct task_struct { void *security; #endif +#ifdef CONFIG_GCC_PLUGIN_STACKLEAK + unsigned long lowest_stack; +#endif + /* * New fields for task_struct should be added above here, so that * they are included in the randomized portion of task_struct. diff --git a/include/linux/stackleak.h b/include/linux/stackleak.h new file mode 100644 index 000000000000..628c2b947b89 --- /dev/null +++ b/include/linux/stackleak.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_STACKLEAK_H +#define _LINUX_STACKLEAK_H + +#include +#include + +/* + * Check that the poison value points to the unused hole in the + * virtual memory map for your platform. + */ +#define STACKLEAK_POISON -0xBEEF +#define STACKLEAK_SEARCH_DEPTH 128 + +#ifdef CONFIG_GCC_PLUGIN_STACKLEAK +#include + +static inline void stackleak_task_init(struct task_struct *t) +{ + t->lowest_stack = (unsigned long)end_of_stack(t) + sizeof(unsigned long); +} +#else /* !CONFIG_GCC_PLUGIN_STACKLEAK */ +static inline void stackleak_task_init(struct task_struct *t) { } +#endif + +#endif diff --git a/kernel/Makefile b/kernel/Makefile index 7a63d567fdb5..7343b3a9bff0 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -117,6 +117,10 @@ obj-$(CONFIG_HAS_IOMEM) += iomem.o obj-$(CONFIG_ZONE_DEVICE) += memremap.o obj-$(CONFIG_RSEQ) += rseq.o +obj-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak.o +KASAN_SANITIZE_stackleak.o := n +KCOV_INSTRUMENT_stackleak.o := n + $(obj)/configs.o: $(obj)/config_data.h targets += config_data.gz diff --git a/kernel/fork.c b/kernel/fork.c index d896e9ca38b0..47911e49c2b1 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -91,6 +91,7 @@ #include #include #include +#include #include #include @@ -1880,6 +1881,8 @@ static __latent_entropy struct task_struct *copy_process( if (retval) goto bad_fork_cleanup_io; + stackleak_task_init(p); + if (pid != &init_struct_pid) { pid = alloc_pid(p->nsproxy->pid_ns_for_children); if (IS_ERR(pid)) { diff --git a/kernel/stackleak.c b/kernel/stackleak.c new file mode 100644 index 000000000000..deba0d8992f9 --- /dev/null +++ b/kernel/stackleak.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This code fills the used part of the kernel stack with a poison value + * before returning to userspace. It's part of the STACKLEAK feature + * ported from grsecurity/PaX. + * + * Author: Alexander Popov + * + * STACKLEAK reduces the information which kernel stack leak bugs can + * reveal and blocks some uninitialized stack variable attacks. + */ + +#include + +asmlinkage void stackleak_erase(void) +{ + /* It would be nice not to have 'kstack_ptr' and 'boundary' on stack */ + unsigned long kstack_ptr = current->lowest_stack; + unsigned long boundary = (unsigned long)end_of_stack(current); + unsigned int poison_count = 0; + const unsigned int depth = STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long); + + /* Check that 'lowest_stack' value is sane */ + if (unlikely(kstack_ptr - boundary >= THREAD_SIZE)) + kstack_ptr = boundary; + + /* Search for the poison value in the kernel stack */ + while (kstack_ptr > boundary && poison_count <= depth) { + if (*(unsigned long *)kstack_ptr == STACKLEAK_POISON) + poison_count++; + else + poison_count = 0; + + kstack_ptr -= sizeof(unsigned long); + } + + /* + * One 'long int' at the bottom of the thread stack is reserved and + * should not be poisoned (see CONFIG_SCHED_STACK_END_CHECK=y). + */ + if (kstack_ptr == boundary) + kstack_ptr += sizeof(unsigned long); + + /* + * Now write the poison value to the kernel stack. Start from + * 'kstack_ptr' and move up till the new 'boundary'. We assume that + * the stack pointer doesn't change when we write poison. + */ + if (on_thread_stack()) + boundary = current_stack_pointer; + else + boundary = current_top_of_stack(); + + while (kstack_ptr < boundary) { + *(unsigned long *)kstack_ptr = STACKLEAK_POISON; + kstack_ptr += sizeof(unsigned long); + } + + /* Reset the 'lowest_stack' value for the next syscall */ + current->lowest_stack = current_top_of_stack() - THREAD_SIZE/64; +} + diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index cb0c889e13aa..977b84e69787 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -139,4 +139,23 @@ config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE in structures. This reduces the performance hit of RANDSTRUCT at the cost of weakened randomization. +config GCC_PLUGIN_STACKLEAK + bool "Erase the kernel stack before returning from syscalls" + depends on GCC_PLUGINS + depends on HAVE_ARCH_STACKLEAK + help + This option makes the kernel erase the kernel stack before + returning from system calls. That reduces the information which + kernel stack leak bugs can reveal and blocks some uninitialized + stack variable attacks. + + The tradeoff is the performance impact: on a single CPU system kernel + compilation sees a 1% slowdown, other systems and workloads may vary + and you are advised to test this feature on your expected workload + before deploying it. + + This plugin was ported from grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + endif From 10e9ae9fabaf96c8e5227c1cd4827d58b3aa406d Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:16:59 +0300 Subject: [PATCH 050/836] gcc-plugins: Add STACKLEAK plugin for tracking the kernel stack The STACKLEAK feature erases the kernel stack before returning from syscalls. That reduces the information which kernel stack leak bugs can reveal and blocks some uninitialized stack variable attacks. This commit introduces the STACKLEAK gcc plugin. It is needed for tracking the lowest border of the kernel stack, which is important for the code erasing the used part of the kernel stack at the end of syscalls (comes in a separate commit). The STACKLEAK feature is ported from grsecurity/PaX. More information at: https://grsecurity.net/ https://pax.grsecurity.net/ This code is modified from Brad Spengler/PaX Team's code in the last public patch of grsecurity/PaX based on our understanding of the code. Changes or omissions from the original code are ours and don't reflect the original grsecurity/PaX code. Signed-off-by: Alexander Popov Tested-by: Laura Abbott Signed-off-by: Kees Cook --- kernel/stackleak.c | 28 ++ scripts/Makefile.gcc-plugins | 10 + scripts/gcc-plugins/Kconfig | 12 + scripts/gcc-plugins/stackleak_plugin.c | 427 +++++++++++++++++++++++++ 4 files changed, 477 insertions(+) create mode 100644 scripts/gcc-plugins/stackleak_plugin.c diff --git a/kernel/stackleak.c b/kernel/stackleak.c index deba0d8992f9..628485db37ba 100644 --- a/kernel/stackleak.c +++ b/kernel/stackleak.c @@ -60,3 +60,31 @@ asmlinkage void stackleak_erase(void) current->lowest_stack = current_top_of_stack() - THREAD_SIZE/64; } +void __used stackleak_track_stack(void) +{ + /* + * N.B. stackleak_erase() fills the kernel stack with the poison value, + * which has the register width. That code assumes that the value + * of 'lowest_stack' is aligned on the register width boundary. + * + * That is true for x86 and x86_64 because of the kernel stack + * alignment on these platforms (for details, see 'cc_stack_align' in + * arch/x86/Makefile). Take care of that when you port STACKLEAK to + * new platforms. + */ + unsigned long sp = (unsigned long)&sp; + + /* + * Having CONFIG_STACKLEAK_TRACK_MIN_SIZE larger than + * STACKLEAK_SEARCH_DEPTH makes the poison search in + * stackleak_erase() unreliable. Let's prevent that. + */ + BUILD_BUG_ON(CONFIG_STACKLEAK_TRACK_MIN_SIZE > STACKLEAK_SEARCH_DEPTH); + + if (sp < current->lowest_stack && + sp >= (unsigned long)task_stack_page(current) + + sizeof(unsigned long)) { + current->lowest_stack = sp; + } +} +EXPORT_SYMBOL(stackleak_track_stack); diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 0a482f341576..46c5c6809806 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -26,6 +26,16 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \ += -fplugin-arg-randomize_layout_plugin-performance-mode +gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -DSTACKLEAK_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) +ifdef CONFIG_GCC_PLUGIN_STACKLEAK + DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable +endif +export DISABLE_STACKLEAK_PLUGIN + # All the plugin CFLAGS are collected here in case a build target needs to # filter them out of the KBUILD_CFLAGS. GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index 977b84e69787..c65fdd823591 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -158,4 +158,16 @@ config GCC_PLUGIN_STACKLEAK * https://grsecurity.net/ * https://pax.grsecurity.net/ +config STACKLEAK_TRACK_MIN_SIZE + int "Minimum stack frame size of functions tracked by STACKLEAK" + default 100 + range 0 4096 + depends on GCC_PLUGIN_STACKLEAK + help + The STACKLEAK gcc plugin instruments the kernel code for tracking + the lowest border of the kernel stack (and for some other purposes). + It inserts the stackleak_track_stack() call for the functions with + a stack frame size greater than or equal to this parameter. + If unsure, leave the default value 100. + endif diff --git a/scripts/gcc-plugins/stackleak_plugin.c b/scripts/gcc-plugins/stackleak_plugin.c new file mode 100644 index 000000000000..2f48da98b5d4 --- /dev/null +++ b/scripts/gcc-plugins/stackleak_plugin.c @@ -0,0 +1,427 @@ +/* + * Copyright 2011-2017 by the PaX Team + * Modified by Alexander Popov + * Licensed under the GPL v2 + * + * Note: the choice of the license means that the compilation process is + * NOT 'eligible' as defined by gcc's library exception to the GPL v3, + * but for the kernel it doesn't matter since it doesn't link against + * any of the gcc libraries + * + * This gcc plugin is needed for tracking the lowest border of the kernel stack. + * It instruments the kernel code inserting stackleak_track_stack() calls: + * - after alloca(); + * - for the functions with a stack frame size greater than or equal + * to the "track-min-size" plugin parameter. + * + * This plugin is ported from grsecurity/PaX. For more information see: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + * + * Debugging: + * - use fprintf() to stderr, debug_generic_expr(), debug_gimple_stmt(), + * print_rtl() and print_simple_rtl(); + * - add "-fdump-tree-all -fdump-rtl-all" to the plugin CFLAGS in + * Makefile.gcc-plugins to see the verbose dumps of the gcc passes; + * - use gcc -E to understand the preprocessing shenanigans; + * - use gcc with enabled CFG/GIMPLE/SSA verification (--enable-checking). + */ + +#include "gcc-common.h" + +__visible int plugin_is_GPL_compatible; + +static int track_frame_size = -1; +static const char track_function[] = "stackleak_track_stack"; + +/* + * Mark these global variables (roots) for gcc garbage collector since + * they point to the garbage-collected memory. + */ +static GTY(()) tree track_function_decl; + +static struct plugin_info stackleak_plugin_info = { + .version = "201707101337", + .help = "track-min-size=nn\ttrack stack for functions with a stack frame size >= nn bytes\n" + "disable\t\tdo not activate the plugin\n" +}; + +static void stackleak_add_track_stack(gimple_stmt_iterator *gsi, bool after) +{ + gimple stmt; + gcall *stackleak_track_stack; + cgraph_node_ptr node; + int frequency; + basic_block bb; + + /* Insert call to void stackleak_track_stack(void) */ + stmt = gimple_build_call(track_function_decl, 0); + stackleak_track_stack = as_a_gcall(stmt); + if (after) { + gsi_insert_after(gsi, stackleak_track_stack, + GSI_CONTINUE_LINKING); + } else { + gsi_insert_before(gsi, stackleak_track_stack, GSI_SAME_STMT); + } + + /* Update the cgraph */ + bb = gimple_bb(stackleak_track_stack); + node = cgraph_get_create_node(track_function_decl); + gcc_assert(node); + frequency = compute_call_stmt_bb_frequency(current_function_decl, bb); + cgraph_create_edge(cgraph_get_node(current_function_decl), node, + stackleak_track_stack, bb->count, frequency); +} + +static bool is_alloca(gimple stmt) +{ + if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA)) + return true; + +#if BUILDING_GCC_VERSION >= 4007 + if (gimple_call_builtin_p(stmt, BUILT_IN_ALLOCA_WITH_ALIGN)) + return true; +#endif + + return false; +} + +/* + * Work with the GIMPLE representation of the code. Insert the + * stackleak_track_stack() call after alloca() and into the beginning + * of the function if it is not instrumented. + */ +static unsigned int stackleak_instrument_execute(void) +{ + basic_block bb, entry_bb; + bool prologue_instrumented = false, is_leaf = true; + gimple_stmt_iterator gsi; + + /* + * ENTRY_BLOCK_PTR is a basic block which represents possible entry + * point of a function. This block does not contain any code and + * has a CFG edge to its successor. + */ + gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); + entry_bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); + + /* + * Loop through the GIMPLE statements in each of cfun basic blocks. + * cfun is a global variable which represents the function that is + * currently processed. + */ + FOR_EACH_BB_FN(bb, cfun) { + for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { + gimple stmt; + + stmt = gsi_stmt(gsi); + + /* Leaf function is a function which makes no calls */ + if (is_gimple_call(stmt)) + is_leaf = false; + + if (!is_alloca(stmt)) + continue; + + /* Insert stackleak_track_stack() call after alloca() */ + stackleak_add_track_stack(&gsi, true); + if (bb == entry_bb) + prologue_instrumented = true; + } + } + + if (prologue_instrumented) + return 0; + + /* + * Special cases to skip the instrumentation. + * + * Taking the address of static inline functions materializes them, + * but we mustn't instrument some of them as the resulting stack + * alignment required by the function call ABI will break other + * assumptions regarding the expected (but not otherwise enforced) + * register clobbering ABI. + * + * Case in point: native_save_fl on amd64 when optimized for size + * clobbers rdx if it were instrumented here. + * + * TODO: any more special cases? + */ + if (is_leaf && + !TREE_PUBLIC(current_function_decl) && + DECL_DECLARED_INLINE_P(current_function_decl)) { + return 0; + } + + if (is_leaf && + !strncmp(IDENTIFIER_POINTER(DECL_NAME(current_function_decl)), + "_paravirt_", 10)) { + return 0; + } + + /* Insert stackleak_track_stack() call at the function beginning */ + bb = entry_bb; + if (!single_pred_p(bb)) { + /* gcc_assert(bb_loop_depth(bb) || + (bb->flags & BB_IRREDUCIBLE_LOOP)); */ + split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); + gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); + bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); + } + gsi = gsi_after_labels(bb); + stackleak_add_track_stack(&gsi, false); + + return 0; +} + +static bool large_stack_frame(void) +{ +#if BUILDING_GCC_VERSION >= 8000 + return maybe_ge(get_frame_size(), track_frame_size); +#else + return (get_frame_size() >= track_frame_size); +#endif +} + +/* + * Work with the RTL representation of the code. + * Remove the unneeded stackleak_track_stack() calls from the functions + * which don't call alloca() and don't have a large enough stack frame size. + */ +static unsigned int stackleak_cleanup_execute(void) +{ + rtx_insn *insn, *next; + + if (cfun->calls_alloca) + return 0; + + if (large_stack_frame()) + return 0; + + /* + * Find stackleak_track_stack() calls. Loop through the chain of insns, + * which is an RTL representation of the code for a function. + * + * The example of a matching insn: + * (call_insn 8 4 10 2 (call (mem (symbol_ref ("stackleak_track_stack") + * [flags 0x41] ) + * [0 stackleak_track_stack S1 A8]) (0)) 675 {*call} (expr_list + * (symbol_ref ("stackleak_track_stack") [flags 0x41] ) (expr_list (0) (nil))) (nil)) + */ + for (insn = get_insns(); insn; insn = next) { + rtx body; + + next = NEXT_INSN(insn); + + /* Check the expression code of the insn */ + if (!CALL_P(insn)) + continue; + + /* + * Check the expression code of the insn body, which is an RTL + * Expression (RTX) describing the side effect performed by + * that insn. + */ + body = PATTERN(insn); + + if (GET_CODE(body) == PARALLEL) + body = XVECEXP(body, 0, 0); + + if (GET_CODE(body) != CALL) + continue; + + /* + * Check the first operand of the call expression. It should + * be a mem RTX describing the needed subroutine with a + * symbol_ref RTX. + */ + body = XEXP(body, 0); + if (GET_CODE(body) != MEM) + continue; + + body = XEXP(body, 0); + if (GET_CODE(body) != SYMBOL_REF) + continue; + + if (SYMBOL_REF_DECL(body) != track_function_decl) + continue; + + /* Delete the stackleak_track_stack() call */ + delete_insn_and_edges(insn); +#if BUILDING_GCC_VERSION >= 4007 && BUILDING_GCC_VERSION < 8000 + if (GET_CODE(next) == NOTE && + NOTE_KIND(next) == NOTE_INSN_CALL_ARG_LOCATION) { + insn = next; + next = NEXT_INSN(insn); + delete_insn_and_edges(insn); + } +#endif + } + + return 0; +} + +static bool stackleak_gate(void) +{ + tree section; + + section = lookup_attribute("section", + DECL_ATTRIBUTES(current_function_decl)); + if (section && TREE_VALUE(section)) { + section = TREE_VALUE(TREE_VALUE(section)); + + if (!strncmp(TREE_STRING_POINTER(section), ".init.text", 10)) + return false; + if (!strncmp(TREE_STRING_POINTER(section), ".devinit.text", 13)) + return false; + if (!strncmp(TREE_STRING_POINTER(section), ".cpuinit.text", 13)) + return false; + if (!strncmp(TREE_STRING_POINTER(section), ".meminit.text", 13)) + return false; + } + + return track_frame_size >= 0; +} + +/* Build the function declaration for stackleak_track_stack() */ +static void stackleak_start_unit(void *gcc_data __unused, + void *user_data __unused) +{ + tree fntype; + + /* void stackleak_track_stack(void) */ + fntype = build_function_type_list(void_type_node, NULL_TREE); + track_function_decl = build_fn_decl(track_function, fntype); + DECL_ASSEMBLER_NAME(track_function_decl); /* for LTO */ + TREE_PUBLIC(track_function_decl) = 1; + TREE_USED(track_function_decl) = 1; + DECL_EXTERNAL(track_function_decl) = 1; + DECL_ARTIFICIAL(track_function_decl) = 1; + DECL_PRESERVE_P(track_function_decl) = 1; +} + +/* + * Pass gate function is a predicate function that gets executed before the + * corresponding pass. If the return value is 'true' the pass gets executed, + * otherwise, it is skipped. + */ +static bool stackleak_instrument_gate(void) +{ + return stackleak_gate(); +} + +#define PASS_NAME stackleak_instrument +#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg +#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts +#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func \ + | TODO_update_ssa | TODO_rebuild_cgraph_edges +#include "gcc-generate-gimple-pass.h" + +static bool stackleak_cleanup_gate(void) +{ + return stackleak_gate(); +} + +#define PASS_NAME stackleak_cleanup +#define TODO_FLAGS_FINISH TODO_dump_func +#include "gcc-generate-rtl-pass.h" + +/* + * Every gcc plugin exports a plugin_init() function that is called right + * after the plugin is loaded. This function is responsible for registering + * the plugin callbacks and doing other required initialization. + */ +__visible int plugin_init(struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + const int argc = plugin_info->argc; + const struct plugin_argument * const argv = plugin_info->argv; + int i = 0; + + /* Extra GGC root tables describing our GTY-ed data */ + static const struct ggc_root_tab gt_ggc_r_gt_stackleak[] = { + { + .base = &track_function_decl, + .nelt = 1, + .stride = sizeof(track_function_decl), + .cb = >_ggc_mx_tree_node, + .pchw = >_pch_nx_tree_node + }, + LAST_GGC_ROOT_TAB + }; + + /* + * The stackleak_instrument pass should be executed before the + * "optimized" pass, which is the control flow graph cleanup that is + * performed just before expanding gcc trees to the RTL. In former + * versions of the plugin this new pass was inserted before the + * "tree_profile" pass, which is currently called "profile". + */ + PASS_INFO(stackleak_instrument, "optimized", 1, + PASS_POS_INSERT_BEFORE); + + /* + * The stackleak_cleanup pass should be executed after the + * "reload" pass, when the stack frame size is final. + */ + PASS_INFO(stackleak_cleanup, "reload", 1, PASS_POS_INSERT_AFTER); + + if (!plugin_default_version_check(version, &gcc_version)) { + error(G_("incompatible gcc/plugin versions")); + return 1; + } + + /* Parse the plugin arguments */ + for (i = 0; i < argc; i++) { + if (!strcmp(argv[i].key, "disable")) + return 0; + + if (!strcmp(argv[i].key, "track-min-size")) { + if (!argv[i].value) { + error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), + plugin_name, argv[i].key); + return 1; + } + + track_frame_size = atoi(argv[i].value); + if (track_frame_size < 0) { + error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), + plugin_name, argv[i].key, argv[i].value); + return 1; + } + } else { + error(G_("unknown option '-fplugin-arg-%s-%s'"), + plugin_name, argv[i].key); + return 1; + } + } + + /* Give the information about the plugin */ + register_callback(plugin_name, PLUGIN_INFO, NULL, + &stackleak_plugin_info); + + /* Register to be called before processing a translation unit */ + register_callback(plugin_name, PLUGIN_START_UNIT, + &stackleak_start_unit, NULL); + + /* Register an extra GCC garbage collector (GGC) root table */ + register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, + (void *)>_ggc_r_gt_stackleak); + + /* + * Hook into the Pass Manager to register new gcc passes. + * + * The stack frame size info is available only at the last RTL pass, + * when it's too late to insert complex code like a function call. + * So we register two gcc passes to instrument every function at first + * and remove the unneeded instrumentation later. + */ + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, + &stackleak_instrument_pass_info); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, + &stackleak_cleanup_pass_info); + + return 0; +} From f90d1e0c7804b52e12fea501aa46a12c1ff6a567 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:17:00 +0300 Subject: [PATCH 051/836] lkdtm: Add a test for STACKLEAK Introduce an lkdtm test for the STACKLEAK feature: check that the current task stack is properly erased (filled with STACKLEAK_POISON). Signed-off-by: Alexander Popov Signed-off-by: Tycho Andersen Tested-by: Laura Abbott Signed-off-by: Kees Cook --- drivers/misc/lkdtm/Makefile | 2 + drivers/misc/lkdtm/core.c | 1 + drivers/misc/lkdtm/lkdtm.h | 3 ++ drivers/misc/lkdtm/stackleak.c | 73 ++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 drivers/misc/lkdtm/stackleak.c diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile index 3370a4138e94..951c984de61a 100644 --- a/drivers/misc/lkdtm/Makefile +++ b/drivers/misc/lkdtm/Makefile @@ -8,7 +8,9 @@ lkdtm-$(CONFIG_LKDTM) += perms.o lkdtm-$(CONFIG_LKDTM) += refcount.o lkdtm-$(CONFIG_LKDTM) += rodata_objcopy.o lkdtm-$(CONFIG_LKDTM) += usercopy.o +lkdtm-$(CONFIG_LKDTM) += stackleak.o +KASAN_SANITIZE_stackleak.o := n KCOV_INSTRUMENT_rodata.o := n OBJCOPYFLAGS := diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 2154d1bfd18b..aca26d81e9b8 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -183,6 +183,7 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(USERCOPY_STACK_FRAME_FROM), CRASHTYPE(USERCOPY_STACK_BEYOND), CRASHTYPE(USERCOPY_KERNEL), + CRASHTYPE(STACKLEAK_ERASING), }; diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h index 9e513dcfd809..b611b157c84f 100644 --- a/drivers/misc/lkdtm/lkdtm.h +++ b/drivers/misc/lkdtm/lkdtm.h @@ -83,4 +83,7 @@ void lkdtm_USERCOPY_STACK_FRAME_FROM(void); void lkdtm_USERCOPY_STACK_BEYOND(void); void lkdtm_USERCOPY_KERNEL(void); +/* lkdtm_stackleak.c */ +void lkdtm_STACKLEAK_ERASING(void); + #endif diff --git a/drivers/misc/lkdtm/stackleak.c b/drivers/misc/lkdtm/stackleak.c new file mode 100644 index 000000000000..d5a084475abc --- /dev/null +++ b/drivers/misc/lkdtm/stackleak.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This code tests that the current task stack is properly erased (filled + * with STACKLEAK_POISON). + * + * Authors: + * Alexander Popov + * Tycho Andersen + */ + +#include "lkdtm.h" +#include + +void lkdtm_STACKLEAK_ERASING(void) +{ + unsigned long *sp, left, found, i; + const unsigned long check_depth = + STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long); + + /* + * For the details about the alignment of the poison values, see + * the comment in stackleak_track_stack(). + */ + sp = PTR_ALIGN(&i, sizeof(unsigned long)); + + left = ((unsigned long)sp & (THREAD_SIZE - 1)) / sizeof(unsigned long); + sp--; + + /* + * One 'long int' at the bottom of the thread stack is reserved + * and not poisoned. + */ + if (left > 1) { + left--; + } else { + pr_err("FAIL: not enough stack space for the test\n"); + return; + } + + pr_info("checking unused part of the thread stack (%lu bytes)...\n", + left * sizeof(unsigned long)); + + /* + * Search for 'check_depth' poison values in a row (just like + * stackleak_erase() does). + */ + for (i = 0, found = 0; i < left && found <= check_depth; i++) { + if (*(sp - i) == STACKLEAK_POISON) + found++; + else + found = 0; + } + + if (found <= check_depth) { + pr_err("FAIL: thread stack is not erased (checked %lu bytes)\n", + i * sizeof(unsigned long)); + return; + } + + pr_info("first %lu bytes are unpoisoned\n", + (i - found) * sizeof(unsigned long)); + + /* The rest of thread stack should be erased */ + for (; i < left; i++) { + if (*(sp - i) != STACKLEAK_POISON) { + pr_err("FAIL: thread stack is NOT properly erased\n"); + return; + } + } + + pr_info("OK: the rest of the thread stack is properly erased\n"); + return; +} From c8d126275a5fa59394fe17109bdb9812fed296b8 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:17:01 +0300 Subject: [PATCH 052/836] fs/proc: Show STACKLEAK metrics in the /proc file system Introduce CONFIG_STACKLEAK_METRICS providing STACKLEAK information about tasks via the /proc file system. In particular, /proc//stack_depth shows the maximum kernel stack consumption for the current and previous syscalls. Although this information is not precise, it can be useful for estimating the STACKLEAK performance impact for your workloads. Suggested-by: Ingo Molnar Signed-off-by: Alexander Popov Tested-by: Laura Abbott Signed-off-by: Kees Cook --- fs/proc/base.c | 18 ++++++++++++++++++ include/linux/sched.h | 1 + include/linux/stackleak.h | 3 +++ kernel/stackleak.c | 4 ++++ scripts/gcc-plugins/Kconfig | 12 ++++++++++++ 5 files changed, 38 insertions(+) diff --git a/fs/proc/base.c b/fs/proc/base.c index ccf86f16d9f0..2a238d68610e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2891,6 +2891,21 @@ static int proc_pid_patch_state(struct seq_file *m, struct pid_namespace *ns, } #endif /* CONFIG_LIVEPATCH */ +#ifdef CONFIG_STACKLEAK_METRICS +static int proc_stack_depth(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task) +{ + unsigned long prev_depth = THREAD_SIZE - + (task->prev_lowest_stack & (THREAD_SIZE - 1)); + unsigned long depth = THREAD_SIZE - + (task->lowest_stack & (THREAD_SIZE - 1)); + + seq_printf(m, "previous stack depth: %lu\nstack depth: %lu\n", + prev_depth, depth); + return 0; +} +#endif /* CONFIG_STACKLEAK_METRICS */ + /* * Thread groups */ @@ -2992,6 +3007,9 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_LIVEPATCH ONE("patch_state", S_IRUSR, proc_pid_patch_state), #endif +#ifdef CONFIG_STACKLEAK_METRICS + ONE("stack_depth", S_IRUGO, proc_stack_depth), +#endif }; static int proc_tgid_base_readdir(struct file *file, struct dir_context *ctx) diff --git a/include/linux/sched.h b/include/linux/sched.h index c1a23acd24e7..ae9d10e14b82 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1194,6 +1194,7 @@ struct task_struct { #ifdef CONFIG_GCC_PLUGIN_STACKLEAK unsigned long lowest_stack; + unsigned long prev_lowest_stack; #endif /* diff --git a/include/linux/stackleak.h b/include/linux/stackleak.h index 628c2b947b89..b911b973d328 100644 --- a/include/linux/stackleak.h +++ b/include/linux/stackleak.h @@ -18,6 +18,9 @@ static inline void stackleak_task_init(struct task_struct *t) { t->lowest_stack = (unsigned long)end_of_stack(t) + sizeof(unsigned long); +# ifdef CONFIG_STACKLEAK_METRICS + t->prev_lowest_stack = t->lowest_stack; +# endif } #else /* !CONFIG_GCC_PLUGIN_STACKLEAK */ static inline void stackleak_task_init(struct task_struct *t) { } diff --git a/kernel/stackleak.c b/kernel/stackleak.c index 628485db37ba..f66239572c89 100644 --- a/kernel/stackleak.c +++ b/kernel/stackleak.c @@ -41,6 +41,10 @@ asmlinkage void stackleak_erase(void) if (kstack_ptr == boundary) kstack_ptr += sizeof(unsigned long); +#ifdef CONFIG_STACKLEAK_METRICS + current->prev_lowest_stack = kstack_ptr; +#endif + /* * Now write the poison value to the kernel stack. Start from * 'kstack_ptr' and move up till the new 'boundary'. We assume that diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index c65fdd823591..b0a015ef5268 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -170,4 +170,16 @@ config STACKLEAK_TRACK_MIN_SIZE a stack frame size greater than or equal to this parameter. If unsure, leave the default value 100. +config STACKLEAK_METRICS + bool "Show STACKLEAK metrics in the /proc file system" + depends on GCC_PLUGIN_STACKLEAK + depends on PROC_FS + help + If this is set, STACKLEAK metrics for every task are available in + the /proc file system. In particular, /proc//stack_depth + shows the maximum kernel stack consumption for the current and + previous syscalls. Although this information is not precise, it + can be useful for estimating the STACKLEAK performance impact for + your workloads. + endif From ed535a2dae1836d15c71e250475952881265d244 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:17:02 +0300 Subject: [PATCH 053/836] doc: self-protection: Add information about STACKLEAK feature Add information about STACKLEAK feature to the "Memory poisoning" section of self-protection.rst. Signed-off-by: Alexander Popov Signed-off-by: Kees Cook --- Documentation/security/self-protection.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/security/self-protection.rst b/Documentation/security/self-protection.rst index e1ca698e0006..f584fb74b4ff 100644 --- a/Documentation/security/self-protection.rst +++ b/Documentation/security/self-protection.rst @@ -302,11 +302,11 @@ sure structure holes are cleared. Memory poisoning ---------------- -When releasing memory, it is best to poison the contents (clear stack on -syscall return, wipe heap memory on a free), to avoid reuse attacks that -rely on the old contents of memory. This frustrates many uninitialized -variable attacks, stack content exposures, heap content exposures, and -use-after-free attacks. +When releasing memory, it is best to poison the contents, to avoid reuse +attacks that rely on the old contents of memory. E.g., clear stack on a +syscall return (``CONFIG_GCC_PLUGIN_STACKLEAK``), wipe heap memory on a +free. This frustrates many uninitialized variable attacks, stack content +exposures, heap content exposures, and use-after-free attacks. Destination tracking -------------------- From 964c9dff0091893a9a74a88edf984c6da0b779f7 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:17:03 +0300 Subject: [PATCH 054/836] stackleak: Allow runtime disabling of kernel stack erasing Introduce CONFIG_STACKLEAK_RUNTIME_DISABLE option, which provides 'stack_erasing' sysctl. It can be used in runtime to control kernel stack erasing for kernels built with CONFIG_GCC_PLUGIN_STACKLEAK. Suggested-by: Ingo Molnar Signed-off-by: Alexander Popov Tested-by: Laura Abbott Signed-off-by: Kees Cook --- Documentation/sysctl/kernel.txt | 18 ++++++++++++++++ include/linux/stackleak.h | 6 ++++++ kernel/stackleak.c | 38 +++++++++++++++++++++++++++++++++ kernel/sysctl.c | 15 ++++++++++++- scripts/gcc-plugins/Kconfig | 8 +++++++ 5 files changed, 84 insertions(+), 1 deletion(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 37a679501ddc..1b8775298cf7 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -89,6 +89,7 @@ show up in /proc/sys/kernel: - shmmni - softlockup_all_cpu_backtrace - soft_watchdog +- stack_erasing - stop-a [ SPARC only ] - sysrq ==> Documentation/admin-guide/sysrq.rst - sysctl_writes_strict @@ -987,6 +988,23 @@ detect a hard lockup condition. ============================================================== +stack_erasing + +This parameter can be used to control kernel stack erasing at the end +of syscalls for kernels built with CONFIG_GCC_PLUGIN_STACKLEAK. + +That erasing reduces the information which kernel stack leak bugs +can reveal and blocks some uninitialized stack variable attacks. +The tradeoff is the performance impact: on a single CPU system kernel +compilation sees a 1% slowdown, other systems and workloads may vary. + + 0: kernel stack erasing is disabled, STACKLEAK_METRICS are not updated. + + 1: kernel stack erasing is enabled (default), it is performed before + returning to the userspace at the end of syscalls. + +============================================================== + tainted: Non-zero if the kernel has been tainted. Numeric values, which can be diff --git a/include/linux/stackleak.h b/include/linux/stackleak.h index b911b973d328..3d5c3271a9a8 100644 --- a/include/linux/stackleak.h +++ b/include/linux/stackleak.h @@ -22,6 +22,12 @@ static inline void stackleak_task_init(struct task_struct *t) t->prev_lowest_stack = t->lowest_stack; # endif } + +#ifdef CONFIG_STACKLEAK_RUNTIME_DISABLE +int stack_erasing_sysctl(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); +#endif + #else /* !CONFIG_GCC_PLUGIN_STACKLEAK */ static inline void stackleak_task_init(struct task_struct *t) { } #endif diff --git a/kernel/stackleak.c b/kernel/stackleak.c index f66239572c89..e42892926244 100644 --- a/kernel/stackleak.c +++ b/kernel/stackleak.c @@ -12,6 +12,41 @@ #include +#ifdef CONFIG_STACKLEAK_RUNTIME_DISABLE +#include +#include + +static DEFINE_STATIC_KEY_FALSE(stack_erasing_bypass); + +int stack_erasing_sysctl(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret = 0; + int state = !static_branch_unlikely(&stack_erasing_bypass); + int prev_state = state; + + table->data = &state; + table->maxlen = sizeof(int); + ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + state = !!state; + if (ret || !write || state == prev_state) + return ret; + + if (state) + static_branch_disable(&stack_erasing_bypass); + else + static_branch_enable(&stack_erasing_bypass); + + pr_warn("stackleak: kernel stack erasing is %s\n", + state ? "enabled" : "disabled"); + return ret; +} + +#define skip_erasing() static_branch_unlikely(&stack_erasing_bypass) +#else +#define skip_erasing() false +#endif /* CONFIG_STACKLEAK_RUNTIME_DISABLE */ + asmlinkage void stackleak_erase(void) { /* It would be nice not to have 'kstack_ptr' and 'boundary' on stack */ @@ -20,6 +55,9 @@ asmlinkage void stackleak_erase(void) unsigned int poison_count = 0; const unsigned int depth = STACKLEAK_SEARCH_DEPTH / sizeof(unsigned long); + if (skip_erasing()) + return; + /* Check that 'lowest_stack' value is sane */ if (unlikely(kstack_ptr - boundary >= THREAD_SIZE)) kstack_ptr = boundary; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index cc02050fd0c4..3ae223f7b5df 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -91,7 +91,9 @@ #ifdef CONFIG_CHR_DEV_SG #include #endif - +#ifdef CONFIG_STACKLEAK_RUNTIME_DISABLE +#include +#endif #ifdef CONFIG_LOCKUP_DETECTOR #include #endif @@ -1232,6 +1234,17 @@ static struct ctl_table kern_table[] = { .extra1 = &zero, .extra2 = &one, }, +#endif +#ifdef CONFIG_STACKLEAK_RUNTIME_DISABLE + { + .procname = "stack_erasing", + .data = NULL, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = stack_erasing_sysctl, + .extra1 = &zero, + .extra2 = &one, + }, #endif { } }; diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig index b0a015ef5268..0d5c799688f0 100644 --- a/scripts/gcc-plugins/Kconfig +++ b/scripts/gcc-plugins/Kconfig @@ -182,4 +182,12 @@ config STACKLEAK_METRICS can be useful for estimating the STACKLEAK performance impact for your workloads. +config STACKLEAK_RUNTIME_DISABLE + bool "Allow runtime disabling of kernel stack erasing" + depends on GCC_PLUGIN_STACKLEAK + help + This option provides 'stack_erasing' sysctl, which can be used in + runtime to control kernel stack erasing for kernels built with + CONFIG_GCC_PLUGIN_STACKLEAK. + endif From 6fcde90466738b84a073e4f4d18c50015ee29fb2 Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Fri, 17 Aug 2018 01:17:04 +0300 Subject: [PATCH 055/836] arm64: Drop unneeded stackleak_check_alloca() Drop stackleak_check_alloca() for arm64 since the STACKLEAK gcc plugin now doesn't track stack depth overflow caused by alloca(). Signed-off-by: Alexander Popov Tested-by: Laura Abbott Signed-off-by: Kees Cook --- arch/arm64/kernel/process.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 7f1628effe6d..740b31f77ade 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -493,25 +493,3 @@ void arch_setup_new_exec(void) { current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0; } - -#ifdef CONFIG_GCC_PLUGIN_STACKLEAK -void __used stackleak_check_alloca(unsigned long size) -{ - unsigned long stack_left; - unsigned long current_sp = current_stack_pointer; - struct stack_info info; - - BUG_ON(!on_accessible_stack(current, current_sp, &info)); - - stack_left = current_sp - info.low; - - /* - * There's a good chance we're almost out of stack space if this - * is true. Using panic() over BUG() is more likely to give - * reliable debugging output. - */ - if (size >= stack_left) - panic("alloca() over the kernel stack boundary\n"); -} -EXPORT_SYMBOL(stackleak_check_alloca); -#endif From c2ff8383cc33c2d9c169e4daf1e37a434c3bb420 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Mon, 20 Aug 2018 21:40:13 +0800 Subject: [PATCH 056/836] clk: sunxi-ng: sun50i: h6: Add 2x fixed post-divider to MMC module clocks On the H6, the MMC module clocks are fixed in the new timing mode, i.e. they do not have a bit to select the mode. These clocks have a 2x divider somewhere between the clock and the MMC module. To be consistent with other SoCs supporting the new timing mode, we model the 2x divider as a fixed post-divider on the MMC module clocks. This patch adds the post-dividers to the MMC clocks, following the approach on A64. Fixes: 524353ea480b ("clk: sunxi-ng: add support for the Allwinner H6 CCU") Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 39 +++++++++++++++------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c index d425b47cef17..2193e1495086 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -408,26 +408,29 @@ static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb3", 0x82c, BIT(0), 0); static const char * const mmc_parents[] = { "osc24M", "pll-periph0-2x", "pll-periph1-2x" }; -static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_parents, 0x830, - 0, 4, /* M */ - 8, 2, /* N */ - 24, 3, /* mux */ - BIT(31),/* gate */ - 0); +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0", mmc_parents, 0x830, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ + 0); -static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_parents, 0x834, - 0, 4, /* M */ - 8, 2, /* N */ - 24, 3, /* mux */ - BIT(31),/* gate */ - 0); +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ + 0); -static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_parents, 0x838, - 0, 4, /* M */ - 8, 2, /* N */ - 24, 3, /* mux */ - BIT(31),/* gate */ - 0); +static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838, + 0, 4, /* M */ + 8, 2, /* N */ + 24, 3, /* mux */ + BIT(31), /* gate */ + 2, /* post-div */ + 0); static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0); static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0); From 65b1e8a6ca5f5305962daee6af730bd2d210bb0b Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 4 Sep 2018 12:40:43 +0800 Subject: [PATCH 057/836] clk: sunxi-ng: a64: Add minimal rate for video PLLs According to documentation and experience with other similar SoCs, video PLLs don't work stable if their output frequency is set below 192 MHz. Because of that, set minimal rate to both A64 video PLLs to 192 MHz. Signed-off-by: Jagan Teki Signed-off-by: Icenowy Zheng Reviewed-by: Jernej Skrabec Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 46 ++++++++++++++------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index ee9c12cf3f08..d0e30192f0cf 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -64,17 +64,18 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", BIT(28), /* lock */ CLK_SET_RATE_UNGATE); -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", - "osc24M", 0x010, - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", + "osc24M", 0x010, + 192000000, /* Minimum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", "osc24M", 0x018, @@ -125,17 +126,18 @@ static struct ccu_nk pll_periph1_clk = { }, }; -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", - "osc24M", 0x030, - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", + "osc24M", 0x030, + 192000000, /* Minimum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", "osc24M", 0x038, From 5de39acaf34604bd04834f092479cf4dcc946dd4 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Tue, 4 Sep 2018 12:40:44 +0800 Subject: [PATCH 058/836] clk: sunxi-ng: a64: Add max. rate constraint to video PLLs Video PLLs on A64 can be set to higher rate that it is actually supported by HW. Limit maximum rate to 1008 MHz. This is the maximum allowed rate by BSP clock driver. Interestengly, user manual specifies maximum frequency to be 600 MHz. Historically, this data was wrong in some user manuals for other SoCs, so more faith is put in BSP clock driver. Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 50 ++++++++++++++------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index d0e30192f0cf..5f80eb018014 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -64,18 +64,19 @@ static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", BIT(28), /* lock */ CLK_SET_RATE_UNGATE); -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", - "osc24M", 0x010, - 192000000, /* Minimum rate */ - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0", + "osc24M", 0x010, + 192000000, /* Minimum rate */ + 1008000000, /* Maximum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", "osc24M", 0x018, @@ -126,18 +127,19 @@ static struct ccu_nk pll_periph1_clk = { }, }; -static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", - "osc24M", 0x030, - 192000000, /* Minimum rate */ - 8, 7, /* N */ - 0, 4, /* M */ - BIT(24), /* frac enable */ - BIT(25), /* frac select */ - 270000000, /* frac rate 0 */ - 297000000, /* frac rate 1 */ - BIT(31), /* gate */ - BIT(28), /* lock */ - CLK_SET_RATE_UNGATE); +static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1", + "osc24M", 0x030, + 192000000, /* Minimum rate */ + 1008000000, /* Maximum rate */ + 8, 7, /* N */ + 0, 4, /* M */ + BIT(24), /* frac enable */ + BIT(25), /* frac select */ + 270000000, /* frac rate 0 */ + 297000000, /* frac rate 1 */ + BIT(31), /* gate */ + BIT(28), /* lock */ + CLK_SET_RATE_UNGATE); static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", "osc24M", 0x038, From 8b2a37870419f4aa6e6f837aa8ec627eae984010 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Tue, 4 Sep 2018 12:40:49 +0800 Subject: [PATCH 059/836] dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO0 macro Allwinner A64 HDMI PHY clock has PLL_VIDEO0 as a parent. Include the macro on dt-bindings so-that the same can be used while defining CCU clock phandles. Signed-off-by: Jagan Teki Reviewed-by: Rob Herring Signed-off-by: Icenowy Zheng Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 4 +++- include/dt-bindings/clock/sun50i-a64-ccu.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index 061b6fbb4f95..cd415b968e8c 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -27,7 +27,9 @@ #define CLK_PLL_AUDIO_2X 4 #define CLK_PLL_AUDIO_4X 5 #define CLK_PLL_AUDIO_8X 6 -#define CLK_PLL_VIDEO0 7 + +/* PLL_VIDEO0 exported for HDMI PHY */ + #define CLK_PLL_VIDEO0_2X 8 #define CLK_PLL_VE 9 #define CLK_PLL_DDR0 10 diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h index d66432c6e675..a8ac4cfcdcbc 100644 --- a/include/dt-bindings/clock/sun50i-a64-ccu.h +++ b/include/dt-bindings/clock/sun50i-a64-ccu.h @@ -43,6 +43,7 @@ #ifndef _DT_BINDINGS_CLK_SUN50I_A64_H_ #define _DT_BINDINGS_CLK_SUN50I_A64_H_ +#define CLK_PLL_VIDEO0 7 #define CLK_PLL_PERIPH0 11 #define CLK_BUS_MIPI_DSI 28 From 53e6ab3d07506895a7eef217612bba921b8bf108 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:23 +0200 Subject: [PATCH 060/836] clk: samsung: Remove excessive include Exynos Audio SubSystem and Exynos3250 clock drivers don't use any syscore function, so don't include linux/syscore_ops.h in their code. Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos-audss.c | 1 - drivers/clk/samsung/clk-exynos3250.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c index f659c5cbf1d5..8f8a0f9fc842 100644 --- a/drivers/clk/samsung/clk-exynos-audss.c +++ b/drivers/clk/samsung/clk-exynos-audss.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c index 27c9d23657b3..0e9a41a4cac8 100644 --- a/drivers/clk/samsung/clk-exynos3250.c +++ b/drivers/clk/samsung/clk-exynos3250.c @@ -12,7 +12,6 @@ #include #include #include -#include #include From 6bdac3b4c493f86554bc11013d47d31243022beb Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:24 +0200 Subject: [PATCH 061/836] clk: samsung: s3c2410: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-s3c2410.c | 43 ++----------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index a9c887475054..8cb868f06257 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -11,7 +11,6 @@ #include #include #include -#include #include @@ -40,9 +39,6 @@ enum s3c2410_plls { static void __iomem *reg_base; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *s3c2410_save; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -57,42 +53,6 @@ static unsigned long s3c2410_clk_regs[] __initdata = { CAMDIVN, }; -static int s3c2410_clk_suspend(void) -{ - samsung_clk_save(reg_base, s3c2410_save, - ARRAY_SIZE(s3c2410_clk_regs)); - - return 0; -} - -static void s3c2410_clk_resume(void) -{ - samsung_clk_restore(reg_base, s3c2410_save, - ARRAY_SIZE(s3c2410_clk_regs)); -} - -static struct syscore_ops s3c2410_clk_syscore_ops = { - .suspend = s3c2410_clk_suspend, - .resume = s3c2410_clk_resume, -}; - -static void __init s3c2410_clk_sleep_init(void) -{ - s3c2410_save = samsung_clk_alloc_reg_dump(s3c2410_clk_regs, - ARRAY_SIZE(s3c2410_clk_regs)); - if (!s3c2410_save) { - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); - return; - } - - register_syscore_ops(&s3c2410_clk_syscore_ops); - return; -} -#else -static void __init s3c2410_clk_sleep_init(void) {} -#endif - PNAME(fclk_p) = { "mpll", "div_slow" }; static struct samsung_mux_clock s3c2410_common_muxes[] __initdata = { @@ -461,7 +421,8 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, ARRAY_SIZE(s3c244x_common_aliases)); } - s3c2410_clk_sleep_init(); + samsung_clk_sleep_init(reg_base, s3c2410_clk_regs, + ARRAY_SIZE(s3c2410_clk_regs)); samsung_clk_of_add_provider(np, ctx); } From 1b3493d755c85b0fd206b7e5f04ce7050af90c41 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:25 +0200 Subject: [PATCH 062/836] clk: samsung: s3c2412: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-s3c2412.c | 43 ++----------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c index 6bc94d3aff78..dd1159050a5a 100644 --- a/drivers/clk/samsung/clk-s3c2412.c +++ b/drivers/clk/samsung/clk-s3c2412.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -29,9 +28,6 @@ static void __iomem *reg_base; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *s3c2412_save; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -45,42 +41,6 @@ static unsigned long s3c2412_clk_regs[] __initdata = { CLKSRC, }; -static int s3c2412_clk_suspend(void) -{ - samsung_clk_save(reg_base, s3c2412_save, - ARRAY_SIZE(s3c2412_clk_regs)); - - return 0; -} - -static void s3c2412_clk_resume(void) -{ - samsung_clk_restore(reg_base, s3c2412_save, - ARRAY_SIZE(s3c2412_clk_regs)); -} - -static struct syscore_ops s3c2412_clk_syscore_ops = { - .suspend = s3c2412_clk_suspend, - .resume = s3c2412_clk_resume, -}; - -static void __init s3c2412_clk_sleep_init(void) -{ - s3c2412_save = samsung_clk_alloc_reg_dump(s3c2412_clk_regs, - ARRAY_SIZE(s3c2412_clk_regs)); - if (!s3c2412_save) { - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); - return; - } - - register_syscore_ops(&s3c2412_clk_syscore_ops); - return; -} -#else -static void __init s3c2412_clk_sleep_init(void) {} -#endif - static struct clk_div_table divxti_d[] = { { .val = 0, .div = 1 }, { .val = 1, .div = 2 }, @@ -278,7 +238,8 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f, samsung_clk_register_alias(ctx, s3c2412_aliases, ARRAY_SIZE(s3c2412_aliases)); - s3c2412_clk_sleep_init(); + samsung_clk_sleep_init(reg_base, s3c2412_clk_regs, + ARRAY_SIZE(s3c2412_clk_regs)); samsung_clk_of_add_provider(np, ctx); From b5331e2feafe508f51a8a2b668cdf402f04ccc10 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:26 +0200 Subject: [PATCH 063/836] clk: samsung: s3c2443: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-s3c2443.c | 43 ++----------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c index c46e6d5bc9bc..884067e4f1a1 100644 --- a/drivers/clk/samsung/clk-s3c2443.c +++ b/drivers/clk/samsung/clk-s3c2443.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -43,9 +42,6 @@ enum supported_socs { static void __iomem *reg_base; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *s3c2443_save; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -65,42 +61,6 @@ static unsigned long s3c2443_clk_regs[] __initdata = { SCLKCON, }; -static int s3c2443_clk_suspend(void) -{ - samsung_clk_save(reg_base, s3c2443_save, - ARRAY_SIZE(s3c2443_clk_regs)); - - return 0; -} - -static void s3c2443_clk_resume(void) -{ - samsung_clk_restore(reg_base, s3c2443_save, - ARRAY_SIZE(s3c2443_clk_regs)); -} - -static struct syscore_ops s3c2443_clk_syscore_ops = { - .suspend = s3c2443_clk_suspend, - .resume = s3c2443_clk_resume, -}; - -static void __init s3c2443_clk_sleep_init(void) -{ - s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs, - ARRAY_SIZE(s3c2443_clk_regs)); - if (!s3c2443_save) { - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); - return; - } - - register_syscore_ops(&s3c2443_clk_syscore_ops); - return; -} -#else -static void __init s3c2443_clk_sleep_init(void) {} -#endif - PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" }; PNAME(esysclk_p) = { "epllref", "epll" }; PNAME(mpllref_p) = { "xti", "mdivclk" }; @@ -450,7 +410,8 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, break; } - s3c2443_clk_sleep_init(); + samsung_clk_sleep_init(reg_base, s3c2443_clk_regs, + ARRAY_SIZE(s3c2443_clk_regs)); samsung_clk_of_add_provider(np, ctx); From cc8a4ea182efac95ad4582053f8a51271fab734d Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 18 Jul 2018 18:09:55 +0200 Subject: [PATCH 064/836] platform/chrome: Move mfd/cros_ec_lpc* includes to drivers/platform. The cros-ec-lpc driver lives in drivers/platform because is platform specific, however there are two includes (cros_ec_lpc_mec.h and cros_ec_lpc_reg.h) that lives in include/linux/mfd. These two includes are only used for the platform driver and are not really related to the MFD subsystem, so move the includes from include/linux/mfd to drivers/platform/chrome. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Benson Leung --- drivers/platform/chrome/cros_ec_lpc.c | 3 ++- drivers/platform/chrome/cros_ec_lpc_mec.c | 3 ++- .../linux/mfd => drivers/platform/chrome}/cros_ec_lpc_mec.h | 6 +++--- drivers/platform/chrome/cros_ec_lpc_reg.c | 3 ++- .../linux/mfd => drivers/platform/chrome}/cros_ec_lpc_reg.h | 6 +++--- 5 files changed, 12 insertions(+), 9 deletions(-) rename {include/linux/mfd => drivers/platform/chrome}/cros_ec_lpc_mec.h (96%) rename {include/linux/mfd => drivers/platform/chrome}/cros_ec_lpc_reg.h (94%) diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index 31c8b8c49e45..7ec8789bf161 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c @@ -27,12 +27,13 @@ #include #include #include -#include #include #include #include #include +#include "cros_ec_lpc_reg.h" + #define DRV_NAME "cros_ec_lpcs" #define ACPI_DRV_NAME "GOOG0004" diff --git a/drivers/platform/chrome/cros_ec_lpc_mec.c b/drivers/platform/chrome/cros_ec_lpc_mec.c index 2eda2c2fc210..c4edfa83e493 100644 --- a/drivers/platform/chrome/cros_ec_lpc_mec.c +++ b/drivers/platform/chrome/cros_ec_lpc_mec.c @@ -24,10 +24,11 @@ #include #include #include -#include #include #include +#include "cros_ec_lpc_mec.h" + /* * This mutex must be held while accessing the EMI unit. We can't rely on the * EC mutex because memmap data may be accessed without it being held. diff --git a/include/linux/mfd/cros_ec_lpc_mec.h b/drivers/platform/chrome/cros_ec_lpc_mec.h similarity index 96% rename from include/linux/mfd/cros_ec_lpc_mec.h rename to drivers/platform/chrome/cros_ec_lpc_mec.h index 176496ddc66c..105068c0e919 100644 --- a/include/linux/mfd/cros_ec_lpc_mec.h +++ b/drivers/platform/chrome/cros_ec_lpc_mec.h @@ -21,8 +21,8 @@ * expensive. */ -#ifndef __LINUX_MFD_CROS_EC_MEC_H -#define __LINUX_MFD_CROS_EC_MEC_H +#ifndef __CROS_EC_LPC_MEC_H +#define __CROS_EC_LPC_MEC_H #include @@ -87,4 +87,4 @@ void cros_ec_lpc_mec_destroy(void); u8 cros_ec_lpc_io_bytes_mec(enum cros_ec_lpc_mec_io_type io_type, unsigned int offset, unsigned int length, u8 *buf); -#endif /* __LINUX_MFD_CROS_EC_MEC_H */ +#endif /* __CROS_EC_LPC_MEC_H */ diff --git a/drivers/platform/chrome/cros_ec_lpc_reg.c b/drivers/platform/chrome/cros_ec_lpc_reg.c index dcc7a3e30604..fc23d535c404 100644 --- a/drivers/platform/chrome/cros_ec_lpc_reg.c +++ b/drivers/platform/chrome/cros_ec_lpc_reg.c @@ -24,7 +24,8 @@ #include #include #include -#include + +#include "cros_ec_lpc_mec.h" static u8 lpc_read_bytes(unsigned int offset, unsigned int length, u8 *dest) { diff --git a/include/linux/mfd/cros_ec_lpc_reg.h b/drivers/platform/chrome/cros_ec_lpc_reg.h similarity index 94% rename from include/linux/mfd/cros_ec_lpc_reg.h rename to drivers/platform/chrome/cros_ec_lpc_reg.h index 5560bef63c2b..1c12c38b306a 100644 --- a/include/linux/mfd/cros_ec_lpc_reg.h +++ b/drivers/platform/chrome/cros_ec_lpc_reg.h @@ -21,8 +21,8 @@ * expensive. */ -#ifndef __LINUX_MFD_CROS_EC_REG_H -#define __LINUX_MFD_CROS_EC_REG_H +#ifndef __CROS_EC_LPC_REG_H +#define __CROS_EC_LPC_REG_H /** * cros_ec_lpc_read_bytes - Read bytes from a given LPC-mapped address. @@ -58,4 +58,4 @@ void cros_ec_lpc_reg_init(void); */ void cros_ec_lpc_reg_destroy(void); -#endif /* __LINUX_MFD_CROS_EC_REG_H */ +#endif /* __CROS_EC_LPC_REG_H */ From e2bbf91cad09118d7500f1fdaaa83d7741d30395 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 18 Jul 2018 18:09:56 +0200 Subject: [PATCH 065/836] mfd: cros_ec: Fix and improve kerneldoc comments. cros-ec includes inside the MFD subsystem, specially the file cros_ec_commands.h, has been modified several times and it has grown a lot, unfortunately, we didn't have care too much about the documentation. This patch tries to improve the documentation and also fixes all the issues reported by kerneldoc script. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Benson Leung --- drivers/mfd/cros_ec_dev.h | 13 +- include/linux/mfd/cros_ec.h | 214 ++++++++++--------- include/linux/mfd/cros_ec_commands.h | 295 +++++++++++++++++---------- 3 files changed, 310 insertions(+), 212 deletions(-) diff --git a/drivers/mfd/cros_ec_dev.h b/drivers/mfd/cros_ec_dev.h index 45e9453608c5..978d836a0248 100644 --- a/drivers/mfd/cros_ec_dev.h +++ b/drivers/mfd/cros_ec_dev.h @@ -26,12 +26,13 @@ #define CROS_EC_DEV_VERSION "1.0.0" -/* - * @offset: within EC_LPC_ADDR_MEMMAP region - * @bytes: number of bytes to read. zero means "read a string" (including '\0') - * (at most only EC_MEMMAP_SIZE bytes can be read) - * @buffer: where to store the result - * ioctl returns the number of bytes read, negative on error +/** + * struct cros_ec_readmem - Struct used to read mapped memory. + * @offset: Within EC_LPC_ADDR_MEMMAP region. + * @bytes: Number of bytes to read. Zero means "read a string" (including '\0') + * At most only EC_MEMMAP_SIZE bytes can be read. + * @buffer: Where to store the result. The ioctl returns the number of bytes + * read or negative on error. */ struct cros_ec_readmem { uint32_t offset; diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index 20949dde35cd..e44e3ec8a9c7 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h @@ -36,7 +36,7 @@ * I2C requires 1 additional byte for requests. * I2C requires 2 additional bytes for responses. * SPI requires up to 32 additional bytes for responses. - * */ + */ #define EC_PROTO_VERSION_UNKNOWN 0 #define EC_MAX_REQUEST_OVERHEAD 1 #define EC_MAX_RESPONSE_OVERHEAD 32 @@ -58,13 +58,14 @@ enum { EC_MAX_MSG_BYTES = 64 * 1024, }; -/* - * @version: Command version number (often 0) - * @command: Command to send (EC_CMD_...) - * @outsize: Outgoing length in bytes - * @insize: Max number of bytes to accept from EC - * @result: EC's response to the command (separate from communication failure) - * @data: Where to put the incoming data from EC and outgoing data to EC +/** + * struct cros_ec_command - Information about a ChromeOS EC command. + * @version: Command version number (often 0). + * @command: Command to send (EC_CMD_...). + * @outsize: Outgoing length in bytes. + * @insize: Max number of bytes to accept from the EC. + * @result: EC's response to the command (separate from communication failure). + * @data: Where to put the incoming data from EC and outgoing data to EC. */ struct cros_ec_command { uint32_t version; @@ -76,48 +77,55 @@ struct cros_ec_command { }; /** - * struct cros_ec_device - Information about a ChromeOS EC device - * - * @phys_name: name of physical comms layer (e.g. 'i2c-4') + * struct cros_ec_device - Information about a ChromeOS EC device. + * @phys_name: Name of physical comms layer (e.g. 'i2c-4'). * @dev: Device pointer for physical comms device - * @was_wake_device: true if this device was set to wake the system from - * sleep at the last suspend - * @cmd_readmem: direct read of the EC memory-mapped region, if supported - * @offset is within EC_LPC_ADDR_MEMMAP region. - * @bytes: number of bytes to read. zero means "read a string" (including - * the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be read. - * Caller must ensure that the buffer is large enough for the result when - * reading a string. - * - * @priv: Private data - * @irq: Interrupt to use - * @id: Device id - * @din: input buffer (for data from EC) - * @dout: output buffer (for data to EC) - * \note - * These two buffers will always be dword-aligned and include enough - * space for up to 7 word-alignment bytes also, so we can ensure that - * the body of the message is always dword-aligned (64-bit). - * We use this alignment to keep ARM and x86 happy. Probably word - * alignment would be OK, there might be a small performance advantage - * to using dword. - * @din_size: size of din buffer to allocate (zero to use static din) - * @dout_size: size of dout buffer to allocate (zero to use static dout) - * @wake_enabled: true if this device can wake the system from sleep - * @suspended: true if this device had been suspended - * @cmd_xfer: send command to EC and get response - * Returns the number of bytes received if the communication succeeded, but - * that doesn't mean the EC was happy with the command. The caller - * should check msg.result for the EC's result code. - * @pkt_xfer: send packet to EC and get response - * @lock: one transaction at a time - * @mkbp_event_supported: true if this EC supports the MKBP event protocol. - * @event_notifier: interrupt event notifier for transport devices. - * @event_data: raw payload transferred with the MKBP event. - * @event_size: size in bytes of the event data. + * @was_wake_device: True if this device was set to wake the system from + * sleep at the last suspend. + * @cros_class: The class structure for this device. + * @cmd_readmem: Direct read of the EC memory-mapped region, if supported. + * @offset: Is within EC_LPC_ADDR_MEMMAP region. + * @bytes: Number of bytes to read. zero means "read a string" (including + * the trailing '\0'). At most only EC_MEMMAP_SIZE bytes can be + * read. Caller must ensure that the buffer is large enough for the + * result when reading a string. + * @max_request: Max size of message requested. + * @max_response: Max size of message response. + * @max_passthru: Max sice of passthru message. + * @proto_version: The protocol version used for this device. + * @priv: Private data. + * @irq: Interrupt to use. + * @id: Device id. + * @din: Input buffer (for data from EC). This buffer will always be + * dword-aligned and include enough space for up to 7 word-alignment + * bytes also, so we can ensure that the body of the message is always + * dword-aligned (64-bit). We use this alignment to keep ARM and x86 + * happy. Probably word alignment would be OK, there might be a small + * performance advantage to using dword. + * @dout: Output buffer (for data to EC). This buffer will always be + * dword-aligned and include enough space for up to 7 word-alignment + * bytes also, so we can ensure that the body of the message is always + * dword-aligned (64-bit). We use this alignment to keep ARM and x86 + * happy. Probably word alignment would be OK, there might be a small + * performance advantage to using dword. + * @din_size: Size of din buffer to allocate (zero to use static din). + * @dout_size: Size of dout buffer to allocate (zero to use static dout). + * @wake_enabled: True if this device can wake the system from sleep. + * @suspended: True if this device had been suspended. + * @cmd_xfer: Send command to EC and get response. + * Returns the number of bytes received if the communication + * succeeded, but that doesn't mean the EC was happy with the + * command. The caller should check msg.result for the EC's result + * code. + * @pkt_xfer: Send packet to EC and get response. + * @lock: One transaction at a time. + * @mkbp_event_supported: True if this EC supports the MKBP event protocol. + * @event_notifier: Interrupt event notifier for transport devices. + * @event_data: Raw payload transferred with the MKBP event. + * @event_size: Size in bytes of the event data. + * @host_event_wake_mask: Mask of host events that cause wake from suspend. */ struct cros_ec_device { - /* These are used by other drivers that want to talk to the EC */ const char *phys_name; struct device *dev; @@ -153,20 +161,19 @@ struct cros_ec_device { }; /** - * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information - * + * struct cros_ec_sensor_platform - ChromeOS EC sensor platform information. * @sensor_num: Id of the sensor, as reported by the EC. */ struct cros_ec_sensor_platform { u8 sensor_num; }; -/* struct cros_ec_platform - ChromeOS EC platform information - * - * @ec_name: name of EC device (e.g. 'cros-ec', 'cros-pd', ...) - * used in /dev/ and sysfs. - * @cmd_offset: offset to apply for each command. Set when - * registering a devicde behind another one. +/** + * struct cros_ec_platform - ChromeOS EC platform information. + * @ec_name: Name of EC device (e.g. 'cros-ec', 'cros-pd', ...) + * used in /dev/ and sysfs. + * @cmd_offset: Offset to apply for each command. Set when + * registering a device behind another one. */ struct cros_ec_platform { const char *ec_name; @@ -175,16 +182,16 @@ struct cros_ec_platform { struct cros_ec_debugfs; -/* - * struct cros_ec_dev - ChromeOS EC device entry point - * - * @class_dev: Device structure used in sysfs - * @cdev: Character device structure in /dev - * @ec_dev: cros_ec_device structure to talk to the physical device - * @dev: pointer to the platform device - * @debug_info: cros_ec_debugfs structure for debugging information - * @has_kb_wake_angle: true if at least 2 accelerometer are connected to the EC. - * @cmd_offset: offset to apply for each command. +/** + * struct cros_ec_dev - ChromeOS EC device entry point. + * @class_dev: Device structure used in sysfs. + * @cdev: Character device structure in /dev. + * @ec_dev: cros_ec_device structure to talk to the physical device. + * @dev: Pointer to the platform device. + * @debug_info: cros_ec_debugfs structure for debugging information. + * @has_kb_wake_angle: True if at least 2 accelerometer are connected to the EC. + * @cmd_offset: Offset to apply for each command. + * @features: Features supported by the EC. */ struct cros_ec_dev { struct device class_dev; @@ -200,124 +207,129 @@ struct cros_ec_dev { #define to_cros_ec_dev(dev) container_of(dev, struct cros_ec_dev, class_dev) /** - * cros_ec_suspend - Handle a suspend operation for the ChromeOS EC device + * cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. + * @ec_dev: Device to suspend. * * This can be called by drivers to handle a suspend event. * - * ec_dev: Device to suspend - * @return 0 if ok, -ve on error + * Return: 0 on success or negative error code. */ int cros_ec_suspend(struct cros_ec_device *ec_dev); /** - * cros_ec_resume - Handle a resume operation for the ChromeOS EC device + * cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. + * @ec_dev: Device to resume. * * This can be called by drivers to handle a resume event. * - * @ec_dev: Device to resume - * @return 0 if ok, -ve on error + * Return: 0 on success or negative error code. */ int cros_ec_resume(struct cros_ec_device *ec_dev); /** - * cros_ec_prepare_tx - Prepare an outgoing message in the output buffer + * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer. + * @ec_dev: Device to register. + * @msg: Message to write. * * This is intended to be used by all ChromeOS EC drivers, but at present * only SPI uses it. Once LPC uses the same protocol it can start using it. * I2C could use it now, with a refactor of the existing code. * - * @ec_dev: Device to register - * @msg: Message to write + * Return: 0 on success or negative error code. */ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, struct cros_ec_command *msg); /** - * cros_ec_check_result - Check ec_msg->result + * cros_ec_check_result() - Check ec_msg->result. + * @ec_dev: EC device. + * @msg: Message to check. * * This is used by ChromeOS EC drivers to check the ec_msg->result for * errors and to warn about them. * - * @ec_dev: EC device - * @msg: Message to check + * Return: 0 on success or negative error code. */ int cros_ec_check_result(struct cros_ec_device *ec_dev, struct cros_ec_command *msg); /** - * cros_ec_cmd_xfer - Send a command to the ChromeOS EC + * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC. + * @ec_dev: EC device. + * @msg: Message to write. * * Call this to send a command to the ChromeOS EC. This should be used * instead of calling the EC's cmd_xfer() callback directly. * - * @ec_dev: EC device - * @msg: Message to write + * Return: 0 on success or negative error code. */ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg); /** - * cros_ec_cmd_xfer_status - Send a command to the ChromeOS EC + * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC. + * @ec_dev: EC device. + * @msg: Message to write. * * This function is identical to cros_ec_cmd_xfer, except it returns success * status only if both the command was transmitted successfully and the EC * replied with success status. It's not necessary to check msg->result when * using this function. * - * @ec_dev: EC device - * @msg: Message to write - * @return: Num. of bytes transferred on success, <0 on failure + * Return: The number of bytes transferred on success or negative error code. */ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, struct cros_ec_command *msg); /** - * cros_ec_remove - Remove a ChromeOS EC + * cros_ec_remove() - Remove a ChromeOS EC. + * @ec_dev: Device to register. * * Call this to deregister a ChromeOS EC, then clean up any private data. * - * @ec_dev: Device to register - * @return 0 if ok, -ve on error + * Return: 0 on success or negative error code. */ int cros_ec_remove(struct cros_ec_device *ec_dev); /** - * cros_ec_register - Register a new ChromeOS EC, using the provided info + * cros_ec_register() - Register a new ChromeOS EC, using the provided info. + * @ec_dev: Device to register. * * Before calling this, allocate a pointer to a new device and then fill * in all the fields up to the --private-- marker. * - * @ec_dev: Device to register - * @return 0 if ok, -ve on error + * Return: 0 on success or negative error code. */ int cros_ec_register(struct cros_ec_device *ec_dev); /** - * cros_ec_query_all - Query the protocol version supported by the ChromeOS EC + * cros_ec_query_all() - Query the protocol version supported by the + * ChromeOS EC. + * @ec_dev: Device to register. * - * @ec_dev: Device to register - * @return 0 if ok, -ve on error + * Return: 0 on success or negative error code. */ int cros_ec_query_all(struct cros_ec_device *ec_dev); /** - * cros_ec_get_next_event - Fetch next event from the ChromeOS EC - * - * @ec_dev: Device to fetch event from + * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC. + * @ec_dev: Device to fetch event from. * @wake_event: Pointer to a bool set to true upon return if the event might be * treated as a wake event. Ignored if null. * - * Returns: 0 on success, Linux error number on failure + * Return: 0 on success or negative error code. */ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event); /** - * cros_ec_get_host_event - Return a mask of event set by the EC. + * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC. + * @ec_dev: Device to fetch event from. * - * When MKBP is supported, when the EC raises an interrupt, - * We collect the events raised and call the functions in the ec notifier. + * When MKBP is supported, when the EC raises an interrupt, we collect the + * events raised and call the functions in the ec notifier. This function + * is a helper to know which events are raised. * - * This function is a helper to know which events are raised. + * Return: 0 on success or negative error code. */ u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index 6e1ab9bead28..88100bddf1ab 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h @@ -306,15 +306,18 @@ enum host_event_code { /* Host event mask */ #define EC_HOST_EVENT_MASK(event_code) (1UL << ((event_code) - 1)) -/* Arguments at EC_LPC_ADDR_HOST_ARGS */ +/** + * struct ec_lpc_host_args - Arguments at EC_LPC_ADDR_HOST_ARGS + * @flags: The host argument flags. + * @command_version: Command version. + * @data_size: The length of data. + * @checksum: Checksum; sum of command + flags + command_version + data_size + + * all params/response data bytes. + */ struct ec_lpc_host_args { uint8_t flags; uint8_t command_version; uint8_t data_size; - /* - * Checksum; sum of command + flags + command_version + data_size + - * all params/response data bytes. - */ uint8_t checksum; } __packed; @@ -468,54 +471,43 @@ struct ec_lpc_host_args { #define EC_HOST_REQUEST_VERSION 3 -/* Version 3 request from host */ +/** + * struct ec_host_request - Version 3 request from host. + * @struct_version: Should be 3. The EC will return EC_RES_INVALID_HEADER if it + * receives a header with a version it doesn't know how to + * parse. + * @checksum: Checksum of request and data; sum of all bytes including checksum + * should total to 0. + * @command: Command to send (EC_CMD_...) + * @command_version: Command version. + * @reserved: Unused byte in current protocol version; set to 0. + * @data_len: Length of data which follows this header. + */ struct ec_host_request { - /* Struct version (=3) - * - * EC will return EC_RES_INVALID_HEADER if it receives a header with a - * version it doesn't know how to parse. - */ uint8_t struct_version; - - /* - * Checksum of request and data; sum of all bytes including checksum - * should total to 0. - */ uint8_t checksum; - - /* Command code */ uint16_t command; - - /* Command version */ uint8_t command_version; - - /* Unused byte in current protocol version; set to 0 */ uint8_t reserved; - - /* Length of data which follows this header */ uint16_t data_len; } __packed; #define EC_HOST_RESPONSE_VERSION 3 -/* Version 3 response from EC */ +/** + * struct ec_host_response - Version 3 response from EC. + * @struct_version: Struct version (=3). + * @checksum: Checksum of response and data; sum of all bytes including + * checksum should total to 0. + * @result: EC's response to the command (separate from communication failure) + * @data_len: Length of data which follows this header. + * @reserved: Unused bytes in current protocol version; set to 0. + */ struct ec_host_response { - /* Struct version (=3) */ uint8_t struct_version; - - /* - * Checksum of response and data; sum of all bytes including checksum - * should total to 0. - */ uint8_t checksum; - - /* Result code (EC_RES_*) */ uint16_t result; - - /* Length of data which follows this header */ uint16_t data_len; - - /* Unused bytes in current protocol version; set to 0 */ uint16_t reserved; } __packed; @@ -540,6 +532,10 @@ struct ec_host_response { */ #define EC_CMD_PROTO_VERSION 0x00 +/** + * struct ec_response_proto_version - Response to the proto version command. + * @version: The protocol version. + */ struct ec_response_proto_version { uint32_t version; } __packed; @@ -550,12 +546,20 @@ struct ec_response_proto_version { */ #define EC_CMD_HELLO 0x01 +/** + * struct ec_params_hello - Parameters to the hello command. + * @in_data: Pass anything here. + */ struct ec_params_hello { - uint32_t in_data; /* Pass anything here */ + uint32_t in_data; } __packed; +/** + * struct ec_response_hello - Response to the hello command. + * @out_data: Output will be in_data + 0x01020304. + */ struct ec_response_hello { - uint32_t out_data; /* Output will be in_data + 0x01020304 */ + uint32_t out_data; } __packed; /* Get version number */ @@ -567,22 +571,37 @@ enum ec_current_image { EC_IMAGE_RW }; +/** + * struct ec_response_get_version - Response to the get version command. + * @version_string_ro: Null-terminated RO firmware version string. + * @version_string_rw: Null-terminated RW firmware version string. + * @reserved: Unused bytes; was previously RW-B firmware version string. + * @current_image: One of ec_current_image. + */ struct ec_response_get_version { - /* Null-terminated version strings for RO, RW */ char version_string_ro[32]; char version_string_rw[32]; - char reserved[32]; /* Was previously RW-B string */ - uint32_t current_image; /* One of ec_current_image */ + char reserved[32]; + uint32_t current_image; } __packed; /* Read test */ #define EC_CMD_READ_TEST 0x03 +/** + * struct ec_params_read_test - Parameters for the read test command. + * @offset: Starting value for read buffer. + * @size: Size to read in bytes. + */ struct ec_params_read_test { - uint32_t offset; /* Starting value for read buffer */ - uint32_t size; /* Size to read in bytes */ + uint32_t offset; + uint32_t size; } __packed; +/** + * struct ec_response_read_test - Response to the read test command. + * @data: Data returned by the read test command. + */ struct ec_response_read_test { uint32_t data[32]; } __packed; @@ -597,18 +616,27 @@ struct ec_response_read_test { /* Get chip info */ #define EC_CMD_GET_CHIP_INFO 0x05 +/** + * struct ec_response_get_chip_info - Response to the get chip info command. + * @vendor: Null-terminated string for chip vendor. + * @name: Null-terminated string for chip name. + * @revision: Null-terminated string for chip mask version. + */ struct ec_response_get_chip_info { - /* Null-terminated strings */ char vendor[32]; char name[32]; - char revision[32]; /* Mask version */ + char revision[32]; } __packed; /* Get board HW version */ #define EC_CMD_GET_BOARD_VERSION 0x06 +/** + * struct ec_response_board_version - Response to the board version command. + * @board_version: A monotonously incrementing number. + */ struct ec_response_board_version { - uint16_t board_version; /* A monotonously incrementing number. */ + uint16_t board_version; } __packed; /* @@ -621,27 +649,42 @@ struct ec_response_board_version { */ #define EC_CMD_READ_MEMMAP 0x07 +/** + * struct ec_params_read_memmap - Parameters for the read memory map command. + * @offset: Offset in memmap (EC_MEMMAP_*). + * @size: Size to read in bytes. + */ struct ec_params_read_memmap { - uint8_t offset; /* Offset in memmap (EC_MEMMAP_*) */ - uint8_t size; /* Size to read in bytes */ + uint8_t offset; + uint8_t size; } __packed; /* Read versions supported for a command */ #define EC_CMD_GET_CMD_VERSIONS 0x08 +/** + * struct ec_params_get_cmd_versions - Parameters for the get command versions. + * @cmd: Command to check. + */ struct ec_params_get_cmd_versions { - uint8_t cmd; /* Command to check */ + uint8_t cmd; } __packed; +/** + * struct ec_params_get_cmd_versions_v1 - Parameters for the get command + * versions (v1) + * @cmd: Command to check. + */ struct ec_params_get_cmd_versions_v1 { - uint16_t cmd; /* Command to check */ + uint16_t cmd; } __packed; +/** + * struct ec_response_get_cmd_version - Response to the get command versions. + * @version_mask: Mask of supported versions; use EC_VER_MASK() to compare with + * a desired version. + */ struct ec_response_get_cmd_versions { - /* - * Mask of supported versions; use EC_VER_MASK() to compare with a - * desired version. - */ uint32_t version_mask; } __packed; @@ -659,6 +702,11 @@ enum ec_comms_status { EC_COMMS_STATUS_PROCESSING = 1 << 0, /* Processing cmd */ }; +/** + * struct ec_response_get_comms_status - Response to the get comms status + * command. + * @flags: Mask of enum ec_comms_status. + */ struct ec_response_get_comms_status { uint32_t flags; /* Mask of enum ec_comms_status */ } __packed; @@ -685,19 +733,19 @@ struct ec_response_test_protocol { /* EC_RES_IN_PROGRESS may be returned if a command is slow */ #define EC_PROTOCOL_INFO_IN_PROGRESS_SUPPORTED (1 << 0) +/** + * struct ec_response_get_protocol_info - Response to the get protocol info. + * @protocol_versions: Bitmask of protocol versions supported (1 << n means + * version n). + * @max_request_packet_size: Maximum request packet size in bytes. + * @max_response_packet_size: Maximum response packet size in bytes. + * @flags: see EC_PROTOCOL_INFO_* + */ struct ec_response_get_protocol_info { /* Fields which exist if at least protocol version 3 supported */ - - /* Bitmask of protocol versions supported (1 << n means version n)*/ uint32_t protocol_versions; - - /* Maximum request packet size, in bytes */ uint16_t max_request_packet_size; - - /* Maximum response packet size, in bytes */ uint16_t max_response_packet_size; - - /* Flags; see EC_PROTOCOL_INFO_* */ uint32_t flags; } __packed; @@ -708,8 +756,10 @@ struct ec_response_get_protocol_info { /* The upper byte of .flags tells what to do (nothing means "get") */ #define EC_GSV_SET 0x80000000 -/* The lower three bytes of .flags identifies the parameter, if that has - meaning for an individual command. */ +/* + * The lower three bytes of .flags identifies the parameter, if that has + * meaning for an individual command. + */ #define EC_GSV_PARAM_MASK 0x00ffffff struct ec_params_get_set_value { @@ -810,6 +860,7 @@ enum ec_feature_code { #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) #define EC_FEATURE_MASK_1(event_code) (1UL << (event_code - 32)) + struct ec_response_get_features { uint32_t flags[2]; } __packed; @@ -820,24 +871,22 @@ struct ec_response_get_features { /* Get flash info */ #define EC_CMD_FLASH_INFO 0x10 -/* Version 0 returns these fields */ +/** + * struct ec_response_flash_info - Response to the flash info command. + * @flash_size: Usable flash size in bytes. + * @write_block_size: Write block size. Write offset and size must be a + * multiple of this. + * @erase_block_size: Erase block size. Erase offset and size must be a + * multiple of this. + * @protect_block_size: Protection block size. Protection offset and size + * must be a multiple of this. + * + * Version 0 returns these fields. + */ struct ec_response_flash_info { - /* Usable flash size, in bytes */ uint32_t flash_size; - /* - * Write block size. Write offset and size must be a multiple - * of this. - */ uint32_t write_block_size; - /* - * Erase block size. Erase offset and size must be a multiple - * of this. - */ uint32_t erase_block_size; - /* - * Protection block size. Protection offset and size must be a - * multiple of this. - */ uint32_t protect_block_size; } __packed; @@ -845,7 +894,22 @@ struct ec_response_flash_info { /* EC flash erases bits to 0 instead of 1 */ #define EC_FLASH_INFO_ERASE_TO_0 (1 << 0) -/* +/** + * struct ec_response_flash_info_1 - Response to the flash info v1 command. + * @flash_size: Usable flash size in bytes. + * @write_block_size: Write block size. Write offset and size must be a + * multiple of this. + * @erase_block_size: Erase block size. Erase offset and size must be a + * multiple of this. + * @protect_block_size: Protection block size. Protection offset and size + * must be a multiple of this. + * @write_ideal_size: Ideal write size in bytes. Writes will be fastest if + * size is exactly this and offset is a multiple of this. + * For example, an EC may have a write buffer which can do + * half-page operations if data is aligned, and a slower + * word-at-a-time write mode. + * @flags: Flags; see EC_FLASH_INFO_* + * * Version 1 returns the same initial fields as version 0, with additional * fields following. * @@ -860,15 +924,7 @@ struct ec_response_flash_info_1 { uint32_t protect_block_size; /* Version 1 adds these fields: */ - /* - * Ideal write size in bytes. Writes will be fastest if size is - * exactly this and offset is a multiple of this. For example, an EC - * may have a write buffer which can do half-page operations if data is - * aligned, and a slower word-at-a-time write mode. - */ uint32_t write_ideal_size; - - /* Flags; see EC_FLASH_INFO_* */ uint32_t flags; } __packed; @@ -879,9 +935,14 @@ struct ec_response_flash_info_1 { */ #define EC_CMD_FLASH_READ 0x11 +/** + * struct ec_params_flash_read - Parameters for the flash read command. + * @offset: Byte offset to read. + * @size: Size to read in bytes. + */ struct ec_params_flash_read { - uint32_t offset; /* Byte offset to read */ - uint32_t size; /* Size to read in bytes */ + uint32_t offset; + uint32_t size; } __packed; /* Write flash */ @@ -891,18 +952,28 @@ struct ec_params_flash_read { /* Version 0 of the flash command supported only 64 bytes of data */ #define EC_FLASH_WRITE_VER0_SIZE 64 +/** + * struct ec_params_flash_write - Parameters for the flash write command. + * @offset: Byte offset to write. + * @size: Size to write in bytes. + */ struct ec_params_flash_write { - uint32_t offset; /* Byte offset to write */ - uint32_t size; /* Size to write in bytes */ + uint32_t offset; + uint32_t size; /* Followed by data to write */ } __packed; /* Erase flash */ #define EC_CMD_FLASH_ERASE 0x13 +/** + * struct ec_params_flash_erase - Parameters for the flash erase command. + * @offset: Byte offset to erase. + * @size: Size to erase in bytes. + */ struct ec_params_flash_erase { - uint32_t offset; /* Byte offset to erase */ - uint32_t size; /* Size to erase in bytes */ + uint32_t offset; + uint32_t size; } __packed; /* @@ -941,21 +1012,28 @@ struct ec_params_flash_erase { /* Entile flash code protected when the EC boots */ #define EC_FLASH_PROTECT_ALL_AT_BOOT (1 << 6) +/** + * struct ec_params_flash_protect - Parameters for the flash protect command. + * @mask: Bits in flags to apply. + * @flags: New flags to apply. + */ struct ec_params_flash_protect { - uint32_t mask; /* Bits in flags to apply */ - uint32_t flags; /* New flags to apply */ + uint32_t mask; + uint32_t flags; } __packed; +/** + * struct ec_response_flash_protect - Response to the flash protect command. + * @flags: Current value of flash protect flags. + * @valid_flags: Flags which are valid on this platform. This allows the + * caller to distinguish between flags which aren't set vs. flags + * which can't be set on this platform. + * @writable_flags: Flags which can be changed given the current protection + * state. + */ struct ec_response_flash_protect { - /* Current value of flash protect flags */ uint32_t flags; - /* - * Flags which are valid on this platform. This allows the caller - * to distinguish between flags which aren't set vs. flags which can't - * be set on this platform. - */ uint32_t valid_flags; - /* Flags which can be changed given the current protection state */ uint32_t writable_flags; } __packed; @@ -982,8 +1060,13 @@ enum ec_flash_region { EC_FLASH_REGION_COUNT, }; +/** + * struct ec_params_flash_region_info - Parameters for the flash region info + * command. + * @region: Flash region; see EC_FLASH_REGION_* + */ struct ec_params_flash_region_info { - uint32_t region; /* enum ec_flash_region */ + uint32_t region; } __packed; struct ec_response_flash_region_info { @@ -1094,7 +1177,9 @@ struct rgb_s { }; #define LB_BATTERY_LEVELS 4 -/* List of tweakable parameters. NOTE: It's __packed so it can be sent in a + +/* + * List of tweakable parameters. NOTE: It's __packed so it can be sent in a * host command, but the alignment is the same regardless. Keep it that way. */ struct lightbar_params_v0 { From 5f997580e8b12b9f585e34cc16304925d26ce49e Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Thu, 6 Sep 2018 21:33:57 -0700 Subject: [PATCH 066/836] apparmor: Fix network performance issue in aa_label_sk_perm The netperf benchmark shows a 5.73% reduction in throughput for small (64 byte) transfers by unconfined tasks. DEFINE_AUDIT_SK() in aa_label_sk_perm() should not be performed unconditionally, rather only when the label is confined. netperf-tcp 56974a6fc^ 56974a6fc Min 64 563.48 ( 0.00%) 531.17 ( -5.73%) Min 128 1056.92 ( 0.00%) 999.44 ( -5.44%) Min 256 1945.95 ( 0.00%) 1867.97 ( -4.01%) Min 1024 6761.40 ( 0.00%) 6364.23 ( -5.87%) Min 2048 11110.53 ( 0.00%) 10606.20 ( -4.54%) Min 3312 13692.67 ( 0.00%) 13158.41 ( -3.90%) Min 4096 14926.29 ( 0.00%) 14457.46 ( -3.14%) Min 8192 18399.34 ( 0.00%) 18091.65 ( -1.67%) Min 16384 21384.13 ( 0.00%) 21158.05 ( -1.06%) Hmean 64 564.96 ( 0.00%) 534.38 ( -5.41%) Hmean 128 1064.42 ( 0.00%) 1010.12 ( -5.10%) Hmean 256 1965.85 ( 0.00%) 1879.16 ( -4.41%) Hmean 1024 6839.77 ( 0.00%) 6478.70 ( -5.28%) Hmean 2048 11154.80 ( 0.00%) 10671.13 ( -4.34%) Hmean 3312 13838.12 ( 0.00%) 13249.01 ( -4.26%) Hmean 4096 15009.99 ( 0.00%) 14561.36 ( -2.99%) Hmean 8192 18975.57 ( 0.00%) 18326.54 ( -3.42%) Hmean 16384 21440.44 ( 0.00%) 21324.59 ( -0.54%) Stddev 64 1.24 ( 0.00%) 2.85 (-130.64%) Stddev 128 4.51 ( 0.00%) 6.53 ( -44.84%) Stddev 256 11.67 ( 0.00%) 8.50 ( 27.16%) Stddev 1024 48.33 ( 0.00%) 75.07 ( -55.34%) Stddev 2048 54.82 ( 0.00%) 65.16 ( -18.86%) Stddev 3312 153.57 ( 0.00%) 56.29 ( 63.35%) Stddev 4096 100.25 ( 0.00%) 88.50 ( 11.72%) Stddev 8192 358.13 ( 0.00%) 169.99 ( 52.54%) Stddev 16384 43.99 ( 0.00%) 141.82 (-222.39%) Signed-off-by: Tony Jones Fixes: 56974a6fcfef ("apparmor: add base infastructure for socket mediation") Signed-off-by: John Johansen --- security/apparmor/net.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/security/apparmor/net.c b/security/apparmor/net.c index bb24cfa0a164..d5d72dd1ca1f 100644 --- a/security/apparmor/net.c +++ b/security/apparmor/net.c @@ -146,17 +146,20 @@ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, struct sock *sk) { - struct aa_profile *profile; - DEFINE_AUDIT_SK(sa, op, sk); + int error = 0; AA_BUG(!label); AA_BUG(!sk); - if (unconfined(label)) - return 0; + if (!unconfined(label)) { + struct aa_profile *profile; + DEFINE_AUDIT_SK(sa, op, sk); - return fn_for_each_confined(label, profile, - aa_profile_af_sk_perm(profile, &sa, request, sk)); + error = fn_for_each_confined(label, profile, + aa_profile_af_sk_perm(profile, &sa, request, sk)); + } + + return error; } int aa_sk_perm(const char *op, u32 request, struct sock *sk) From 4a60aa05a0634241ce17f957bf9fb5ac1eed6576 Mon Sep 17 00:00:00 2001 From: Allan Xavier Date: Fri, 7 Sep 2018 08:12:01 -0500 Subject: [PATCH 067/836] objtool: Support per-function rodata sections Add support for processing switch jump tables in objects with multiple .rodata sections, such as those created by '-ffunction-sections' and '-fdata-sections'. Currently, objtool always looks in .rodata for jump table information, which results in many "sibling call from callable instruction with modified stack frame" warnings with objects compiled using those flags. The fix is comprised of three parts: 1. Flagging all .rodata sections when importing ELF information for easier checking later. 2. Keeping a reference to the section each relocation is from in order to get the list_head for the other relocations in that section. 3. Finding jump tables by following relocations to .rodata sections, rather than always referencing a single global .rodata section. The patch has been tested without data sections enabled and no differences in the resulting orc unwind information were seen. Note that as objtool adds terminators to end of each .text section the unwind information generated between a function+data sections build and a normal build aren't directly comparable. Manual inspection suggests that objtool is now generating the correct information, or at least making more of an effort to do so than it did previously. Signed-off-by: Allan Xavier Signed-off-by: Josh Poimboeuf Signed-off-by: Thomas Gleixner Link: https://lkml.kernel.org/r/099bdc375195c490dda04db777ee0b95d566ded1.1536325914.git.jpoimboe@redhat.com --- tools/objtool/check.c | 38 ++++++++++++++++++++++++++++++++------ tools/objtool/check.h | 4 ++-- tools/objtool/elf.c | 1 + tools/objtool/elf.h | 3 ++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 2928939b98ec..0414a0d52262 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -836,7 +836,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn, struct symbol *pfunc = insn->func->pfunc; unsigned int prev_offset = 0; - list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) { + list_for_each_entry_from(rela, &table->rela_sec->rela_list, list) { if (rela == next_table) break; @@ -926,6 +926,7 @@ static struct rela *find_switch_table(struct objtool_file *file, { struct rela *text_rela, *rodata_rela; struct instruction *orig_insn = insn; + struct section *rodata_sec; unsigned long table_offset; /* @@ -953,10 +954,13 @@ static struct rela *find_switch_table(struct objtool_file *file, /* look for a relocation which references .rodata */ text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len); - if (!text_rela || text_rela->sym != file->rodata->sym) + if (!text_rela || text_rela->sym->type != STT_SECTION || + !text_rela->sym->sec->rodata) continue; table_offset = text_rela->addend; + rodata_sec = text_rela->sym->sec; + if (text_rela->type == R_X86_64_PC32) table_offset += 4; @@ -964,10 +968,10 @@ static struct rela *find_switch_table(struct objtool_file *file, * Make sure the .rodata address isn't associated with a * symbol. gcc jump tables are anonymous data. */ - if (find_symbol_containing(file->rodata, table_offset)) + if (find_symbol_containing(rodata_sec, table_offset)) continue; - rodata_rela = find_rela_by_dest(file->rodata, table_offset); + rodata_rela = find_rela_by_dest(rodata_sec, table_offset); if (rodata_rela) { /* * Use of RIP-relative switch jumps is quite rare, and @@ -1052,7 +1056,7 @@ static int add_switch_table_alts(struct objtool_file *file) struct symbol *func; int ret; - if (!file->rodata || !file->rodata->rela) + if (!file->rodata) return 0; for_each_sec(file, sec) { @@ -1198,10 +1202,33 @@ static int read_retpoline_hints(struct objtool_file *file) return 0; } +static void mark_rodata(struct objtool_file *file) +{ + struct section *sec; + bool found = false; + + /* + * This searches for the .rodata section or multiple .rodata.func_name + * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8 + * rodata sections are ignored as they don't contain jump tables. + */ + for_each_sec(file, sec) { + if (!strncmp(sec->name, ".rodata", 7) && + !strstr(sec->name, ".str1.")) { + sec->rodata = true; + found = true; + } + } + + file->rodata = found; +} + static int decode_sections(struct objtool_file *file) { int ret; + mark_rodata(file); + ret = decode_instructions(file); if (ret) return ret; @@ -2171,7 +2198,6 @@ int check(const char *_objname, bool orc) INIT_LIST_HEAD(&file.insn_list); hash_init(file.insn_hash); file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard"); - file.rodata = find_section_by_name(file.elf, ".rodata"); file.c_file = find_section_by_name(file.elf, ".comment"); file.ignore_unreachables = no_unreachable; file.hints = false; diff --git a/tools/objtool/check.h b/tools/objtool/check.h index 95700a2bcb7c..e6e8a655b556 100644 --- a/tools/objtool/check.h +++ b/tools/objtool/check.h @@ -60,8 +60,8 @@ struct objtool_file { struct elf *elf; struct list_head insn_list; DECLARE_HASHTABLE(insn_hash, 16); - struct section *rodata, *whitelist; - bool ignore_unreachables, c_file, hints; + struct section *whitelist; + bool ignore_unreachables, c_file, hints, rodata; }; int check(const char *objname, bool orc); diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 7ec85d567598..f7082de1ee82 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -379,6 +379,7 @@ static int read_relas(struct elf *elf) rela->offset = rela->rela.r_offset; symndx = GELF_R_SYM(rela->rela.r_info); rela->sym = find_symbol_by_index(elf, symndx); + rela->rela_sec = sec; if (!rela->sym) { WARN("can't find rela entry symbol %d for %s", symndx, sec->name); diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h index de5cd2ddded9..bc97ed86b9cd 100644 --- a/tools/objtool/elf.h +++ b/tools/objtool/elf.h @@ -48,7 +48,7 @@ struct section { char *name; int idx; unsigned int len; - bool changed, text; + bool changed, text, rodata; }; struct symbol { @@ -68,6 +68,7 @@ struct rela { struct list_head list; struct hlist_node hash; GElf_Rela rela; + struct section *rela_sec; struct symbol *sym; unsigned int type; unsigned long offset; From ee02950d53eee0d4c7f1c08a35272b77d24b9459 Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Fri, 31 Aug 2018 12:26:36 +0100 Subject: [PATCH 068/836] clk: renesas: r9a06g032: Fix UART34567 clock rate The clock for UARTs 0 through 2 is UART012, the clock for UARTs 3 through 7 is UART34567. For UART012, we stop the clock driver from changing the clock rate. This is because the Synopsys UART driver simply sets the reference clock to 16x the baud rate, but doesn't check if the actual rate is within the required tolerance. The RZ/N1 clock divider can't provide this (we have to rely on the UART's internal divider to set the correct clock rate), so you end up with a clock rate that is way off what you wanted. In addition, since the clock is shared between multiple UARTs, you don't want the driver trying to change the clock rate as it may affect the other UARTs (which may not have been configured yet, so you don't know what baud rate they will use). Normally, the clock rate is set early on before Linux to some very high rate that supports all of the clock rates you want. This change stops the UART34567 clock rate from changing for the same reasons. Signed-off-by: Phil Edworthy Fixes: 4c3d88526eba2143 ("clk: renesas: Renesas R9A06G032 clock driver") Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r9a06g032-clocks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index a0b6ecdc63dd..6d2b56891559 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -539,7 +539,8 @@ r9a06g032_div_round_rate(struct clk_hw *hw, * several uarts attached to this divider, and changing this impacts * everyone. */ - if (clk->index == R9A06G032_DIV_UART) { + if (clk->index == R9A06G032_DIV_UART || + clk->index == R9A06G032_DIV_P2_PG) { pr_devel("%s div uart hack!\n", __func__); return clk_get_rate(hw->clk); } From 5986b503da614df3fccbf90edab3afa4c7550fa1 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 5 Sep 2018 19:59:48 +0300 Subject: [PATCH 069/836] clk: renesas: r8a77970: Add CMT clocks Add the R8A77970 CMT module clocks. Based on the original (and large) patch by Vladimir Barinov. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov Reviewed-by: Chris Paterson Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77970-cpg-mssr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index 07d0ddc1eefa..f07a1eeface6 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -118,6 +118,10 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = { DEF_MOD("mfis", 213, R8A77970_CLK_S2D2), DEF_MOD("sys-dmac2", 217, R8A77970_CLK_S2D1), DEF_MOD("sys-dmac1", 218, R8A77970_CLK_S2D1), + DEF_MOD("cmt3", 300, R8A77970_CLK_R), + DEF_MOD("cmt2", 301, R8A77970_CLK_R), + DEF_MOD("cmt1", 302, R8A77970_CLK_R), + DEF_MOD("cmt0", 303, R8A77970_CLK_R), DEF_MOD("sd-if", 314, R8A77970_CLK_SD0), DEF_MOD("rwdt", 402, R8A77970_CLK_R), DEF_MOD("intc-ex", 407, R8A77970_CLK_CP), From 6207ba04347705481d5e4021206179aadeb8e917 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 6 Sep 2018 23:28:12 +0300 Subject: [PATCH 070/836] clk: renesas: r8a77970: Add TMU clocks The TMU clocks weren't present in the original R8A77970 patch by Daisuke Matsushita, they were added in a later BSP version... Based on the original (and large) patch by Vladimir Barinov. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77970-cpg-mssr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index f07a1eeface6..7a85e1adcd94 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -106,6 +106,11 @@ static const struct cpg_core_clk r8a77970_core_clks[] __initconst = { }; static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = { + DEF_MOD("tmu4", 121, R8A77970_CLK_S2D2), + DEF_MOD("tmu3", 122, R8A77970_CLK_S2D2), + DEF_MOD("tmu2", 123, R8A77970_CLK_S2D2), + DEF_MOD("tmu1", 124, R8A77970_CLK_S2D2), + DEF_MOD("tmu0", 125, R8A77970_CLK_CP), DEF_MOD("ivcp1e", 127, R8A77970_CLK_S2D1), DEF_MOD("scif4", 203, R8A77970_CLK_S2D4), DEF_MOD("scif3", 204, R8A77970_CLK_S2D4), From fde35c9c7db5732cc1fbd89fa5eba5a9e0b25f6e Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 7 Sep 2018 11:58:49 -0500 Subject: [PATCH 071/836] clk: renesas: cpg-mssr: Add R7S9210 support Add support for the R7S9210 (RZ/A2) Clock Pulse Generator and Module Standby. The Module Standby HW in the RZ/A series is very close to R-Car HW, except for how the registers are laid out. The MSTP registers are only 8-bits wide, there are no status registers (MSTPSR), and the register offsets are a little different. Since the RZ/A hardware manuals refer to these registers as the Standby Control Registers, we'll use that name to distinguish the RZ/A type from the R-Car type. Signed-off-by: Chris Brandt Acked-by: Rob Herring # DT bits Signed-off-by: Geert Uytterhoeven --- .../bindings/clock/renesas,cpg-mssr.txt | 5 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r7s9210-cpg-mssr.c | 189 ++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 81 ++++++-- drivers/clk/renesas/renesas-cpg-mssr.h | 13 ++ include/dt-bindings/clock/r7s9210-cpg-mssr.h | 20 ++ 7 files changed, 300 insertions(+), 14 deletions(-) create mode 100644 drivers/clk/renesas/r7s9210-cpg-mssr.c create mode 100644 include/dt-bindings/clock/r7s9210-cpg-mssr.h diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 42d0f83d812b..5e46e6be789b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -13,6 +13,7 @@ They provide the following functionalities: Required Properties: - compatible: Must be one of: + - "renesas,r7s9210-cpg-mssr" for the r7s9210 SoC (RZ/A2) - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) @@ -36,8 +37,8 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, r8a7791, - r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, + - "extal" (r7s9210, r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, + r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index f998a7333acb..2edcb1bdb487 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -3,6 +3,7 @@ config CLK_RENESAS default y if ARCH_RENESAS select CLK_EMEV2 if ARCH_EMEV2 select CLK_RZA1 if ARCH_R7S72100 + select CLK_R7S9210 if ARCH_R7S9210 select CLK_R8A73A4 if ARCH_R8A73A4 select CLK_R8A7740 if ARCH_R8A7740 select CLK_R8A7743 if ARCH_R8A7743 @@ -46,6 +47,10 @@ config CLK_RZA1 bool "RZ/A1H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP +config CLK_R7S9210 + bool "RZ/A2 clock support" if COMPILE_TEST + select CLK_RENESAS_CPG_MSSR + config CLK_R8A73A4 bool "R-Mobile APE6 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 71d4cafe15c0..dbbfd0b0742b 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -2,6 +2,7 @@ # SoC obj-$(CONFIG_CLK_EMEV2) += clk-emev2.o obj-$(CONFIG_CLK_RZA1) += clk-rz.o +obj-$(CONFIG_CLK_R7S9210) += r7s9210-cpg-mssr.o obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c new file mode 100644 index 000000000000..bd1dd4ff2051 --- /dev/null +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R7S9210 Clock Pulse Generator / Module Standby + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2018 Chris Brandt + * Copyright (C) 2018 Renesas Electronics Corp. + * + */ + +#include +#include +#include +#include "renesas-cpg-mssr.h" + +#define CPG_FRQCR 0x00 + +static u8 cpg_mode; + +/* Internal Clock ratio table */ +static const struct { + unsigned int i; + unsigned int g; + unsigned int b; + unsigned int p1; + /* p0 is always 32 */; +} ratio_tab[5] = { /* I, G, B, P1 */ + { 2, 4, 8, 16}, /* FRQCR = 0x012 */ + { 4, 4, 8, 16}, /* FRQCR = 0x112 */ + { 8, 4, 8, 16}, /* FRQCR = 0x212 */ + { 16, 8, 16, 16}, /* FRQCR = 0x322 */ + { 16, 16, 32, 32}, /* FRQCR = 0x333 */ + }; + +enum rz_clk_types { + CLK_TYPE_RZA_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_RZA_PLL, +}; + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R7S9210_CLK_P0, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static struct cpg_core_clk r7s9210_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL), + DEF_BASE(".pll", CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN), + + /* Core Clock Outputs */ + DEF_FIXED("i", R7S9210_CLK_I, CLK_PLL, 2, 1), + DEF_FIXED("g", R7S9210_CLK_G, CLK_PLL, 4, 1), + DEF_FIXED("b", R7S9210_CLK_B, CLK_PLL, 8, 1), + DEF_FIXED("p1", R7S9210_CLK_P1, CLK_PLL, 16, 1), + DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), + DEF_FIXED("p0", R7S9210_CLK_P0, CLK_PLL, 32, 1), +}; + +static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { + DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), + + DEF_MOD_STB("scif4", 43, R7S9210_CLK_P1C), + DEF_MOD_STB("scif3", 44, R7S9210_CLK_P1C), + DEF_MOD_STB("scif2", 45, R7S9210_CLK_P1C), + DEF_MOD_STB("scif1", 46, R7S9210_CLK_P1C), + DEF_MOD_STB("scif0", 47, R7S9210_CLK_P1C), + + DEF_MOD_STB("ether1", 64, R7S9210_CLK_B), + DEF_MOD_STB("ether0", 65, R7S9210_CLK_B), + + DEF_MOD_STB("i2c3", 84, R7S9210_CLK_P1), + DEF_MOD_STB("i2c2", 85, R7S9210_CLK_P1), + DEF_MOD_STB("i2c1", 86, R7S9210_CLK_P1), + DEF_MOD_STB("i2c0", 87, R7S9210_CLK_P1), + +}; + +struct clk * __init rza2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base, + struct raw_notifier_head *notifiers) +{ + struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u16 frqcr; + u8 index; + int i; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->id) { + case CLK_MAIN: + break; + + case CLK_PLL: + if (cpg_mode) + mult = 44; /* Divider 1 is 1/2 */ + else + mult = 88; /* Divider 1 is 1 */ + break; + + default: + return ERR_PTR(-EINVAL); + } + + /* Adjust the dividers based on the current FRQCR setting */ + if (core->id == CLK_MAIN) { + + /* If EXTAL is above 12MHz, then we know it is Mode 1 */ + if (clk_get_rate(parent) > 12000000) + cpg_mode = 1; + + frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; + if (frqcr == 0x012) + index = 0; + else if (frqcr == 0x112) + index = 1; + else if (frqcr == 0x212) + index = 2; + else if (frqcr == 0x322) + index = 3; + else if (frqcr == 0x333) + index = 4; + else + BUG_ON(1); /* Illegal FRQCR value */ + + for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { + switch (r7s9210_core_clks[i].id) { + case R7S9210_CLK_I: + r7s9210_core_clks[i].div = ratio_tab[index].i; + break; + case R7S9210_CLK_G: + r7s9210_core_clks[i].div = ratio_tab[index].g; + break; + case R7S9210_CLK_B: + r7s9210_core_clks[i].div = ratio_tab[index].b; + break; + case R7S9210_CLK_P1: + case R7S9210_CLK_P1C: + r7s9210_core_clks[i].div = ratio_tab[index].p1; + break; + case R7S9210_CLK_P0: + r7s9210_core_clks[i].div = 32; + break; + } + } + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + +const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r7s9210_core_clks, + .num_core_clks = ARRAY_SIZE(r7s9210_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r7s9210_mod_clks, + .num_mod_clks = ARRAY_SIZE(r7s9210_mod_clks), + .num_hw_mod_clks = 11 * 32, /* includes STBCR0 which doesn't exist */ + + /* Callbacks */ + .cpg_clk_register = rza2_cpg_clk_register, + + /* RZ/A2 has Standby Control Registers */ + .stbyctrl = true, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index f90b0d0ba46a..b97e0e3ff0b1 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -73,6 +73,17 @@ static const u16 smstpcr[] = { #define SMSTPCR(i) smstpcr[i] +/* + * Standby Control Register offsets (RZ/A) + * Base address is FRQCR register + */ + +static const u16 stbcr[] = { + 0xFFFF/*dummy*/, 0x010, 0x014, 0x410, 0x414, 0x418, 0x41C, 0x420, + 0x424, 0x428, 0x42C, +}; + +#define STBCR(i) stbcr[i] /* * Software Reset Register offsets @@ -110,6 +121,7 @@ static const u16 srcr[] = { * @notifiers: Notifier chain to save/restore clock state for system resume * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control * @smstpcr_saved[].val: Saved values of SMSTPCR[] + * @stbyctrl: This device has Standby Control Registers */ struct cpg_mssr_priv { #ifdef CONFIG_RESET_CONTROLLER @@ -123,6 +135,7 @@ struct cpg_mssr_priv { unsigned int num_core_clks; unsigned int num_mod_clks; unsigned int last_dt_core_clk; + bool stbyctrl; struct raw_notifier_head notifiers; struct { @@ -162,16 +175,29 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) enable ? "ON" : "OFF"); spin_lock_irqsave(&priv->rmw_lock, flags); - value = readl(priv->base + SMSTPCR(reg)); - if (enable) - value &= ~bitmask; - else - value |= bitmask; - writel(value, priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) { + value = readb(priv->base + STBCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + writeb(value, priv->base + STBCR(reg)); + + /* dummy read to ensure write has completed */ + readb(priv->base + STBCR(reg)); + barrier_data(priv->base + STBCR(reg)); + } else { + value = readl(priv->base + SMSTPCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + writel(value, priv->base + SMSTPCR(reg)); + } spin_unlock_irqrestore(&priv->rmw_lock, flags); - if (!enable) + if (!enable || priv->stbyctrl) return 0; for (i = 1000; i > 0; --i) { @@ -205,7 +231,10 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) struct cpg_mssr_priv *priv = clock->priv; u32 value; - value = readl(priv->base + MSTPSR(clock->index / 32)); + if (priv->stbyctrl) + value = readb(priv->base + STBCR(clock->index / 32)); + else + value = readl(priv->base + MSTPSR(clock->index / 32)); return !(value & BIT(clock->index % 32)); } @@ -226,6 +255,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, unsigned int idx; const char *type; struct clk *clk; + int range_check; switch (clkspec->args[0]) { case CPG_CORE: @@ -240,8 +270,14 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, case CPG_MOD: type = "module"; - idx = MOD_CLK_PACK(clkidx); - if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) { + if (priv->stbyctrl) { + idx = MOD_CLK_PACK_10(clkidx); + range_check = 7 - (clkidx % 10); + } else { + idx = MOD_CLK_PACK(clkidx); + range_check = 31 - (clkidx % 100); + } + if (range_check < 0 || idx >= priv->num_mod_clks) { dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); @@ -646,6 +682,12 @@ static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv) static const struct of_device_id cpg_mssr_match[] = { +#ifdef CONFIG_CLK_R7S9210 + { + .compatible = "renesas,r7s9210-cpg-mssr", + .data = &r7s9210_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7743 { .compatible = "renesas,r8a7743-cpg-mssr", @@ -791,13 +833,23 @@ static int cpg_mssr_resume_noirq(struct device *dev) if (!mask) continue; - oldval = readl(priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) + oldval = readb(priv->base + STBCR(reg)); + else + oldval = readl(priv->base + SMSTPCR(reg)); newval = oldval & ~mask; newval |= priv->smstpcr_saved[reg].val & mask; if (newval == oldval) continue; - writel(newval, priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) { + writeb(newval, priv->base + STBCR(reg)); + /* dummy read to ensure write has completed */ + readb(priv->base + STBCR(reg)); + barrier_data(priv->base + STBCR(reg)); + continue; + } else + writel(newval, priv->base + SMSTPCR(reg)); /* Wait until enabled clocks are really enabled */ mask &= ~priv->smstpcr_saved[reg].val; @@ -869,6 +921,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); + priv->stbyctrl = info->stbyctrl; for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); @@ -894,6 +947,10 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) if (error) return error; + /* Reset Controller not supported for Standby Control SoCs */ + if (info->stbyctrl) + return 0; + error = cpg_mssr_reset_controller_register(priv); if (error) return error; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 2e1730bc5ef2..35f60b3d0e09 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -78,6 +78,13 @@ struct mssr_mod_clk { #define DEF_MOD(_name, _mod, _parent...) \ { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent } +/* Convert from sparse base-10 to packed index space */ +#define MOD_CLK_PACK_10(x) ((x / 10) * 32 + (x % 10)) + +#define MOD_CLK_ID_10(x) (MOD_CLK_BASE + MOD_CLK_PACK_10(x)) + +#define DEF_MOD_STB(_name, _mod, _parent...) \ + { .name = _name, .id = MOD_CLK_ID_10(_mod), .parent = _parent } struct device_node; @@ -103,6 +110,10 @@ struct device_node; * * @init: Optional callback to perform SoC-specific initialization * @cpg_clk_register: Optional callback to handle special Core Clock types + * + * @stbyctrl: This device has Standby Control Registers which are 8-bits + * wide, no status registers (MSTPSR) and have different address + * offsets. */ struct cpg_mssr_info { @@ -111,6 +122,7 @@ struct cpg_mssr_info { unsigned int num_core_clks; unsigned int last_dt_core_clk; unsigned int num_total_core_clks; + bool stbyctrl; /* Module Clocks */ const struct mssr_mod_clk *mod_clks; @@ -134,6 +146,7 @@ struct cpg_mssr_info { struct raw_notifier_head *notifiers); }; +extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; diff --git a/include/dt-bindings/clock/r7s9210-cpg-mssr.h b/include/dt-bindings/clock/r7s9210-cpg-mssr.h new file mode 100644 index 000000000000..b6f85ca149aa --- /dev/null +++ b/include/dt-bindings/clock/r7s9210-cpg-mssr.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + */ + +#ifndef __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ + +#include + +/* R7S9210 CPG Core Clocks */ +#define R7S9210_CLK_I 0 +#define R7S9210_CLK_G 1 +#define R7S9210_CLK_B 2 +#define R7S9210_CLK_P1 3 +#define R7S9210_CLK_P1C 4 +#define R7S9210_CLK_P0 5 + +#endif /* __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ */ From 0b59c25f91002c1dec0d0d848e5aaefa5f213c85 Mon Sep 17 00:00:00 2001 From: Igor Stoppa Date: Fri, 31 Aug 2018 22:44:22 +0300 Subject: [PATCH 072/836] mm: percpu: remove unnecessary unlikely() WARN_ON() already contains an unlikely(), so it's not necessary to wrap it into another. Signed-off-by: Igor Stoppa Cc: Tejun Heo Cc: zijun_hu Cc: Christoph Lameter Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Dennis Zhou --- mm/percpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/percpu.c b/mm/percpu.c index a749d4d96e3e..f5c2796fe63e 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -2588,7 +2588,7 @@ int __init pcpu_page_first_chunk(size_t reserved_size, BUG_ON(ai->nr_groups != 1); upa = ai->alloc_size/ai->unit_size; nr_g0_units = roundup(num_possible_cpus(), upa); - if (unlikely(WARN_ON(ai->groups[0].nr_units != nr_g0_units))) { + if (WARN_ON(ai->groups[0].nr_units != nr_g0_units)) { pcpu_free_alloc_info(ai); return -EINVAL; } From 1f8266ff58840d698a1e96d2274189de1bdf7969 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 13 Sep 2018 18:12:09 +0200 Subject: [PATCH 073/836] apparmor: don't try to replace stale label in ptrace access check As a comment above begin_current_label_crit_section() explains, begin_current_label_crit_section() must run in sleepable context because when label_is_stale() is true, aa_replace_current_label() runs, which uses prepare_creds(), which can sleep. Until now, the ptrace access check (which runs with a task lock held) violated this rule. Also add a might_sleep() assertion to begin_current_label_crit_section(), because asserts are less likely to be ignored than comments. Fixes: b2d09ae449ced ("apparmor: move ptrace checks to using labels") Signed-off-by: Jann Horn Signed-off-by: John Johansen --- security/apparmor/include/cred.h | 2 ++ security/apparmor/lsm.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/security/apparmor/include/cred.h b/security/apparmor/include/cred.h index e287b7d0d4be..265ae6641a06 100644 --- a/security/apparmor/include/cred.h +++ b/security/apparmor/include/cred.h @@ -151,6 +151,8 @@ static inline struct aa_label *begin_current_label_crit_section(void) { struct aa_label *label = aa_current_raw_label(); + might_sleep(); + if (label_is_stale(label)) { label = aa_get_newest_label(label); if (aa_replace_current_label(label) == 0) diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 74f17376202b..f09fea0b4db7 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -114,13 +114,13 @@ static int apparmor_ptrace_access_check(struct task_struct *child, struct aa_label *tracer, *tracee; int error; - tracer = begin_current_label_crit_section(); + tracer = __begin_current_label_crit_section(); tracee = aa_get_task_label(child); error = aa_may_ptrace(tracer, tracee, (mode & PTRACE_MODE_READ) ? AA_PTRACE_READ : AA_PTRACE_TRACE); aa_put_label(tracee); - end_current_label_crit_section(tracer); + __end_current_label_crit_section(tracer); return error; } From 5d169ce7371227d899d749cc5289ce50aff7d99f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 7 Sep 2018 01:52:28 +0000 Subject: [PATCH 074/836] dt-bindings: clock: renesas: Convert to SPDX identifiers This patch updates license to use SPDX-License-Identifier instead of verbose license text on Renesas related headers. Signed-off-by: Kuninori Morimoto Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r7s72100-clock.h | 7 ++----- include/dt-bindings/clock/r8a7743-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7745-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7790-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7791-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7792-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7793-clock.h | 12 ++---------- include/dt-bindings/clock/r8a7793-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7794-clock.h | 8 ++------ include/dt-bindings/clock/r8a7794-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7795-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a7796-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a77970-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/r8a77995-cpg-mssr.h | 8 ++------ include/dt-bindings/clock/renesas-cpg-mssr.h | 8 ++------ 15 files changed, 30 insertions(+), 93 deletions(-) diff --git a/include/dt-bindings/clock/r7s72100-clock.h b/include/dt-bindings/clock/r7s72100-clock.h index 0dcb3e87d44c..a267ac250143 100644 --- a/include/dt-bindings/clock/r7s72100-clock.h +++ b/include/dt-bindings/clock/r7s72100-clock.h @@ -1,10 +1,7 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * Copyright (C) 2014 Renesas Solutions Corp. * Copyright (C) 2014 Wolfram Sang, Sang Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #ifndef __DT_BINDINGS_CLOCK_R7S72100_H__ diff --git a/include/dt-bindings/clock/r8a7743-cpg-mssr.h b/include/dt-bindings/clock/r8a7743-cpg-mssr.h index e1d1f3c6a99e..3ba936029d9f 100644 --- a/include/dt-bindings/clock/r8a7743-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7743-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2016 Cogent Embedded Inc. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2016 Cogent Embedded Inc. */ #ifndef __DT_BINDINGS_CLOCK_R8A7743_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_R8A7743_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7745-cpg-mssr.h b/include/dt-bindings/clock/r8a7745-cpg-mssr.h index 56ad6f0c6760..f81066c9d192 100644 --- a/include/dt-bindings/clock/r8a7745-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7745-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2016 Cogent Embedded Inc. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2016 Cogent Embedded Inc. */ #ifndef __DT_BINDINGS_CLOCK_R8A7745_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_R8A7745_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7790-cpg-mssr.h b/include/dt-bindings/clock/r8a7790-cpg-mssr.h index 1625b8bf3482..c5955b56b36d 100644 --- a/include/dt-bindings/clock/r8a7790-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7790-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7790_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7791-cpg-mssr.h b/include/dt-bindings/clock/r8a7791-cpg-mssr.h index e8823410c01c..aadd06c566c0 100644 --- a/include/dt-bindings/clock/r8a7791-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7791-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7791_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7792-cpg-mssr.h b/include/dt-bindings/clock/r8a7792-cpg-mssr.h index 72ce85cb2f94..829c44db0271 100644 --- a/include/dt-bindings/clock/r8a7792-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7792-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7792_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7793-clock.h b/include/dt-bindings/clock/r8a7793-clock.h index 7318d45d4e7e..49c66d8ed178 100644 --- a/include/dt-bindings/clock/r8a7793-clock.h +++ b/include/dt-bindings/clock/r8a7793-clock.h @@ -1,16 +1,8 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * r8a7793 clock definition * * Copyright (C) 2014 Renesas Electronics Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __DT_BINDINGS_CLOCK_R8A7793_H__ diff --git a/include/dt-bindings/clock/r8a7793-cpg-mssr.h b/include/dt-bindings/clock/r8a7793-cpg-mssr.h index 8809b0f62d61..d1ff646c31f2 100644 --- a/include/dt-bindings/clock/r8a7793-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7793-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7793_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7794-clock.h b/include/dt-bindings/clock/r8a7794-clock.h index 93e99c3ffc8d..649f005782d0 100644 --- a/include/dt-bindings/clock/r8a7794-clock.h +++ b/include/dt-bindings/clock/r8a7794-clock.h @@ -1,11 +1,7 @@ -/* +/* SPDX-License-Identifier: GPL-2.0+ + * * Copyright (C) 2014 Renesas Electronics Corporation * Copyright 2013 Ideas On Board SPRL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __DT_BINDINGS_CLOCK_R8A7794_H__ diff --git a/include/dt-bindings/clock/r8a7794-cpg-mssr.h b/include/dt-bindings/clock/r8a7794-cpg-mssr.h index 9d720311ae3a..6314e23b51af 100644 --- a/include/dt-bindings/clock/r8a7794-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7794-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7794_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7795-cpg-mssr.h b/include/dt-bindings/clock/r8a7795-cpg-mssr.h index f047eaf261f3..948389641565 100644 --- a/include/dt-bindings/clock/r8a7795-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7795-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_R8A7795_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a7796-cpg-mssr.h b/include/dt-bindings/clock/r8a7796-cpg-mssr.h index 1e5942695f0d..e6087f2f7e3a 100644 --- a/include/dt-bindings/clock/r8a7796-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a7796-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2016 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2016 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_R8A7796_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a77970-cpg-mssr.h b/include/dt-bindings/clock/r8a77970-cpg-mssr.h index 4146395595b1..6145ebe66361 100644 --- a/include/dt-bindings/clock/r8a77970-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a77970-cpg-mssr.h @@ -1,11 +1,7 @@ -/* +/* SPDX-License-Identifier: GPL-2.0+ + * * Copyright (C) 2016 Renesas Electronics Corp. * Copyright (C) 2017 Cogent Embedded, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_R8A77970_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/r8a77995-cpg-mssr.h b/include/dt-bindings/clock/r8a77995-cpg-mssr.h index 4e8ae3dee590..1eb11acfa563 100644 --- a/include/dt-bindings/clock/r8a77995-cpg-mssr.h +++ b/include/dt-bindings/clock/r8a77995-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2017 Glider bvba +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2017 Glider bvba */ #ifndef __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ diff --git a/include/dt-bindings/clock/renesas-cpg-mssr.h b/include/dt-bindings/clock/renesas-cpg-mssr.h index 569a3cc33ffb..8169ad063f0a 100644 --- a/include/dt-bindings/clock/renesas-cpg-mssr.h +++ b/include/dt-bindings/clock/renesas-cpg-mssr.h @@ -1,10 +1,6 @@ -/* - * Copyright (C) 2015 Renesas Electronics Corp. +/* SPDX-License-Identifier: GPL-2.0+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2015 Renesas Electronics Corp. */ #ifndef __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ #define __DT_BINDINGS_CLOCK_RENESAS_CPG_MSSR_H__ From bbd71915ee9c56cc585c76b4b3aee791152ffbff Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 11 Sep 2018 11:12:47 +0100 Subject: [PATCH 075/836] dt-bindings: clock: renesas: cpg-mssr: Document r8a7744 binding Add binding documentation for the RZ/G1N (R8A7744) Clock Pulse Generator driver. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 5e46e6be789b..629dd4f8ddac 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -15,6 +15,7 @@ Required Properties: - compatible: Must be one of: - "renesas,r7s9210-cpg-mssr" for the r7s9210 SoC (RZ/A2) - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) + - "renesas,r8a7744-cpg-mssr" for the r8a7744 SoC (RZ/G1N) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) @@ -37,12 +38,12 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r7s9210, r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, - r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, - r8a77970, r8a77980, r8a77990, r8a77995) + - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1, + r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, + r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, - r8a7794) + - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791, + r8a7793, r8a7794) - #clock-cells: Must be 2 - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" From 6ff9cb53dabca55952ef66853ff145f7c424f6bd Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 11 Sep 2018 11:12:48 +0100 Subject: [PATCH 076/836] clk: renesas: Add r8a7744 CPG Core Clock Definitions Add all RZ/G1N Clock Pulse Generator Core Clock Outputs, as listed in Table 7.2b ("List of Clocks [RZ/G1M/N]") of the RZ/G1 Hardware User's Manual. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r8a7744-cpg-mssr.h | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 include/dt-bindings/clock/r8a7744-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a7744-cpg-mssr.h b/include/dt-bindings/clock/r8a7744-cpg-mssr.h new file mode 100644 index 000000000000..2690be0c3e22 --- /dev/null +++ b/include/dt-bindings/clock/r8a7744-cpg-mssr.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A7744_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A7744_CPG_MSSR_H__ + +#include + +/* r8a7744 CPG Core Clocks */ +#define R8A7744_CLK_Z 0 +#define R8A7744_CLK_ZG 1 +#define R8A7744_CLK_ZTR 2 +#define R8A7744_CLK_ZTRD2 3 +#define R8A7744_CLK_ZT 4 +#define R8A7744_CLK_ZX 5 +#define R8A7744_CLK_ZS 6 +#define R8A7744_CLK_HP 7 +#define R8A7744_CLK_B 9 +#define R8A7744_CLK_LB 10 +#define R8A7744_CLK_P 11 +#define R8A7744_CLK_CL 12 +#define R8A7744_CLK_M2 13 +#define R8A7744_CLK_ZB3 15 +#define R8A7744_CLK_ZB3D2 16 +#define R8A7744_CLK_DDR 17 +#define R8A7744_CLK_SDH 18 +#define R8A7744_CLK_SD0 19 +#define R8A7744_CLK_SD2 20 +#define R8A7744_CLK_SD3 21 +#define R8A7744_CLK_MMC0 22 +#define R8A7744_CLK_MP 23 +#define R8A7744_CLK_QSPI 26 +#define R8A7744_CLK_CP 27 +#define R8A7744_CLK_RCAN 28 +#define R8A7744_CLK_R 29 +#define R8A7744_CLK_OSC 30 + +#endif /* __DT_BINDINGS_CLOCK_R8A7744_CPG_MSSR_H__ */ From 016f9663156fe7e1402ef5ebaaca55d67f639966 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 11 Sep 2018 11:12:49 +0100 Subject: [PATCH 077/836] clk: renesas: r8a7743: Add r8a7744 support Add RZ/G1N (R8A7744) Clock Pulse Generator / Module Standby and Software Reset support. Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 2 +- drivers/clk/renesas/r8a7743-cpg-mssr.c | 13 ++++++++++++- drivers/clk/renesas/renesas-cpg-mssr.c | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 2edcb1bdb487..7a6ceecc213e 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -6,7 +6,7 @@ config CLK_RENESAS select CLK_R7S9210 if ARCH_R7S9210 select CLK_R8A73A4 if ARCH_R8A73A4 select CLK_R8A7740 if ARCH_R8A7740 - select CLK_R8A7743 if ARCH_R8A7743 + select CLK_R8A7743 if ARCH_R8A7743 || ARCH_R8A7744 select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A774A1 if ARCH_R8A774A1 diff --git a/drivers/clk/renesas/r8a7743-cpg-mssr.c b/drivers/clk/renesas/r8a7743-cpg-mssr.c index 011c170ec3f9..ab994f4c1ec8 100644 --- a/drivers/clk/renesas/r8a7743-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7743-cpg-mssr.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ enum clk_ids { MOD_CLK_BASE }; -static const struct cpg_core_clk r8a7743_core_clks[] __initconst = { +static struct cpg_core_clk r8a7743_core_clks[] __initdata = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), DEF_INPUT("usb_extal", CLK_USB_EXTAL), @@ -238,6 +239,8 @@ static const struct rcar_gen2_cpg_pll_config cpg_pll_configs[8] __initconst = { static int __init r8a7743_cpg_mssr_init(struct device *dev) { const struct rcar_gen2_cpg_pll_config *cpg_pll_config; + struct device_node *np = dev->of_node; + unsigned int i; u32 cpg_mode; int error; @@ -247,6 +250,14 @@ static int __init r8a7743_cpg_mssr_init(struct device *dev) cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (of_device_is_compatible(np, "renesas,r8a7744-cpg-mssr")) { + /* RZ/G1N uses a 1/5 divider for ZG */ + for (i = 0; i < ARRAY_SIZE(r8a7743_core_clks); i++) + if (r8a7743_core_clks[i].id == R8A7743_CLK_ZG) { + r8a7743_core_clks[i].div = 5; + break; + } + } return rcar_gen2_cpg_init(cpg_pll_config, 2, cpg_mode); } diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index b97e0e3ff0b1..c4beec7b563f 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -693,6 +693,11 @@ static const struct of_device_id cpg_mssr_match[] = { .compatible = "renesas,r8a7743-cpg-mssr", .data = &r8a7743_cpg_mssr_info, }, + /* RZ/G1N is (almost) identical to RZ/G1M w.r.t. clocks. */ + { + .compatible = "renesas,r8a7744-cpg-mssr", + .data = &r8a7743_cpg_mssr_info, + }, #endif #ifdef CONFIG_CLK_R8A7745 { From 0acb6b53df36b8453be4fc2563e37e84450eed25 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Wed, 12 Sep 2018 11:41:52 +0100 Subject: [PATCH 078/836] clk: renesas: Add r8a774c0 CPG Core Clock Definitions Add all RZ/G2E (a.k.a. R8A774C0) Clock Pulse Generator Core Clock Outputs, as listed in Table 8.2g ("List of Clocks [RZ/G2E]") of the RZ/G2 Hardware User's Manual. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Simon Horman Reviewed-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- include/dt-bindings/clock/r8a774c0-cpg-mssr.h | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 include/dt-bindings/clock/r8a774c0-cpg-mssr.h diff --git a/include/dt-bindings/clock/r8a774c0-cpg-mssr.h b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h new file mode 100644 index 000000000000..8fe51b6aca28 --- /dev/null +++ b/include/dt-bindings/clock/r8a774c0-cpg-mssr.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ + +#include + +/* r8a774c0 CPG Core Clocks */ +#define R8A774C0_CLK_Z2 0 +#define R8A774C0_CLK_ZG 1 +#define R8A774C0_CLK_ZTR 2 +#define R8A774C0_CLK_ZT 3 +#define R8A774C0_CLK_ZX 4 +#define R8A774C0_CLK_S0D1 5 +#define R8A774C0_CLK_S0D3 6 +#define R8A774C0_CLK_S0D6 7 +#define R8A774C0_CLK_S0D12 8 +#define R8A774C0_CLK_S0D24 9 +#define R8A774C0_CLK_S1D1 10 +#define R8A774C0_CLK_S1D2 11 +#define R8A774C0_CLK_S1D4 12 +#define R8A774C0_CLK_S2D1 13 +#define R8A774C0_CLK_S2D2 14 +#define R8A774C0_CLK_S2D4 15 +#define R8A774C0_CLK_S3D1 16 +#define R8A774C0_CLK_S3D2 17 +#define R8A774C0_CLK_S3D4 18 +#define R8A774C0_CLK_S0D6C 19 +#define R8A774C0_CLK_S3D1C 20 +#define R8A774C0_CLK_S3D2C 21 +#define R8A774C0_CLK_S3D4C 22 +#define R8A774C0_CLK_LB 23 +#define R8A774C0_CLK_CL 24 +#define R8A774C0_CLK_ZB3 25 +#define R8A774C0_CLK_ZB3D2 26 +#define R8A774C0_CLK_CR 27 +#define R8A774C0_CLK_CRD2 28 +#define R8A774C0_CLK_SD0H 29 +#define R8A774C0_CLK_SD0 30 +#define R8A774C0_CLK_SD1H 31 +#define R8A774C0_CLK_SD1 32 +#define R8A774C0_CLK_SD3H 33 +#define R8A774C0_CLK_SD3 34 +#define R8A774C0_CLK_RPC 35 +#define R8A774C0_CLK_RPCD2 36 +#define R8A774C0_CLK_ZA2 37 +#define R8A774C0_CLK_ZA8 38 +#define R8A774C0_CLK_Z2D 39 +#define R8A774C0_CLK_MSO 40 +#define R8A774C0_CLK_R 41 +#define R8A774C0_CLK_OSC 42 +#define R8A774C0_CLK_LV0 43 +#define R8A774C0_CLK_LV1 44 +#define R8A774C0_CLK_CSI0 45 +#define R8A774C0_CLK_CP 46 +#define R8A774C0_CLK_CPEX 47 + +#endif /* __DT_BINDINGS_CLOCK_R8A774C0_CPG_MSSR_H__ */ From 906e0a4a6d1ef2d3940cd7f17287b111730382da Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Wed, 12 Sep 2018 11:41:53 +0100 Subject: [PATCH 079/836] clk: renesas: cpg-mssr: Add r8a774c0 support Add RZ/G2E (R8A774C0) Clock Pulse Generator / Module Standby and Software Reset support. Based on Table 8.2g of "RZ/G Series, 2nd Generation User's Manual: Hardware (Rev. 0.61, June 12, 2018)". Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a774c0-cpg-mssr.c | 286 ++++++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 5 files changed, 299 insertions(+) create mode 100644 drivers/clk/renesas/r8a774c0-cpg-mssr.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 7a6ceecc213e..8d5a6fbef7e9 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -10,6 +10,7 @@ config CLK_RENESAS select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A774A1 if ARCH_R8A774A1 + select CLK_R8A774C0 if ARCH_R8A774C0 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 select CLK_R8A7790 if ARCH_R8A7790 @@ -77,6 +78,10 @@ config CLK_R8A774A1 bool "RZ/G2M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A774C0 + bool "RZ/G2E clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A7778 bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index dbbfd0b0742b..c793e3cc9452 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c new file mode 100644 index 000000000000..10b96895d452 --- /dev/null +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774c0 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on r8a77990-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774C0_CLK_CPEX, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL0D4, + CLK_PLL0D8, + CLK_PLL0D20, + CLK_PLL0D24, + CLK_PLL1D2, + CLK_PE, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + CLK_OCO, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + + DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100), + DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1), + DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1), + DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1), + DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1), + DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), + DEF_FIXED(".pe", CLK_PE, CLK_PLL0D20, 1, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), + + /* Core Clock Outputs */ + DEF_FIXED("za2", R8A774C0_CLK_ZA2, CLK_PLL0D24, 1, 1), + DEF_FIXED("za8", R8A774C0_CLK_ZA8, CLK_PLL0D8, 1, 1), + DEF_FIXED("ztr", R8A774C0_CLK_ZTR, CLK_PLL1, 6, 1), + DEF_FIXED("zt", R8A774C0_CLK_ZT, CLK_PLL1, 4, 1), + DEF_FIXED("zx", R8A774C0_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("s0d1", R8A774C0_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d3", R8A774C0_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d6", R8A774C0_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d12", R8A774C0_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s0d24", R8A774C0_CLK_S0D24, CLK_S0, 24, 1), + DEF_FIXED("s1d1", R8A774C0_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A774C0_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774C0_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774C0_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774C0_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774C0_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774C0_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774C0_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774C0_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, CLK_SDSRC, 0x026c), + + DEF_FIXED("cl", R8A774C0_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A774C0_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774C0_CLK_CPEX, CLK_EXTAL, 4, 1), + + DEF_DIV6_RO("osc", R8A774C0_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + + DEF_GEN3_PE("s0d6c", R8A774C0_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2), + DEF_GEN3_PE("s3d1c", R8A774C0_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), + DEF_GEN3_PE("s3d2c", R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), + DEF_GEN3_PE("s3d4c", R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), + + DEF_DIV6P1("csi0", R8A774C0_CLK_CSI0, CLK_PLL1D2, 0x00c), + DEF_DIV6P1("mso", R8A774C0_CLK_MSO, CLK_PLL1D2, 0x014), + + DEF_GEN3_RCKSEL("r", R8A774C0_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4), +}; + +static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C), + DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C), + DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C), + DEF_MOD("scif1", 206, R8A774C0_CLK_S3D4C), + DEF_MOD("scif0", 207, R8A774C0_CLK_S3D4C), + DEF_MOD("msiof3", 208, R8A774C0_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774C0_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774C0_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774C0_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774C0_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774C0_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774C0_CLK_S3D1), + + DEF_MOD("cmt3", 300, R8A774C0_CLK_R), + DEF_MOD("cmt2", 301, R8A774C0_CLK_R), + DEF_MOD("cmt1", 302, R8A774C0_CLK_R), + DEF_MOD("cmt0", 303, R8A774C0_CLK_R), + DEF_MOD("scif2", 310, R8A774C0_CLK_S3D4C), + DEF_MOD("sdif3", 311, R8A774C0_CLK_SD3), + DEF_MOD("sdif1", 313, R8A774C0_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774C0_CLK_SD0), + DEF_MOD("pcie0", 319, R8A774C0_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774C0_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774C0_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774C0_CLK_S3D1), + + DEF_MOD("rwdt", 402, R8A774C0_CLK_R), + DEF_MOD("intc-ex", 407, R8A774C0_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774C0_CLK_S0D3), + + DEF_MOD("audmac0", 502, R8A774C0_CLK_S3D4), + DEF_MOD("hscif4", 516, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif3", 517, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif2", 518, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif1", 519, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif0", 520, R8A774C0_CLK_S3D1C), + DEF_MOD("thermal", 522, R8A774C0_CLK_CP), + DEF_MOD("pwm", 523, R8A774C0_CLK_S3D4C), + + DEF_MOD("fcpvd1", 602, R8A774C0_CLK_S1D2), + DEF_MOD("fcpvd0", 603, R8A774C0_CLK_S1D2), + DEF_MOD("fcpvb0", 607, R8A774C0_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774C0_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774C0_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774C0_CLK_S0D1), + DEF_MOD("vspd1", 622, R8A774C0_CLK_S1D2), + DEF_MOD("vspd0", 623, R8A774C0_CLK_S1D2), + DEF_MOD("vspb", 626, R8A774C0_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774C0_CLK_S0D1), + + DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D4), + DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0), + DEF_MOD("du1", 723, R8A774C0_CLK_S2D1), + DEF_MOD("du0", 724, R8A774C0_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774C0_CLK_S2D1), + + DEF_MOD("vin5", 806, R8A774C0_CLK_S1D2), + DEF_MOD("vin4", 807, R8A774C0_CLK_S1D2), + DEF_MOD("etheravb", 812, R8A774C0_CLK_S3D2), + + DEF_MOD("gpio6", 906, R8A774C0_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774C0_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774C0_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774C0_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774C0_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774C0_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774C0_CLK_S3D4), + DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), + DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2), + DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP), + DEF_MOD("i2c4", 927, R8A774C0_CLK_S3D2), + DEF_MOD("i2c3", 928, R8A774C0_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A774C0_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774C0_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774C0_CLK_S3D2), + + DEF_MOD("i2c7", 1003, R8A774C0_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774C0_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774C0_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a774c0_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 + *-------------------------------------------------------------------- + * 0 48 x 1 x100/1 x100/3 x100/3 + * 1 48 x 1 x100/1 x100/3 x58/3 + */ +#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 100, 3, 100, 3, }, + { 1, 100, 3, 58, 3, }, +}; + +static int __init r8a774c0_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode); +} + +const struct cpg_mssr_info r8a774c0_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774c0_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774c0_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774c0_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774c0_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774c0_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774c0_crit_mod_clks), + + /* Callbacks */ + .init = r8a774c0_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index c4beec7b563f..e0c11a5b1761 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -717,6 +717,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a774a1_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774C0 + { + .compatible = "renesas,r8a774c0-cpg-mssr", + .data = &r8a774c0_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7790 { .compatible = "renesas,r8a7790-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 35f60b3d0e09..d43d00351638 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -151,6 +151,7 @@ extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; From 7c0043c0a48c18fccd43e5cd9f45751316564647 Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Wed, 12 Sep 2018 11:41:54 +0100 Subject: [PATCH 080/836] dt-bindings: clock: renesas: cpg-mssr: Document r8a774c0 This patch documents RZ/G2E (a.k.a. R8A774C0) bindings for the Clock Pulse Generator driver. Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Reviewed-by: Rob Herring Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 629dd4f8ddac..916a601b76a7 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -19,6 +19,7 @@ Required Properties: - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) + - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E) - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H) @@ -39,8 +40,9 @@ Required Properties: clock-names - clock-names: List of external parent clock names. Valid names are: - "extal" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1, - r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, - r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) + r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, + r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990, + r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) From 5915838b7a4fa6bd6819819de11bfc30a4323ad9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 18 Sep 2018 10:55:29 +0200 Subject: [PATCH 081/836] clk: renesas: r8a77990: Fix incorrect PLL0 divider in comment PLL0 runs at 4.8 GHz, i.e. EXTAL x 100. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/r8a77990-cpg-mssr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index 7e000d070589..9eb80180eea0 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -250,8 +250,8 @@ static const unsigned int r8a77990_crit_mod_clks[] __initconst = { /* * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 *-------------------------------------------------------------------- - * 0 48 x 1 x100/4 x100/3 x100/3 - * 1 48 x 1 x100/4 x100/3 x58/3 + * 0 48 x 1 x100/1 x100/3 x100/3 + * 1 48 x 1 x100/1 x100/3 x58/3 */ #define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) From 9ef5e0370d3834a1ff11e22ae0a3220330890d36 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 19 Sep 2018 21:10:40 +0300 Subject: [PATCH 082/836] clk: renesas: r8a77970: Add TPU clock The TPU0 clock wasn't present in the original R8A77970 patch by Daisuke Matsushita, it was added in a later BSP version... Based on the original (and large) patch by Vladimir Barinov. Signed-off-by: Vladimir Barinov Signed-off-by: Sergei Shtylyov Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r8a77970-cpg-mssr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index 7a85e1adcd94..71341ffa2016 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -127,6 +127,7 @@ static const struct mssr_mod_clk r8a77970_mod_clks[] __initconst = { DEF_MOD("cmt2", 301, R8A77970_CLK_R), DEF_MOD("cmt1", 302, R8A77970_CLK_R), DEF_MOD("cmt0", 303, R8A77970_CLK_R), + DEF_MOD("tpu0", 304, R8A77970_CLK_S2D4), DEF_MOD("sd-if", 314, R8A77970_CLK_SD0), DEF_MOD("rwdt", 402, R8A77970_CLK_R), DEF_MOD("intc-ex", 407, R8A77970_CLK_CP), From 30ea32ab1951c80c6113f300fce2c70cd12659e4 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Tue, 25 Sep 2018 13:01:27 -0600 Subject: [PATCH 083/836] vfio/pci: Fix potential memory leak in vfio_msi_cap_len Free allocated vdev->msi_perm in error path. Signed-off-by: Li Qiang Reviewed-by: Eric Auger Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci_config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 115a36f6f403..62023b4a373b 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -1180,8 +1180,10 @@ static int vfio_msi_cap_len(struct vfio_pci_device *vdev, u8 pos) return -ENOMEM; ret = init_pci_cap_msi_perm(vdev->msi_perm, len, flags); - if (ret) + if (ret) { + kfree(vdev->msi_perm); return ret; + } return len; } From db04264fe9bc0f2b62e036629f9afb530324b693 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 25 Sep 2018 13:01:27 -0600 Subject: [PATCH 084/836] vfio/pci: Mask buggy SR-IOV VF INTx support The SR-IOV spec requires that VFs must report zero for the INTx pin register as VFs are precluded from INTx support. It's much easier for the host kernel to understand whether a device is a VF and therefore whether a non-zero pin register value is bogus than it is to do the same in userspace. Override the INTx count for such devices and virtualize the pin register to provide a consistent view of the device to the user. As this is clearly a spec violation, warn about it to support hardware validation, but also provide a known whitelist as it doesn't do much good to continue complaining if the hardware vendor doesn't plan to fix it. Known devices with this issue: 8086:270c Tested-by: Gage Eads Reviewed-by: Ashok Raj Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 10 +++++++--- drivers/vfio/pci/vfio_pci_config.c | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index cddb453a1ba5..50cdedfca9fe 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -434,10 +434,14 @@ static int vfio_pci_get_irq_count(struct vfio_pci_device *vdev, int irq_type) { if (irq_type == VFIO_PCI_INTX_IRQ_INDEX) { u8 pin; - pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); - if (IS_ENABLED(CONFIG_VFIO_PCI_INTX) && !vdev->nointx && pin) - return 1; + if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || + vdev->nointx || vdev->pdev->is_virtfn) + return 0; + + pci_read_config_byte(vdev->pdev, PCI_INTERRUPT_PIN, &pin); + + return pin ? 1 : 0; } else if (irq_type == VFIO_PCI_MSI_IRQ_INDEX) { u8 pos; u16 flags; diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 62023b4a373b..423ea1f98441 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -1611,6 +1611,15 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev) return 0; } +/* + * Nag about hardware bugs, hopefully to have vendors fix them, but at least + * to collect a list of dependencies for the VF INTx pin quirk below. + */ +static const struct pci_device_id known_bogus_vf_intx_pin[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x270c) }, + {} +}; + /* * For each device we allocate a pci_config_map that indicates the * capability occupying each dword and thus the struct perm_bits we @@ -1676,6 +1685,24 @@ int vfio_config_init(struct vfio_pci_device *vdev) if (pdev->is_virtfn) { *(__le16 *)&vconfig[PCI_VENDOR_ID] = cpu_to_le16(pdev->vendor); *(__le16 *)&vconfig[PCI_DEVICE_ID] = cpu_to_le16(pdev->device); + + /* + * Per SR-IOV spec rev 1.1, 3.4.1.18 the interrupt pin register + * does not apply to VFs and VFs must implement this register + * as read-only with value zero. Userspace is not readily able + * to identify whether a device is a VF and thus that the pin + * definition on the device is bogus should it violate this + * requirement. We already virtualize the pin register for + * other purposes, so we simply need to replace the bogus value + * and consider VFs when we determine INTx IRQ count. + */ + if (vconfig[PCI_INTERRUPT_PIN] && + !pci_match_id(known_bogus_vf_intx_pin, pdev)) + pci_warn(pdev, + "Hardware bug: VF reports bogus INTx pin %d\n", + vconfig[PCI_INTERRUPT_PIN]); + + vconfig[PCI_INTERRUPT_PIN] = 0; /* Gratuitous for good VFs */ } if (!IS_ENABLED(CONFIG_VFIO_PCI_INTX) || vdev->nointx) From cf3f98c7f466a7c79458cdeb779afb9309e243e0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 25 Sep 2018 13:01:28 -0600 Subject: [PATCH 085/836] drivers/vfio: Allow type-1 IOMMU instantiation with all ARM/ARM64 IOMMUs Currently the type-1 IOMMU instantiation depends on "ARM_SMMU || ARM_SMMU_V3", while it applies to other ARM/ARM64 platforms with an IOMMU (e.g. Renesas VMSA-compatible IPMMUs). Instead of extending the list of IOMMU types on ARM platforms, replace the list by "ARM || ARM64", like other architectures do. The feature is still restricted to ARM/ARM64 platforms with an IOMMU by the dependency on IOMMU_API. Signed-off-by: Geert Uytterhoeven Reviewed-by: Robin Murphy Reviewed-by: Simon Horman Signed-off-by: Alex Williamson --- drivers/vfio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vfio/Kconfig b/drivers/vfio/Kconfig index c84333eb5eb5..9de5ed38da83 100644 --- a/drivers/vfio/Kconfig +++ b/drivers/vfio/Kconfig @@ -21,7 +21,7 @@ config VFIO_VIRQFD menuconfig VFIO tristate "VFIO Non-Privileged userspace driver framework" depends on IOMMU_API - select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM_SMMU || ARM_SMMU_V3) + select VFIO_IOMMU_TYPE1 if (X86 || S390 || ARM || ARM64) select ANON_INODES help VFIO provides a framework for secure userspace device drivers. From b5bb425871186303e6936fa2581521bdd1964a58 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Tue, 25 Sep 2018 12:44:59 -0700 Subject: [PATCH 086/836] arm64: percpu: Initialize ret in the default case Clang warns that if the default case is taken, ret will be uninitialized. ./arch/arm64/include/asm/percpu.h:196:2: warning: variable 'ret' is used uninitialized whenever switch default is taken [-Wsometimes-uninitialized] default: ^~~~~~~ ./arch/arm64/include/asm/percpu.h:200:9: note: uninitialized use occurs here return ret; ^~~ ./arch/arm64/include/asm/percpu.h:157:19: note: initialize the variable 'ret' to silence this warning unsigned long ret, loop; ^ = 0 This warning appears several times while building the erofs filesystem. While it's not strictly wrong, the BUILD_BUG will prevent this from becoming a true problem. Initialize ret to 0 in the default case right before the BUILD_BUG to silence all of these warnings. Reported-by: Prasad Sodagudi Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Signed-off-by: Dennis Zhou --- arch/arm64/include/asm/percpu.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h index 9234013e759e..21a81b59a0cc 100644 --- a/arch/arm64/include/asm/percpu.h +++ b/arch/arm64/include/asm/percpu.h @@ -96,6 +96,7 @@ static inline unsigned long __percpu_##op(void *ptr, \ : [val] "Ir" (val)); \ break; \ default: \ + ret = 0; \ BUILD_BUG(); \ } \ \ @@ -125,6 +126,7 @@ static inline unsigned long __percpu_read(void *ptr, int size) ret = READ_ONCE(*(u64 *)ptr); break; default: + ret = 0; BUILD_BUG(); } @@ -194,6 +196,7 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val, : [val] "r" (val)); break; default: + ret = 0; BUILD_BUG(); } From ca9184f0797c4893db928527fb2b6999eb753ccb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 23 Jul 2018 11:31:59 +0300 Subject: [PATCH 087/836] tracing: Trivia spelling fix containerof() -> container_of() This is the only location on kernel that has wrong spelling of the container_of() helper. Fix it. Signed-off-by: Andy Shevchenko Acked-by: Steven Rostedt (VMware) Signed-off-by: Andy Shevchenko --- kernel/trace/trace_printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index b0875b327f5c..c3fd849d4a8f 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c @@ -115,7 +115,7 @@ static int module_trace_bprintk_format_notify(struct notifier_block *self, * section, then we need to read the link list pointers. The trick is * we pass the address of the string to the seq function just like * we do for the kernel core formats. To get back the structure that - * holds the format, we simply use containerof() and then go to the + * holds the format, we simply use container_of() and then go to the * next format in the list. */ static const char ** From 6fd30d014483d6c00e04a45ead8840a375aeab5d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 31 Jul 2018 17:50:28 +0300 Subject: [PATCH 088/836] MAINTAINERS: Use my infradead account exclusively for PDx86 work ACPI PMIC subsystem listed me as a designated reviewer with infradead email which is not what I want. I'm using infradead email only for PDx86 related work. Thus, update MAINTAINERS accordingly. Signed-off-by: Andy Shevchenko --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a5b256b25905..af26a231cd3e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -377,7 +377,7 @@ F: drivers/platform/x86/i2c-multi-instantiate.c ACPI PMIC DRIVERS M: "Rafael J. Wysocki" M: Len Brown -R: Andy Shevchenko +R: Andy Shevchenko R: Mika Westerberg L: linux-acpi@vger.kernel.org Q: https://patchwork.kernel.org/project/linux-acpi/list/ From e40c7e3cda07099a92ea68d022f3304c14f9659f Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 1 Aug 2018 16:00:50 +0200 Subject: [PATCH 089/836] clk: meson: clk-pll: add enable bit Add the enable the bit of the pll clocks. These pll clocks may be disabled but we can't model this as an external gate since the pll needs to lock when enabled. Adding this bit allows to drop the poke of the first register of PLL. This will be useful to model the different components of the pll using generic clocks elements Acked-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Tested-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 28 +++++++++++++++++++--- drivers/clk/meson/clk-pll.c | 47 +++++++++++++++++++++++++++++++++---- drivers/clk/meson/clkc.h | 1 + drivers/clk/meson/gxbb.c | 32 +++++++++++++++++++++++-- drivers/clk/meson/meson8b.c | 15 ++++++++++++ 5 files changed, 113 insertions(+), 10 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 00ce62ad6416..6d8976554656 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -24,6 +24,11 @@ static DEFINE_SPINLOCK(meson_clk_lock); static struct clk_regmap axg_fixed_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_MPLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_MPLL_CNTL, .shift = 0, @@ -65,6 +70,11 @@ static struct clk_regmap axg_fixed_pll = { static struct clk_regmap axg_sys_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_SYS_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 0, @@ -197,11 +207,15 @@ static const struct reg_sequence axg_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, - { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 }, }; static struct clk_regmap axg_gp0_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP0_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_GP0_PLL_CNTL, .shift = 0, @@ -250,11 +264,15 @@ static const struct reg_sequence axg_hifi_init_regs[] = { { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x0a6a3a88 }, { .reg = HHI_HIFI_PLL_CNTL4, .def = 0xc000004d }, { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, - { .reg = HHI_HIFI_PLL_CNTL, .def = 0x40010250 }, }; static struct clk_regmap axg_hifi_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HIFI_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_HIFI_PLL_CNTL, .shift = 0, @@ -637,7 +655,6 @@ static const struct pll_rate_table axg_pcie_pll_rate_table[] = { }; static const struct reg_sequence axg_pcie_init_regs[] = { - { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, @@ -648,6 +665,11 @@ static const struct reg_sequence axg_pcie_init_regs[] = { static struct clk_regmap axg_pcie_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_PCIE_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_PCIE_PLL_CNTL, .shift = 0, diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 3e04617ac47f..8aaefe67025f 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -185,12 +185,45 @@ static void meson_clk_pll_init(struct clk_hw *hw) } } +static int meson_clk_pll_enable(struct clk_hw *hw) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); + + /* Make sure the pll is in reset */ + meson_parm_write(clk->map, &pll->rst, 1); + + /* Enable the pll */ + meson_parm_write(clk->map, &pll->en, 1); + + /* Take the pll out reset */ + meson_parm_write(clk->map, &pll->rst, 0); + + if (meson_clk_pll_wait_lock(hw)) + return -EIO; + + return 0; +} + +static void meson_clk_pll_disable(struct clk_hw *hw) +{ + struct clk_regmap *clk = to_clk_regmap(hw); + struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); + + /* Put the pll is in reset */ + meson_parm_write(clk->map, &pll->rst, 1); + + /* Disable the pll */ + meson_parm_write(clk->map, &pll->en, 0); +} + static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); const struct pll_rate_table *pllt; + unsigned int enabled; unsigned long old_rate; u16 frac = 0; @@ -203,8 +236,9 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, if (!pllt) return -EINVAL; - /* Put the pll in reset to write the params */ - meson_parm_write(clk->map, &pll->rst, 1); + enabled = meson_parm_read(clk->map, &pll->en); + if (enabled) + meson_clk_pll_disable(hw); meson_parm_write(clk->map, &pll->n, pllt->n); meson_parm_write(clk->map, &pll->m, pllt->m); @@ -221,10 +255,11 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, meson_parm_write(clk->map, &pll->frac, frac); } - /* make sure the reset is cleared at this point */ - meson_parm_write(clk->map, &pll->rst, 0); + /* If the pll is stopped, bail out now */ + if (!enabled) + return 0; - if (meson_clk_pll_wait_lock(hw)) { + if (meson_clk_pll_enable(hw)) { pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", __func__, old_rate); /* @@ -244,6 +279,8 @@ const struct clk_ops meson_clk_pll_ops = { .recalc_rate = meson_clk_pll_recalc_rate, .round_rate = meson_clk_pll_round_rate, .set_rate = meson_clk_pll_set_rate, + .enable = meson_clk_pll_enable, + .disable = meson_clk_pll_disable }; const struct clk_ops meson_clk_pll_ro_ops = { diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 24cec16b6038..c2ee37a78ceb 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -63,6 +63,7 @@ struct pll_rate_table { #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) struct meson_clk_pll_data { + struct parm en; struct parm m; struct parm n; struct parm frac; diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 86d3ae58e84c..5ed34566917c 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -177,6 +177,11 @@ static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { static struct clk_regmap gxbb_fixed_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_MPLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_MPLL_CNTL, .shift = 0, @@ -230,6 +235,11 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { static struct clk_regmap gxbb_hdmi_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HDMI_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_HDMI_PLL_CNTL, .shift = 0, @@ -282,6 +292,11 @@ static struct clk_regmap gxbb_hdmi_pll = { static struct clk_regmap gxl_hdmi_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HDMI_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_HDMI_PLL_CNTL, .shift = 0, @@ -340,6 +355,11 @@ static struct clk_regmap gxl_hdmi_pll = { static struct clk_regmap gxbb_sys_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_SYS_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 0, @@ -379,11 +399,15 @@ static const struct reg_sequence gxbb_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL2, .def = 0x69c80000 }, { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a5590c4 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, - { .reg = HHI_GP0_PLL_CNTL, .def = 0x4a000228 }, }; static struct clk_regmap gxbb_gp0_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP0_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_GP0_PLL_CNTL, .shift = 0, @@ -428,11 +452,15 @@ static const struct reg_sequence gxl_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL3, .def = 0x0a59a288 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0xc000004d }, { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, - { .reg = HHI_GP0_PLL_CNTL, .def = 0x40010250 }, }; static struct clk_regmap gxl_gp0_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP0_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_GP0_PLL_CNTL, .shift = 0, diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 7447d96a265f..fd4c414893f5 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -96,6 +96,11 @@ static struct clk_fixed_rate meson8b_xtal = { static struct clk_regmap meson8b_fixed_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_MPLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_MPLL_CNTL, .shift = 0, @@ -138,6 +143,11 @@ static struct clk_regmap meson8b_fixed_pll = { static struct clk_regmap meson8b_vid_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_VID_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_VID_PLL_CNTL, .shift = 0, @@ -175,6 +185,11 @@ static struct clk_regmap meson8b_vid_pll = { static struct clk_regmap meson8b_sys_pll = { .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_SYS_PLL_CNTL, + .shift = 30, + .width = 1, + }, .m = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 0, From 2303a9ca693e585a558497ad737728fec97e2b8a Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 1 Aug 2018 16:00:51 +0200 Subject: [PATCH 090/836] clk: meson: clk-pll: drop CLK_GET_RATE_NOCACHE where unnecessary CLK_GET_RATE_NOCACHE should only be necessary when the registers controlling the rate of clock may change outside of CCF. On Amlogic, it should only be the case for the hdmi pll which is directly controlled by the display driver (WIP to fix this). The other plls should not require this flag. Reviewed-by: Martin Blumenstingl Tested-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 1 - drivers/clk/meson/gxbb.c | 12 ++++++++---- drivers/clk/meson/meson8b.c | 3 --- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 6d8976554656..991fa511c05a 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -106,7 +106,6 @@ static struct clk_regmap axg_sys_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 5ed34566917c..01e3f80e88cc 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -218,7 +218,6 @@ static struct clk_regmap gxbb_fixed_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -286,6 +285,10 @@ static struct clk_regmap gxbb_hdmi_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, .num_parents = 1, + /* + * Display directly handle hdmi pll registers ATM, we need + * NOCACHE to keep our view of the clock as accurate as possible + */ .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -349,6 +352,10 @@ static struct clk_regmap gxl_hdmi_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, + /* + * Display directly handle hdmi pll registers ATM, we need + * NOCACHE to keep our view of the clock as accurate as possible + */ .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -391,7 +398,6 @@ static struct clk_regmap gxbb_sys_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -442,7 +448,6 @@ static struct clk_regmap gxbb_gp0_pll = { .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -500,7 +505,6 @@ static struct clk_regmap gxl_gp0_pll = { .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index fd4c414893f5..ec1f97725b9f 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -137,7 +137,6 @@ static struct clk_regmap meson8b_fixed_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -179,7 +178,6 @@ static struct clk_regmap meson8b_vid_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; @@ -222,7 +220,6 @@ static struct clk_regmap meson8b_sys_pll = { .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - .flags = CLK_GET_RATE_NOCACHE, }, }; From 87173557d2f6d28ba6e19f8aaf6b7f3d45d51511 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 1 Aug 2018 16:00:52 +0200 Subject: [PATCH 091/836] clk: meson: clk-pll: remove od parameters Remove od parameters from pll clocks and add post dividers clocks instead. Some clock, especially the one which feature several ods, may provide output between those ods. Also, some drivers, such as the hdmi driver, may require a more detailed control of the clock dividers, compared to what CCF would perform automatically. One added benefit of removing ods is that it also greatly reduce the size of the rate parameter tables. In the future, we could possibly take the predivider 'n' out of this driver as well. To do so, we will need to understand the constraints for the PLL to lock and whether or not it depends on the input clock rate. Acked-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Tested-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 284 +++++++++++---------- drivers/clk/meson/axg.h | 8 +- drivers/clk/meson/clk-pll.c | 40 +-- drivers/clk/meson/clkc.h | 9 +- drivers/clk/meson/gxbb.c | 492 +++++++++++++++++------------------- drivers/clk/meson/gxbb.h | 8 +- drivers/clk/meson/meson8b.c | 151 +++++------ drivers/clk/meson/meson8b.h | 5 +- 8 files changed, 496 insertions(+), 501 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 991fa511c05a..a5e4f7b22f39 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -22,7 +22,7 @@ static DEFINE_SPINLOCK(meson_clk_lock); -static struct clk_regmap axg_fixed_pll = { +static struct clk_regmap axg_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_MPLL_CNTL, @@ -39,11 +39,6 @@ static struct clk_regmap axg_fixed_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_MPLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_MPLL_CNTL2, .shift = 0, @@ -61,14 +56,33 @@ static struct clk_regmap axg_fixed_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "fixed_pll", + .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; -static struct clk_regmap axg_sys_pll = { +static struct clk_regmap axg_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "fixed_pll_dco" }, + .num_parents = 1, + /* + * This clock won't ever change at runtime so + * CLK_SET_RATE_PARENT is not required + */ + }, +}; + +static struct clk_regmap axg_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_SYS_PLL_CNTL, @@ -85,11 +99,6 @@ static struct clk_regmap axg_sys_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 31, @@ -102,101 +111,59 @@ static struct clk_regmap axg_sys_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "sys_pll", + .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_sys_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct pll_rate_table axg_gp0_pll_rate_table[] = { - PLL_RATE(240000000, 40, 1, 2), - PLL_RATE(246000000, 41, 1, 2), - PLL_RATE(252000000, 42, 1, 2), - PLL_RATE(258000000, 43, 1, 2), - PLL_RATE(264000000, 44, 1, 2), - PLL_RATE(270000000, 45, 1, 2), - PLL_RATE(276000000, 46, 1, 2), - PLL_RATE(282000000, 47, 1, 2), - PLL_RATE(288000000, 48, 1, 2), - PLL_RATE(294000000, 49, 1, 2), - PLL_RATE(300000000, 50, 1, 2), - PLL_RATE(306000000, 51, 1, 2), - PLL_RATE(312000000, 52, 1, 2), - PLL_RATE(318000000, 53, 1, 2), - PLL_RATE(324000000, 54, 1, 2), - PLL_RATE(330000000, 55, 1, 2), - PLL_RATE(336000000, 56, 1, 2), - PLL_RATE(342000000, 57, 1, 2), - PLL_RATE(348000000, 58, 1, 2), - PLL_RATE(354000000, 59, 1, 2), - PLL_RATE(360000000, 60, 1, 2), - PLL_RATE(366000000, 61, 1, 2), - PLL_RATE(372000000, 62, 1, 2), - PLL_RATE(378000000, 63, 1, 2), - PLL_RATE(384000000, 64, 1, 2), - PLL_RATE(390000000, 65, 1, 3), - PLL_RATE(396000000, 66, 1, 3), - PLL_RATE(402000000, 67, 1, 3), - PLL_RATE(408000000, 68, 1, 3), - PLL_RATE(480000000, 40, 1, 1), - PLL_RATE(492000000, 41, 1, 1), - PLL_RATE(504000000, 42, 1, 1), - PLL_RATE(516000000, 43, 1, 1), - PLL_RATE(528000000, 44, 1, 1), - PLL_RATE(540000000, 45, 1, 1), - PLL_RATE(552000000, 46, 1, 1), - PLL_RATE(564000000, 47, 1, 1), - PLL_RATE(576000000, 48, 1, 1), - PLL_RATE(588000000, 49, 1, 1), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(612000000, 51, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(636000000, 53, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(660000000, 55, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(684000000, 57, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(708000000, 59, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(732000000, 61, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(756000000, 63, 1, 1), - PLL_RATE(768000000, 64, 1, 1), - PLL_RATE(780000000, 65, 1, 1), - PLL_RATE(792000000, 66, 1, 1), - PLL_RATE(804000000, 67, 1, 1), - PLL_RATE(816000000, 68, 1, 1), - PLL_RATE(960000000, 40, 1, 0), - PLL_RATE(984000000, 41, 1, 0), - PLL_RATE(1008000000, 42, 1, 0), - PLL_RATE(1032000000, 43, 1, 0), - PLL_RATE(1056000000, 44, 1, 0), - PLL_RATE(1080000000, 45, 1, 0), - PLL_RATE(1104000000, 46, 1, 0), - PLL_RATE(1128000000, 47, 1, 0), - PLL_RATE(1152000000, 48, 1, 0), - PLL_RATE(1176000000, 49, 1, 0), - PLL_RATE(1200000000, 50, 1, 0), - PLL_RATE(1224000000, 51, 1, 0), - PLL_RATE(1248000000, 52, 1, 0), - PLL_RATE(1272000000, 53, 1, 0), - PLL_RATE(1296000000, 54, 1, 0), - PLL_RATE(1320000000, 55, 1, 0), - PLL_RATE(1344000000, 56, 1, 0), - PLL_RATE(1368000000, 57, 1, 0), - PLL_RATE(1392000000, 58, 1, 0), - PLL_RATE(1416000000, 59, 1, 0), - PLL_RATE(1440000000, 60, 1, 0), - PLL_RATE(1464000000, 61, 1, 0), - PLL_RATE(1488000000, 62, 1, 0), - PLL_RATE(1512000000, 63, 1, 0), - PLL_RATE(1536000000, 64, 1, 0), - PLL_RATE(1560000000, 65, 1, 0), - PLL_RATE(1584000000, 66, 1, 0), - PLL_RATE(1608000000, 67, 1, 0), - PLL_RATE(1632000000, 68, 1, 0), + PLL_RATE(960000000, 40, 1), + PLL_RATE(984000000, 41, 1), + PLL_RATE(1008000000, 42, 1), + PLL_RATE(1032000000, 43, 1), + PLL_RATE(1056000000, 44, 1), + PLL_RATE(1080000000, 45, 1), + PLL_RATE(1104000000, 46, 1), + PLL_RATE(1128000000, 47, 1), + PLL_RATE(1152000000, 48, 1), + PLL_RATE(1176000000, 49, 1), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), + PLL_RATE(1512000000, 63, 1), + PLL_RATE(1536000000, 64, 1), + PLL_RATE(1560000000, 65, 1), + PLL_RATE(1584000000, 66, 1), + PLL_RATE(1608000000, 67, 1), + PLL_RATE(1632000000, 68, 1), { /* sentinel */ }, }; @@ -208,7 +175,7 @@ static const struct reg_sequence axg_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, }; -static struct clk_regmap axg_gp0_pll = { +static struct clk_regmap axg_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_GP0_PLL_CNTL, @@ -225,11 +192,6 @@ static struct clk_regmap axg_gp0_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_GP0_PLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_GP0_PLL_CNTL1, .shift = 0, @@ -250,13 +212,29 @@ static struct clk_regmap axg_gp0_pll = { .init_count = ARRAY_SIZE(axg_gp0_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", + .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP0_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "gp0_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct reg_sequence axg_hifi_init_regs[] = { { .reg = HHI_HIFI_PLL_CNTL1, .def = 0xc084b000 }, { .reg = HHI_HIFI_PLL_CNTL2, .def = 0xb75020be }, @@ -265,7 +243,7 @@ static const struct reg_sequence axg_hifi_init_regs[] = { { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x00058000 }, }; -static struct clk_regmap axg_hifi_pll = { +static struct clk_regmap axg_hifi_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_HIFI_PLL_CNTL, @@ -282,11 +260,6 @@ static struct clk_regmap axg_hifi_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_HIFI_PLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_HIFI_PLL_CNTL5, .shift = 0, @@ -308,13 +281,29 @@ static struct clk_regmap axg_hifi_pll = { .flags = CLK_MESON_PLL_ROUND_CLOSEST, }, .hw.init = &(struct clk_init_data){ - .name = "hifi_pll", + .name = "hifi_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_hifi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HIFI_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "hifi_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_fixed_factor axg_fclk_div2_div = { .mult = 1, .div = 2, @@ -644,11 +633,9 @@ static struct clk_regmap axg_mpll3 = { static const struct pll_rate_table axg_pcie_pll_rate_table[] = { { - .rate = 100000000, + .rate = 1600000000, .m = 200, .n = 3, - .od = 1, - .od2 = 3, }, { /* sentinel */ }, }; @@ -660,9 +647,10 @@ static const struct reg_sequence axg_pcie_init_regs[] = { { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, + { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, }; -static struct clk_regmap axg_pcie_pll = { +static struct clk_regmap axg_pcie_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_PCIE_PLL_CNTL, @@ -679,16 +667,6 @@ static struct clk_regmap axg_pcie_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_PCIE_PLL_CNTL, - .shift = 16, - .width = 2, - }, - .od2 = { - .reg_off = HHI_PCIE_PLL_CNTL6, - .shift = 6, - .width = 2, - }, .frac = { .reg_off = HHI_PCIE_PLL_CNTL1, .shift = 0, @@ -709,13 +687,45 @@ static struct clk_regmap axg_pcie_pll = { .init_count = ARRAY_SIZE(axg_pcie_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "pcie_pll", + .name = "pcie_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap axg_pcie_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_PCIE_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "pcie_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap axg_pcie_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_PCIE_PLL_CNTL6, + .shift = 6, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "pcie_pll_od" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap axg_pcie_mux = { .data = &(struct clk_regmap_mux_data){ .offset = HHI_PCIE_PLL_CNTL6, @@ -1128,6 +1138,12 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = { [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, [CLKID_GEN_CLK] = &axg_gen_clk.hw, + [CLKID_SYS_PLL_DCO] = &axg_sys_pll_dco.hw, + [CLKID_FIXED_PLL_DCO] = &axg_fixed_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &axg_gp0_pll_dco.hw, + [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, + [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, + [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -1206,6 +1222,8 @@ static struct clk_regmap *const axg_clk_regmaps[] = { &axg_fclk_div4, &axg_fclk_div5, &axg_fclk_div7, + &axg_pcie_pll_dco, + &axg_pcie_pll_od, &axg_pcie_pll, &axg_pcie_mux, &axg_pcie_ref, @@ -1215,6 +1233,12 @@ static struct clk_regmap *const axg_clk_regmaps[] = { &axg_gen_clk_sel, &axg_gen_clk_div, &axg_gen_clk, + &axg_fixed_pll_dco, + &axg_sys_pll_dco, + &axg_gp0_pll_dco, + &axg_hifi_pll_dco, + &axg_pcie_pll_dco, + &axg_pcie_pll_od, }; static const struct of_device_id clkc_match_table[] = { diff --git a/drivers/clk/meson/axg.h b/drivers/clk/meson/axg.h index 1d04144a1b2c..0431dabac629 100644 --- a/drivers/clk/meson/axg.h +++ b/drivers/clk/meson/axg.h @@ -133,8 +133,14 @@ #define CLKID_PCIE_REF 78 #define CLKID_GEN_CLK_SEL 82 #define CLKID_GEN_CLK_DIV 83 +#define CLKID_SYS_PLL_DCO 85 +#define CLKID_FIXED_PLL_DCO 86 +#define CLKID_GP0_PLL_DCO 87 +#define CLKID_HIFI_PLL_DCO 88 +#define CLKID_PCIE_PLL_DCO 89 +#define CLKID_PCIE_PLL_OD 90 -#define NR_CLKS 85 +#define NR_CLKS 91 /* include the CLKIDs that have been made part of the DT binding */ #include diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 8aaefe67025f..348a866f09eb 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -11,15 +11,19 @@ * In the most basic form, a Meson PLL is composed as follows: * * PLL - * +------------------------------+ - * | | - * in -----[ /N ]---[ *M ]---[ >>OD ]----->> out - * | ^ ^ | - * +------------------------------+ - * | | - * FREF VCO + * +--------------------------------+ + * | | + * | +--+ | + * in >>-----[ /N ]--->| | +-----+ | + * | | |------| DCO |---->> out + * | +--------->| | +--v--+ | + * | | +--+ | | + * | | | | + * | +--[ *(M + (F/Fmax) ]<--+ | + * | | + * +--------------------------------+ * - * out = in * (m + frac / frac_max) / (n << sum(ods)) + * out = in * (m + frac / frac_max) / n */ #include @@ -46,7 +50,6 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, struct meson_clk_pll_data *pll) { u64 rate = (u64)parent_rate * pllt->m; - unsigned int od = pllt->od + pllt->od2 + pllt->od3; if (frac && MESON_PARM_APPLICABLE(&pll->frac)) { u64 frac_rate = (u64)parent_rate * frac; @@ -55,7 +58,7 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate, (1 << pll->frac.width)); } - return DIV_ROUND_UP_ULL(rate, pllt->n << od); + return DIV_ROUND_UP_ULL(rate, pllt->n); } static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, @@ -68,15 +71,6 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, pllt.n = meson_parm_read(clk->map, &pll->n); pllt.m = meson_parm_read(clk->map, &pll->m); - pllt.od = meson_parm_read(clk->map, &pll->od); - - pllt.od2 = MESON_PARM_APPLICABLE(&pll->od2) ? - meson_parm_read(clk->map, &pll->od2) : - 0; - - pllt.od3 = MESON_PARM_APPLICABLE(&pll->od3) ? - meson_parm_read(clk->map, &pll->od3) : - 0; frac = MESON_PARM_APPLICABLE(&pll->frac) ? meson_parm_read(clk->map, &pll->frac) : @@ -93,8 +87,6 @@ static u16 __pll_params_with_frac(unsigned long rate, u16 frac_max = (1 << pll->frac.width); u64 val = (u64)rate * pllt->n; - val <<= pllt->od + pllt->od2 + pllt->od3; - if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate); else @@ -242,13 +234,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, meson_parm_write(clk->map, &pll->n, pllt->n); meson_parm_write(clk->map, &pll->m, pllt->m); - meson_parm_write(clk->map, &pll->od, pllt->od); - if (MESON_PARM_APPLICABLE(&pll->od2)) - meson_parm_write(clk->map, &pll->od2, pllt->od2); - - if (MESON_PARM_APPLICABLE(&pll->od3)) - meson_parm_write(clk->map, &pll->od3, pllt->od3); if (MESON_PARM_APPLICABLE(&pll->frac)) { frac = __pll_params_with_frac(rate, parent_rate, pllt, pll); diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index c2ee37a78ceb..a2245e857f70 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -47,17 +47,13 @@ struct pll_rate_table { unsigned long rate; u16 m; u16 n; - u16 od; - u16 od2; - u16 od3; }; -#define PLL_RATE(_r, _m, _n, _od) \ +#define PLL_RATE(_r, _m, _n) \ { \ .rate = (_r), \ .m = (_m), \ .n = (_n), \ - .od = (_od), \ } #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) @@ -67,9 +63,6 @@ struct meson_clk_pll_data { struct parm m; struct parm n; struct parm frac; - struct parm od; - struct parm od2; - struct parm od3; struct parm l; struct parm rst; const struct reg_sequence *init_regs; diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 01e3f80e88cc..af59f2607dc1 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -19,163 +19,70 @@ static DEFINE_SPINLOCK(meson_clk_lock); static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { - PLL_RATE(96000000, 32, 1, 3), - PLL_RATE(99000000, 33, 1, 3), - PLL_RATE(102000000, 34, 1, 3), - PLL_RATE(105000000, 35, 1, 3), - PLL_RATE(108000000, 36, 1, 3), - PLL_RATE(111000000, 37, 1, 3), - PLL_RATE(114000000, 38, 1, 3), - PLL_RATE(117000000, 39, 1, 3), - PLL_RATE(120000000, 40, 1, 3), - PLL_RATE(123000000, 41, 1, 3), - PLL_RATE(126000000, 42, 1, 3), - PLL_RATE(129000000, 43, 1, 3), - PLL_RATE(132000000, 44, 1, 3), - PLL_RATE(135000000, 45, 1, 3), - PLL_RATE(138000000, 46, 1, 3), - PLL_RATE(141000000, 47, 1, 3), - PLL_RATE(144000000, 48, 1, 3), - PLL_RATE(147000000, 49, 1, 3), - PLL_RATE(150000000, 50, 1, 3), - PLL_RATE(153000000, 51, 1, 3), - PLL_RATE(156000000, 52, 1, 3), - PLL_RATE(159000000, 53, 1, 3), - PLL_RATE(162000000, 54, 1, 3), - PLL_RATE(165000000, 55, 1, 3), - PLL_RATE(168000000, 56, 1, 3), - PLL_RATE(171000000, 57, 1, 3), - PLL_RATE(174000000, 58, 1, 3), - PLL_RATE(177000000, 59, 1, 3), - PLL_RATE(180000000, 60, 1, 3), - PLL_RATE(183000000, 61, 1, 3), - PLL_RATE(186000000, 62, 1, 3), - PLL_RATE(192000000, 32, 1, 2), - PLL_RATE(198000000, 33, 1, 2), - PLL_RATE(204000000, 34, 1, 2), - PLL_RATE(210000000, 35, 1, 2), - PLL_RATE(216000000, 36, 1, 2), - PLL_RATE(222000000, 37, 1, 2), - PLL_RATE(228000000, 38, 1, 2), - PLL_RATE(234000000, 39, 1, 2), - PLL_RATE(240000000, 40, 1, 2), - PLL_RATE(246000000, 41, 1, 2), - PLL_RATE(252000000, 42, 1, 2), - PLL_RATE(258000000, 43, 1, 2), - PLL_RATE(264000000, 44, 1, 2), - PLL_RATE(270000000, 45, 1, 2), - PLL_RATE(276000000, 46, 1, 2), - PLL_RATE(282000000, 47, 1, 2), - PLL_RATE(288000000, 48, 1, 2), - PLL_RATE(294000000, 49, 1, 2), - PLL_RATE(300000000, 50, 1, 2), - PLL_RATE(306000000, 51, 1, 2), - PLL_RATE(312000000, 52, 1, 2), - PLL_RATE(318000000, 53, 1, 2), - PLL_RATE(324000000, 54, 1, 2), - PLL_RATE(330000000, 55, 1, 2), - PLL_RATE(336000000, 56, 1, 2), - PLL_RATE(342000000, 57, 1, 2), - PLL_RATE(348000000, 58, 1, 2), - PLL_RATE(354000000, 59, 1, 2), - PLL_RATE(360000000, 60, 1, 2), - PLL_RATE(366000000, 61, 1, 2), - PLL_RATE(372000000, 62, 1, 2), - PLL_RATE(384000000, 32, 1, 1), - PLL_RATE(396000000, 33, 1, 1), - PLL_RATE(408000000, 34, 1, 1), - PLL_RATE(420000000, 35, 1, 1), - PLL_RATE(432000000, 36, 1, 1), - PLL_RATE(444000000, 37, 1, 1), - PLL_RATE(456000000, 38, 1, 1), - PLL_RATE(468000000, 39, 1, 1), - PLL_RATE(480000000, 40, 1, 1), - PLL_RATE(492000000, 41, 1, 1), - PLL_RATE(504000000, 42, 1, 1), - PLL_RATE(516000000, 43, 1, 1), - PLL_RATE(528000000, 44, 1, 1), - PLL_RATE(540000000, 45, 1, 1), - PLL_RATE(552000000, 46, 1, 1), - PLL_RATE(564000000, 47, 1, 1), - PLL_RATE(576000000, 48, 1, 1), - PLL_RATE(588000000, 49, 1, 1), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(612000000, 51, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(636000000, 53, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(660000000, 55, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(684000000, 57, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(708000000, 59, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(732000000, 61, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(768000000, 32, 1, 0), - PLL_RATE(792000000, 33, 1, 0), - PLL_RATE(816000000, 34, 1, 0), - PLL_RATE(840000000, 35, 1, 0), - PLL_RATE(864000000, 36, 1, 0), - PLL_RATE(888000000, 37, 1, 0), - PLL_RATE(912000000, 38, 1, 0), - PLL_RATE(936000000, 39, 1, 0), - PLL_RATE(960000000, 40, 1, 0), - PLL_RATE(984000000, 41, 1, 0), - PLL_RATE(1008000000, 42, 1, 0), - PLL_RATE(1032000000, 43, 1, 0), - PLL_RATE(1056000000, 44, 1, 0), - PLL_RATE(1080000000, 45, 1, 0), - PLL_RATE(1104000000, 46, 1, 0), - PLL_RATE(1128000000, 47, 1, 0), - PLL_RATE(1152000000, 48, 1, 0), - PLL_RATE(1176000000, 49, 1, 0), - PLL_RATE(1200000000, 50, 1, 0), - PLL_RATE(1224000000, 51, 1, 0), - PLL_RATE(1248000000, 52, 1, 0), - PLL_RATE(1272000000, 53, 1, 0), - PLL_RATE(1296000000, 54, 1, 0), - PLL_RATE(1320000000, 55, 1, 0), - PLL_RATE(1344000000, 56, 1, 0), - PLL_RATE(1368000000, 57, 1, 0), - PLL_RATE(1392000000, 58, 1, 0), - PLL_RATE(1416000000, 59, 1, 0), - PLL_RATE(1440000000, 60, 1, 0), - PLL_RATE(1464000000, 61, 1, 0), - PLL_RATE(1488000000, 62, 1, 0), + PLL_RATE(768000000, 32, 1), + PLL_RATE(792000000, 33, 1), + PLL_RATE(816000000, 34, 1), + PLL_RATE(840000000, 35, 1), + PLL_RATE(864000000, 36, 1), + PLL_RATE(888000000, 37, 1), + PLL_RATE(912000000, 38, 1), + PLL_RATE(936000000, 39, 1), + PLL_RATE(960000000, 40, 1), + PLL_RATE(984000000, 41, 1), + PLL_RATE(1008000000, 42, 1), + PLL_RATE(1032000000, 43, 1), + PLL_RATE(1056000000, 44, 1), + PLL_RATE(1080000000, 45, 1), + PLL_RATE(1104000000, 46, 1), + PLL_RATE(1128000000, 47, 1), + PLL_RATE(1152000000, 48, 1), + PLL_RATE(1176000000, 49, 1), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), { /* sentinel */ }, }; static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { - PLL_RATE(504000000, 42, 1, 1), - PLL_RATE(516000000, 43, 1, 1), - PLL_RATE(528000000, 44, 1, 1), - PLL_RATE(540000000, 45, 1, 1), - PLL_RATE(552000000, 46, 1, 1), - PLL_RATE(564000000, 47, 1, 1), - PLL_RATE(576000000, 48, 1, 1), - PLL_RATE(588000000, 49, 1, 1), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(612000000, 51, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(636000000, 53, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(660000000, 55, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(684000000, 57, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(708000000, 59, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(732000000, 61, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(756000000, 63, 1, 1), - PLL_RATE(768000000, 64, 1, 1), - PLL_RATE(780000000, 65, 1, 1), - PLL_RATE(792000000, 66, 1, 1), + PLL_RATE(1008000000, 42, 1), + PLL_RATE(1032000000, 43, 1), + PLL_RATE(1056000000, 44, 1), + PLL_RATE(1080000000, 45, 1), + PLL_RATE(1104000000, 46, 1), + PLL_RATE(1128000000, 47, 1), + PLL_RATE(1152000000, 48, 1), + PLL_RATE(1176000000, 49, 1), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), + PLL_RATE(1512000000, 63, 1), + PLL_RATE(1536000000, 64, 1), + PLL_RATE(1560000000, 65, 1), + PLL_RATE(1584000000, 66, 1), { /* sentinel */ }, }; -static struct clk_regmap gxbb_fixed_pll = { +static struct clk_regmap gxbb_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_MPLL_CNTL, @@ -192,11 +99,6 @@ static struct clk_regmap gxbb_fixed_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_MPLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_MPLL_CNTL2, .shift = 0, @@ -214,13 +116,32 @@ static struct clk_regmap gxbb_fixed_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "fixed_pll", + .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap gxbb_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "fixed_pll_dco" }, + .num_parents = 1, + /* + * This clock won't ever change at runtime so + * CLK_SET_RATE_PARENT is not required + */ + }, +}; + static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { .mult = 2, .div = 1, @@ -232,7 +153,7 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = { }, }; -static struct clk_regmap gxbb_hdmi_pll = { +static struct clk_regmap gxbb_hdmi_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_HDMI_PLL_CNTL, @@ -254,21 +175,6 @@ static struct clk_regmap gxbb_hdmi_pll = { .shift = 0, .width = 12, }, - .od = { - .reg_off = HHI_HDMI_PLL_CNTL2, - .shift = 16, - .width = 2, - }, - .od2 = { - .reg_off = HHI_HDMI_PLL_CNTL2, - .shift = 22, - .width = 2, - }, - .od3 = { - .reg_off = HHI_HDMI_PLL_CNTL2, - .shift = 18, - .width = 2, - }, .l = { .reg_off = HHI_HDMI_PLL_CNTL, .shift = 31, @@ -281,7 +187,7 @@ static struct clk_regmap gxbb_hdmi_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll", + .name = "hdmi_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "hdmi_pll_pre_mult" }, .num_parents = 1, @@ -293,111 +199,151 @@ static struct clk_regmap gxbb_hdmi_pll = { }, }; +static struct clk_regmap gxbb_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL2, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_hdmi_pll_od2 = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL2, + .shift = 22, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od2", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL2, + .shift = 18, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxl_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL + 8, + .shift = 21, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_dco" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxl_hdmi_pll_od2 = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL + 8, + .shift = 23, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od2", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap gxl_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_HDMI_PLL_CNTL + 8, + .shift = 19, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "hdmi_pll_od2" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap gxbb_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { - .reg_off = HHI_HDMI_PLL_CNTL, + .reg_off = HHI_SYS_PLL_CNTL, .shift = 30, .width = 1, }, .m = { - .reg_off = HHI_HDMI_PLL_CNTL, + .reg_off = HHI_SYS_PLL_CNTL, .shift = 0, .width = 9, }, .n = { - .reg_off = HHI_HDMI_PLL_CNTL, + .reg_off = HHI_SYS_PLL_CNTL, .shift = 9, .width = 5, }, - .frac = { - /* - * On gxl, there is a register shift due to - * HHI_HDMI_PLL_CNTL1 which does not exist on gxbb, - * so we compute the register offset based on the PLL - * base to get it right - */ - .reg_off = HHI_HDMI_PLL_CNTL + 4, - .shift = 0, - .width = 12, - }, - .od = { - .reg_off = HHI_HDMI_PLL_CNTL + 8, - .shift = 21, - .width = 2, - }, - .od2 = { - .reg_off = HHI_HDMI_PLL_CNTL + 8, - .shift = 23, - .width = 2, - }, - .od3 = { - .reg_off = HHI_HDMI_PLL_CNTL + 8, - .shift = 19, - .width = 2, - }, .l = { - .reg_off = HHI_HDMI_PLL_CNTL, + .reg_off = HHI_SYS_PLL_CNTL, .shift = 31, .width = 1, }, .rst = { - .reg_off = HHI_HDMI_PLL_CNTL, + .reg_off = HHI_SYS_PLL_CNTL, .shift = 29, .width = 1, }, }, .hw.init = &(struct clk_init_data){ - .name = "hdmi_pll", + .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, - /* - * Display directly handle hdmi pll registers ATM, we need - * NOCACHE to keep our view of the clock as accurate as possible - */ - .flags = CLK_GET_RATE_NOCACHE, }, }; static struct clk_regmap gxbb_sys_pll = { - .data = &(struct meson_clk_pll_data){ - .en = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 30, - .width = 1, - }, - .m = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 0, - .width = 9, - }, - .n = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 9, - .width = 5, - }, - .od = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 10, - .width = 2, - }, - .l = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 31, - .width = 1, - }, - .rst = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 29, - .width = 1, - }, + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_PLL_CNTL, + .shift = 10, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, }, .hw.init = &(struct clk_init_data){ .name = "sys_pll", - .ops = &meson_clk_pll_ro_ops, - .parent_names = (const char *[]){ "xtal" }, + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys_pll_dco" }, .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, }, }; @@ -407,7 +353,7 @@ static const struct reg_sequence gxbb_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL4, .def = 0x0000500d }, }; -static struct clk_regmap gxbb_gp0_pll = { +static struct clk_regmap gxbb_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_GP0_PLL_CNTL, @@ -424,11 +370,6 @@ static struct clk_regmap gxbb_gp0_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_GP0_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_GP0_PLL_CNTL, .shift = 31, @@ -444,7 +385,7 @@ static struct clk_regmap gxbb_gp0_pll = { .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", + .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, @@ -459,7 +400,7 @@ static const struct reg_sequence gxl_gp0_init_regs[] = { { .reg = HHI_GP0_PLL_CNTL5, .def = 0x00078000 }, }; -static struct clk_regmap gxl_gp0_pll = { +static struct clk_regmap gxl_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_GP0_PLL_CNTL, @@ -476,11 +417,6 @@ static struct clk_regmap gxl_gp0_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_GP0_PLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_GP0_PLL_CNTL1, .shift = 0, @@ -501,13 +437,29 @@ static struct clk_regmap gxl_gp0_pll = { .init_count = ARRAY_SIZE(gxl_gp0_init_regs), }, .hw.init = &(struct clk_init_data){ - .name = "gp0_pll", + .name = "gp0_pll_dco", .ops = &meson_clk_pll_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap gxbb_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_GP0_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]){ "gp0_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_fixed_factor gxbb_fclk_div2_div = { .mult = 1, .div = 2, @@ -1965,6 +1917,12 @@ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, + [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, + [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &gxbb_hdmi_pll_od.hw, + [CLKID_HDMI_PLL_OD2] = &gxbb_hdmi_pll_od2.hw, + [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &gxbb_gp0_pll_dco.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -1980,7 +1938,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_FCLK_DIV4] = &gxbb_fclk_div4.hw, [CLKID_FCLK_DIV5] = &gxbb_fclk_div5.hw, [CLKID_FCLK_DIV7] = &gxbb_fclk_div7.hw, - [CLKID_GP0_PLL] = &gxl_gp0_pll.hw, + [CLKID_GP0_PLL] = &gxbb_gp0_pll.hw, [CLKID_MPEG_SEL] = &gxbb_mpeg_clk_sel.hw, [CLKID_MPEG_DIV] = &gxbb_mpeg_clk_div.hw, [CLKID_CLK81] = &gxbb_clk81.hw, @@ -2130,19 +2088,29 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, + [CLKID_FIXED_PLL_DCO] = &gxbb_fixed_pll_dco.hw, + [CLKID_HDMI_PLL_DCO] = &gxbb_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &gxl_hdmi_pll_od.hw, + [CLKID_HDMI_PLL_OD2] = &gxl_hdmi_pll_od2.hw, + [CLKID_SYS_PLL_DCO] = &gxbb_sys_pll_dco.hw, + [CLKID_GP0_PLL_DCO] = &gxl_gp0_pll_dco.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, }; static struct clk_regmap *const gxbb_clk_regmaps[] = { - &gxbb_gp0_pll, + &gxbb_gp0_pll_dco, &gxbb_hdmi_pll, + &gxbb_hdmi_pll_od, + &gxbb_hdmi_pll_od2, }; static struct clk_regmap *const gxl_clk_regmaps[] = { - &gxl_gp0_pll, + &gxl_gp0_pll_dco, &gxl_hdmi_pll, + &gxl_hdmi_pll_od, + &gxl_hdmi_pll_od2, }; static struct clk_regmap *const gx_clk_regmaps[] = { @@ -2297,6 +2265,10 @@ static struct clk_regmap *const gx_clk_regmaps[] = { &gxbb_gen_clk_sel, &gxbb_gen_clk_div, &gxbb_gen_clk, + &gxbb_fixed_pll_dco, + &gxbb_hdmi_pll_dco, + &gxbb_sys_pll_dco, + &gxbb_gp0_pll, }; struct clkc_data { diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index 20dfb1daf5b8..72bc077d9663 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -159,8 +159,14 @@ #define CLKID_VDEC_HEVC_DIV 155 #define CLKID_GEN_CLK_SEL 157 #define CLKID_GEN_CLK_DIV 158 +#define CLKID_FIXED_PLL_DCO 160 +#define CLKID_HDMI_PLL_DCO 161 +#define CLKID_HDMI_PLL_OD 162 +#define CLKID_HDMI_PLL_OD2 163 +#define CLKID_SYS_PLL_DCO 164 +#define CLKID_GP0_PLL_DCO 165 -#define NR_CLKS 160 +#define NR_CLKS 166 /* include the CLKIDs that have been made part of the DT binding */ #include diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index ec1f97725b9f..4c061c1d3683 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -30,58 +30,21 @@ struct meson8b_clk_reset { }; static const struct pll_rate_table sys_pll_rate_table[] = { - PLL_RATE(312000000, 52, 1, 2), - PLL_RATE(336000000, 56, 1, 2), - PLL_RATE(360000000, 60, 1, 2), - PLL_RATE(384000000, 64, 1, 2), - PLL_RATE(408000000, 68, 1, 2), - PLL_RATE(432000000, 72, 1, 2), - PLL_RATE(456000000, 76, 1, 2), - PLL_RATE(480000000, 80, 1, 2), - PLL_RATE(504000000, 84, 1, 2), - PLL_RATE(528000000, 88, 1, 2), - PLL_RATE(552000000, 92, 1, 2), - PLL_RATE(576000000, 96, 1, 2), - PLL_RATE(600000000, 50, 1, 1), - PLL_RATE(624000000, 52, 1, 1), - PLL_RATE(648000000, 54, 1, 1), - PLL_RATE(672000000, 56, 1, 1), - PLL_RATE(696000000, 58, 1, 1), - PLL_RATE(720000000, 60, 1, 1), - PLL_RATE(744000000, 62, 1, 1), - PLL_RATE(768000000, 64, 1, 1), - PLL_RATE(792000000, 66, 1, 1), - PLL_RATE(816000000, 68, 1, 1), - PLL_RATE(840000000, 70, 1, 1), - PLL_RATE(864000000, 72, 1, 1), - PLL_RATE(888000000, 74, 1, 1), - PLL_RATE(912000000, 76, 1, 1), - PLL_RATE(936000000, 78, 1, 1), - PLL_RATE(960000000, 80, 1, 1), - PLL_RATE(984000000, 82, 1, 1), - PLL_RATE(1008000000, 84, 1, 1), - PLL_RATE(1032000000, 86, 1, 1), - PLL_RATE(1056000000, 88, 1, 1), - PLL_RATE(1080000000, 90, 1, 1), - PLL_RATE(1104000000, 92, 1, 1), - PLL_RATE(1128000000, 94, 1, 1), - PLL_RATE(1152000000, 96, 1, 1), - PLL_RATE(1176000000, 98, 1, 1), - PLL_RATE(1200000000, 50, 1, 0), - PLL_RATE(1224000000, 51, 1, 0), - PLL_RATE(1248000000, 52, 1, 0), - PLL_RATE(1272000000, 53, 1, 0), - PLL_RATE(1296000000, 54, 1, 0), - PLL_RATE(1320000000, 55, 1, 0), - PLL_RATE(1344000000, 56, 1, 0), - PLL_RATE(1368000000, 57, 1, 0), - PLL_RATE(1392000000, 58, 1, 0), - PLL_RATE(1416000000, 59, 1, 0), - PLL_RATE(1440000000, 60, 1, 0), - PLL_RATE(1464000000, 61, 1, 0), - PLL_RATE(1488000000, 62, 1, 0), - PLL_RATE(1512000000, 63, 1, 0), - PLL_RATE(1536000000, 64, 1, 0), + PLL_RATE(1200000000, 50, 1), + PLL_RATE(1224000000, 51, 1), + PLL_RATE(1248000000, 52, 1), + PLL_RATE(1272000000, 53, 1), + PLL_RATE(1296000000, 54, 1), + PLL_RATE(1320000000, 55, 1), + PLL_RATE(1344000000, 56, 1), + PLL_RATE(1368000000, 57, 1), + PLL_RATE(1392000000, 58, 1), + PLL_RATE(1416000000, 59, 1), + PLL_RATE(1440000000, 60, 1), + PLL_RATE(1464000000, 61, 1), + PLL_RATE(1488000000, 62, 1), + PLL_RATE(1512000000, 63, 1), + PLL_RATE(1536000000, 64, 1), { /* sentinel */ }, }; @@ -94,7 +57,7 @@ static struct clk_fixed_rate meson8b_xtal = { }, }; -static struct clk_regmap meson8b_fixed_pll = { +static struct clk_regmap meson8b_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_MPLL_CNTL, @@ -111,11 +74,6 @@ static struct clk_regmap meson8b_fixed_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_MPLL_CNTL, - .shift = 16, - .width = 2, - }, .frac = { .reg_off = HHI_MPLL_CNTL2, .shift = 0, @@ -133,14 +91,33 @@ static struct clk_regmap meson8b_fixed_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "fixed_pll", + .name = "fixed_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; -static struct clk_regmap meson8b_vid_pll = { +static struct clk_regmap meson8b_fixed_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "fixed_pll_dco" }, + .num_parents = 1, + /* + * This clock won't ever change at runtime so + * CLK_SET_RATE_PARENT is not required + */ + }, +}; + +static struct clk_regmap meson8b_vid_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_VID_PLL_CNTL, @@ -157,11 +134,6 @@ static struct clk_regmap meson8b_vid_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_VID_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_VID_PLL_CNTL, .shift = 31, @@ -174,14 +146,30 @@ static struct clk_regmap meson8b_vid_pll = { }, }, .hw.init = &(struct clk_init_data){ - .name = "vid_pll", + .name = "vid_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; -static struct clk_regmap meson8b_sys_pll = { +static struct clk_regmap meson8b_vid_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_VID_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "vid_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "vid_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap meson8b_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { .reg_off = HHI_SYS_PLL_CNTL, @@ -198,11 +186,6 @@ static struct clk_regmap meson8b_sys_pll = { .shift = 9, .width = 5, }, - .od = { - .reg_off = HHI_SYS_PLL_CNTL, - .shift = 16, - .width = 2, - }, .l = { .reg_off = HHI_SYS_PLL_CNTL, .shift = 31, @@ -216,13 +199,29 @@ static struct clk_regmap meson8b_sys_pll = { .table = sys_pll_rate_table, }, .hw.init = &(struct clk_init_data){ - .name = "sys_pll", + .name = "sys_pll_dco", .ops = &meson_clk_pll_ro_ops, .parent_names = (const char *[]){ "xtal" }, .num_parents = 1, }, }; +static struct clk_regmap meson8b_sys_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SYS_PLL_CNTL, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &clk_regmap_divider_ro_ops, + .parent_names = (const char *[]){ "sys_pll_dco" }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_fixed_factor meson8b_fclk_div2_div = { .mult = 1, .div = 2, @@ -891,6 +890,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { [CLKID_NAND_SEL] = &meson8b_nand_clk_sel.hw, [CLKID_NAND_DIV] = &meson8b_nand_clk_div.hw, [CLKID_NAND_CLK] = &meson8b_nand_clk_gate.hw, + [CLKID_PLL_FIXED_DCO] = &meson8b_fixed_pll_dco.hw, + [CLKID_PLL_VID_DCO] = &meson8b_vid_pll_dco.hw, + [CLKID_PLL_SYS_DCO] = &meson8b_sys_pll_dco.hw, [CLK_NR_CLKS] = NULL, }, .num = CLK_NR_CLKS, @@ -999,6 +1001,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = { &meson8b_nand_clk_sel, &meson8b_nand_clk_div, &meson8b_nand_clk_gate, + &meson8b_fixed_pll_dco, + &meson8b_vid_pll_dco, + &meson8b_sys_pll_dco, }; static const struct meson8b_clk_reset_line { diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h index 5d09412b5084..1c6fb180e6a2 100644 --- a/drivers/clk/meson/meson8b.h +++ b/drivers/clk/meson/meson8b.h @@ -75,8 +75,11 @@ #define CLKID_FCLK_DIV7_DIV 109 #define CLKID_NAND_SEL 110 #define CLKID_NAND_DIV 111 +#define CLKID_PLL_FIXED_DCO 113 +#define CLKID_PLL_VID_DCO 114 +#define CLKID_PLL_SYS_DCO 115 -#define CLK_NR_CLKS 113 +#define CLK_NR_CLKS 116 /* * include the CLKID and RESETID that have From dd601dbc011e4eeda9e4c8c19ffe5b2fb33223dc Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 1 Aug 2018 16:00:53 +0200 Subject: [PATCH 092/836] clk: meson: clk-pll: drop hard-coded rates from pll tables Putting hard-coded rates inside the parameter tables assumes that the parent is known and will never change. That's a big assumption we should not make. We have everything we need to recalculate the output rate using the parent rate and the rest of the parameters. Let's do so and drop the rates from the tables. Acked-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Tested-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 73 +++++++++++----------- drivers/clk/meson/clk-pll.c | 69 ++++++++++++++------- drivers/clk/meson/clkc.h | 8 +-- drivers/clk/meson/gxbb.c | 120 ++++++++++++++++++------------------ drivers/clk/meson/meson8b.c | 34 +++++----- 5 files changed, 162 insertions(+), 142 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index a5e4f7b22f39..7511b3e26d40 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -134,36 +134,36 @@ static struct clk_regmap axg_sys_pll = { }, }; -static const struct pll_rate_table axg_gp0_pll_rate_table[] = { - PLL_RATE(960000000, 40, 1), - PLL_RATE(984000000, 41, 1), - PLL_RATE(1008000000, 42, 1), - PLL_RATE(1032000000, 43, 1), - PLL_RATE(1056000000, 44, 1), - PLL_RATE(1080000000, 45, 1), - PLL_RATE(1104000000, 46, 1), - PLL_RATE(1128000000, 47, 1), - PLL_RATE(1152000000, 48, 1), - PLL_RATE(1176000000, 49, 1), - PLL_RATE(1200000000, 50, 1), - PLL_RATE(1224000000, 51, 1), - PLL_RATE(1248000000, 52, 1), - PLL_RATE(1272000000, 53, 1), - PLL_RATE(1296000000, 54, 1), - PLL_RATE(1320000000, 55, 1), - PLL_RATE(1344000000, 56, 1), - PLL_RATE(1368000000, 57, 1), - PLL_RATE(1392000000, 58, 1), - PLL_RATE(1416000000, 59, 1), - PLL_RATE(1440000000, 60, 1), - PLL_RATE(1464000000, 61, 1), - PLL_RATE(1488000000, 62, 1), - PLL_RATE(1512000000, 63, 1), - PLL_RATE(1536000000, 64, 1), - PLL_RATE(1560000000, 65, 1), - PLL_RATE(1584000000, 66, 1), - PLL_RATE(1608000000, 67, 1), - PLL_RATE(1632000000, 68, 1), +static const struct pll_params_table axg_gp0_pll_params_table[] = { + PLL_PARAMS(40, 1), + PLL_PARAMS(41, 1), + PLL_PARAMS(42, 1), + PLL_PARAMS(43, 1), + PLL_PARAMS(44, 1), + PLL_PARAMS(45, 1), + PLL_PARAMS(46, 1), + PLL_PARAMS(47, 1), + PLL_PARAMS(48, 1), + PLL_PARAMS(49, 1), + PLL_PARAMS(50, 1), + PLL_PARAMS(51, 1), + PLL_PARAMS(52, 1), + PLL_PARAMS(53, 1), + PLL_PARAMS(54, 1), + PLL_PARAMS(55, 1), + PLL_PARAMS(56, 1), + PLL_PARAMS(57, 1), + PLL_PARAMS(58, 1), + PLL_PARAMS(59, 1), + PLL_PARAMS(60, 1), + PLL_PARAMS(61, 1), + PLL_PARAMS(62, 1), + PLL_PARAMS(63, 1), + PLL_PARAMS(64, 1), + PLL_PARAMS(65, 1), + PLL_PARAMS(66, 1), + PLL_PARAMS(67, 1), + PLL_PARAMS(68, 1), { /* sentinel */ }, }; @@ -207,7 +207,7 @@ static struct clk_regmap axg_gp0_pll_dco = { .shift = 29, .width = 1, }, - .table = axg_gp0_pll_rate_table, + .table = axg_gp0_pll_params_table, .init_regs = axg_gp0_init_regs, .init_count = ARRAY_SIZE(axg_gp0_init_regs), }, @@ -275,7 +275,7 @@ static struct clk_regmap axg_hifi_pll_dco = { .shift = 29, .width = 1, }, - .table = axg_gp0_pll_rate_table, + .table = axg_gp0_pll_params_table, .init_regs = axg_hifi_init_regs, .init_count = ARRAY_SIZE(axg_hifi_init_regs), .flags = CLK_MESON_PLL_ROUND_CLOSEST, @@ -631,11 +631,10 @@ static struct clk_regmap axg_mpll3 = { }, }; -static const struct pll_rate_table axg_pcie_pll_rate_table[] = { +static const struct pll_params_table axg_pcie_pll_params_table[] = { { - .rate = 1600000000, - .m = 200, - .n = 3, + .m = 200, + .n = 3, }, { /* sentinel */ }, }; @@ -682,7 +681,7 @@ static struct clk_regmap axg_pcie_pll_dco = { .shift = 29, .width = 1, }, - .table = axg_pcie_pll_rate_table, + .table = axg_pcie_pll_params_table, .init_regs = axg_pcie_init_regs, .init_count = ARRAY_SIZE(axg_pcie_init_regs), }, diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 348a866f09eb..f5b5b3fabe3c 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -45,7 +45,7 @@ meson_clk_pll_data(struct clk_regmap *clk) } static unsigned long __pll_params_to_rate(unsigned long parent_rate, - const struct pll_rate_table *pllt, + const struct pll_params_table *pllt, u16 frac, struct meson_clk_pll_data *pll) { @@ -66,7 +66,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); - struct pll_rate_table pllt; + struct pll_params_table pllt; u16 frac; pllt.n = meson_parm_read(clk->map, &pll->n); @@ -81,7 +81,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw, static u16 __pll_params_with_frac(unsigned long rate, unsigned long parent_rate, - const struct pll_rate_table *pllt, + const struct pll_params_table *pllt, struct meson_clk_pll_data *pll) { u16 frac_max = (1 << pll->frac.width); @@ -97,29 +97,50 @@ static u16 __pll_params_with_frac(unsigned long rate, return min((u16)val, (u16)(frac_max - 1)); } -static const struct pll_rate_table * +static bool meson_clk_pll_is_better(unsigned long rate, + unsigned long best, + unsigned long now, + struct meson_clk_pll_data *pll) +{ + if (!(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) || + MESON_PARM_APPLICABLE(&pll->frac)) { + /* Round down */ + if (now < rate && best < now) + return true; + } else { + /* Round Closest */ + if (abs(now - rate) < abs(best - rate)) + return true; + } + + return false; +} + +static const struct pll_params_table * meson_clk_get_pll_settings(unsigned long rate, + unsigned long parent_rate, struct meson_clk_pll_data *pll) { - const struct pll_rate_table *table = pll->table; - unsigned int i = 0; + const struct pll_params_table *table = pll->table; + unsigned long best = 0, now = 0; + unsigned int i, best_i = 0; if (!table) return NULL; - /* Find the first table element exceeding rate */ - while (table[i].rate && table[i].rate <= rate) - i++; + for (i = 0; table[i].n; i++) { + now = __pll_params_to_rate(parent_rate, &table[i], 0, pll); - if (i != 0) { - if (MESON_PARM_APPLICABLE(&pll->frac) || - !(pll->flags & CLK_MESON_PLL_ROUND_CLOSEST) || - (abs(rate - table[i - 1].rate) < - abs(rate - table[i].rate))) - i--; + /* If we get an exact match, don't bother any further */ + if (now == rate) { + return &table[i]; + } else if (meson_clk_pll_is_better(rate, best, now, pll)) { + best = now; + best_i = i; + } } - return (struct pll_rate_table *)&table[i]; + return (struct pll_params_table *)&table[best_i]; } static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, @@ -127,16 +148,18 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); - const struct pll_rate_table *pllt = - meson_clk_get_pll_settings(rate, pll); + const struct pll_params_table *pllt = + meson_clk_get_pll_settings(rate, *parent_rate, pll); + unsigned long round; u16 frac; if (!pllt) return meson_clk_pll_recalc_rate(hw, *parent_rate); - if (!MESON_PARM_APPLICABLE(&pll->frac) - || rate == pllt->rate) - return pllt->rate; + round = __pll_params_to_rate(*parent_rate, pllt, 0, pll); + + if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round) + return round; /* * The rate provided by the setting is not an exact match, let's @@ -214,7 +237,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); - const struct pll_rate_table *pllt; + const struct pll_params_table *pllt; unsigned int enabled; unsigned long old_rate; u16 frac = 0; @@ -224,7 +247,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, old_rate = rate; - pllt = meson_clk_get_pll_settings(rate, pll); + pllt = meson_clk_get_pll_settings(rate, parent_rate, pll); if (!pllt) return -EINVAL; diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index a2245e857f70..6b96d55c047d 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -43,15 +43,13 @@ static inline void meson_parm_write(struct regmap *map, struct parm *p, } -struct pll_rate_table { - unsigned long rate; +struct pll_params_table { u16 m; u16 n; }; -#define PLL_RATE(_r, _m, _n) \ +#define PLL_PARAMS(_m, _n) \ { \ - .rate = (_r), \ .m = (_m), \ .n = (_n), \ } @@ -67,7 +65,7 @@ struct meson_clk_pll_data { struct parm rst; const struct reg_sequence *init_regs; unsigned int init_count; - const struct pll_rate_table *table; + const struct pll_params_table *table; u8 flags; }; diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index af59f2607dc1..9309cfaaa464 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -18,67 +18,67 @@ static DEFINE_SPINLOCK(meson_clk_lock); -static const struct pll_rate_table gxbb_gp0_pll_rate_table[] = { - PLL_RATE(768000000, 32, 1), - PLL_RATE(792000000, 33, 1), - PLL_RATE(816000000, 34, 1), - PLL_RATE(840000000, 35, 1), - PLL_RATE(864000000, 36, 1), - PLL_RATE(888000000, 37, 1), - PLL_RATE(912000000, 38, 1), - PLL_RATE(936000000, 39, 1), - PLL_RATE(960000000, 40, 1), - PLL_RATE(984000000, 41, 1), - PLL_RATE(1008000000, 42, 1), - PLL_RATE(1032000000, 43, 1), - PLL_RATE(1056000000, 44, 1), - PLL_RATE(1080000000, 45, 1), - PLL_RATE(1104000000, 46, 1), - PLL_RATE(1128000000, 47, 1), - PLL_RATE(1152000000, 48, 1), - PLL_RATE(1176000000, 49, 1), - PLL_RATE(1200000000, 50, 1), - PLL_RATE(1224000000, 51, 1), - PLL_RATE(1248000000, 52, 1), - PLL_RATE(1272000000, 53, 1), - PLL_RATE(1296000000, 54, 1), - PLL_RATE(1320000000, 55, 1), - PLL_RATE(1344000000, 56, 1), - PLL_RATE(1368000000, 57, 1), - PLL_RATE(1392000000, 58, 1), - PLL_RATE(1416000000, 59, 1), - PLL_RATE(1440000000, 60, 1), - PLL_RATE(1464000000, 61, 1), - PLL_RATE(1488000000, 62, 1), +static const struct pll_params_table gxbb_gp0_pll_params_table[] = { + PLL_PARAMS(32, 1), + PLL_PARAMS(33, 1), + PLL_PARAMS(34, 1), + PLL_PARAMS(35, 1), + PLL_PARAMS(36, 1), + PLL_PARAMS(37, 1), + PLL_PARAMS(38, 1), + PLL_PARAMS(39, 1), + PLL_PARAMS(40, 1), + PLL_PARAMS(41, 1), + PLL_PARAMS(42, 1), + PLL_PARAMS(43, 1), + PLL_PARAMS(44, 1), + PLL_PARAMS(45, 1), + PLL_PARAMS(46, 1), + PLL_PARAMS(47, 1), + PLL_PARAMS(48, 1), + PLL_PARAMS(49, 1), + PLL_PARAMS(50, 1), + PLL_PARAMS(51, 1), + PLL_PARAMS(52, 1), + PLL_PARAMS(53, 1), + PLL_PARAMS(54, 1), + PLL_PARAMS(55, 1), + PLL_PARAMS(56, 1), + PLL_PARAMS(57, 1), + PLL_PARAMS(58, 1), + PLL_PARAMS(59, 1), + PLL_PARAMS(60, 1), + PLL_PARAMS(61, 1), + PLL_PARAMS(62, 1), { /* sentinel */ }, }; -static const struct pll_rate_table gxl_gp0_pll_rate_table[] = { - PLL_RATE(1008000000, 42, 1), - PLL_RATE(1032000000, 43, 1), - PLL_RATE(1056000000, 44, 1), - PLL_RATE(1080000000, 45, 1), - PLL_RATE(1104000000, 46, 1), - PLL_RATE(1128000000, 47, 1), - PLL_RATE(1152000000, 48, 1), - PLL_RATE(1176000000, 49, 1), - PLL_RATE(1200000000, 50, 1), - PLL_RATE(1224000000, 51, 1), - PLL_RATE(1248000000, 52, 1), - PLL_RATE(1272000000, 53, 1), - PLL_RATE(1296000000, 54, 1), - PLL_RATE(1320000000, 55, 1), - PLL_RATE(1344000000, 56, 1), - PLL_RATE(1368000000, 57, 1), - PLL_RATE(1392000000, 58, 1), - PLL_RATE(1416000000, 59, 1), - PLL_RATE(1440000000, 60, 1), - PLL_RATE(1464000000, 61, 1), - PLL_RATE(1488000000, 62, 1), - PLL_RATE(1512000000, 63, 1), - PLL_RATE(1536000000, 64, 1), - PLL_RATE(1560000000, 65, 1), - PLL_RATE(1584000000, 66, 1), +static const struct pll_params_table gxl_gp0_pll_params_table[] = { + PLL_PARAMS(42, 1), + PLL_PARAMS(43, 1), + PLL_PARAMS(44, 1), + PLL_PARAMS(45, 1), + PLL_PARAMS(46, 1), + PLL_PARAMS(47, 1), + PLL_PARAMS(48, 1), + PLL_PARAMS(49, 1), + PLL_PARAMS(50, 1), + PLL_PARAMS(51, 1), + PLL_PARAMS(52, 1), + PLL_PARAMS(53, 1), + PLL_PARAMS(54, 1), + PLL_PARAMS(55, 1), + PLL_PARAMS(56, 1), + PLL_PARAMS(57, 1), + PLL_PARAMS(58, 1), + PLL_PARAMS(59, 1), + PLL_PARAMS(60, 1), + PLL_PARAMS(61, 1), + PLL_PARAMS(62, 1), + PLL_PARAMS(63, 1), + PLL_PARAMS(64, 1), + PLL_PARAMS(65, 1), + PLL_PARAMS(66, 1), { /* sentinel */ }, }; @@ -380,7 +380,7 @@ static struct clk_regmap gxbb_gp0_pll_dco = { .shift = 29, .width = 1, }, - .table = gxbb_gp0_pll_rate_table, + .table = gxbb_gp0_pll_params_table, .init_regs = gxbb_gp0_init_regs, .init_count = ARRAY_SIZE(gxbb_gp0_init_regs), }, @@ -432,7 +432,7 @@ static struct clk_regmap gxl_gp0_pll_dco = { .shift = 29, .width = 1, }, - .table = gxl_gp0_pll_rate_table, + .table = gxl_gp0_pll_params_table, .init_regs = gxl_gp0_init_regs, .init_count = ARRAY_SIZE(gxl_gp0_init_regs), }, diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 4c061c1d3683..978485146ec3 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -29,22 +29,22 @@ struct meson8b_clk_reset { void __iomem *base; }; -static const struct pll_rate_table sys_pll_rate_table[] = { - PLL_RATE(1200000000, 50, 1), - PLL_RATE(1224000000, 51, 1), - PLL_RATE(1248000000, 52, 1), - PLL_RATE(1272000000, 53, 1), - PLL_RATE(1296000000, 54, 1), - PLL_RATE(1320000000, 55, 1), - PLL_RATE(1344000000, 56, 1), - PLL_RATE(1368000000, 57, 1), - PLL_RATE(1392000000, 58, 1), - PLL_RATE(1416000000, 59, 1), - PLL_RATE(1440000000, 60, 1), - PLL_RATE(1464000000, 61, 1), - PLL_RATE(1488000000, 62, 1), - PLL_RATE(1512000000, 63, 1), - PLL_RATE(1536000000, 64, 1), +static const struct pll_params_table sys_pll_params_table[] = { + PLL_PARAMS(50, 1), + PLL_PARAMS(51, 1), + PLL_PARAMS(52, 1), + PLL_PARAMS(53, 1), + PLL_PARAMS(54, 1), + PLL_PARAMS(55, 1), + PLL_PARAMS(56, 1), + PLL_PARAMS(57, 1), + PLL_PARAMS(58, 1), + PLL_PARAMS(59, 1), + PLL_PARAMS(60, 1), + PLL_PARAMS(61, 1), + PLL_PARAMS(62, 1), + PLL_PARAMS(63, 1), + PLL_PARAMS(64, 1), { /* sentinel */ }, }; @@ -196,7 +196,7 @@ static struct clk_regmap meson8b_sys_pll_dco = { .shift = 29, .width = 1, }, - .table = sys_pll_rate_table, + .table = sys_pll_params_table, }, .hw.init = &(struct clk_init_data){ .name = "sys_pll_dco", From 56dbabc0ff733ab0828e9567c886933fe77fa087 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Wed, 1 Aug 2018 16:07:32 +0200 Subject: [PATCH 093/836] clk: meson: axg: round audio system master clocks down Some of the master clocks provided by the axg audio clock controller are system clock (spdifin and pdm sysclk). They are used to clock an internal DSP of the related devices. Having them constantly rounded down instead of closest is preferable. Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg-audio.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index a0ed41e73bde..5f6c860aa122 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -101,10 +101,16 @@ static const char * const mst_mux_parent_names[] = { "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7", }; -#define AXG_MST_MCLK_MUX(_name, _reg) \ - AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, CLK_MUX_ROUND_CLOSEST, \ +#define AXG_MST_MUX(_name, _reg, _flag) \ + AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \ mst_mux_parent_names, CLK_SET_RATE_PARENT) +#define AXG_MST_MCLK_MUX(_name, _reg) \ + AXG_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST) + +#define AXG_MST_SYS_MUX(_name, _reg) \ + AXG_MST_MUX(_name, _reg, 0) + static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); @@ -112,13 +118,19 @@ static AXG_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AXG_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AXG_MST_MCLK_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static AXG_MST_SYS_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static AXG_MST_SYS_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -#define AXG_MST_MCLK_DIV(_name, _reg) \ - AXG_AUD_DIV(_name##_div, _reg, 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \ - "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ +#define AXG_MST_DIV(_name, _reg, _flag) \ + AXG_AUD_DIV(_name##_div, _reg, 0, 16, _flag, \ + "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ + +#define AXG_MST_MCLK_DIV(_name, _reg) \ + AXG_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST) + +#define AXG_MST_SYS_DIV(_name, _reg) \ + AXG_MST_DIV(_name, _reg, 0) static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); @@ -127,12 +139,12 @@ static AXG_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); -static AXG_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); -static AXG_MST_MCLK_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); +static AXG_MST_SYS_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); +static AXG_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); -#define AXG_MST_MCLK_GATE(_name, _reg) \ - AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ +#define AXG_MST_MCLK_GATE(_name, _reg) \ + AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ CLK_SET_RATE_PARENT) static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); From 69b93104c7ec5668019caf5d2dbfd0e182df06db Mon Sep 17 00:00:00 2001 From: Yixun Lan Date: Wed, 1 Aug 2018 12:16:24 +0000 Subject: [PATCH 094/836] clk: meson-axg: pcie: drop the mpll3 clock parent We found the PCIe driver doesn't really work with the mpll3 clock which is actually reserved for debug, So drop it from the mux list. Fixes: 33b89db68236 ("clk: meson-axg: add clocks required by pcie driver") Tested-by: Jianxin Qin Signed-off-by: Yixun Lan Signed-off-by: Jerome Brunet --- drivers/clk/meson/axg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c index 7511b3e26d40..c981159b02c0 100644 --- a/drivers/clk/meson/axg.c +++ b/drivers/clk/meson/axg.c @@ -730,12 +730,14 @@ static struct clk_regmap axg_pcie_mux = { .offset = HHI_PCIE_PLL_CNTL6, .mask = 0x1, .shift = 2, + /* skip the parent mpll3, reserved for debug */ + .table = (u32[]){ 1 }, }, .hw.init = &(struct clk_init_data){ .name = "pcie_mux", .ops = &clk_regmap_mux_ops, - .parent_names = (const char *[]){ "mpll3", "pcie_pll" }, - .num_parents = 2, + .parent_names = (const char *[]){ "pcie_pll" }, + .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, }; From 6291b8c5ac67d0f1121d8dfd83a82c83272e3499 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 21 Jul 2018 21:13:59 +0200 Subject: [PATCH 095/836] clk: meson: meson8b: register the clock controller early Until now only the reset controller (part of the clock controller register space) was registered early in the boot process, while the clock controller itself was registered later on. However, some parts of the SoC are initialized early in the boot process, such as the SRAM and the TWD timer. The bootloader already enables these clocks so we didn't see any issues so far. Register the clock controller early so other drivers (such as the SRAM and TWD timer) can use the clocks early in the boot process. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 94 ++++++++++++++----------------------- 1 file changed, 34 insertions(+), 60 deletions(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 978485146ec3..2a31d6eeef37 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -22,8 +21,6 @@ static DEFINE_SPINLOCK(meson_clk_lock); -static void __iomem *clk_base; - struct meson8b_clk_reset { struct reset_controller_dev reset; void __iomem *base; @@ -1111,62 +1108,12 @@ static const struct regmap_config clkc_regmap_config = { .reg_stride = 4, }; -static int meson8b_clkc_probe(struct platform_device *pdev) -{ - int ret, i; - struct device *dev = &pdev->dev; - struct regmap *map; - - if (!clk_base) - return -ENXIO; - - map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config); - if (IS_ERR(map)) - return PTR_ERR(map); - - /* Populate regmap for the regmap backed clocks */ - for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++) - meson8b_clk_regmaps[i]->map = map; - - /* - * register all clks - * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 - */ - for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { - /* array might be sparse */ - if (!meson8b_hw_onecell_data.hws[i]) - continue; - - ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]); - if (ret) - return ret; - } - - return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, - &meson8b_hw_onecell_data); -} - -static const struct of_device_id meson8b_clkc_match_table[] = { - { .compatible = "amlogic,meson8-clkc" }, - { .compatible = "amlogic,meson8b-clkc" }, - { .compatible = "amlogic,meson8m2-clkc" }, - { } -}; - -static struct platform_driver meson8b_driver = { - .probe = meson8b_clkc_probe, - .driver = { - .name = "meson8b-clkc", - .of_match_table = meson8b_clkc_match_table, - }, -}; - -builtin_platform_driver(meson8b_driver); - -static void __init meson8b_clkc_reset_init(struct device_node *np) +static void __init meson8b_clkc_init(struct device_node *np) { struct meson8b_clk_reset *rstc; - int ret; + void __iomem *clk_base; + struct regmap *map; + int i, ret; /* Generic clocks, PLLs and some of the reset-bits */ clk_base = of_iomap(np, 1); @@ -1175,6 +1122,10 @@ static void __init meson8b_clkc_reset_init(struct device_node *np) return; } + map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config); + if (IS_ERR(map)) + return; + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); if (!rstc) return; @@ -1190,11 +1141,34 @@ static void __init meson8b_clkc_reset_init(struct device_node *np) __func__, ret); return; } + + /* Populate regmap for the regmap backed clocks */ + for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++) + meson8b_clk_regmaps[i]->map = map; + + /* + * register all clks + * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1 + */ + for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) { + /* array might be sparse */ + if (!meson8b_hw_onecell_data.hws[i]) + continue; + + ret = clk_hw_register(NULL, meson8b_hw_onecell_data.hws[i]); + if (ret) + return; + } + + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, + &meson8b_hw_onecell_data); + if (ret) + pr_err("%s: failed to register clock provider\n", __func__); } CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", - meson8b_clkc_reset_init); + meson8b_clkc_init); CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", - meson8b_clkc_reset_init); + meson8b_clkc_init); CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", - meson8b_clkc_reset_init); + meson8b_clkc_init); From 93c873d686461652921fe18b137ac28002dfe166 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 21 Jul 2018 21:14:00 +0200 Subject: [PATCH 096/836] clk: meson: meson8b: use the regmap in the internal reset controller For now the reset controller was using raw register access because the early init did not initialize the regmap. However, now that clocks are initialized early we can simply use the regmap also for the reset controller. No functional changes. Signed-off-by: Martin Blumenstingl Signed-off-by: Jerome Brunet --- drivers/clk/meson/meson8b.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 2a31d6eeef37..346b9e165b7a 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -23,7 +23,7 @@ static DEFINE_SPINLOCK(meson_clk_lock); struct meson8b_clk_reset { struct reset_controller_dev reset; - void __iomem *base; + struct regmap *regmap; }; static const struct pll_params_table sys_pll_params_table[] = { @@ -1064,7 +1064,6 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, container_of(rcdev, struct meson8b_clk_reset, reset); unsigned long flags; const struct meson8b_clk_reset_line *reset; - u32 val; if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) return -EINVAL; @@ -1073,12 +1072,12 @@ static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, spin_lock_irqsave(&meson_clk_lock, flags); - val = readl(meson8b_clk_reset->base + reset->reg); if (assert) - val |= BIT(reset->bit_idx); + regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, + BIT(reset->bit_idx), BIT(reset->bit_idx)); else - val &= ~BIT(reset->bit_idx); - writel(val, meson8b_clk_reset->base + reset->reg); + regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, + BIT(reset->bit_idx), 0); spin_unlock_irqrestore(&meson_clk_lock, flags); @@ -1131,7 +1130,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; /* Reset Controller */ - rstc->base = clk_base; + rstc->regmap = map; rstc->reset.ops = &meson8b_clk_reset_ops; rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits); rstc->reset.of_node = np; From 1f7db7bbf031828178216527523b29cb6001f86f Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Mon, 24 Sep 2018 11:49:35 -0500 Subject: [PATCH 097/836] clk: renesas: cpg-mssr: Add early clock support Add support for SoCs that need to register core and module clocks early in order to use OF drivers that exclusively use macros such as TIMER_OF_DECLARE. Signed-off-by: Chris Brandt Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 97 ++++++++++++++++++++------ drivers/clk/renesas/renesas-cpg-mssr.h | 13 ++++ 2 files changed, 89 insertions(+), 21 deletions(-) diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index e0c11a5b1761..394a7d10392a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -130,6 +130,7 @@ struct cpg_mssr_priv { struct device *dev; void __iomem *base; spinlock_t rmw_lock; + struct device_node *np; struct clk **clks; unsigned int num_core_clks; @@ -144,6 +145,7 @@ struct cpg_mssr_priv { } smstpcr_saved[ARRAY_SIZE(smstpcr)]; }; +static struct cpg_mssr_priv *cpg_mssr_priv; /** * struct mstp_clock - MSTP gating clock @@ -319,7 +321,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, switch (core->type) { case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); + clk = of_clk_get_by_name(priv->np, core->name); break; case CLK_TYPE_FF: @@ -891,42 +893,43 @@ static const struct dev_pm_ops cpg_mssr_pm = { #define DEV_PM_OPS NULL #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ -static int __init cpg_mssr_probe(struct platform_device *pdev) +static int __init cpg_mssr_common_init(struct device *dev, + struct device_node *np, + const struct cpg_mssr_info *info) { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct cpg_mssr_info *info; struct cpg_mssr_priv *priv; + struct clk **clks = NULL; unsigned int nclks, i; - struct resource *res; - struct clk **clks; int error; - info = of_device_get_match_data(dev); if (info->init) { error = info->init(dev); if (error) return error; } - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->np = np; priv->dev = dev; spin_lock_init(&priv->rmw_lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + priv->base = of_iomap(np, 0); + if (!priv->base) { + error = -ENOMEM; + goto out_err; + } nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; + clks = kmalloc_array(nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) { + error = -ENOMEM; + goto out_err; + } - dev_set_drvdata(dev, priv); + cpg_mssr_priv = priv; priv->clks = clks; priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; @@ -937,16 +940,68 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) + goto out_err; + + return 0; + +out_err: + kfree(clks); + if (priv->base) + iounmap(priv->base); + kfree(priv); + + return error; +} + +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info) +{ + int error; + int i; + + error = cpg_mssr_common_init(NULL, np, info); + if (error) + return; + + for (i = 0; i < info->num_early_core_clks; i++) + cpg_mssr_register_core_clk(&info->early_core_clks[i], info, + cpg_mssr_priv); + + for (i = 0; i < info->num_early_mod_clks; i++) + cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info, + cpg_mssr_priv); + +} + +static int __init cpg_mssr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct cpg_mssr_info *info; + struct cpg_mssr_priv *priv; + unsigned int i; + int error; + + info = of_device_get_match_data(dev); + + if (!cpg_mssr_priv) { + error = cpg_mssr_common_init(dev, dev->of_node, info); + if (error) + return error; + } + + priv = cpg_mssr_priv; + priv->dev = dev; + dev_set_drvdata(dev, priv); + for (i = 0; i < info->num_core_clks; i++) cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); for (i = 0; i < info->num_mod_clks; i++) cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); - error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); - if (error) - return error; - error = devm_add_action_or_reset(dev, cpg_mssr_del_clk_provider, np); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index d43d00351638..4e639fb8da9a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -91,6 +91,11 @@ struct device_node; /** * SoC-specific CPG/MSSR Description * + * @early_core_clks: Array of Early Core Clock definitions + * @num_early_core_clks: Number of entries in early_core_clks[] + * @early_mod_clks: Array of Early Module Clock definitions + * @num_early_mod_clks: Number of entries in early_mod_clks[] + * * @core_clks: Array of Core Clock definitions * @num_core_clks: Number of entries in core_clks[] * @last_dt_core_clk: ID of the last Core Clock exported to DT @@ -117,6 +122,12 @@ struct device_node; */ struct cpg_mssr_info { + /* Early Clocks */ + const struct cpg_core_clk *early_core_clks; + unsigned int num_early_core_clks; + const struct mssr_mod_clk *early_mod_clks; + unsigned int num_early_mod_clks; + /* Core Clocks */ const struct cpg_core_clk *core_clks; unsigned int num_core_clks; @@ -164,6 +175,8 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77990_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info); /* * Helpers for fixing up clock tables depending on SoC revision From b9553c13b10e90c7ee3c1830b88d6af3cb4fd371 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Mon, 24 Sep 2018 11:49:36 -0500 Subject: [PATCH 098/836] clk: renesas: r7s9210: Convert some clocks to early The OSTM timer driver for RZ/A2 uses TIMER_OF_DECLARE which requires the ostm module clocks to be registers early in boot. Signed-off-by: Chris Brandt Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r7s9210-cpg-mssr.c | 32 +++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index bd1dd4ff2051..7ab9030ef8b9 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -53,7 +53,7 @@ enum clk_ids { MOD_CLK_BASE }; -static struct cpg_core_clk r7s9210_core_clks[] = { +static struct cpg_core_clk r7s9210_early_core_clks[] = { /* External Clock Inputs */ DEF_INPUT("extal", CLK_EXTAL), @@ -61,20 +61,26 @@ static struct cpg_core_clk r7s9210_core_clks[] = { DEF_BASE(".main", CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL), DEF_BASE(".pll", CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN), + /* Core Clock Outputs */ + DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), +}; + +static const struct mssr_mod_clk r7s9210_early_mod_clks[] __initconst = { + DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), +}; + +static struct cpg_core_clk r7s9210_core_clks[] = { /* Core Clock Outputs */ DEF_FIXED("i", R7S9210_CLK_I, CLK_PLL, 2, 1), DEF_FIXED("g", R7S9210_CLK_G, CLK_PLL, 4, 1), DEF_FIXED("b", R7S9210_CLK_B, CLK_PLL, 8, 1), DEF_FIXED("p1", R7S9210_CLK_P1, CLK_PLL, 16, 1), - DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), DEF_FIXED("p0", R7S9210_CLK_P0, CLK_PLL, 32, 1), }; static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { - DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), - DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), - DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), - DEF_MOD_STB("scif4", 43, R7S9210_CLK_P1C), DEF_MOD_STB("scif3", 44, R7S9210_CLK_P1C), DEF_MOD_STB("scif2", 45, R7S9210_CLK_P1C), @@ -170,6 +176,12 @@ struct clk * __init rza2_cpg_clk_register(struct device *dev, } const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = { + /* Early Clocks */ + .early_core_clks = r7s9210_early_core_clks, + .num_early_core_clks = ARRAY_SIZE(r7s9210_early_core_clks), + .early_mod_clks = r7s9210_early_mod_clks, + .num_early_mod_clks = ARRAY_SIZE(r7s9210_early_mod_clks), + /* Core Clocks */ .core_clks = r7s9210_core_clks, .num_core_clks = ARRAY_SIZE(r7s9210_core_clks), @@ -187,3 +199,11 @@ const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = { /* RZ/A2 has Standby Control Registers */ .stbyctrl = true, }; + +static void __init r7s9210_cpg_mssr_early_init(struct device_node *np) +{ + cpg_mssr_early_init(np, &r7s9210_cpg_mssr_info); +} + +CLK_OF_DECLARE_DRIVER(cpg_mstp_clks, "renesas,r7s9210-cpg-mssr", + r7s9210_cpg_mssr_early_init); From 4cb1480f5f63178952cd9e457f405fd806260bc0 Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Mon, 24 Sep 2018 11:49:37 -0500 Subject: [PATCH 099/836] clk: renesas: r7s9210: Move table update to separate function Same functionality, just easier to read. Signed-off-by: Chris Brandt Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r7s9210-cpg-mssr.c | 95 ++++++++++++++------------ 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index 7ab9030ef8b9..d8ff4cb0defc 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -97,6 +97,54 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { }; +/* The clock dividers in the table vary based on DT and register settings */ +static void __init r7s9210_update_clk_table(struct clk *extal_clk, + void __iomem *base) +{ + int i; + u16 frqcr; + u8 index; + + /* If EXTAL is above 12MHz, then we know it is Mode 1 */ + if (clk_get_rate(extal_clk) > 12000000) + cpg_mode = 1; + + frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; + if (frqcr == 0x012) + index = 0; + else if (frqcr == 0x112) + index = 1; + else if (frqcr == 0x212) + index = 2; + else if (frqcr == 0x322) + index = 3; + else if (frqcr == 0x333) + index = 4; + else + BUG_ON(1); /* Illegal FRQCR value */ + + for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { + switch (r7s9210_core_clks[i].id) { + case R7S9210_CLK_I: + r7s9210_core_clks[i].div = ratio_tab[index].i; + break; + case R7S9210_CLK_G: + r7s9210_core_clks[i].div = ratio_tab[index].g; + break; + case R7S9210_CLK_B: + r7s9210_core_clks[i].div = ratio_tab[index].b; + break; + case R7S9210_CLK_P1: + case R7S9210_CLK_P1C: + r7s9210_core_clks[i].div = ratio_tab[index].p1; + break; + case R7S9210_CLK_P0: + r7s9210_core_clks[i].div = 32; + break; + } + } +} + struct clk * __init rza2_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, struct clk **clks, void __iomem *base, @@ -105,9 +153,6 @@ struct clk * __init rza2_cpg_clk_register(struct device *dev, struct clk *parent; unsigned int mult = 1; unsigned int div = 1; - u16 frqcr; - u8 index; - int i; parent = clks[core->parent]; if (IS_ERR(parent)) @@ -128,48 +173,8 @@ struct clk * __init rza2_cpg_clk_register(struct device *dev, return ERR_PTR(-EINVAL); } - /* Adjust the dividers based on the current FRQCR setting */ - if (core->id == CLK_MAIN) { - - /* If EXTAL is above 12MHz, then we know it is Mode 1 */ - if (clk_get_rate(parent) > 12000000) - cpg_mode = 1; - - frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; - if (frqcr == 0x012) - index = 0; - else if (frqcr == 0x112) - index = 1; - else if (frqcr == 0x212) - index = 2; - else if (frqcr == 0x322) - index = 3; - else if (frqcr == 0x333) - index = 4; - else - BUG_ON(1); /* Illegal FRQCR value */ - - for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { - switch (r7s9210_core_clks[i].id) { - case R7S9210_CLK_I: - r7s9210_core_clks[i].div = ratio_tab[index].i; - break; - case R7S9210_CLK_G: - r7s9210_core_clks[i].div = ratio_tab[index].g; - break; - case R7S9210_CLK_B: - r7s9210_core_clks[i].div = ratio_tab[index].b; - break; - case R7S9210_CLK_P1: - case R7S9210_CLK_P1C: - r7s9210_core_clks[i].div = ratio_tab[index].p1; - break; - case R7S9210_CLK_P0: - r7s9210_core_clks[i].div = 32; - break; - } - } - } + if (core->id == CLK_MAIN) + r7s9210_update_clk_table(parent, base); return clk_register_fixed_factor(NULL, core->name, __clk_get_name(parent), 0, mult, div); From f31fb2fe1ea4a03279c538612e7ecf0e5017639a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 21 Sep 2018 12:13:07 +0200 Subject: [PATCH 100/836] pwm: tegra: Remove gratuituous blank line It's common to follow a device tree ID table by the MODULE_DEVICE_TABLE immediately, without an extra blank line between. Signed-off-by: Thierry Reding Signed-off-by: Thierry Reding --- drivers/pwm/pwm-tegra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index f8ebbece57b7..48c4595a0ffc 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -300,7 +300,6 @@ static const struct of_device_id tegra_pwm_of_match[] = { { .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc }, { } }; - MODULE_DEVICE_TABLE(of, tegra_pwm_of_match); static const struct dev_pm_ops tegra_pwm_pm_ops = { From 31e56f2305bbc213e9e9f0e21826cceab70d5336 Mon Sep 17 00:00:00 2001 From: Zhang Xianwei Date: Tue, 4 Sep 2018 15:08:19 +0800 Subject: [PATCH 101/836] platform/x86: ideapad-laptop: Use __func__ instead of read_ec_cmd in pr_err Refer to the commit f1395edbcec8 ("platform/x86: ideapad-laptop: Use __func__ instead of write_ec_cmd in pr_err"), prefer using '"%s...", __func__' to using 'read_ec_cmd' in read_ec_data. Signed-off-by: Zhang Xianwei Acked-by: Ike Panhc Signed-off-by: Andy Shevchenko --- drivers/platform/x86/ideapad-laptop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index d4f1259ff5a2..f856d59361f2 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -212,7 +212,7 @@ static int read_ec_data(acpi_handle handle, int cmd, unsigned long *data) return 0; } } - pr_err("timeout in read_ec_cmd\n"); + pr_err("timeout in %s\n", __func__); return -1; } From 96402de65afcd9d7f12e04bf8a14d5a321aca4af Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 19 Sep 2018 20:14:51 +0200 Subject: [PATCH 102/836] platform/x86: intel_int0002_vgpio: Enable the driver on Bay Trail platforms The intel_int0002_vgpio driver was added to avoid an IRQ 9 storm on Cherry Trail platforms. When originally merged the CPU ID for Bay Trail SoCs was commented out of the list of valid CPU IDs because we did not have any reports of the IRQ storm on Bay Trail platforms. We now have a report of the IRQ 9 storm on the Bay Trail based Thinkpad Tablet 10 which is fixed by enabling this driver, so lets enable it on Bay Trail too. I've tested various other Bay Trail device with this driver enabled without adverse side-effects. BugLink: https://www.dpin.de/nf/finally-s0i3-is-there-thinkpad-tablet-10-sleeps-deeply-with-linux-kernel-4-15rc/#comments Reported-and-tested-by: Nicole Faerber Signed-off-by: Hans de Goede Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_int0002_vgpio.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index a473dc51b18d..987a3b03f225 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c @@ -57,11 +57,7 @@ #define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } static const struct x86_cpu_id int0002_cpu_ids[] = { -/* - * Limit ourselves to Cherry Trail for now, until testing shows we - * need to handle the INT0002 device on Baytrail too. - * ICPU(INTEL_FAM6_ATOM_SILVERMONT1), * Valleyview, Bay Trail * - */ + ICPU(INTEL_FAM6_ATOM_SILVERMONT1), /* Valleyview, Bay Trail */ ICPU(INTEL_FAM6_ATOM_AIRMONT), /* Braswell, Cherry Trail */ {} }; From c3b8e884defae3ad50956ee77bdba3638fe4852f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 24 Sep 2018 16:37:19 +0200 Subject: [PATCH 103/836] platform/x86: intel_int0002_vgpio: Implement irq_set_wake We were relying on the interrupt being shared with the ACPI SCI and the ACPI core calling irq_set_wake. But that does not always happen on Bay Trail devices, so we should do it ourselves. This fixes wake from USB not working on various Bay Trail devices. Signed-off-by: Hans de Goede Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_int0002_vgpio.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index 987a3b03f225..33c3489f5bc1 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c @@ -106,6 +106,21 @@ static void int0002_irq_mask(struct irq_data *data) outl(gpe_en_reg, GPE0A_EN_PORT); } +static int int0002_irq_set_wake(struct irq_data *data, unsigned int on) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct platform_device *pdev = to_platform_device(chip->parent); + int irq = platform_get_irq(pdev, 0); + + /* Propagate to parent irq */ + if (on) + enable_irq_wake(irq); + else + disable_irq_wake(irq); + + return 0; +} + static irqreturn_t int0002_irq(int irq, void *data) { struct gpio_chip *chip = data; @@ -128,6 +143,7 @@ static struct irq_chip int0002_irqchip = { .irq_ack = int0002_irq_ack, .irq_mask = int0002_irq_mask, .irq_unmask = int0002_irq_unmask, + .irq_set_wake = int0002_irq_set_wake, }; static int int0002_probe(struct platform_device *pdev) From a8b60e484f3d245bf90e934d608f75c814aaa70c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 31 Aug 2018 11:34:31 +0300 Subject: [PATCH 104/836] platform/x86: intel_mid_powerbtn: Get rid of custom ICPU() macro Replace custom grown macro with generic INTEL_CPU_FAM6() one. No functional change intended. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_mid_powerbtn.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index d79fbf924b13..c93299002169 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -121,12 +121,9 @@ static const struct mid_pb_ddata mrfld_ddata = { .setup = mrfld_setup, }; -#define ICPU(model, ddata) \ - { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (kernel_ulong_t)&ddata } - static const struct x86_cpu_id mid_pb_cpu_ids[] = { - ICPU(INTEL_FAM6_ATOM_PENWELL, mfld_ddata), - ICPU(INTEL_FAM6_ATOM_MERRIFIELD, mrfld_ddata), + INTEL_CPU_FAM6(ATOM_PENWELL, mfld_ddata), + INTEL_CPU_FAM6(ATOM_MERRIFIELD, mrfld_ddata), {} }; From 3836b816ddac7fcf4b3c9c55c5b57f41cea2a236 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 20 Sep 2018 21:44:16 -0400 Subject: [PATCH 105/836] platform/x86: acerhdf: clarify modinfo messages for BIOS override Normally, a module parameter for a BIOS check override implies "pretend you support this version" (and the user will enter their local version). However, this driver uses the model/BIOS module parameters in a way that is "pretend my system is the supported model XYZ with BIOS version ABC." which is less common. Since the help strings don't make such a distinction, one gets this somewhat frustrating scenario, where the user sees the error, enters *their* BIOS version and then gets the same error: root@gw:~# modprobe acerhdf acerhdf: Acer Aspire One Fan driver, v.0.7.0 acerhdf: unknown (unsupported) BIOS version Gateway /LT31 /v1.3307 , please report, aborting! modprobe: ERROR: could not insert 'acerhdf': Invalid argument root@gw:~# modprobe acerhdf force_bios=v1.3307 acerhdf: Acer Aspire One Fan driver, v.0.7.0 acerhdf: forcing BIOS version: v1.3307 acerhdf: unknown (unsupported) BIOS version Gateway /LT31 /v1.3307 , please report, aborting! modprobe: ERROR: could not insert 'acerhdf': Invalid argument Clarify the module param help text to make it clear that the driver expects a choice from existing supported models/versions. Cc: Peter Feuerer Cc: Darren Hart Cc: Andy Shevchenko Signed-off-by: Paul Gortmaker Signed-off-by: Andy Shevchenko Reviewed-by: Peter Feuerer --- drivers/platform/x86/acerhdf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index ea22591ee66f..3d5c4e183111 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -105,9 +105,9 @@ MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature"); module_param(verbose, uint, 0600); MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); module_param_string(force_bios, force_bios, 16, 0); -MODULE_PARM_DESC(force_bios, "Force BIOS version and omit BIOS check"); +MODULE_PARM_DESC(force_bios, "Pretend system has this known supported BIOS version"); module_param_string(force_product, force_product, 16, 0); -MODULE_PARM_DESC(force_product, "Force BIOS product and omit BIOS check"); +MODULE_PARM_DESC(force_product, "Pretend system is this known supported model"); /* * cmd_off: to switch the fan completely off and check if the fan is off From 291bd0e4605ee5d3cc8adefb79f8ef2047219571 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 20 Sep 2018 21:44:17 -0400 Subject: [PATCH 106/836] platform/x86: acerhdf: Enable ability to list supported systems This driver has two module parameters that allow an override of the checks for matching model and BIOS version. However, both parameters expect you to choose an entry from the existing list of supported systems, encoded within the driver itself. Without the source, such as in a binary distribution, the end user does not have access to this information, thus rendering the two module parameters essentially useless. Add a module parameter that allows the end user to dump the list of make/model/versions so that they can then pick one that most closely matches their own system. Cc: Peter Feuerer Cc: Darren Hart Cc: Andy Shevchenko Signed-off-by: Paul Gortmaker Signed-off-by: Andy Shevchenko Reviewed-by: Peter Feuerer --- drivers/platform/x86/acerhdf.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 3d5c4e183111..2735815c73c5 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -86,6 +86,7 @@ static unsigned int interval = 10; static unsigned int fanon = 60000; static unsigned int fanoff = 53000; static unsigned int verbose; +static unsigned int list_supported; static unsigned int fanstate = ACERHDF_FAN_AUTO; static char force_bios[16]; static char force_product[16]; @@ -104,6 +105,8 @@ module_param(fanoff, uint, 0600); MODULE_PARM_DESC(fanoff, "Turn the fan off below this temperature"); module_param(verbose, uint, 0600); MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); +module_param(list_supported, uint, 0600); +MODULE_PARM_DESC(list_supported, "List supported models and BIOS versions"); module_param_string(force_bios, force_bios, 16, 0); MODULE_PARM_DESC(force_bios, "Pretend system has this known supported BIOS version"); module_param_string(force_product, force_product, 16, 0); @@ -632,6 +635,17 @@ static int acerhdf_check_hardware(void) pr_info("Acer Aspire One Fan driver, v.%s\n", DRV_VER); + if (list_supported) { + pr_info("List of supported Manufacturer/Model/BIOS:\n"); + pr_info("---------------------------------------------------\n"); + for (bt = bios_tbl; bt->vendor[0]; bt++) { + pr_info("%-13s | %-17s | %-10s\n", bt->vendor, + bt->product, bt->version); + } + pr_info("---------------------------------------------------\n"); + return -ECANCELED; + } + if (force_bios[0]) { version = force_bios; pr_info("forcing BIOS version: %s\n", version); From 14c20688292583b3f7a8a595b65f6b5665616752 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 20 Sep 2018 21:44:18 -0400 Subject: [PATCH 107/836] platform/x86: acerhdf: Remove cut-and-paste trap from instructions Just like we avoid specifying actual block devices like sda for fdisk and dd examples, we should not specify specific thermal zones here. On the platform I was testing on, zone0 was acpitz, and zone1 was for this acerhdf driver. Make the printk such that it won't work with a blind cut-and-paste, and force the user to determine which zone is correct for this driver. Cc: Peter Feuerer Cc: Darren Hart Cc: Andy Shevchenko Signed-off-by: Paul Gortmaker Signed-off-by: Andy Shevchenko Reviewed-by: Peter Feuerer --- drivers/platform/x86/Kconfig | 5 ++++- drivers/platform/x86/acerhdf.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 0c1aa6c314f5..1fca33c97e8a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -60,7 +60,10 @@ config ACERHDF After loading this driver the BIOS is still in control of the fan. To let the kernel handle the fan, do: - echo -n enabled > /sys/class/thermal/thermal_zone0/mode + echo -n enabled > /sys/class/thermal/thermal_zoneN/mode + where N=0,1,2... depending on the number of thermal nodes and the + detection order of your particular system. The "type" parameter + in the same node directory will tell you if it is "acerhdf". For more information about this driver see diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 2735815c73c5..fef3b727bc24 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -688,7 +688,7 @@ static int acerhdf_check_hardware(void) */ if (!kernelmode) { pr_notice("Fan control off, to enable do:\n"); - pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zone0/mode\n"); + pr_notice("echo -n \"enabled\" > /sys/class/thermal/thermal_zoneN/mode # N=0,1,2...\n"); } return 0; From 684238d79ad85c5e19a71bb5818e77e329912fbc Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 20 Sep 2018 21:44:19 -0400 Subject: [PATCH 108/836] platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307 To fix: acerhdf: unknown (unsupported) BIOS version Gateway /LT31 /v1.3307 , please report, aborting! As can be seen in the context, the BIOS registers haven't changed in the previous versions, so the assumption is they won't have changed in this last update for this somewhat older platform either. Cc: Peter Feuerer Cc: Darren Hart Cc: Andy Shevchenko Signed-off-by: Paul Gortmaker Signed-off-by: Andy Shevchenko Reviewed-by: Peter Feuerer --- drivers/platform/x86/acerhdf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index fef3b727bc24..eddcd8e94a88 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -236,6 +236,7 @@ static const struct bios_settings bios_tbl[] = { {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00}, 0}, {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00}, 0}, {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00}, 0}, + {"Gateway", "LT31", "v1.3307", 0x55, 0x58, {0x9e, 0x00}, 0}, /* Packard Bell */ {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00}, 0}, {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00}, 0}, From 1d0c3fd01afbd52cc365460d46176b6b4131960d Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 20 Sep 2018 21:44:20 -0400 Subject: [PATCH 109/836] platform/x86: acerhdf: mark appropriate content with __init prefix These three functions are only called from the probe code which is already marked __init and hence these can be __init as well. Cc: Peter Feuerer Cc: Darren Hart Cc: Andy Shevchenko Signed-off-by: Paul Gortmaker Signed-off-by: Andy Shevchenko Reviewed-by: Peter Feuerer --- drivers/platform/x86/acerhdf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index eddcd8e94a88..5f579fcde315 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -619,7 +619,7 @@ static int str_starts_with(const char *str, const char *start) } /* check hardware */ -static int acerhdf_check_hardware(void) +static int __init acerhdf_check_hardware(void) { char const *vendor, *version, *product; const struct bios_settings *bt = NULL; @@ -695,7 +695,7 @@ static int acerhdf_check_hardware(void) return 0; } -static int acerhdf_register_platform(void) +static int __init acerhdf_register_platform(void) { int err = 0; @@ -727,7 +727,7 @@ static void acerhdf_unregister_platform(void) platform_driver_unregister(&acerhdf_driver); } -static int acerhdf_register_thermal(void) +static int __init acerhdf_register_thermal(void) { cl_dev = thermal_cooling_device_register("acerhdf-fan", NULL, &acerhdf_cooling_ops); From f7eaf3fb9d10cc72669fe8c8bd204087a65e50f6 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 20 Sep 2018 21:44:21 -0400 Subject: [PATCH 110/836] platform/x86: acerhdf: restructure to allow large BIOS table be __initconst There is a table of Vendor/Model/Version {control data} in this driver, but outside of the initial probe, the V/M/V is never used again, and neither are any of the entries for platforms other than the one which matches the running target. By simply storing the {control data} for the matched platform, we can mark the large table __initconst, which reduces the loaded driver size by 20 percent. Before: root@gw:~/git/linux-head# lsmod Module Size Used by acerhdf 20480 0 root@gw:~/git/linux-head# After: root@gw:~/git/linux-head# lsmod Module Size Used by acerhdf 16384 0 root@gw:~/git/linux-head# Cc: Peter Feuerer Cc: Darren Hart Cc: Andy Shevchenko Signed-off-by: Paul Gortmaker Signed-off-by: Andy Shevchenko Reviewed-by: Peter Feuerer --- drivers/platform/x86/acerhdf.c | 41 +++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 5f579fcde315..505224225378 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -133,7 +133,7 @@ static const struct manualcmd mcmd = { .moff = 0xff, }; -/* BIOS settings */ +/* BIOS settings - only used during probe */ struct bios_settings { const char *vendor; const char *product; @@ -144,8 +144,18 @@ struct bios_settings { int mcmd_enable; }; +/* This could be a daughter struct in the above, but not worth the redirect */ +struct ctrl_settings { + u8 fanreg; + u8 tempreg; + struct fancmd cmd; + int mcmd_enable; +}; + +static struct ctrl_settings ctrl_cfg __read_mostly; + /* Register addresses and values for different BIOS versions */ -static const struct bios_settings bios_tbl[] = { +static const struct bios_settings bios_tbl[] __initconst = { /* AOA110 */ {"Acer", "AOA110", "v0.3109", 0x55, 0x58, {0x1f, 0x00}, 0}, {"Acer", "AOA110", "v0.3114", 0x55, 0x58, {0x1f, 0x00}, 0}, @@ -260,8 +270,6 @@ static const struct bios_settings bios_tbl[] = { {"", "", "", 0, 0, {0, 0}, 0} }; -static const struct bios_settings *bios_cfg __read_mostly; - /* * this struct is used to instruct thermal layer to use bang_bang instead of * default governor for acerhdf @@ -274,7 +282,7 @@ static int acerhdf_get_temp(int *temp) { u8 read_temp; - if (ec_read(bios_cfg->tempreg, &read_temp)) + if (ec_read(ctrl_cfg.tempreg, &read_temp)) return -EINVAL; *temp = read_temp * 1000; @@ -286,10 +294,10 @@ static int acerhdf_get_fanstate(int *state) { u8 fan; - if (ec_read(bios_cfg->fanreg, &fan)) + if (ec_read(ctrl_cfg.fanreg, &fan)) return -EINVAL; - if (fan != bios_cfg->cmd.cmd_off) + if (fan != ctrl_cfg.cmd.cmd_off) *state = ACERHDF_FAN_AUTO; else *state = ACERHDF_FAN_OFF; @@ -310,13 +318,13 @@ static void acerhdf_change_fanstate(int state) state = ACERHDF_FAN_AUTO; } - cmd = (state == ACERHDF_FAN_OFF) ? bios_cfg->cmd.cmd_off - : bios_cfg->cmd.cmd_auto; + cmd = (state == ACERHDF_FAN_OFF) ? ctrl_cfg.cmd.cmd_off + : ctrl_cfg.cmd.cmd_auto; fanstate = state; - ec_write(bios_cfg->fanreg, cmd); + ec_write(ctrl_cfg.fanreg, cmd); - if (bios_cfg->mcmd_enable && state == ACERHDF_FAN_OFF) { + if (ctrl_cfg.mcmd_enable && state == ACERHDF_FAN_OFF) { if (verbose) pr_notice("turning off fan manually\n"); ec_write(mcmd.mreg, mcmd.moff); @@ -623,6 +631,7 @@ static int __init acerhdf_check_hardware(void) { char const *vendor, *version, *product; const struct bios_settings *bt = NULL; + int found = 0; /* get BIOS data */ vendor = dmi_get_system_info(DMI_SYS_VENDOR); @@ -672,17 +681,23 @@ static int __init acerhdf_check_hardware(void) if (str_starts_with(vendor, bt->vendor) && str_starts_with(product, bt->product) && str_starts_with(version, bt->version)) { - bios_cfg = bt; + found = 1; break; } } - if (!bios_cfg) { + if (!found) { pr_err("unknown (unsupported) BIOS version %s/%s/%s, please report, aborting!\n", vendor, product, version); return -EINVAL; } + /* Copy control settings from BIOS table before we free it. */ + ctrl_cfg.fanreg = bt->fanreg; + ctrl_cfg.tempreg = bt->tempreg; + memcpy(&ctrl_cfg.cmd, &bt->cmd, sizeof(struct fancmd)); + ctrl_cfg.mcmd_enable = bt->mcmd_enable; + /* * if started with kernel mode off, prevent the kernel from switching * off the fan From 6aecee6ad41cf97c0270f72da032c10eef025bf0 Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 26 Sep 2018 16:50:17 -0500 Subject: [PATCH 111/836] firmware: dell_rbu: Make payload memory uncachable The dell_rbu driver takes firmware update payloads and puts them in memory so the system BIOS can find them after a reboot. This sometimes fails (though rarely), because the memory containing the payload is in the CPU cache but never gets written back to main memory before the system is rebooted (CPU cache contents are lost on reboot). With this patch, the payload memory will be changed to uncachable to ensure that the payload is actually in main memory before the system is rebooted. Signed-off-by: Stuart Hayes Signed-off-by: Andy Shevchenko --- drivers/firmware/dell_rbu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c index fb8af5cb7c9b..ccefa84f7305 100644 --- a/drivers/firmware/dell_rbu.c +++ b/drivers/firmware/dell_rbu.c @@ -45,6 +45,7 @@ #include #include #include +#include MODULE_AUTHOR("Abhay Salunke "); MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems"); @@ -181,6 +182,11 @@ static int create_packet(void *data, size_t length) packet_data_temp_buf = NULL; } } + /* + * set to uncachable or it may never get written back before reboot + */ + set_memory_uc((unsigned long)packet_data_temp_buf, 1 << ordernum); + spin_lock(&rbu_data.lock); newpacket->data = packet_data_temp_buf; @@ -349,6 +355,8 @@ static void packet_empty_list(void) * to make sure there are no stale RBU packets left in memory */ memset(newpacket->data, 0, rbu_data.packetsize); + set_memory_wb((unsigned long)newpacket->data, + 1 << newpacket->ordernum); free_pages((unsigned long) newpacket->data, newpacket->ordernum); kfree(newpacket); From 12c956c4f32e08799de452abe1e1ec6021b1e41f Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 26 Sep 2018 16:50:18 -0500 Subject: [PATCH 112/836] firmware: dcdbas: Add support for WSMT ACPI table If the WSMT ACPI table is present and indicates that a fixed communication buffer should be used, use the firmware-specified buffer instead of allocating a buffer in memory for communications between the dcdbas driver and firmare. Signed-off-by: Stuart Hayes Signed-off-by: Andy Shevchenko --- drivers/firmware/dcdbas.c | 123 ++++++++++++++++++++++++++++++++++++-- drivers/firmware/dcdbas.h | 10 ++++ 2 files changed, 127 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 0bdea60c65dd..ae28e48ff7dc 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -41,7 +42,7 @@ #include "dcdbas.h" #define DRIVER_NAME "dcdbas" -#define DRIVER_VERSION "5.6.0-3.2" +#define DRIVER_VERSION "5.6.0-3.3" #define DRIVER_DESCRIPTION "Dell Systems Management Base Driver" static struct platform_device *dcdbas_pdev; @@ -49,19 +50,23 @@ static struct platform_device *dcdbas_pdev; static u8 *smi_data_buf; static dma_addr_t smi_data_buf_handle; static unsigned long smi_data_buf_size; +static unsigned long max_smi_data_buf_size = MAX_SMI_DATA_BUF_SIZE; static u32 smi_data_buf_phys_addr; static DEFINE_MUTEX(smi_data_lock); +static u8 *eps_buffer; static unsigned int host_control_action; static unsigned int host_control_smi_type; static unsigned int host_control_on_shutdown; +static bool wsmt_enabled; + /** * smi_data_buf_free: free SMI data buffer */ static void smi_data_buf_free(void) { - if (!smi_data_buf) + if (!smi_data_buf || wsmt_enabled) return; dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n", @@ -86,7 +91,7 @@ static int smi_data_buf_realloc(unsigned long size) if (smi_data_buf_size >= size) return 0; - if (size > MAX_SMI_DATA_BUF_SIZE) + if (size > max_smi_data_buf_size) return -EINVAL; /* new buffer is needed */ @@ -169,7 +174,7 @@ static ssize_t smi_data_write(struct file *filp, struct kobject *kobj, { ssize_t ret; - if ((pos + count) > MAX_SMI_DATA_BUF_SIZE) + if ((pos + count) > max_smi_data_buf_size) return -EINVAL; mutex_lock(&smi_data_lock); @@ -322,8 +327,20 @@ static ssize_t smi_request_store(struct device *dev, ret = count; break; case 1: - /* Calling Interface SMI */ - smi_cmd->ebx = (u32) virt_to_phys(smi_cmd->command_buffer); + /* + * Calling Interface SMI + * + * Provide physical address of command buffer field within + * the struct smi_cmd to BIOS. + * + * Because the address that smi_cmd (smi_data_buf) points to + * will be from memremap() of a non-memory address if WSMT + * is present, we can't use virt_to_phys() on smi_cmd, so + * we have to use the physical address that was saved when + * the virtual address for smi_cmd was received. + */ + smi_cmd->ebx = smi_data_buf_phys_addr + + offsetof(struct smi_cmd, command_buffer); ret = dcdbas_smi_request(smi_cmd); if (!ret) ret = count; @@ -482,6 +499,93 @@ static void dcdbas_host_control(void) } } +/* WSMT */ + +static u8 checksum(u8 *buffer, u8 length) +{ + u8 sum = 0; + u8 *end = buffer + length; + + while (buffer < end) + sum += *buffer++; + return sum; +} + +static inline struct smm_eps_table *check_eps_table(u8 *addr) +{ + struct smm_eps_table *eps = (struct smm_eps_table *)addr; + + if (strncmp(eps->smm_comm_buff_anchor, SMM_EPS_SIG, 4) != 0) + return NULL; + + if (checksum(addr, eps->length) != 0) + return NULL; + + return eps; +} + +static int dcdbas_check_wsmt(void) +{ + struct acpi_table_wsmt *wsmt = NULL; + struct smm_eps_table *eps = NULL; + u64 remap_size; + u8 *addr; + + acpi_get_table(ACPI_SIG_WSMT, 0, (struct acpi_table_header **)&wsmt); + if (!wsmt) + return 0; + + /* Check if WSMT ACPI table shows that protection is enabled */ + if (!(wsmt->protection_flags & ACPI_WSMT_FIXED_COMM_BUFFERS) || + !(wsmt->protection_flags & ACPI_WSMT_COMM_BUFFER_NESTED_PTR_PROTECTION)) + return 0; + + /* Scan for EPS (entry point structure) */ + for (addr = (u8 *)__va(0xf0000); + addr < (u8 *)__va(0x100000 - sizeof(struct smm_eps_table)); + addr += 16) { + eps = check_eps_table(addr); + if (eps) + break; + } + + if (!eps) { + dev_dbg(&dcdbas_pdev->dev, "found WSMT, but no EPS found\n"); + return -ENODEV; + } + + /* + * Get physical address of buffer and map to virtual address. + * Table gives size in 4K pages, regardless of actual system page size. + */ + if (upper_32_bits(eps->smm_comm_buff_addr + 8)) { + dev_warn(&dcdbas_pdev->dev, "found WSMT, but EPS buffer address is above 4GB\n"); + return -EINVAL; + } + /* + * Limit remap size to MAX_SMI_DATA_BUF_SIZE + 8 (since the first 8 + * bytes are used for a semaphore, not the data buffer itself). + */ + remap_size = eps->num_of_4k_pages * PAGE_SIZE; + if (remap_size > MAX_SMI_DATA_BUF_SIZE + 8) + remap_size = MAX_SMI_DATA_BUF_SIZE + 8; + eps_buffer = memremap(eps->smm_comm_buff_addr, remap_size, MEMREMAP_WB); + if (!eps_buffer) { + dev_warn(&dcdbas_pdev->dev, "found WSMT, but failed to map EPS buffer\n"); + return -ENOMEM; + } + + /* First 8 bytes is for a semaphore, not part of the smi_data_buf */ + smi_data_buf_phys_addr = eps->smm_comm_buff_addr + 8; + smi_data_buf = eps_buffer + 8; + smi_data_buf_size = remap_size - 8; + max_smi_data_buf_size = smi_data_buf_size; + wsmt_enabled = true; + dev_info(&dcdbas_pdev->dev, + "WSMT found, using firmware-provided SMI buffer.\n"); + return 1; +} + /** * dcdbas_reboot_notify: handle reboot notification for host control */ @@ -548,6 +652,11 @@ static int dcdbas_probe(struct platform_device *dev) dcdbas_pdev = dev; + /* Check if ACPI WSMT table specifies protected SMI buffer address */ + error = dcdbas_check_wsmt(); + if (error < 0) + return error; + /* * BIOS SMI calls require buffer addresses be in 32-bit address space. * This is done by setting the DMA mask below. @@ -635,6 +744,8 @@ static void __exit dcdbas_exit(void) */ if (dcdbas_pdev) smi_data_buf_free(); + if (eps_buffer) + memunmap(eps_buffer); platform_device_unregister(dcdbas_pdev_reg); platform_driver_unregister(&dcdbas_driver); } diff --git a/drivers/firmware/dcdbas.h b/drivers/firmware/dcdbas.h index ca3cb0a54ab6..52729a494b00 100644 --- a/drivers/firmware/dcdbas.h +++ b/drivers/firmware/dcdbas.h @@ -53,6 +53,7 @@ #define EXPIRED_TIMER (0) #define SMI_CMD_MAGIC (0x534D4931) +#define SMM_EPS_SIG "$SCB" #define DCDBAS_DEV_ATTR_RW(_name) \ DEVICE_ATTR(_name,0600,_name##_show,_name##_store); @@ -103,5 +104,14 @@ struct apm_cmd { int dcdbas_smi_request(struct smi_cmd *smi_cmd); +struct smm_eps_table { + char smm_comm_buff_anchor[4]; + u8 length; + u8 checksum; + u8 version; + u64 smm_comm_buff_addr; + u64 num_of_4k_pages; +} __packed; + #endif /* _DCDBAS_H_ */ From c48e2ffd717ca4a67b4938bb60d110b7eeed39c4 Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 26 Sep 2018 16:50:19 -0500 Subject: [PATCH 113/836] firmware: dell_rbu: Move dell_rbu to drivers/platform/x86 Move dell_rbu to the more appropriate directory drivers/platform/x86. Signed-off-by: Stuart Hayes Signed-off-by: Andy Shevchenko --- drivers/firmware/Kconfig | 12 ------------ drivers/firmware/Makefile | 1 - drivers/platform/x86/Kconfig | 12 ++++++++++++ drivers/platform/x86/Makefile | 1 + drivers/{firmware => platform/x86}/dell_rbu.c | 0 5 files changed, 13 insertions(+), 13 deletions(-) rename drivers/{firmware => platform/x86}/dell_rbu.c (100%) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 6e83880046d7..02f39d20efce 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -145,18 +145,6 @@ config EFI_PCDP See DIG64_HCDPv20_042804.pdf available from -config DELL_RBU - tristate "BIOS update support for DELL systems via sysfs" - depends on X86 - select FW_LOADER - select FW_LOADER_USER_HELPER - help - Say m if you want to have the option of updating the BIOS for your - DELL system. Note you need a Dell OpenManage or Dell Update package (DUP) - supporting application to communicate with the BIOS regarding the new - image for the image update to take effect. - See for more details on the driver. - config DCDBAS tristate "Dell Systems Management Base Driver" depends on X86 diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index e18a041cfc53..61887ba9df1d 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_DMI) += dmi_scan.o obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o obj-$(CONFIG_EDD) += edd.o obj-$(CONFIG_EFI_PCDP) += pcdp.o -obj-$(CONFIG_DELL_RBU) += dell_rbu.o obj-$(CONFIG_DCDBAS) += dcdbas.o obj-$(CONFIG_DMIID) += dmi-id.o obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 1fca33c97e8a..097212c712f7 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -230,6 +230,18 @@ config DELL_RBTN To compile this driver as a module, choose M here: the module will be called dell-rbtn. +config DELL_RBU + tristate "BIOS update support for DELL systems via sysfs" + depends on X86 + select FW_LOADER + select FW_LOADER_USER_HELPER + help + Say m if you want to have the option of updating the BIOS for your + DELL system. Note you need a Dell OpenManage or Dell Update package (DUP) + supporting application to communicate with the BIOS regarding the new + image for the image update to take effect. + See for more details on the driver. + config FUJITSU_LAPTOP tristate "Fujitsu Laptop Extras" diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index e6d1becf81ce..8843f8e22127 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o +obj-$(CONFIG_DELL_RBU) += dell_rbu.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o obj-$(CONFIG_ACERHDF) += acerhdf.o diff --git a/drivers/firmware/dell_rbu.c b/drivers/platform/x86/dell_rbu.c similarity index 100% rename from drivers/firmware/dell_rbu.c rename to drivers/platform/x86/dell_rbu.c From 8e5cddd1262cdee59257d554440cc9a80e5fcb7b Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 26 Sep 2018 16:50:20 -0500 Subject: [PATCH 114/836] firmware: dcdbas: Move dcdbas to drivers/platform/x86 Move dcdbas to the more appropriate directory drivers/platform/x86. Signed-off-by: Stuart Hayes Signed-off-by: Andy Shevchenko --- drivers/firmware/Kconfig | 16 ---------------- drivers/firmware/Makefile | 1 - drivers/platform/x86/Kconfig | 16 ++++++++++++++++ drivers/platform/x86/Makefile | 1 + drivers/{firmware => platform/x86}/dcdbas.c | 0 drivers/{firmware => platform/x86}/dcdbas.h | 0 drivers/platform/x86/dell-smbios-smm.c | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) rename drivers/{firmware => platform/x86}/dcdbas.c (100%) rename drivers/{firmware => platform/x86}/dcdbas.h (100%) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 02f39d20efce..6d0c28fd3bad 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -145,22 +145,6 @@ config EFI_PCDP See DIG64_HCDPv20_042804.pdf available from -config DCDBAS - tristate "Dell Systems Management Base Driver" - depends on X86 - help - The Dell Systems Management Base Driver provides a sysfs interface - for systems management software to perform System Management - Interrupts (SMIs) and Host Control Actions (system power cycle or - power off after OS shutdown) on certain Dell systems. - - See for more details on the driver - and the Dell systems on which Dell systems management software makes - use of this driver. - - Say Y or M here to enable the driver for use by Dell systems - management software such as Dell OpenManage. - config DMIID bool "Export DMI identification via sysfs to userspace" depends on DMI diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 61887ba9df1d..edda4206d8fc 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_DMI) += dmi_scan.o obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o obj-$(CONFIG_EDD) += edd.o obj-$(CONFIG_EFI_PCDP) += pcdp.o -obj-$(CONFIG_DCDBAS) += dcdbas.o obj-$(CONFIG_DMIID) += dmi-id.o obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 097212c712f7..4283239115ca 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -108,6 +108,22 @@ config ASUS_LAPTOP If you have an ACPI-compatible ASUS laptop, say Y or M here. +config DCDBAS + tristate "Dell Systems Management Base Driver" + depends on X86 + help + The Dell Systems Management Base Driver provides a sysfs interface + for systems management software to perform System Management + Interrupts (SMIs) and Host Control Actions (system power cycle or + power off after OS shutdown) on certain Dell systems. + + See for more details on the driver + and the Dell systems on which Dell systems management software makes + use of this driver. + + Say Y or M here to enable the driver for use by Dell systems + management software such as Dell OpenManage. + # # The DELL_SMBIOS driver depends on ACPI_WMI and/or DCDBAS if those # backends are selected. The "depends" line prevents a configuration diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 8843f8e22127..4e2712c9c0b0 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o +obj-$(CONFIG_DCDBAS) += dcdbas.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o dell-smbios-objs := dell-smbios-base.o dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o diff --git a/drivers/firmware/dcdbas.c b/drivers/platform/x86/dcdbas.c similarity index 100% rename from drivers/firmware/dcdbas.c rename to drivers/platform/x86/dcdbas.c diff --git a/drivers/firmware/dcdbas.h b/drivers/platform/x86/dcdbas.h similarity index 100% rename from drivers/firmware/dcdbas.h rename to drivers/platform/x86/dcdbas.h diff --git a/drivers/platform/x86/dell-smbios-smm.c b/drivers/platform/x86/dell-smbios-smm.c index 97a90bebc360..ab9b822a6dfe 100644 --- a/drivers/platform/x86/dell-smbios-smm.c +++ b/drivers/platform/x86/dell-smbios-smm.c @@ -18,7 +18,7 @@ #include #include #include -#include "../../firmware/dcdbas.h" +#include "dcdbas.h" #include "dell-smbios.h" static int da_command_address; From bfb25c86ef2bb9fa2ddeae4daca9910fd19754bc Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Wed, 26 Sep 2018 16:50:21 -0500 Subject: [PATCH 115/836] MAINTAINERS: Update maintainer for dcdbas and dell_rbu Assign maintainer for dell_rbu driver, and reassign maintainer of dcdbas from inactive maintainer (current maintainer is aware of this change-- see https://www.spinics.net/lists/platform-driver-x86/msg16336.html). Signed-off-by: Stuart Hayes Acked-by: Doug Warzecha Signed-off-by: Andy Shevchenko --- MAINTAINERS | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index af26a231cd3e..2614592f8fa4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4187,6 +4187,12 @@ M: Pali Rohár S: Maintained F: drivers/platform/x86/dell-rbtn.* +DELL REMOTE BIOS UPDATE DRIVER +M: Stuart Hayes +L: platform-driver-x86@vger.kernel.org +S: Maintained +F: drivers/platform/x86/dell_rbu.c + DELL LAPTOP SMM DRIVER M: Pali Rohár S: Maintained @@ -4194,10 +4200,11 @@ F: drivers/hwmon/dell-smm-hwmon.c F: include/uapi/linux/i8k.h DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas) -M: Doug Warzecha +M: Stuart Hayes +L: platform-driver-x86@vger.kernel.org S: Maintained F: Documentation/dcdbas.txt -F: drivers/firmware/dcdbas.* +F: drivers/platform/x86/dcdbas.* DELL WMI NOTIFICATIONS DRIVER M: Matthew Garrett From 24c6f7200bb326122e65528e44a12962403185fe Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 116/836] platform/x86: intel_bxtwc_tmu: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_bxtwc_tmu.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/platform/x86/intel_bxtwc_tmu.c b/drivers/platform/x86/intel_bxtwc_tmu.c index 227943a20212..951c105bafc1 100644 --- a/drivers/platform/x86/intel_bxtwc_tmu.c +++ b/drivers/platform/x86/intel_bxtwc_tmu.c @@ -1,21 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_bxtwc_tmu.c - Intel BXT Whiskey Cove PMIC TMU driver + * Intel BXT Whiskey Cove PMIC TMU driver * * Copyright (C) 2016 Intel Corporation. All rights reserved. * * This driver adds TMU (Time Management Unit) support for Intel BXT platform. * It enables the alarm wake-up functionality in the TMU unit of Whiskey Cove * PMIC. - * - * 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 in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include From 83e8ee26cb5ad54d37d6f6359979e004ce7cb9e9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 117/836] platform/x86: intel_cht_int33fe: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_cht_int33fe.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c index 39d4100c60a2..6531a0c3cc0d 100644 --- a/drivers/platform/x86/intel_cht_int33fe.c +++ b/drivers/platform/x86/intel_cht_int33fe.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Cherry Trail ACPI INT33FE pseudo device driver * * Copyright (C) 2017 Hans de Goede * - * 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. - * * Some Intel Cherry Trail based device which ship with Windows 10, have * this weird INT33FE ACPI device with a CRS table with 4 I2cSerialBusV2 * resources, for 4 different chips attached to various i2c busses: @@ -266,4 +263,4 @@ module_i2c_driver(cht_int33fe_driver); MODULE_DESCRIPTION("Intel Cherry Trail ACPI INT33FE pseudo device driver"); MODULE_AUTHOR("Hans de Goede "); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); From 924931745bf392a5aa25ad88c09edbb414556334 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:58:52 +0300 Subject: [PATCH 118/836] platform/x86: intel_chtdc_ti_pwrbtn: Add SPDX identifier Driver misses the licence text or identifier, thus, append it here. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_chtdc_ti_pwrbtn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c b/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c index 38b8e7cfe88c..0df2e82dd249 100644 --- a/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c +++ b/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Power-button driver for Dollar Cove TI PMIC * Copyright (C) 2014 Intel Corp From 31daa5dd32fc77d3114ad0f6e1a2f1aedfe43616 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 119/836] platform/x86: intel-hid: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel-hid.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c index 6cf9b7fa5bf0..e28bcf61b126 100644 --- a/drivers/platform/x86/intel-hid.c +++ b/drivers/platform/x86/intel-hid.c @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Intel HID event & 5 button array driver * * Copyright (C) 2015 Alex Hung * Copyright (C) 2015 Andrew Lutomirski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include From 79c24dbdcbcb23e722e5c2680dba642fcc74a357 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 120/836] platform/x86: intel_int0002_vgpio: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_int0002_vgpio.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index 33c3489f5bc1..c958a628c375 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel INT0002 "Virtual GPIO" driver * @@ -9,10 +10,6 @@ * * Author: Dyut Kumar Sil * - * 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. - * * Some peripherals on Bay Trail and Cherry Trail platforms signal a Power * Management Event (PME) to the Power Management Controller (PMC) to wakeup * the system. When this happens software needs to clear the PME bus 0 status @@ -228,4 +225,4 @@ module_platform_driver(int0002_driver); MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Intel INT0002 Virtual GPIO driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); From c4e4c94641109095b04024ba15b899f621c52ca4 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 121/836] platform/x86: intel-ips: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_ips.c | 15 ++------------- drivers/platform/x86/intel_ips.h | 13 +------------ 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c5ece7ef08c6..225638a1b09e 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2009-2010 Intel Corporation * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - * * Authors: * Jesse Barnes */ @@ -1697,6 +1686,6 @@ static struct pci_driver ips_pci_driver = { module_pci_driver(ips_pci_driver); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Jesse Barnes "); MODULE_DESCRIPTION("Intelligent Power Sharing Driver"); diff --git a/drivers/platform/x86/intel_ips.h b/drivers/platform/x86/intel_ips.h index 60f4e3ddbe9f..512ad234ad0d 100644 --- a/drivers/platform/x86/intel_ips.h +++ b/drivers/platform/x86/intel_ips.h @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2010 Intel Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". */ void ips_link_to_i915_driver(void); From 8855ab3b2ef65de985484c063301cdc1b2aab187 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 122/836] platform/x86: intel_menlow: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_menlow.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index ef9b0af8cdd3..76854f0bf70b 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c @@ -29,15 +29,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include -#include -#include -#include #include #include +#include #include -#include +#include MODULE_AUTHOR("Thomas Sujith"); MODULE_AUTHOR("Zhang Rui"); From 0b5d9856b6070fe2ffc3906e0190d48f465ae771 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 123/836] platform/x86: intel_menlow: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_menlow.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 76854f0bf70b..77eb8709c931 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c @@ -1,25 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_menlow.c - Intel menlow Driver for thermal management extension + * Intel menlow Driver for thermal management extension * * Copyright (C) 2008 Intel Corp * Copyright (C) 2008 Sujith Thomas * Copyright (C) 2008 Zhang Rui - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This driver creates the sys I/F for programming the sensors. * It also implements the driver for intel menlow memory controller (hardware @@ -41,7 +26,7 @@ MODULE_AUTHOR("Thomas Sujith"); MODULE_AUTHOR("Zhang Rui"); MODULE_DESCRIPTION("Intel Menlow platform specific driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); /* * Memory controller device control From f7949b185b8eb15bb61610f627c7014c7f042feb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 124/836] platform/x86: intel_mid_powerbtn: Remove unnecessary init.h inclusion No need to include linux/init.h when linux/module.h is. No functional change intended. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_mid_powerbtn.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index c93299002169..b8d659233c6a 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -16,7 +16,6 @@ * General Public License for more details. */ -#include #include #include #include From f6b27d0907d0381c330c09ae6f7149c8121c3f37 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 125/836] platform/x86: intel_mid_powerbtn: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_mid_powerbtn.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index b8d659233c6a..a8c0fbb7f799 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Power button driver for Intel MID platforms. * @@ -5,15 +6,6 @@ * * Author: Hong Liu * Author: Andy Shevchenko - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include From e6e69a31dc7412ac9fb40881ae9788ad82ac6c98 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 126/836] platform/x86: intel_mid_thermal: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_mid_thermal.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index 008a76903cbf..3fa8207dd34e 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -24,16 +24,15 @@ #define pr_fmt(fmt) "intel_mid_thermal: " fmt -#include -#include -#include -#include #include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include /* Number of thermal sensors */ #define MSIC_THERMAL_SENSORS 4 From 56df47de25402ba44382b89cab4665faed783711 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 127/836] platform/x86: intel_mid_thermal: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_mid_thermal.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c index 3fa8207dd34e..f402e2e74a38 100644 --- a/drivers/platform/x86/intel_mid_thermal.c +++ b/drivers/platform/x86/intel_mid_thermal.c @@ -1,24 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_mid_thermal.c - Intel MID platform thermal driver + * Intel MID platform thermal driver * * Copyright (C) 2011 Intel Corporation * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Author: Durgadoss R */ @@ -566,4 +551,4 @@ module_platform_driver(mid_thermal_driver); MODULE_AUTHOR("Durgadoss R "); MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); From bce99455f56ee45f128ffedd5c87201003850188 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 128/836] platform/x86: intel_oaktrail: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_oaktrail.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index 5747f63c8d9f..1d98fd9ca1ea 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c @@ -38,18 +38,18 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include #include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include +#include +#include #include + #include #define DRIVER_NAME "intel_oaktrail" From 56ca5ec102b4a4e8f6b945a3ed132d8677be528b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 129/836] platform/x86: intel_oaktrail: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_oaktrail.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index 1d98fd9ca1ea..3c0438ba385e 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c @@ -1,5 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* - * intel_oaktrail.c - Intel OakTrail Platform support. + * Intel OakTrail Platform support * * Copyright (C) 2010-2011 Intel Corporation * Author: Yin Kangkai (kangkai.yin@intel.com) @@ -8,21 +9,6 @@ * , based on MSI driver * Copyright (C) 2006 Lennart Poettering * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * * This driver does below things: * 1. registers itself in the Linux backlight control in * /sys/class/backlight/intel_oaktrail/ From 908817720056ce19bfabd9c02e9bd09ff696d898 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 130/836] platform/x86: intel_pmc: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_pmc_ipc.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index e7edc8c63936..8b88e1743e41 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -15,25 +15,24 @@ * core through IPC mechanism which in turn messaging between IA core ad PMC. */ -#include +#include +#include +#include #include -#include -#include #include -#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include #include -#include -#include #include -#include -#include -#include -#include -#include #include +#include #include From ad51f287ff593efb559f23e655312f3b6694fd90 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 131/836] platform/x86: intel_pmc: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_pmc_core.c | 11 +---------- drivers/platform/x86/intel_pmc_core.h | 11 +---------- drivers/platform/x86/intel_pmc_ipc.c | 12 ++++-------- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index 2d272a3e0176..6b31d410cb09 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Core SoC Power Management Controller Driver * @@ -6,16 +7,6 @@ * * Authors: Rajneesh Bhardwaj * Vishwanath Somayaji - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h index 93a7e99e1f8b..be045348ad86 100644 --- a/drivers/platform/x86/intel_pmc_core.h +++ b/drivers/platform/x86/intel_pmc_core.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Core SoC Power Management Controller Header File * @@ -6,16 +7,6 @@ * * Authors: Rajneesh Bhardwaj * Vishwanath Somayaji - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #ifndef PMC_CORE_H diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c index 8b88e1743e41..7964ba22ef8d 100644 --- a/drivers/platform/x86/intel_pmc_ipc.c +++ b/drivers/platform/x86/intel_pmc_ipc.c @@ -1,16 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_pmc_ipc.c: Driver for the Intel PMC IPC mechanism + * Driver for the Intel PMC IPC mechanism * * (C) Copyright 2014-2015 Intel Corporation * - * This driver is based on Intel SCU IPC driver(intel_scu_opc.c) by + * This driver is based on Intel SCU IPC driver(intel_scu_ipc.c) by * Sreedhara DS * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - * * PMC running in ARC processor communicates with other entity running in IA * core through IPC mechanism which in turn messaging between IA core ad PMC. */ @@ -1028,7 +1024,7 @@ static void __exit intel_pmc_ipc_exit(void) MODULE_AUTHOR("Zha Qipeng "); MODULE_DESCRIPTION("Intel PMC IPC driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); /* Some modules are dependent on this, so init earlier */ fs_initcall(intel_pmc_ipc_init); From 5e66d08e6b485bcb691c2c15806cfaaac8740da3 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 132/836] platform/x86: intel_punit_ipc: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_punit_ipc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index 2efeab650345..8eaa60c9ad69 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -11,15 +11,16 @@ * which provide mailbox interface for power management usage. */ -#include -#include #include -#include #include +#include #include #include #include +#include +#include #include + #include /* IPC Mailbox registers */ From bc15757e0cfd1264bb4fae8bbd65ea736e7617af Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 133/836] platform/x86: intel_punit_ipc: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_punit_ipc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c index 8eaa60c9ad69..79671927f4ef 100644 --- a/drivers/platform/x86/intel_punit_ipc.c +++ b/drivers/platform/x86/intel_punit_ipc.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the Intel P-Unit Mailbox IPC mechanism * * (C) Copyright 2015 Intel Corporation * - * 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. - * * The heart of the P-Unit is the Foxton microcontroller and its firmware, * which provide mailbox interface for power management usage. */ From 5f4ad6afe96b69886b57ca3cbc6b5e88b7911367 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 134/836] platform/x86: intel-rst: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel-rst.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c index 7344d841f4d9..56abf5cbb824 100644 --- a/drivers/platform/x86/intel-rst.c +++ b/drivers/platform/x86/intel-rst.c @@ -17,10 +17,9 @@ */ -#include +#include #include #include -#include MODULE_LICENSE("GPL"); From bd7c5866bbe09f085c51e87578c1fa94c22728e0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 135/836] platform/x86: intel-rst: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, throw away some extra blank lines. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel-rst.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c index 56abf5cbb824..3b81cb896fed 100644 --- a/drivers/platform/x86/intel-rst.c +++ b/drivers/platform/x86/intel-rst.c @@ -1,22 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2013 Matthew Garrett - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #include #include #include @@ -52,12 +38,10 @@ static ssize_t irst_store_wakeup_events(struct device *dev, acpi = to_acpi_device(dev); error = kstrtoul(buf, 0, &value); - if (error) return error; status = acpi_execute_simple_method(acpi->handle, "SFFS", value); - if (ACPI_FAILURE(status)) return -EINVAL; @@ -98,12 +82,10 @@ static ssize_t irst_store_wakeup_time(struct device *dev, acpi = to_acpi_device(dev); error = kstrtoul(buf, 0, &value); - if (error) return error; status = acpi_execute_simple_method(acpi->handle, "SFTV", value); - if (ACPI_FAILURE(status)) return -EINVAL; From 2d0554e8ba555eeed84741099f1565437ae4b574 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 136/836] platform/x86: intel_scu_ipc: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_scu_ipc.c | 8 +++++--- drivers/platform/x86/intel_scu_ipcutil.c | 12 ++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 75c8fef7a482..3f4b24a33430 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -16,14 +16,16 @@ * IPC-1 Driver provides an API for power control unit registers (e.g. MSIC) * along with other APIs. */ + #include +#include #include #include -#include -#include -#include #include +#include +#include #include + #include #include diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c index aa454241489c..2a65cabe87f4 100644 --- a/drivers/platform/x86/intel_scu_ipcutil.c +++ b/drivers/platform/x86/intel_scu_ipcutil.c @@ -12,16 +12,16 @@ * This driver provides ioctl interfaces to call intel scu ipc driver api */ -#include -#include #include -#include -#include #include +#include +#include +#include #include -#include #include -#include +#include +#include + #include static int major; From 9b748e0efee547f5a17c07c674cebe3ca148233f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 137/836] platform/x86: intel_scu_ipc: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_scu_ipc.c | 8 ++------ drivers/platform/x86/intel_scu_ipcutil.c | 12 ++++-------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 3f4b24a33430..cdab916fbf92 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism + * Driver for the Intel SCU IPC mechanism * * (C) Copyright 2008-2010,2015 Intel Corporation * Author: Sreedhara DS (sreedhara.ds@intel.com) * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - * * SCU running in ARC processor communicates with other entity running in IA * core through IPC mechanism which in turn messaging between IA core ad SCU. * SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c index 2a65cabe87f4..8afe6fa06d7b 100644 --- a/drivers/platform/x86/intel_scu_ipcutil.c +++ b/drivers/platform/x86/intel_scu_ipcutil.c @@ -1,15 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_scu_ipc.c: Driver for the Intel SCU IPC mechanism + * Driver for the Intel SCU IPC mechanism * * (C) Copyright 2008-2010 Intel Corporation * Author: Sreedhara DS (sreedhara.ds@intel.com) * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - * - * This driver provides ioctl interfaces to call intel scu ipc driver api + * This driver provides IOCTL interfaces to call Intel SCU IPC driver API. */ #include @@ -26,7 +22,7 @@ static int major; -/* ioctl commnds */ +/* IOCTL commands */ #define INTE_SCU_IPC_REGISTER_READ 0 #define INTE_SCU_IPC_REGISTER_WRITE 1 #define INTE_SCU_IPC_REGISTER_UPDATE 2 From 8046f0499c14819fb36176a589d21d225e69ae01 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 138/836] platform/x86: intel-smartconnect: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. While here, remove unneeded linux/init.h inclusion and move MODULE_DEVICE_TABLE() close to the table. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel-smartconnect.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel-smartconnect.c b/drivers/platform/x86/intel-smartconnect.c index bbe4c06c769f..274ac488afcb 100644 --- a/drivers/platform/x86/intel-smartconnect.c +++ b/drivers/platform/x86/intel-smartconnect.c @@ -17,9 +17,8 @@ */ -#include -#include #include +#include MODULE_LICENSE("GPL"); @@ -44,6 +43,7 @@ static const struct acpi_device_id smartconnect_ids[] = { {"INT33A0", 0}, {"", 0} }; +MODULE_DEVICE_TABLE(acpi, smartconnect_ids); static struct acpi_driver smartconnect_driver = { .owner = THIS_MODULE, @@ -56,5 +56,3 @@ static struct acpi_driver smartconnect_driver = { }; module_acpi_driver(smartconnect_driver); - -MODULE_DEVICE_TABLE(acpi, smartconnect_ids); From 3e57f2648a09622b0ef3738aefb8d27b83dec60f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 139/836] platform/x86: intel-smartconnect: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, throw away some extra blank lines. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel-smartconnect.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/platform/x86/intel-smartconnect.c b/drivers/platform/x86/intel-smartconnect.c index 274ac488afcb..64c2dc93472f 100644 --- a/drivers/platform/x86/intel-smartconnect.c +++ b/drivers/platform/x86/intel-smartconnect.c @@ -1,22 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2013 Matthew Garrett - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - #include #include From 917f450aa3fa84c7682537b008b837806a77d99a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 140/836] platform/x86: intel_telemetry: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_telemetry_core.c | 12 ++---------- drivers/platform/x86/intel_telemetry_debugfs.c | 12 ++---------- drivers/platform/x86/intel_telemetry_pltdrv.c | 12 ++---------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/drivers/platform/x86/intel_telemetry_core.c b/drivers/platform/x86/intel_telemetry_core.c index f378621b5fe9..d4040bb222b4 100644 --- a/drivers/platform/x86/intel_telemetry_core.c +++ b/drivers/platform/x86/intel_telemetry_core.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel SoC Core Telemetry Driver * Copyright (C) 2015, Intel Corporation. * All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * * Telemetry Framework provides platform related PM and performance statistics. * This file provides the core telemetry API implementation. */ @@ -460,4 +452,4 @@ module_exit(telemetry_module_exit); MODULE_AUTHOR("Souvik Kumar Chakravarty "); MODULE_DESCRIPTION("Intel SoC Telemetry Interface"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c index ffd0474b0531..badd1682f9c1 100644 --- a/drivers/platform/x86/intel_telemetry_debugfs.c +++ b/drivers/platform/x86/intel_telemetry_debugfs.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel SOC Telemetry debugfs Driver: Currently supports APL * Copyright (c) 2015, Intel Corporation. * All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * * This file provides the debugfs interfaces for telemetry. * /sys/kernel/debug/telemetry/pss_info: Shows Primary Control Sub-Sys Counters * /sys/kernel/debug/telemetry/ioss_info: Shows IO Sub-System Counters @@ -1037,4 +1029,4 @@ module_exit(telemetry_debugfs_exit); MODULE_AUTHOR("Souvik Kumar Chakravarty "); MODULE_DESCRIPTION("Intel SoC Telemetry debugfs Interface"); MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/platform/x86/intel_telemetry_pltdrv.c b/drivers/platform/x86/intel_telemetry_pltdrv.c index 2f889d6c270e..62531d2524d8 100644 --- a/drivers/platform/x86/intel_telemetry_pltdrv.c +++ b/drivers/platform/x86/intel_telemetry_pltdrv.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel SOC Telemetry Platform Driver: Currently supports APL * Copyright (c) 2015, Intel Corporation. * All Rights Reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * * This file provides the platform specific telemetry implementation for APL. * It used the PUNIT and PMC IPC interfaces for configuring the counters. * The accumulated results are fetched from SRAM. @@ -1242,4 +1234,4 @@ module_exit(telemetry_module_exit); MODULE_AUTHOR("Souvik Kumar Chakravarty "); MODULE_DESCRIPTION("Intel SoC Telemetry Platform Driver"); MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); From 303211089c966db3933d4efc91bcaf10e235ad34 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:14 +0300 Subject: [PATCH 141/836] platform/x86: intel_turbo_max_3: Sort headers alphabetically Sort headers alphabetically for better maintenance. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_turbo_max_3.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/intel_turbo_max_3.c b/drivers/platform/x86/intel_turbo_max_3.c index a6d5aa0c3c47..0e1bdb883ceb 100644 --- a/drivers/platform/x86/intel_turbo_max_3.c +++ b/drivers/platform/x86/intel_turbo_max_3.c @@ -17,12 +17,13 @@ */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include +#include +#include #include +#include #include #include -#include -#include + #include #include From de415deeb68b1a5c0a036fbbcb10389b83d47e02 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 142/836] platform/x86: intel_turbo_max_3: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel_turbo_max_3.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/platform/x86/intel_turbo_max_3.c b/drivers/platform/x86/intel_turbo_max_3.c index 0e1bdb883ceb..7b9cc841ab65 100644 --- a/drivers/platform/x86/intel_turbo_max_3.c +++ b/drivers/platform/x86/intel_turbo_max_3.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Intel Turbo Boost Max Technology 3.0 legacy (non HWP) enumeration driver * Copyright (c) 2017, Intel Corporation. * All rights reserved. * * Author: Srinivas Pandruvada - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt From a8694eebae878aadcee8d3306379c3d74924d89b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 26 Sep 2018 18:27:40 +0300 Subject: [PATCH 143/836] platform/x86: intel-wmi-thunderbolt: Convert to use SPDX identifier Reduce size of duplicated comments by switching to use SPDX identifier. No functional change. While here, correct MODULE_LICENSE() string to be aligned with license text. Signed-off-by: Andy Shevchenko --- drivers/platform/x86/intel-wmi-thunderbolt.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/platform/x86/intel-wmi-thunderbolt.c b/drivers/platform/x86/intel-wmi-thunderbolt.c index c2257bd06f18..b029a70b084a 100644 --- a/drivers/platform/x86/intel-wmi-thunderbolt.c +++ b/drivers/platform/x86/intel-wmi-thunderbolt.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * WMI Thunderbolt driver * * Copyright (C) 2017 Dell Inc. All Rights Reserved. - * - * 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 in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -95,4 +87,4 @@ module_wmi_driver(intel_wmi_thunderbolt_driver); MODULE_ALIAS("wmi:" INTEL_WMI_THUNDERBOLT_GUID); MODULE_AUTHOR("Mario Limonciello "); MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); From 7eccb5edba24cec9bb0a2b990ac66e755456303a Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 26 Sep 2018 11:10:58 -0500 Subject: [PATCH 144/836] platform/x86: intel-wmi-thunderbolt: Add dynamic debugging Some users have been reporting issues with thunderbolt being turned off before fully initialized. This is suspected to be caused by userspace turning off the Thunderbolt controller using intel-wmi-thunderbolt prematurely. Userspace has already made some mitigations for this situation: https://github.com/hughsie/fwupd/commit/ef6f1d76983c9b66 https://github.com/hughsie/fwupd/commit/c07ce5b4889a5384 To allow easier debugging of this situation add output that can be turned on with dynamic debugging to better root cause this problem. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199631 BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=201227 Suggested-by: Mika Westerberg Signed-off-by: Mario Limonciello Signed-off-by: Andy Shevchenko Reviewed-by: Mika Westerberg --- drivers/platform/x86/intel-wmi-thunderbolt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/intel-wmi-thunderbolt.c b/drivers/platform/x86/intel-wmi-thunderbolt.c index b029a70b084a..9ded8e2af312 100644 --- a/drivers/platform/x86/intel-wmi-thunderbolt.c +++ b/drivers/platform/x86/intel-wmi-thunderbolt.c @@ -30,12 +30,16 @@ static ssize_t force_power_store(struct device *dev, input.length = sizeof(u8); input.pointer = &mode; mode = hex_to_bin(buf[0]); + dev_dbg(dev, "force_power: storing %#x\n", mode); if (mode == 0 || mode == 1) { status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1, &input, NULL); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + dev_dbg(dev, "force_power: failed to evaluate ACPI method\n"); return -ENODEV; + } } else { + dev_dbg(dev, "force_power: unsupported mode\n"); return -EINVAL; } return count; From a53a28dca4124048c90b4a8de457668ede57e67c Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Wed, 26 Sep 2018 08:39:56 -0500 Subject: [PATCH 145/836] clk: renesas: r7s9210: Add SPI clocks Add RSPI clocks for RZ/A2. Signed-off-by: Chris Brandt Reviewed-by: Simon Horman Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/r7s9210-cpg-mssr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c index d8ff4cb0defc..5135f13ec628 100644 --- a/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -95,6 +95,9 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { DEF_MOD_STB("i2c1", 86, R7S9210_CLK_P1), DEF_MOD_STB("i2c0", 87, R7S9210_CLK_P1), + DEF_MOD_STB("spi2", 95, R7S9210_CLK_P1), + DEF_MOD_STB("spi1", 96, R7S9210_CLK_P1), + DEF_MOD_STB("spi0", 97, R7S9210_CLK_P1), }; /* The clock dividers in the table vary based on DT and register settings */ From bc78abbd55dd28e2287ec6d6502b842321a17c87 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Tue, 25 Sep 2018 12:28:55 +0300 Subject: [PATCH 146/836] fuse: Fix use-after-free in fuse_dev_do_read() We may pick freed req in this way: [cpu0] [cpu1] fuse_dev_do_read() fuse_dev_do_write() list_move_tail(&req->list, ...); ... spin_unlock(&fpq->lock); ... ... request_end(fc, req); ... fuse_put_request(fc, req); if (test_bit(FR_INTERRUPTED, ...)) queue_interrupt(fiq, req); Fix that by keeping req alive until we finish all manipulations. Reported-by: syzbot+4e975615ca01f2277bdd@syzkaller.appspotmail.com Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi Fixes: 46c34a348b0a ("fuse: no fc->lock for pqueue parts") Cc: # v4.2 --- fs/fuse/dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 11ea2c4a38ab..675caed3e655 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1311,12 +1311,14 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, goto out_end; } list_move_tail(&req->list, &fpq->processing); + __fuse_get_request(req); spin_unlock(&fpq->lock); set_bit(FR_SENT, &req->flags); /* matches barrier in request_wait_answer() */ smp_mb__after_atomic(); if (test_bit(FR_INTERRUPTED, &req->flags)) queue_interrupt(fiq, req); + fuse_put_request(fc, req); return reqsize; From d2d2d4fb1f54eff0f3faa9762d84f6446a4bc5d0 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Tue, 25 Sep 2018 12:52:42 +0300 Subject: [PATCH 147/836] fuse: Fix use-after-free in fuse_dev_do_write() After we found req in request_find() and released the lock, everything may happen with the req in parallel: cpu0 cpu1 fuse_dev_do_write() fuse_dev_do_write() req = request_find(fpq, ...) ... spin_unlock(&fpq->lock) ... ... req = request_find(fpq, oh.unique) ... spin_unlock(&fpq->lock) queue_interrupt(&fc->iq, req); ... ... ... ... ... request_end(fc, req); fuse_put_request(fc, req); ... queue_interrupt(&fc->iq, req); Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi Fixes: 46c34a348b0a ("fuse: no fc->lock for pqueue parts") Cc: # v4.2 --- fs/fuse/dev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 675caed3e655..c2af8042f176 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1877,16 +1877,20 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, /* Is it an interrupt reply? */ if (req->intr_unique == oh.unique) { + __fuse_get_request(req); spin_unlock(&fpq->lock); err = -EINVAL; - if (nbytes != sizeof(struct fuse_out_header)) + if (nbytes != sizeof(struct fuse_out_header)) { + fuse_put_request(fc, req); goto err_finish; + } if (oh.error == -ENOSYS) fc->no_interrupt = 1; else if (oh.error == -EAGAIN) queue_interrupt(&fc->iq, req); + fuse_put_request(fc, req); fuse_copy_finish(cs); return nbytes; From 4c316f2f3ff315cb48efb7435621e5bfb81df96d Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 28 Sep 2018 16:43:22 +0200 Subject: [PATCH 148/836] fuse: set FR_SENT while locked Otherwise fuse_dev_do_write() could come in and finish off the request, and the set_bit(FR_SENT, ...) could trigger the WARN_ON(test_bit(FR_SENT, ...)) in request_end(). Signed-off-by: Miklos Szeredi Reported-by: syzbot+ef054c4d3f64cd7f7cec@syzkaller.appspotmai Fixes: 46c34a348b0a ("fuse: no fc->lock for pqueue parts") Cc: # v4.2 --- fs/fuse/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index c2af8042f176..34976b42f3e1 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1312,8 +1312,8 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, } list_move_tail(&req->list, &fpq->processing); __fuse_get_request(req); - spin_unlock(&fpq->lock); set_bit(FR_SENT, &req->flags); + spin_unlock(&fpq->lock); /* matches barrier in request_wait_answer() */ smp_mb__after_atomic(); if (test_bit(FR_INTERRUPTED, &req->flags)) From 908a572b80f6e9577b45e81b3dfe2e22111286b8 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 28 Sep 2018 16:43:22 +0200 Subject: [PATCH 149/836] fuse: fix blocked_waitq wakeup Using waitqueue_active() is racy. Make sure we issue a wake_up() unconditionally after storing into fc->blocked. After that it's okay to optimize with waitqueue_active() since the first wake up provides the necessary barrier for all waiters, not the just the woken one. Signed-off-by: Miklos Szeredi Fixes: 3c18ef8117f0 ("fuse: optimize wake_up") Cc: # v3.10 --- fs/fuse/dev.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 34976b42f3e1..51eb602a435b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -391,12 +391,19 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) if (test_bit(FR_BACKGROUND, &req->flags)) { spin_lock(&fc->lock); clear_bit(FR_BACKGROUND, &req->flags); - if (fc->num_background == fc->max_background) + if (fc->num_background == fc->max_background) { fc->blocked = 0; - - /* Wake up next waiter, if any */ - if (!fc->blocked && waitqueue_active(&fc->blocked_waitq)) wake_up(&fc->blocked_waitq); + } else if (!fc->blocked) { + /* + * Wake up next waiter, if any. It's okay to use + * waitqueue_active(), as we've already synced up + * fc->blocked with waiters with the wake_up() call + * above. + */ + if (waitqueue_active(&fc->blocked_waitq)) + wake_up(&fc->blocked_waitq); + } if (fc->num_background == fc->congestion_threshold && fc->sb) { clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); From 88bc7d5097a11d9bdcf08ecf85c81ba998353437 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Tue, 21 Aug 2018 14:36:31 +0200 Subject: [PATCH 150/836] fuse: add support for copy_file_range() There are several FUSE filesystems that can implement server-side copy or other efficient copy/duplication/clone methods. The copy_file_range() syscall is the standard interface that users have access to while not depending on external libraries that bypass FUSE. Signed-off-by: Niels de Vos Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 77 +++++++++++++++++++++++++++ fs/fuse/fuse_i.h | 3 ++ include/uapi/linux/fuse.h | 106 +++++++++++++++++++++----------------- 3 files changed, 140 insertions(+), 46 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 32d0b883e74f..63136a2c23ab 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3011,6 +3011,82 @@ out: return err; } +static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in, + struct file *file_out, loff_t pos_out, + size_t len, unsigned int flags) +{ + struct fuse_file *ff_in = file_in->private_data; + struct fuse_file *ff_out = file_out->private_data; + struct inode *inode_out = file_inode(file_out); + struct fuse_inode *fi_out = get_fuse_inode(inode_out); + struct fuse_conn *fc = ff_in->fc; + FUSE_ARGS(args); + struct fuse_copy_file_range_in inarg = { + .fh_in = ff_in->fh, + .off_in = pos_in, + .nodeid_out = ff_out->nodeid, + .fh_out = ff_out->fh, + .off_out = pos_out, + .len = len, + .flags = flags + }; + struct fuse_write_out outarg; + ssize_t err; + /* mark unstable when write-back is not used, and file_out gets + * extended */ + bool is_unstable = (!fc->writeback_cache) && + ((pos_out + len) > inode_out->i_size); + + if (fc->no_copy_file_range) + return -EOPNOTSUPP; + + inode_lock(inode_out); + + if (fc->writeback_cache) { + err = filemap_write_and_wait_range(inode_out->i_mapping, + pos_out, pos_out + len); + if (err) + goto out; + + fuse_sync_writes(inode_out); + } + + if (is_unstable) + set_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state); + + args.in.h.opcode = FUSE_COPY_FILE_RANGE; + args.in.h.nodeid = ff_in->nodeid; + args.in.numargs = 1; + args.in.args[0].size = sizeof(inarg); + args.in.args[0].value = &inarg; + args.out.numargs = 1; + args.out.args[0].size = sizeof(outarg); + args.out.args[0].value = &outarg; + err = fuse_simple_request(fc, &args); + if (err == -ENOSYS) { + fc->no_copy_file_range = 1; + err = -EOPNOTSUPP; + } + if (err) + goto out; + + if (fc->writeback_cache) { + fuse_write_update_size(inode_out, pos_out + outarg.size); + file_update_time(file_out); + } + + fuse_invalidate_attr(inode_out); + + err = outarg.size; +out: + if (is_unstable) + clear_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state); + + inode_unlock(inode_out); + + return err; +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read_iter = fuse_file_read_iter, @@ -3027,6 +3103,7 @@ static const struct file_operations fuse_file_operations = { .compat_ioctl = fuse_file_compat_ioctl, .poll = fuse_file_poll, .fallocate = fuse_file_fallocate, + .copy_file_range = fuse_copy_file_range, }; static const struct file_operations fuse_direct_io_file_operations = { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f78e9614bb5f..3e45d408a644 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -637,6 +637,9 @@ struct fuse_conn { /** Allow other than the mounter user to access the filesystem ? */ unsigned allow_other:1; + /** Does the filesystem support copy_file_range? */ + unsigned no_copy_file_range:1; + /** The number of requests waiting for completion */ atomic_t num_waiting; diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 92fa24c24c92..d27b50a44f74 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -116,6 +116,9 @@ * * 7.27 * - add FUSE_ABORT_ERROR + * + * 7.28 + * - add FUSE_COPY_FILE_RANGE */ #ifndef _LINUX_FUSE_H @@ -151,7 +154,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 27 +#define FUSE_KERNEL_MINOR_VERSION 28 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -337,53 +340,54 @@ struct fuse_file_lock { #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) enum fuse_opcode { - FUSE_LOOKUP = 1, - FUSE_FORGET = 2, /* no reply */ - FUSE_GETATTR = 3, - FUSE_SETATTR = 4, - FUSE_READLINK = 5, - FUSE_SYMLINK = 6, - FUSE_MKNOD = 8, - FUSE_MKDIR = 9, - FUSE_UNLINK = 10, - FUSE_RMDIR = 11, - FUSE_RENAME = 12, - FUSE_LINK = 13, - FUSE_OPEN = 14, - FUSE_READ = 15, - FUSE_WRITE = 16, - FUSE_STATFS = 17, - FUSE_RELEASE = 18, - FUSE_FSYNC = 20, - FUSE_SETXATTR = 21, - FUSE_GETXATTR = 22, - FUSE_LISTXATTR = 23, - FUSE_REMOVEXATTR = 24, - FUSE_FLUSH = 25, - FUSE_INIT = 26, - FUSE_OPENDIR = 27, - FUSE_READDIR = 28, - FUSE_RELEASEDIR = 29, - FUSE_FSYNCDIR = 30, - FUSE_GETLK = 31, - FUSE_SETLK = 32, - FUSE_SETLKW = 33, - FUSE_ACCESS = 34, - FUSE_CREATE = 35, - FUSE_INTERRUPT = 36, - FUSE_BMAP = 37, - FUSE_DESTROY = 38, - FUSE_IOCTL = 39, - FUSE_POLL = 40, - FUSE_NOTIFY_REPLY = 41, - FUSE_BATCH_FORGET = 42, - FUSE_FALLOCATE = 43, - FUSE_READDIRPLUS = 44, - FUSE_RENAME2 = 45, - FUSE_LSEEK = 46, + FUSE_LOOKUP = 1, + FUSE_FORGET = 2, /* no reply */ + FUSE_GETATTR = 3, + FUSE_SETATTR = 4, + FUSE_READLINK = 5, + FUSE_SYMLINK = 6, + FUSE_MKNOD = 8, + FUSE_MKDIR = 9, + FUSE_UNLINK = 10, + FUSE_RMDIR = 11, + FUSE_RENAME = 12, + FUSE_LINK = 13, + FUSE_OPEN = 14, + FUSE_READ = 15, + FUSE_WRITE = 16, + FUSE_STATFS = 17, + FUSE_RELEASE = 18, + FUSE_FSYNC = 20, + FUSE_SETXATTR = 21, + FUSE_GETXATTR = 22, + FUSE_LISTXATTR = 23, + FUSE_REMOVEXATTR = 24, + FUSE_FLUSH = 25, + FUSE_INIT = 26, + FUSE_OPENDIR = 27, + FUSE_READDIR = 28, + FUSE_RELEASEDIR = 29, + FUSE_FSYNCDIR = 30, + FUSE_GETLK = 31, + FUSE_SETLK = 32, + FUSE_SETLKW = 33, + FUSE_ACCESS = 34, + FUSE_CREATE = 35, + FUSE_INTERRUPT = 36, + FUSE_BMAP = 37, + FUSE_DESTROY = 38, + FUSE_IOCTL = 39, + FUSE_POLL = 40, + FUSE_NOTIFY_REPLY = 41, + FUSE_BATCH_FORGET = 42, + FUSE_FALLOCATE = 43, + FUSE_READDIRPLUS = 44, + FUSE_RENAME2 = 45, + FUSE_LSEEK = 46, + FUSE_COPY_FILE_RANGE = 47, /* CUSE specific operations */ - CUSE_INIT = 4096, + CUSE_INIT = 4096, }; enum fuse_notify_code { @@ -792,4 +796,14 @@ struct fuse_lseek_out { uint64_t offset; }; +struct fuse_copy_file_range_in { + uint64_t fh_in; + uint64_t off_in; + uint64_t nodeid_out; + uint64_t fh_out; + uint64_t off_out; + uint64_t len; + uint64_t flags; +}; + #endif /* _LINUX_FUSE_H */ From e287179afe2190faa7b97915cb89215dde5e044b Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Tue, 31 Jul 2018 13:25:25 +0300 Subject: [PATCH 151/836] fuse: use list_first_entry() in flush_bg_queue() This cleanup patch makes the function to use the primitive instead of direct dereferencing. Also, move fiq dereferencing out of cycle, since it's always constant. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 51eb602a435b..6a7d3b4424e1 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -353,12 +353,13 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, static void flush_bg_queue(struct fuse_conn *fc) { + struct fuse_iqueue *fiq = &fc->iq; + while (fc->active_background < fc->max_background && !list_empty(&fc->bg_queue)) { struct fuse_req *req; - struct fuse_iqueue *fiq = &fc->iq; - req = list_entry(fc->bg_queue.next, struct fuse_req, list); + req = list_first_entry(&fc->bg_queue, struct fuse_req, list); list_del(&req->list); fc->active_background++; spin_lock(&fiq->waitq.lock); From 2a23f2b8adbe4bd584f936f7ac17a99750eed9d7 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 27 Aug 2018 18:29:29 +0300 Subject: [PATCH 152/836] fuse: use READ_ONCE on congestion_threshold and max_background Since they are of unsigned int type, it's allowed to read them unlocked during reporting to userspace. Let's underline this fact with READ_ONCE() macroses. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 0b694655d988..acc35819aae6 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -107,7 +107,7 @@ static ssize_t fuse_conn_max_background_read(struct file *file, if (!fc) return 0; - val = fc->max_background; + val = READ_ONCE(fc->max_background); fuse_conn_put(fc); return fuse_conn_limit_read(file, buf, len, ppos, val); @@ -144,7 +144,7 @@ static ssize_t fuse_conn_congestion_threshold_read(struct file *file, if (!fc) return 0; - val = fc->congestion_threshold; + val = READ_ONCE(fc->congestion_threshold); fuse_conn_put(fc); return fuse_conn_limit_read(file, buf, len, ppos, val); From 2b30a533148af4f3865c0dcd619ad93ab3f4ba52 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 27 Aug 2018 18:29:37 +0300 Subject: [PATCH 153/836] fuse: add locking to max_background and congestion_threshold changes Functions sequences like request_end()->flush_bg_queue() require that max_background and congestion_threshold are constant during their execution. Otherwise, checks like if (fc->num_background == fc->max_background) made in different time may behave not like expected. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/control.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/fs/fuse/control.c b/fs/fuse/control.c index acc35819aae6..eaa0e2b21623 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -125,7 +125,12 @@ static ssize_t fuse_conn_max_background_write(struct file *file, if (ret > 0) { struct fuse_conn *fc = fuse_ctl_file_conn_get(file); if (fc) { + spin_lock(&fc->lock); fc->max_background = val; + fc->blocked = fc->num_background >= fc->max_background; + if (!fc->blocked) + wake_up(&fc->blocked_waitq); + spin_unlock(&fc->lock); fuse_conn_put(fc); } } @@ -155,18 +160,31 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, size_t count, loff_t *ppos) { unsigned uninitialized_var(val); + struct fuse_conn *fc; ssize_t ret; ret = fuse_conn_limit_write(file, buf, count, ppos, &val, max_user_congthresh); - if (ret > 0) { - struct fuse_conn *fc = fuse_ctl_file_conn_get(file); - if (fc) { - fc->congestion_threshold = val; - fuse_conn_put(fc); + if (ret <= 0) + goto out; + fc = fuse_ctl_file_conn_get(file); + if (!fc) + goto out; + + spin_lock(&fc->lock); + fc->congestion_threshold = val; + if (fc->sb) { + if (fc->num_background < fc->congestion_threshold) { + clear_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); + clear_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); + } else { + set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); + set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); } } - + spin_unlock(&fc->lock); + fuse_conn_put(fc); +out: return ret; } From ae2dffa39485c6fd4f22321814c7287c274b473a Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 27 Aug 2018 18:29:46 +0300 Subject: [PATCH 154/836] fuse: introduce fc->bg_lock To reduce contention of fc->lock, this patch introduces bg_lock for protection of fields related to background queue. These are: max_background, congestion_threshold, num_background, active_background, bg_queue and blocked. This allows next patch to make async reads not requiring fc->lock, so async reads and writes will have better performance executed in parallel. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/control.c | 8 ++++---- fs/fuse/dev.c | 20 ++++++++++++-------- fs/fuse/file.c | 2 +- fs/fuse/fuse_i.h | 8 ++++++-- fs/fuse/inode.c | 3 +++ 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/fs/fuse/control.c b/fs/fuse/control.c index eaa0e2b21623..989df5accaee 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -125,12 +125,12 @@ static ssize_t fuse_conn_max_background_write(struct file *file, if (ret > 0) { struct fuse_conn *fc = fuse_ctl_file_conn_get(file); if (fc) { - spin_lock(&fc->lock); + spin_lock(&fc->bg_lock); fc->max_background = val; fc->blocked = fc->num_background >= fc->max_background; if (!fc->blocked) wake_up(&fc->blocked_waitq); - spin_unlock(&fc->lock); + spin_unlock(&fc->bg_lock); fuse_conn_put(fc); } } @@ -171,7 +171,7 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, if (!fc) goto out; - spin_lock(&fc->lock); + spin_lock(&fc->bg_lock); fc->congestion_threshold = val; if (fc->sb) { if (fc->num_background < fc->congestion_threshold) { @@ -182,7 +182,7 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); } } - spin_unlock(&fc->lock); + spin_unlock(&fc->bg_lock); fuse_conn_put(fc); out: return ret; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 6a7d3b4424e1..d4b9ffc6544d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -287,10 +287,10 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) * We get here in the unlikely case that a background * request was allocated but not sent */ - spin_lock(&fc->lock); + spin_lock(&fc->bg_lock); if (!fc->blocked) wake_up(&fc->blocked_waitq); - spin_unlock(&fc->lock); + spin_unlock(&fc->bg_lock); } if (test_bit(FR_WAITING, &req->flags)) { @@ -390,7 +390,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) WARN_ON(test_bit(FR_PENDING, &req->flags)); WARN_ON(test_bit(FR_SENT, &req->flags)); if (test_bit(FR_BACKGROUND, &req->flags)) { - spin_lock(&fc->lock); + spin_lock(&fc->bg_lock); clear_bit(FR_BACKGROUND, &req->flags); if (fc->num_background == fc->max_background) { fc->blocked = 0; @@ -413,7 +413,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) fc->num_background--; fc->active_background--; flush_bg_queue(fc); - spin_unlock(&fc->lock); + spin_unlock(&fc->bg_lock); } wake_up(&req->waitq); if (req->end) @@ -586,8 +586,8 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) * * fc->connected must have been checked previously */ -void fuse_request_send_background_locked(struct fuse_conn *fc, - struct fuse_req *req) +void fuse_request_send_background_nocheck(struct fuse_conn *fc, + struct fuse_req *req) { BUG_ON(!test_bit(FR_BACKGROUND, &req->flags)); if (!test_bit(FR_WAITING, &req->flags)) { @@ -595,6 +595,7 @@ void fuse_request_send_background_locked(struct fuse_conn *fc, atomic_inc(&fc->num_waiting); } __set_bit(FR_ISREPLY, &req->flags); + spin_lock(&fc->bg_lock); fc->num_background++; if (fc->num_background == fc->max_background) fc->blocked = 1; @@ -604,6 +605,7 @@ void fuse_request_send_background_locked(struct fuse_conn *fc, } list_add_tail(&req->list, &fc->bg_queue); flush_bg_queue(fc); + spin_unlock(&fc->bg_lock); } void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) @@ -611,7 +613,7 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) BUG_ON(!req->end); spin_lock(&fc->lock); if (fc->connected) { - fuse_request_send_background_locked(fc, req); + fuse_request_send_background_nocheck(fc, req); spin_unlock(&fc->lock); } else { spin_unlock(&fc->lock); @@ -2118,7 +2120,6 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort) LIST_HEAD(to_end); fc->connected = 0; - fc->blocked = 0; fc->aborted = is_abort; fuse_set_initialized(fc); list_for_each_entry(fud, &fc->devices, entry) { @@ -2140,8 +2141,11 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort) list_splice_tail_init(&fpq->processing, &to_end); spin_unlock(&fpq->lock); } + spin_lock(&fc->bg_lock); + fc->blocked = 0; fc->max_background = UINT_MAX; flush_bg_queue(fc); + spin_unlock(&fc->bg_lock); spin_lock(&fiq->waitq.lock); fiq->connected = 0; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 63136a2c23ab..65351d43c2b6 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1502,7 +1502,7 @@ __acquires(fc->lock) req->in.args[1].size = inarg->size; fi->writectr++; - fuse_request_send_background_locked(fc, req); + fuse_request_send_background_nocheck(fc, req); return; out_free: diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 3e45d408a644..d6d55641a5a6 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -500,6 +500,10 @@ struct fuse_conn { /** The list of background requests set aside for later queuing */ struct list_head bg_queue; + /** Protects: max_background, congestion_threshold, num_background, + * active_background, bg_queue, blocked */ + spinlock_t bg_lock; + /** Flag indicating that INIT reply has been received. Allocating * any fuse request will be suspended until the flag is set */ int initialized; @@ -860,8 +864,8 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args); */ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req); -void fuse_request_send_background_locked(struct fuse_conn *fc, - struct fuse_req *req); +void fuse_request_send_background_nocheck(struct fuse_conn *fc, + struct fuse_req *req); /* Abort all requests */ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index db9e60b7eb69..ed3f49628ce2 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -605,6 +605,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns) { memset(fc, 0, sizeof(*fc)); spin_lock_init(&fc->lock); + spin_lock_init(&fc->bg_lock); init_rwsem(&fc->killsb); refcount_set(&fc->count, 1); atomic_set(&fc->dev_count, 1); @@ -852,6 +853,7 @@ static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg) sanitize_global_limit(&max_user_bgreq); sanitize_global_limit(&max_user_congthresh); + spin_lock(&fc->bg_lock); if (arg->max_background) { fc->max_background = arg->max_background; @@ -865,6 +867,7 @@ static void process_init_limits(struct fuse_conn *fc, struct fuse_init_out *arg) fc->congestion_threshold > max_user_congthresh) fc->congestion_threshold = max_user_congthresh; } + spin_unlock(&fc->bg_lock); } static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) From 63825b4e1da5a3cba79d835a5925e5daf7db3a77 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Mon, 27 Aug 2018 18:29:56 +0300 Subject: [PATCH 155/836] fuse: do not take fc->lock in fuse_request_send_background() Currently, we take fc->lock there only to check for fc->connected. But this flag is changed only on connection abort, which is very rare operation. So allow checking fc->connected under just fc->bg_lock and use this lock (as well as fc->lock) when resetting fc->connected. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 46 +++++++++++++++++++++++----------------------- fs/fuse/file.c | 4 +++- fs/fuse/fuse_i.h | 4 +--- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index d4b9ffc6544d..071feb8cb265 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -581,42 +581,38 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) return ret; } -/* - * Called under fc->lock - * - * fc->connected must have been checked previously - */ -void fuse_request_send_background_nocheck(struct fuse_conn *fc, - struct fuse_req *req) +bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req) { - BUG_ON(!test_bit(FR_BACKGROUND, &req->flags)); + bool queued = false; + + WARN_ON(!test_bit(FR_BACKGROUND, &req->flags)); if (!test_bit(FR_WAITING, &req->flags)) { __set_bit(FR_WAITING, &req->flags); atomic_inc(&fc->num_waiting); } __set_bit(FR_ISREPLY, &req->flags); spin_lock(&fc->bg_lock); - fc->num_background++; - if (fc->num_background == fc->max_background) - fc->blocked = 1; - if (fc->num_background == fc->congestion_threshold && fc->sb) { - set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); - set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); + if (likely(fc->connected)) { + fc->num_background++; + if (fc->num_background == fc->max_background) + fc->blocked = 1; + if (fc->num_background == fc->congestion_threshold && fc->sb) { + set_bdi_congested(fc->sb->s_bdi, BLK_RW_SYNC); + set_bdi_congested(fc->sb->s_bdi, BLK_RW_ASYNC); + } + list_add_tail(&req->list, &fc->bg_queue); + flush_bg_queue(fc); + queued = true; } - list_add_tail(&req->list, &fc->bg_queue); - flush_bg_queue(fc); spin_unlock(&fc->bg_lock); + + return queued; } void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) { - BUG_ON(!req->end); - spin_lock(&fc->lock); - if (fc->connected) { - fuse_request_send_background_nocheck(fc, req); - spin_unlock(&fc->lock); - } else { - spin_unlock(&fc->lock); + WARN_ON(!req->end); + if (!fuse_request_queue_background(fc, req)) { req->out.h.error = -ENOTCONN; req->end(fc, req); fuse_put_request(fc, req); @@ -2119,7 +2115,11 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort) struct fuse_req *req, *next; LIST_HEAD(to_end); + /* Background queuing checks fc->connected under bg_lock */ + spin_lock(&fc->bg_lock); fc->connected = 0; + spin_unlock(&fc->bg_lock); + fc->aborted = is_abort; fuse_set_initialized(fc); list_for_each_entry(fud, &fc->devices, entry) { diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 65351d43c2b6..d15c14912e72 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1487,6 +1487,7 @@ __acquires(fc->lock) struct fuse_inode *fi = get_fuse_inode(req->inode); struct fuse_write_in *inarg = &req->misc.write.in; __u64 data_size = req->num_pages * PAGE_SIZE; + bool queued; if (!fc->connected) goto out_free; @@ -1502,7 +1503,8 @@ __acquires(fc->lock) req->in.args[1].size = inarg->size; fi->writectr++; - fuse_request_send_background_nocheck(fc, req); + queued = fuse_request_queue_background(fc, req); + WARN_ON(!queued); return; out_free: diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d6d55641a5a6..6e6eab8127a4 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -863,9 +863,7 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args); * Send a request in the background */ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req); - -void fuse_request_send_background_nocheck(struct fuse_conn *fc, - struct fuse_req *req); +bool fuse_request_queue_background(struct fuse_conn *fc, struct fuse_req *req); /* Abort all requests */ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort); From c59fd85e4fd07fdf0ab523a5e9734f5338d6aa19 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Tue, 11 Sep 2018 13:11:56 +0300 Subject: [PATCH 156/836] fuse: change interrupt requests allocation algorithm Using of two unconnected IDs req->in.h.unique and req->intr_unique does not allow to link requests to a hash table. We need can't use none of them as a key to calculate hash. This patch changes the algorithm of allocation of IDs for a request. Plain requests obtain even ID, while interrupt requests are encoded in the low bit. So, in next patches we will be able to use the rest of ID bits to calculate hash, and the hash will be the same for plain and interrupt requests. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 071feb8cb265..38bb46ab2d7b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -25,6 +25,10 @@ MODULE_ALIAS_MISCDEV(FUSE_MINOR); MODULE_ALIAS("devname:fuse"); +/* Ordinary requests have even IDs, while interrupts IDs are odd */ +#define FUSE_INT_REQ_BIT (1ULL << 0) +#define FUSE_REQ_ID_STEP (1ULL << 1) + static struct kmem_cache *fuse_req_cachep; static struct fuse_dev *fuse_get_dev(struct file *file) @@ -319,7 +323,8 @@ static unsigned len_args(unsigned numargs, struct fuse_arg *args) static u64 fuse_get_unique(struct fuse_iqueue *fiq) { - return ++fiq->reqctr; + fiq->reqctr += FUSE_REQ_ID_STEP; + return fiq->reqctr; } static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req) @@ -1090,7 +1095,7 @@ __releases(fiq->waitq.lock) int err; list_del_init(&req->intr_entry); - req->intr_unique = fuse_get_unique(fiq); + req->intr_unique = (req->in.h.unique | FUSE_INT_REQ_BIT); memset(&ih, 0, sizeof(ih)); memset(&arg, 0, sizeof(arg)); ih.len = reqsize; From 3a5358d1a1b70bb3360578f09894d6856629ecdf Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Tue, 11 Sep 2018 13:12:05 +0300 Subject: [PATCH 157/836] fuse: kill req->intr_unique This field is not needed after the previous patch, since we can easily convert request ID to interrupt request ID and vice versa. Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 11 +++++------ fs/fuse/fuse_i.h | 3 --- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 38bb46ab2d7b..eee43057b99b 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1095,12 +1095,11 @@ __releases(fiq->waitq.lock) int err; list_del_init(&req->intr_entry); - req->intr_unique = (req->in.h.unique | FUSE_INT_REQ_BIT); memset(&ih, 0, sizeof(ih)); memset(&arg, 0, sizeof(arg)); ih.len = reqsize; ih.opcode = FUSE_INTERRUPT; - ih.unique = req->intr_unique; + ih.unique = (req->in.h.unique | FUSE_INT_REQ_BIT); arg.unique = req->in.h.unique; spin_unlock(&fiq->waitq.lock); @@ -1808,7 +1807,7 @@ static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique) struct fuse_req *req; list_for_each_entry(req, &fpq->processing, list) { - if (req->in.h.unique == unique || req->intr_unique == unique) + if (req->in.h.unique == unique) return req; } return NULL; @@ -1882,12 +1881,12 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, if (!fpq->connected) goto err_unlock_pq; - req = request_find(fpq, oh.unique); + req = request_find(fpq, oh.unique & ~FUSE_INT_REQ_BIT); if (!req) goto err_unlock_pq; - /* Is it an interrupt reply? */ - if (req->intr_unique == oh.unique) { + /* Is it an interrupt reply ID? */ + if (oh.unique & FUSE_INT_REQ_BIT) { __fuse_get_request(req); spin_unlock(&fpq->lock); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 6e6eab8127a4..1d7b5b7a051d 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -311,9 +311,6 @@ struct fuse_req { /** refcount */ refcount_t count; - /** Unique ID for the interrupt request */ - u64 intr_unique; - /* Request flags, updated with test/set/clear_bit() */ unsigned long flags; From be2ff42c5d6ebc8552c82a7d1697afae30510ed9 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Tue, 11 Sep 2018 13:12:14 +0300 Subject: [PATCH 158/836] fuse: Use hash table to link processing request We noticed the performance bottleneck in FUSE running our Virtuozzo storage over rdma. On some types of workload we observe 20% of times spent in request_find() in profiler. This function is iterating over long requests list, and it scales bad. The patch introduces hash table to reduce the number of iterations, we do in this function. Hash generating algorithm is taken from hash_add() function, while 256 lines table is used to store pending requests. This fixes problem and improves the performance. Reported-by: Alexey Kuznetsov Signed-off-by: Kirill Tkhai Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 21 +++++++++++++++++---- fs/fuse/fuse_i.h | 7 +++++-- fs/fuse/inode.c | 27 +++++++++++++++++++-------- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index eee43057b99b..91b4ecf85dc7 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -327,6 +327,11 @@ static u64 fuse_get_unique(struct fuse_iqueue *fiq) return fiq->reqctr; } +static unsigned int fuse_req_hash(u64 unique) +{ + return hash_long(unique & ~FUSE_INT_REQ_BIT, FUSE_PQ_HASH_BITS); +} + static void queue_request(struct fuse_iqueue *fiq, struct fuse_req *req) { req->in.h.len = sizeof(struct fuse_in_header) + @@ -1248,6 +1253,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, struct fuse_req *req; struct fuse_in *in; unsigned reqsize; + unsigned int hash; restart: spin_lock(&fiq->waitq.lock); @@ -1320,7 +1326,8 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, err = reqsize; goto out_end; } - list_move_tail(&req->list, &fpq->processing); + hash = fuse_req_hash(req->in.h.unique); + list_move_tail(&req->list, &fpq->processing[hash]); __fuse_get_request(req); set_bit(FR_SENT, &req->flags); spin_unlock(&fpq->lock); @@ -1804,9 +1811,10 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code, /* Look up request on processing list by unique ID */ static struct fuse_req *request_find(struct fuse_pqueue *fpq, u64 unique) { + unsigned int hash = fuse_req_hash(unique); struct fuse_req *req; - list_for_each_entry(req, &fpq->processing, list) { + list_for_each_entry(req, &fpq->processing[hash], list) { if (req->in.h.unique == unique) return req; } @@ -2118,6 +2126,7 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort) struct fuse_dev *fud; struct fuse_req *req, *next; LIST_HEAD(to_end); + unsigned int i; /* Background queuing checks fc->connected under bg_lock */ spin_lock(&fc->bg_lock); @@ -2142,7 +2151,9 @@ void fuse_abort_conn(struct fuse_conn *fc, bool is_abort) } spin_unlock(&req->waitq.lock); } - list_splice_tail_init(&fpq->processing, &to_end); + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) + list_splice_tail_init(&fpq->processing[i], + &to_end); spin_unlock(&fpq->lock); } spin_lock(&fc->bg_lock); @@ -2185,10 +2196,12 @@ int fuse_dev_release(struct inode *inode, struct file *file) struct fuse_conn *fc = fud->fc; struct fuse_pqueue *fpq = &fud->pq; LIST_HEAD(to_end); + unsigned int i; spin_lock(&fpq->lock); WARN_ON(!list_empty(&fpq->io)); - list_splice_init(&fpq->processing, &to_end); + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) + list_splice_init(&fpq->processing[i], &to_end); spin_unlock(&fpq->lock); end_requests(fc, &to_end); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1d7b5b7a051d..2c4272076f62 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -408,6 +408,9 @@ struct fuse_iqueue { struct fasync_struct *fasync; }; +#define FUSE_PQ_HASH_BITS 8 +#define FUSE_PQ_HASH_SIZE (1 << FUSE_PQ_HASH_BITS) + struct fuse_pqueue { /** Connection established */ unsigned connected; @@ -415,8 +418,8 @@ struct fuse_pqueue { /** Lock protecting accessess to members of this structure */ spinlock_t lock; - /** The list of requests being processed */ - struct list_head processing; + /** Hash table of requests being processed */ + struct list_head *processing; /** The list of requests under I/O */ struct list_head io; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ed3f49628ce2..9383b47b3d9b 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -594,9 +594,11 @@ static void fuse_iqueue_init(struct fuse_iqueue *fiq) static void fuse_pqueue_init(struct fuse_pqueue *fpq) { - memset(fpq, 0, sizeof(struct fuse_pqueue)); + unsigned int i; + spin_lock_init(&fpq->lock); - INIT_LIST_HEAD(&fpq->processing); + for (i = 0; i < FUSE_PQ_HASH_SIZE; i++) + INIT_LIST_HEAD(&fpq->processing[i]); INIT_LIST_HEAD(&fpq->io); fpq->connected = 1; } @@ -1025,17 +1027,26 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc) { struct fuse_dev *fud; + struct list_head *pq; fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL); - if (fud) { - fud->fc = fuse_conn_get(fc); - fuse_pqueue_init(&fud->pq); + if (!fud) + return NULL; - spin_lock(&fc->lock); - list_add_tail(&fud->entry, &fc->devices); - spin_unlock(&fc->lock); + pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL); + if (!pq) { + kfree(fud); + return NULL; } + fud->pq.processing = pq; + fud->fc = fuse_conn_get(fc); + fuse_pqueue_init(&fud->pq); + + spin_lock(&fc->lock); + list_add_tail(&fud->entry, &fc->devices); + spin_unlock(&fc->lock); + return fud; } EXPORT_SYMBOL_GPL(fuse_dev_alloc); From d123d8e1833c5d854b56f2a7da17cafd0a901df8 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 28 Sep 2018 16:43:23 +0200 Subject: [PATCH 159/836] fuse: split out readdir.c Directory reading code is about to grow larger, so split it out from dir.c into a new source file. Signed-off-by: Miklos Szeredi --- fs/fuse/Makefile | 2 +- fs/fuse/dir.c | 259 +--------------------------------------------- fs/fuse/fuse_i.h | 12 +++ fs/fuse/readdir.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 274 insertions(+), 258 deletions(-) create mode 100644 fs/fuse/readdir.c diff --git a/fs/fuse/Makefile b/fs/fuse/Makefile index 60da84a86dab..f7b807bc1027 100644 --- a/fs/fuse/Makefile +++ b/fs/fuse/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_FUSE_FS) += fuse.o obj-$(CONFIG_CUSE) += cuse.o -fuse-objs := dev.o dir.o file.o inode.o control.o xattr.o acl.o +fuse-objs := dev.o dir.o file.o inode.o control.o xattr.o acl.o readdir.o diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 0979609d6eba..3a333b0ea9ad 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -16,22 +16,6 @@ #include #include -static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) -{ - struct fuse_conn *fc = get_fuse_conn(dir); - struct fuse_inode *fi = get_fuse_inode(dir); - - if (!fc->do_readdirplus) - return false; - if (!fc->readdirplus_auto) - return true; - if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state)) - return true; - if (ctx->pos == 0) - return true; - return false; -} - static void fuse_advise_use_readdirplus(struct inode *dir) { struct fuse_inode *fi = get_fuse_inode(dir); @@ -80,8 +64,7 @@ static u64 time_to_jiffies(u64 sec, u32 nsec) * Set dentry and possibly attribute timeouts from the lookup/mk* * replies */ -static void fuse_change_entry_timeout(struct dentry *entry, - struct fuse_entry_out *o) +void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o) { fuse_dentry_settime(entry, time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); @@ -92,7 +75,7 @@ static u64 attr_timeout(struct fuse_attr_out *o) return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); } -static u64 entry_attr_timeout(struct fuse_entry_out *o) +u64 entry_attr_timeout(struct fuse_entry_out *o) { return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); } @@ -262,11 +245,6 @@ invalid: goto out; } -static int invalid_nodeid(u64 nodeid) -{ - return !nodeid || nodeid == FUSE_ROOT_ID; -} - static int fuse_dentry_init(struct dentry *dentry) { dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL); @@ -1165,239 +1143,6 @@ static int fuse_permission(struct inode *inode, int mask) return err; } -static int parse_dirfile(char *buf, size_t nbytes, struct file *file, - struct dir_context *ctx) -{ - while (nbytes >= FUSE_NAME_OFFSET) { - struct fuse_dirent *dirent = (struct fuse_dirent *) buf; - size_t reclen = FUSE_DIRENT_SIZE(dirent); - if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) - return -EIO; - if (reclen > nbytes) - break; - if (memchr(dirent->name, '/', dirent->namelen) != NULL) - return -EIO; - - if (!dir_emit(ctx, dirent->name, dirent->namelen, - dirent->ino, dirent->type)) - break; - - buf += reclen; - nbytes -= reclen; - ctx->pos = dirent->off; - } - - return 0; -} - -static int fuse_direntplus_link(struct file *file, - struct fuse_direntplus *direntplus, - u64 attr_version) -{ - struct fuse_entry_out *o = &direntplus->entry_out; - struct fuse_dirent *dirent = &direntplus->dirent; - struct dentry *parent = file->f_path.dentry; - struct qstr name = QSTR_INIT(dirent->name, dirent->namelen); - struct dentry *dentry; - struct dentry *alias; - struct inode *dir = d_inode(parent); - struct fuse_conn *fc; - struct inode *inode; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); - - if (!o->nodeid) { - /* - * Unlike in the case of fuse_lookup, zero nodeid does not mean - * ENOENT. Instead, it only means the userspace filesystem did - * not want to return attributes/handle for this entry. - * - * So do nothing. - */ - return 0; - } - - if (name.name[0] == '.') { - /* - * We could potentially refresh the attributes of the directory - * and its parent? - */ - if (name.len == 1) - return 0; - if (name.name[1] == '.' && name.len == 2) - return 0; - } - - if (invalid_nodeid(o->nodeid)) - return -EIO; - if (!fuse_valid_type(o->attr.mode)) - return -EIO; - - fc = get_fuse_conn(dir); - - name.hash = full_name_hash(parent, name.name, name.len); - dentry = d_lookup(parent, &name); - if (!dentry) { -retry: - dentry = d_alloc_parallel(parent, &name, &wq); - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - } - if (!d_in_lookup(dentry)) { - struct fuse_inode *fi; - inode = d_inode(dentry); - if (!inode || - get_node_id(inode) != o->nodeid || - ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { - d_invalidate(dentry); - dput(dentry); - goto retry; - } - if (is_bad_inode(inode)) { - dput(dentry); - return -EIO; - } - - fi = get_fuse_inode(inode); - spin_lock(&fc->lock); - fi->nlookup++; - spin_unlock(&fc->lock); - - forget_all_cached_acls(inode); - fuse_change_attributes(inode, &o->attr, - entry_attr_timeout(o), - attr_version); - /* - * The other branch comes via fuse_iget() - * which bumps nlookup inside - */ - } else { - inode = fuse_iget(dir->i_sb, o->nodeid, o->generation, - &o->attr, entry_attr_timeout(o), - attr_version); - if (!inode) - inode = ERR_PTR(-ENOMEM); - - alias = d_splice_alias(inode, dentry); - d_lookup_done(dentry); - if (alias) { - dput(dentry); - dentry = alias; - } - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - } - if (fc->readdirplus_auto) - set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); - fuse_change_entry_timeout(dentry, o); - - dput(dentry); - return 0; -} - -static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, - struct dir_context *ctx, u64 attr_version) -{ - struct fuse_direntplus *direntplus; - struct fuse_dirent *dirent; - size_t reclen; - int over = 0; - int ret; - - while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) { - direntplus = (struct fuse_direntplus *) buf; - dirent = &direntplus->dirent; - reclen = FUSE_DIRENTPLUS_SIZE(direntplus); - - if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) - return -EIO; - if (reclen > nbytes) - break; - if (memchr(dirent->name, '/', dirent->namelen) != NULL) - return -EIO; - - if (!over) { - /* We fill entries into dstbuf only as much as - it can hold. But we still continue iterating - over remaining entries to link them. If not, - we need to send a FORGET for each of those - which we did not link. - */ - over = !dir_emit(ctx, dirent->name, dirent->namelen, - dirent->ino, dirent->type); - if (!over) - ctx->pos = dirent->off; - } - - buf += reclen; - nbytes -= reclen; - - ret = fuse_direntplus_link(file, direntplus, attr_version); - if (ret) - fuse_force_forget(file, direntplus->entry_out.nodeid); - } - - return 0; -} - -static int fuse_readdir(struct file *file, struct dir_context *ctx) -{ - int plus, err; - size_t nbytes; - struct page *page; - struct inode *inode = file_inode(file); - struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_req *req; - u64 attr_version = 0; - bool locked; - - if (is_bad_inode(inode)) - return -EIO; - - req = fuse_get_req(fc, 1); - if (IS_ERR(req)) - return PTR_ERR(req); - - page = alloc_page(GFP_KERNEL); - if (!page) { - fuse_put_request(fc, req); - return -ENOMEM; - } - - plus = fuse_use_readdirplus(inode, ctx); - req->out.argpages = 1; - req->num_pages = 1; - req->pages[0] = page; - req->page_descs[0].length = PAGE_SIZE; - if (plus) { - attr_version = fuse_get_attr_version(fc); - fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, - FUSE_READDIRPLUS); - } else { - fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, - FUSE_READDIR); - } - locked = fuse_lock_inode(inode); - fuse_request_send(fc, req); - fuse_unlock_inode(inode, locked); - nbytes = req->out.args[0].size; - err = req->out.h.error; - fuse_put_request(fc, req); - if (!err) { - if (plus) { - err = parse_dirplusfile(page_address(page), nbytes, - file, ctx, - attr_version); - } else { - err = parse_dirfile(page_address(page), nbytes, file, - ctx); - } - } - - __free_page(page); - fuse_invalidate_atime(inode); - return err; -} - static const char *fuse_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 2c4272076f62..dfe10c2df6a9 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -704,6 +704,11 @@ static inline u64 get_node_id(struct inode *inode) return get_fuse_inode(inode)->nodeid; } +static inline int invalid_nodeid(u64 nodeid) +{ + return !nodeid || nodeid == FUSE_ROOT_ID; +} + /** Device operations */ extern const struct file_operations fuse_dev_operations; @@ -878,6 +883,9 @@ void fuse_invalidate_entry_cache(struct dentry *entry); void fuse_invalidate_atime(struct inode *inode); +u64 entry_attr_timeout(struct fuse_entry_out *o); +void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o); + /** * Acquire reference to fuse_conn */ @@ -997,4 +1005,8 @@ struct posix_acl; struct posix_acl *fuse_get_acl(struct inode *inode, int type); int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type); + +/* readdir.c */ +int fuse_readdir(struct file *file, struct dir_context *ctx); + #endif /* _FS_FUSE_I_H */ diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c new file mode 100644 index 000000000000..3e100e00e21e --- /dev/null +++ b/fs/fuse/readdir.c @@ -0,0 +1,259 @@ +/* + FUSE: Filesystem in Userspace + Copyright (C) 2001-2018 Miklos Szeredi + + This program can be distributed under the terms of the GNU GPL. + See the file COPYING. +*/ + + +#include "fuse_i.h" +#include + +static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) +{ + struct fuse_conn *fc = get_fuse_conn(dir); + struct fuse_inode *fi = get_fuse_inode(dir); + + if (!fc->do_readdirplus) + return false; + if (!fc->readdirplus_auto) + return true; + if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state)) + return true; + if (ctx->pos == 0) + return true; + return false; +} + +static int parse_dirfile(char *buf, size_t nbytes, struct file *file, + struct dir_context *ctx) +{ + while (nbytes >= FUSE_NAME_OFFSET) { + struct fuse_dirent *dirent = (struct fuse_dirent *) buf; + size_t reclen = FUSE_DIRENT_SIZE(dirent); + if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) + return -EIO; + if (reclen > nbytes) + break; + if (memchr(dirent->name, '/', dirent->namelen) != NULL) + return -EIO; + + if (!dir_emit(ctx, dirent->name, dirent->namelen, + dirent->ino, dirent->type)) + break; + + buf += reclen; + nbytes -= reclen; + ctx->pos = dirent->off; + } + + return 0; +} + +static int fuse_direntplus_link(struct file *file, + struct fuse_direntplus *direntplus, + u64 attr_version) +{ + struct fuse_entry_out *o = &direntplus->entry_out; + struct fuse_dirent *dirent = &direntplus->dirent; + struct dentry *parent = file->f_path.dentry; + struct qstr name = QSTR_INIT(dirent->name, dirent->namelen); + struct dentry *dentry; + struct dentry *alias; + struct inode *dir = d_inode(parent); + struct fuse_conn *fc; + struct inode *inode; + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); + + if (!o->nodeid) { + /* + * Unlike in the case of fuse_lookup, zero nodeid does not mean + * ENOENT. Instead, it only means the userspace filesystem did + * not want to return attributes/handle for this entry. + * + * So do nothing. + */ + return 0; + } + + if (name.name[0] == '.') { + /* + * We could potentially refresh the attributes of the directory + * and its parent? + */ + if (name.len == 1) + return 0; + if (name.name[1] == '.' && name.len == 2) + return 0; + } + + if (invalid_nodeid(o->nodeid)) + return -EIO; + if (!fuse_valid_type(o->attr.mode)) + return -EIO; + + fc = get_fuse_conn(dir); + + name.hash = full_name_hash(parent, name.name, name.len); + dentry = d_lookup(parent, &name); + if (!dentry) { +retry: + dentry = d_alloc_parallel(parent, &name, &wq); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + } + if (!d_in_lookup(dentry)) { + struct fuse_inode *fi; + inode = d_inode(dentry); + if (!inode || + get_node_id(inode) != o->nodeid || + ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { + d_invalidate(dentry); + dput(dentry); + goto retry; + } + if (is_bad_inode(inode)) { + dput(dentry); + return -EIO; + } + + fi = get_fuse_inode(inode); + spin_lock(&fc->lock); + fi->nlookup++; + spin_unlock(&fc->lock); + + forget_all_cached_acls(inode); + fuse_change_attributes(inode, &o->attr, + entry_attr_timeout(o), + attr_version); + /* + * The other branch comes via fuse_iget() + * which bumps nlookup inside + */ + } else { + inode = fuse_iget(dir->i_sb, o->nodeid, o->generation, + &o->attr, entry_attr_timeout(o), + attr_version); + if (!inode) + inode = ERR_PTR(-ENOMEM); + + alias = d_splice_alias(inode, dentry); + d_lookup_done(dentry); + if (alias) { + dput(dentry); + dentry = alias; + } + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + } + if (fc->readdirplus_auto) + set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); + fuse_change_entry_timeout(dentry, o); + + dput(dentry); + return 0; +} + +static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, + struct dir_context *ctx, u64 attr_version) +{ + struct fuse_direntplus *direntplus; + struct fuse_dirent *dirent; + size_t reclen; + int over = 0; + int ret; + + while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) { + direntplus = (struct fuse_direntplus *) buf; + dirent = &direntplus->dirent; + reclen = FUSE_DIRENTPLUS_SIZE(direntplus); + + if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) + return -EIO; + if (reclen > nbytes) + break; + if (memchr(dirent->name, '/', dirent->namelen) != NULL) + return -EIO; + + if (!over) { + /* We fill entries into dstbuf only as much as + it can hold. But we still continue iterating + over remaining entries to link them. If not, + we need to send a FORGET for each of those + which we did not link. + */ + over = !dir_emit(ctx, dirent->name, dirent->namelen, + dirent->ino, dirent->type); + if (!over) + ctx->pos = dirent->off; + } + + buf += reclen; + nbytes -= reclen; + + ret = fuse_direntplus_link(file, direntplus, attr_version); + if (ret) + fuse_force_forget(file, direntplus->entry_out.nodeid); + } + + return 0; +} + +int fuse_readdir(struct file *file, struct dir_context *ctx) +{ + int plus, err; + size_t nbytes; + struct page *page; + struct inode *inode = file_inode(file); + struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_req *req; + u64 attr_version = 0; + bool locked; + + if (is_bad_inode(inode)) + return -EIO; + + req = fuse_get_req(fc, 1); + if (IS_ERR(req)) + return PTR_ERR(req); + + page = alloc_page(GFP_KERNEL); + if (!page) { + fuse_put_request(fc, req); + return -ENOMEM; + } + + plus = fuse_use_readdirplus(inode, ctx); + req->out.argpages = 1; + req->num_pages = 1; + req->pages[0] = page; + req->page_descs[0].length = PAGE_SIZE; + if (plus) { + attr_version = fuse_get_attr_version(fc); + fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, + FUSE_READDIRPLUS); + } else { + fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, + FUSE_READDIR); + } + locked = fuse_lock_inode(inode); + fuse_request_send(fc, req); + fuse_unlock_inode(inode, locked); + nbytes = req->out.args[0].size; + err = req->out.h.error; + fuse_put_request(fc, req); + if (!err) { + if (plus) { + err = parse_dirplusfile(page_address(page), nbytes, + file, ctx, attr_version); + } else { + err = parse_dirfile(page_address(page), nbytes, file, + ctx); + } + } + + __free_page(page); + fuse_invalidate_atime(inode); + return err; +} From 6433b8998a21dc597002731c4ceb4144e856edc4 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 28 Sep 2018 16:43:23 +0200 Subject: [PATCH 160/836] fuse: add FOPEN_CACHE_DIR Add flag returned by OPENDIR request to allow kernel to cache directory contents in page cache. The effect of FOPEN_CACHE_DIR is twofold: a) if not already cached, it writes entries into the cache b) if already cached, it allows reading entries from the cache The FOPEN_KEEP_CACHE has the same effect as on regular files: unless this flag is given the cache is cleared upon completion of open. So FOPEN_KEEP_CACHE and FOPEN_KEEP_CACHE flags should be used together to make use of the directory caching facility introduced in the following patches. The FUSE_AUTO_INVAL_DATA flag returned in INIT reply also has the same affect on the directory cache as it has on data cache for regular files. Signed-off-by: Miklos Szeredi --- include/uapi/linux/fuse.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index d27b50a44f74..31a504f1ee60 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -119,6 +119,7 @@ * * 7.28 * - add FUSE_COPY_FILE_RANGE + * - add FOPEN_CACHE_DIR */ #ifndef _LINUX_FUSE_H @@ -222,10 +223,12 @@ struct fuse_file_lock { * FOPEN_DIRECT_IO: bypass page cache for this open file * FOPEN_KEEP_CACHE: don't invalidate the data cache on open * FOPEN_NONSEEKABLE: the file is not seekable + * FOPEN_CACHE_DIR: allow caching this directory */ #define FOPEN_DIRECT_IO (1 << 0) #define FOPEN_KEEP_CACHE (1 << 1) #define FOPEN_NONSEEKABLE (1 << 2) +#define FOPEN_CACHE_DIR (1 << 3) /** * INIT request/reply flags From 18172b10b674a7cd5340b2dd70202ce6622400bd Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 28 Sep 2018 16:43:23 +0200 Subject: [PATCH 161/836] fuse: extract fuse_emit() helper Prepare for cache filling by introducing a helper for emitting a single directory entry. Signed-off-by: Miklos Szeredi --- fs/fuse/readdir.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 3e100e00e21e..65336c93c1f4 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -26,6 +26,13 @@ static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) return false; } +static bool fuse_emit(struct file *file, struct dir_context *ctx, + struct fuse_dirent *dirent) +{ + return dir_emit(ctx, dirent->name, dirent->namelen, dirent->ino, + dirent->type); +} + static int parse_dirfile(char *buf, size_t nbytes, struct file *file, struct dir_context *ctx) { @@ -39,8 +46,7 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file, if (memchr(dirent->name, '/', dirent->namelen) != NULL) return -EIO; - if (!dir_emit(ctx, dirent->name, dirent->namelen, - dirent->ino, dirent->type)) + if (!fuse_emit(file, ctx, dirent)) break; buf += reclen; @@ -183,8 +189,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, we need to send a FORGET for each of those which we did not link. */ - over = !dir_emit(ctx, dirent->name, dirent->namelen, - dirent->ino, dirent->type); + over = !fuse_emit(file, ctx, dirent); if (!over) ctx->pos = dirent->off; } From 9e288cefcc551c7b5b04f8abc7099d3451a70f5f Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 25 Sep 2018 09:34:05 +0200 Subject: [PATCH 162/836] clk: renesas: Convert to SPDX identifiers This patch updates license to use SPDX-License-Identifier instead of verbose license text. Signed-off-by: Kuninori Morimoto [rebased against clk-spdx] Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman Signed-off-by: Stephen Boyd --- drivers/clk/renesas/Kconfig | 2 ++ drivers/clk/renesas/clk-emev2.c | 14 +------------- drivers/clk/renesas/clk-mstp.c | 5 +---- drivers/clk/renesas/clk-r8a73a4.c | 5 +---- drivers/clk/renesas/clk-r8a7740.c | 5 +---- drivers/clk/renesas/clk-r8a7778.c | 5 +---- drivers/clk/renesas/clk-r8a7779.c | 5 +---- drivers/clk/renesas/clk-rcar-gen2.c | 5 +---- drivers/clk/renesas/clk-rz.c | 5 +---- drivers/clk/renesas/clk-sh73a0.c | 5 +---- drivers/clk/renesas/r8a7743-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a7745-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a7790-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a7791-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a7792-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a7794-cpg-mssr.c | 5 +---- drivers/clk/renesas/r8a77970-cpg-mssr.c | 5 +---- drivers/clk/renesas/rcar-gen2-cpg.c | 5 +---- drivers/clk/renesas/rcar-gen2-cpg.h | 7 ++----- drivers/clk/renesas/rcar-gen3-cpg.h | 7 ++----- drivers/clk/renesas/renesas-cpg-mssr.h | 4 ++-- include/linux/clk/renesas.h | 8 ++------ 22 files changed, 27 insertions(+), 95 deletions(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 9022bbe1297e..ab2110f96225 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config CLK_RENESAS bool "Renesas SoC clock support" if COMPILE_TEST && !ARCH_RENESAS default y if ARCH_RENESAS diff --git a/drivers/clk/renesas/clk-emev2.c b/drivers/clk/renesas/clk-emev2.c index a91825471c79..7f3b5f9631bd 100644 --- a/drivers/clk/renesas/clk-emev2.c +++ b/drivers/clk/renesas/clk-emev2.c @@ -1,21 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * EMMA Mobile EV2 common clock framework support * * Copyright (C) 2013 Takashi Yoshii * Copyright (C) 2012 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index e82adcb16a52..7df14bb1cbbc 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R-Car MSTP clocks * @@ -5,10 +6,6 @@ * Copyright (C) 2015 Glider bvba * * Contact: Laurent Pinchart - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c index 7b903ce4c901..e1a9e89defdd 100644 --- a/drivers/clk/renesas/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a73a4 Core CPG Clocks * * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index a7a30d2eca41..d68171263137 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7740 Core CPG Clocks * * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c index 886a8380e912..f986ba34661d 100644 --- a/drivers/clk/renesas/clk-r8a7778.c +++ b/drivers/clk/renesas/clk-r8a7778.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7778 Core CPG Clocks * * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c index 5adcca4656c3..437d92cb0630 100644 --- a/drivers/clk/renesas/clk-r8a7779.c +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7779 Core CPG Clocks * * Copyright (C) 2013, 2014 Horms Solutions Ltd. * * Contact: Simon Horman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index bccd62f2cb09..738b723045ce 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * rcar_gen2 Core CPG Clocks * * Copyright (C) 2013 Ideas On Board SPRL * * Contact: Laurent Pinchart - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c index ac2f86d626b6..7fe8729bf66c 100644 --- a/drivers/clk/renesas/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RZ/A1 Core CPG Clocks * * Copyright (C) 2013 Ideas On Board SPRL * Copyright (C) 2014 Wolfram Sang, Sang Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index bab33610eb6c..576259237666 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * sh73a0 Core CPG Clocks * * Copyright (C) 2014 Ulrich Hecht - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a7743-cpg-mssr.c b/drivers/clk/renesas/r8a7743-cpg-mssr.c index 011c170ec3f9..f880b9cb72e0 100644 --- a/drivers/clk/renesas/r8a7743-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7743-cpg-mssr.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7743 Clock Pulse Generator / Module Standby and Software Reset * * Copyright (C) 2016 Cogent Embedded Inc. - * - * 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; of the License. */ #include diff --git a/drivers/clk/renesas/r8a7745-cpg-mssr.c b/drivers/clk/renesas/r8a7745-cpg-mssr.c index 4b0a9243b748..493874e5ebee 100644 --- a/drivers/clk/renesas/r8a7745-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7745-cpg-mssr.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7745 Clock Pulse Generator / Module Standby and Software Reset * * Copyright (C) 2016 Cogent Embedded Inc. - * - * 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; of the License. */ #include diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c index f936cb74b681..c57cb93f8315 100644 --- a/drivers/clk/renesas/r8a7790-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7790 Clock Pulse Generator / Module Standby and Software Reset * @@ -6,10 +7,6 @@ * Based on clk-rcar-gen2.c * * Copyright (C) 2013 Ideas On Board SPRL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c index 1b91f03b7598..65702debcabb 100644 --- a/drivers/clk/renesas/r8a7791-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7791 Clock Pulse Generator / Module Standby and Software Reset * @@ -6,10 +7,6 @@ * Based on clk-rcar-gen2.c * * Copyright (C) 2013 Ideas On Board SPRL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c index 493e07859f5f..cf8b84a3a060 100644 --- a/drivers/clk/renesas/r8a7792-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7792 Clock Pulse Generator / Module Standby and Software Reset * @@ -6,10 +7,6 @@ * Based on clk-rcar-gen2.c * * Copyright (C) 2013 Ideas On Board SPRL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c index 088f4b79fdfc..c1948693c5c1 100644 --- a/drivers/clk/renesas/r8a7794-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a7794 Clock Pulse Generator / Module Standby and Software Reset * @@ -6,10 +7,6 @@ * Based on clk-rcar-gen2.c * * Copyright (C) 2013 Ideas On Board SPRL - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index f55842917e8d..38509873d06c 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * r8a77970 Clock Pulse Generator / Module Standby and Software Reset * @@ -6,10 +7,6 @@ * Based on r8a7795-cpg-mssr.c * * Copyright (C) 2015 Glider bvba - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #include diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index daf88bc2cdae..f596a2dafcf4 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R-Car Gen2 Clock Pulse Generator * * Copyright (C) 2016 Cogent Embedded Inc. - * - * 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. */ #include diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h index 020a3baad015..bff9551c7a38 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.h +++ b/drivers/clk/renesas/rcar-gen2-cpg.h @@ -1,11 +1,8 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * R-Car Gen2 Clock Pulse Generator * * Copyright (C) 2016 Cogent Embedded Inc. - * - * 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; version 2 of the License. */ #ifndef __CLK_RENESAS_RCAR_GEN2_CPG_H__ diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h index ea4f8fc3c4c9..6ebc4b42c5a3 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.h +++ b/drivers/clk/renesas/rcar-gen3-cpg.h @@ -1,11 +1,8 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * R-Car Gen3 Clock Pulse Generator * * Copyright (C) 2015-2016 Glider bvba - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. */ #ifndef __CLK_RENESAS_RCAR_GEN3_CPG_H__ diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 59b1b30c1dba..d52d1f8da9d7 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -1,5 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * Renesas Clock Pulse Generator / Module Standby and Software Reset * * Copyright (C) 2015 Glider bvba diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index 9ebf1f8243bb..0ebbe2f0b45e 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -1,14 +1,10 @@ -/* +/* SPDX-License-Identifier: GPL-2.0+ + * * Copyright 2013 Ideas On Board SPRL * Copyright 2013, 2014 Horms Solutions Ltd. * * Contact: Laurent Pinchart * Contact: Simon Horman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #ifndef __LINUX_CLK_RENESAS_H_ From 29efbc6aea9d9bd9aa9870a9afc1882046303cf9 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 30 Aug 2018 19:07:27 +0200 Subject: [PATCH 163/836] Compiler Attributes: remove unused attributes __optimize and __deprecate_for_modules are unused in the whole kernel tree. Simply drop them. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler-gcc.h | 2 -- include/linux/compiler.h | 4 ---- include/linux/compiler_types.h | 1 - 3 files changed, 7 deletions(-) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 4d36b27214fd..1302b425e625 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -81,8 +81,6 @@ #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) -#define __optimize(level) __attribute__((__optimize__(level))) - #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) #ifndef __CHECKER__ diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 681d866efb1e..7c0157d50964 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -301,10 +301,6 @@ static inline void *offset_to_ptr(const int *off) #endif /* __ASSEMBLY__ */ -#ifndef __optimize -# define __optimize(level) -#endif - /* Compile time object size, -1 for unknown */ #ifndef __compiletime_object_size # define __compiletime_object_size(obj) -1 diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index db192becfec4..a19562cb047c 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -108,7 +108,6 @@ struct ftrace_likely_data { /* Don't. Just don't. */ #define __deprecated -#define __deprecated_for_modules #endif /* __KERNEL__ */ From 5c67a52f3da0f0d22764f2daec417702695a8112 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 30 Aug 2018 19:13:37 +0200 Subject: [PATCH 164/836] Compiler Attributes: always use the extra-underscores syntax The attribute syntax optionally allows to surround attribute names with "__" in order to avoid collisions with macros of the same name (see https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html). This homogenizes all attributes to use the syntax with underscores. While there are currently only a handful of cases of some TUs defining macros like "error" which may collide with the attributes, this should prevent futures surprises. This has been done only for "standard" attributes supported by the major compilers. In other words, those of third-party tools (e.g. sparse, plugins...) have not been changed for the moment. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler-clang.h | 2 +- include/linux/compiler-gcc.h | 12 +++++----- include/linux/compiler-intel.h | 2 +- include/linux/compiler.h | 8 +++---- include/linux/compiler_types.h | 42 +++++++++++++++++----------------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index b1ce500fe8b3..d11cad61ba5c 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -21,7 +21,7 @@ #define __SANITIZE_ADDRESS__ #endif -#define __no_sanitize_address __attribute__((no_sanitize("address"))) +#define __no_sanitize_address __attribute__((__no_sanitize__("address"))) /* * Not all versions of clang implement the the type-generic versions diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 1302b425e625..7a1de7683df5 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -76,7 +76,7 @@ #endif #ifdef RETPOLINE -#define __noretpoline __attribute__((indirect_branch("keep"))) +#define __noretpoline __attribute__((__indirect_branch__("keep"))) #endif #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) @@ -84,8 +84,8 @@ #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) #ifndef __CHECKER__ -#define __compiletime_warning(message) __attribute__((warning(message))) -#define __compiletime_error(message) __attribute__((error(message))) +#define __compiletime_warning(message) __attribute__((__warning__(message))) +#define __compiletime_error(message) __attribute__((__error__(message))) #ifdef LATENT_ENTROPY_PLUGIN #define __latent_entropy __attribute__((latent_entropy)) @@ -134,7 +134,7 @@ * optimizer that something else uses this function or variable, thus preventing * this. */ -#define __visible __attribute__((externally_visible)) +#define __visible __attribute__((__externally_visible__)) /* gcc version specific checks */ @@ -191,7 +191,7 @@ * should not be applied to that function. * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 */ -#define __no_sanitize_address __attribute__((no_sanitize_address)) +#define __no_sanitize_address __attribute__((__no_sanitize_address__)) #endif #if GCC_VERSION >= 50100 @@ -199,7 +199,7 @@ * Mark structures as requiring designated initializers. * https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html */ -#define __designated_init __attribute__((designated_init)) +#define __designated_init __attribute__((__designated_init__)) #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 #endif diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index 4c7f9befa9f6..fef8bb3e53ef 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -42,4 +42,4 @@ * and may be redefined here because they should not be shared with other * compilers, like clang. */ -#define __visible __attribute__((externally_visible)) +#define __visible __attribute__((__externally_visible__)) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 7c0157d50964..ec4a28bad2c6 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -24,7 +24,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, long ______r; \ static struct ftrace_likely_data \ __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_annotated_branch"))) \ + __attribute__((__section__("_ftrace_annotated_branch"))) \ ______f = { \ .data.func = __func__, \ .data.file = __FILE__, \ @@ -60,7 +60,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, int ______r; \ static struct ftrace_branch_data \ __attribute__((__aligned__(4))) \ - __attribute__((section("_ftrace_branch"))) \ + __attribute__((__section__("_ftrace_branch"))) \ ______f = { \ .func = __func__, \ .file = __FILE__, \ @@ -146,7 +146,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, extern typeof(sym) sym; \ static const unsigned long __kentry_##sym \ __used \ - __attribute__((section("___kentry" "+" #sym ), used)) \ + __attribute__((__section__("___kentry" "+" #sym ), used)) \ = (unsigned long)&sym; #endif @@ -287,7 +287,7 @@ unsigned long read_word_at_a_time(const void *addr) * visible to the compiler. */ #define __ADDRESSABLE(sym) \ - static void * __attribute__((section(".discard.addressable"), used)) \ + static void * __attribute__((__section__(".discard.addressable"), used)) \ __PASTE(__addressable_##sym, __LINE__) = (void *)&sym; /** diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index a19562cb047c..8fbdd47dd3d0 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -195,26 +195,26 @@ struct ftrace_likely_data { * would be. * [...] */ -#define __pure __attribute__((pure)) -#define __aligned(x) __attribute__((aligned(x))) -#define __aligned_largest __attribute__((aligned)) -#define __printf(a, b) __attribute__((format(printf, a, b))) -#define __scanf(a, b) __attribute__((format(scanf, a, b))) -#define __maybe_unused __attribute__((unused)) -#define __always_unused __attribute__((unused)) -#define __mode(x) __attribute__((mode(x))) +#define __pure __attribute__((__pure__)) +#define __aligned(x) __attribute__((__aligned__(x))) +#define __aligned_largest __attribute__((__aligned__)) +#define __printf(a, b) __attribute__((__format__(printf, a, b))) +#define __scanf(a, b) __attribute__((__format__(scanf, a, b))) +#define __maybe_unused __attribute__((__unused__)) +#define __always_unused __attribute__((__unused__)) +#define __mode(x) __attribute__((__mode__(x))) #define __malloc __attribute__((__malloc__)) #define __used __attribute__((__used__)) -#define __noreturn __attribute__((noreturn)) -#define __packed __attribute__((packed)) -#define __weak __attribute__((weak)) -#define __alias(symbol) __attribute__((alias(#symbol))) -#define __cold __attribute__((cold)) +#define __noreturn __attribute__((__noreturn__)) +#define __packed __attribute__((__packed__)) +#define __weak __attribute__((__weak__)) +#define __alias(symbol) __attribute__((__alias__(#symbol))) +#define __cold __attribute__((__cold__)) #define __section(S) __attribute__((__section__(#S))) #ifdef CONFIG_ENABLE_MUST_CHECK -#define __must_check __attribute__((warn_unused_result)) +#define __must_check __attribute__((__warn_unused_result__)) #else #define __must_check #endif @@ -222,7 +222,7 @@ struct ftrace_likely_data { #if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__) #define notrace __attribute__((hotpatch(0, 0))) #else -#define notrace __attribute__((no_instrument_function)) +#define notrace __attribute__((__no_instrument_function__)) #endif /* @@ -231,7 +231,7 @@ struct ftrace_likely_data { * stack and frame pointer being set up and there is no chance to * restore the lr register to the value before mcount was called. */ -#define __naked __attribute__((naked)) notrace +#define __naked __attribute__((__naked__)) notrace #define __compiler_offsetof(a, b) __builtin_offsetof(a, b) @@ -242,7 +242,7 @@ struct ftrace_likely_data { * defined so the gnu89 semantics are the default. */ #ifdef __GNUC_STDC_INLINE__ -# define __gnu_inline __attribute__((gnu_inline)) +# define __gnu_inline __attribute__((__gnu_inline__)) #else # define __gnu_inline #endif @@ -262,17 +262,17 @@ struct ftrace_likely_data { #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ !defined(CONFIG_OPTIMIZE_INLINING) #define inline \ - inline __attribute__((always_inline, unused)) notrace __gnu_inline + inline __attribute__((__always_inline__, __unused__)) notrace __gnu_inline #else -#define inline inline __attribute__((unused)) notrace __gnu_inline +#define inline inline __attribute__((__unused__)) notrace __gnu_inline #endif #define __inline__ inline #define __inline inline -#define noinline __attribute__((noinline)) +#define noinline __attribute__((__noinline__)) #ifndef __always_inline -#define __always_inline inline __attribute__((always_inline)) +#define __always_inline inline __attribute__((__always_inline__)) #endif /* From c2c640aa04cc4e6caf0ff17ff18b3784e0c99566 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 30 Aug 2018 19:45:01 +0200 Subject: [PATCH 165/836] Compiler Attributes: remove unneeded tests Attributes const and always_inline have tests around them which are unneeded, since they are supported by gcc >= 4.6, clang >= 3 and icc >= 13. https://godbolt.org/z/DFPq37 In the case of gnu_inline, we do not need to test for __GNUC_STDC_INLINE__ because, regardless of the current inlining behavior, we can simply always force the old GCC inlining behavior by using the attribute in all cases. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler_types.h | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 8fbdd47dd3d0..5ff9cda893f4 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -158,10 +158,6 @@ struct ftrace_likely_data { (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) -#ifndef __attribute_const__ -#define __attribute_const__ __attribute__((__const__)) -#endif - #ifndef __noclone #define __noclone #endif @@ -196,6 +192,7 @@ struct ftrace_likely_data { * [...] */ #define __pure __attribute__((__pure__)) +#define __attribute_const__ __attribute__((__const__)) #define __aligned(x) __attribute__((__aligned__(x))) #define __aligned_largest __attribute__((__aligned__)) #define __printf(a, b) __attribute__((__format__(printf, a, b))) @@ -211,6 +208,8 @@ struct ftrace_likely_data { #define __alias(symbol) __attribute__((__alias__(#symbol))) #define __cold __attribute__((__cold__)) #define __section(S) __attribute__((__section__(#S))) +#define __always_inline inline __attribute__((__always_inline__)) +#define __gnu_inline __attribute__((__gnu_inline__)) #ifdef CONFIG_ENABLE_MUST_CHECK @@ -235,18 +234,6 @@ struct ftrace_likely_data { #define __compiler_offsetof(a, b) __builtin_offsetof(a, b) -/* - * Feature detection for gnu_inline (gnu89 extern inline semantics). Either - * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics, - * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not - * defined so the gnu89 semantics are the default. - */ -#ifdef __GNUC_STDC_INLINE__ -# define __gnu_inline __attribute__((__gnu_inline__)) -#else -# define __gnu_inline -#endif - /* * Force always-inline if the user requests it so via the .config. * GCC does not warn about unused static inline functions for @@ -271,10 +258,6 @@ struct ftrace_likely_data { #define __inline inline #define noinline __attribute__((__noinline__)) -#ifndef __always_inline -#define __always_inline inline __attribute__((__always_inline__)) -#endif - /* * Rather then using noinline to prevent stack consumption, use * noinline_for_stack instead. For documentation reasons. From ec0bbef66f867854691d5af18c2231d746958e0e Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 30 Aug 2018 19:25:14 +0200 Subject: [PATCH 166/836] Compiler Attributes: homogenize __must_be_array Different definitions of __must_be_array: * gcc: disabled for __CHECKER__ * clang: same definition as gcc's, but without __CHECKER__ * intel: the comment claims __builtin_types_compatible_p() is unsupported; but icc seems to support it since 13.0.1 (released in 2012). See https://godbolt.org/z/S0l6QQ Therefore, we can remove all of them and have a single definition in compiler.h Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler-clang.h | 1 - include/linux/compiler-gcc.h | 7 ------- include/linux/compiler-intel.h | 3 --- include/linux/compiler.h | 7 +++++++ 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index d11cad61ba5c..fa9532f8d885 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -41,6 +41,5 @@ * compilers, like ICC. */ #define barrier() __asm__ __volatile__("" : : : "memory") -#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) #define __assume_aligned(a, ...) \ __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 7a1de7683df5..3b32bbfa5a49 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -68,13 +68,6 @@ */ #define uninitialized_var(x) x = x -#ifdef __CHECKER__ -#define __must_be_array(a) 0 -#else -/* &a[0] degrades to a pointer: a different type from an array */ -#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) -#endif - #ifdef RETPOLINE #define __noretpoline __attribute__((__indirect_branch__("keep"))) #endif diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index fef8bb3e53ef..6004b4588bd4 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -29,9 +29,6 @@ */ #define OPTIMIZER_HIDE_VAR(var) barrier() -/* Intel ECC compiler doesn't support __builtin_types_compatible_p() */ -#define __must_be_array(a) 0 - #endif /* icc has this, but it's called _bswap16 */ diff --git a/include/linux/compiler.h b/include/linux/compiler.h index ec4a28bad2c6..165b1d5683ed 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -357,4 +357,11 @@ static inline void *offset_to_ptr(const int *off) compiletime_assert(__native_word(t), \ "Need native word sized stores/loads for atomicity.") +#ifdef __CHECKER__ +#define __must_be_array(a) 0 +#else +/* &a[0] degrades to a pointer: a different type from an array */ +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +#endif + #endif /* __LINUX_COMPILER_H */ From 989bd5000f36052df604888ed12bb6ef390786b7 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 31 Aug 2018 18:00:16 +0200 Subject: [PATCH 167/836] Compiler Attributes: remove unneeded sparse (__CHECKER__) tests Sparse knows about a few more attributes now, so we can remove the __CHECKER__ conditions from them (which, in turn, allow us to move some of them later on to compiler_attributes.h). * assume_aligned: since sparse's commit ffc860b ("sparse: ignore __assume_aligned__ attribute"), included in 0.5.1 * error: since sparse's commit 0a04210 ("sparse: Add 'error' to ignored attributes"), included in 0.5.0 * hotpatch: since sparse's commit 6043210 ("sparse/parse.c: ignore hotpatch attribute"), included in 0.5.1 * warning: since sparse's commit 977365d ("Avoid "attribute 'warning': unknown attribute" warning"), included in 0.4.2 On top of that, __must_be_array does not need it either because: * Even ancient versions of sparse do not have a problem * BUILD_BUG_ON_ZERO() is currently disabled for __CHECKER__ Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler-gcc.h | 6 ++---- include/linux/compiler.h | 4 ---- include/linux/compiler_types.h | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 3b32bbfa5a49..1ca6a51cfaa9 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -76,14 +76,12 @@ #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) -#ifndef __CHECKER__ #define __compiletime_warning(message) __attribute__((__warning__(message))) #define __compiletime_error(message) __attribute__((__error__(message))) -#ifdef LATENT_ENTROPY_PLUGIN +#if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__) #define __latent_entropy __attribute__((latent_entropy)) #endif -#endif /* __CHECKER__ */ /* * calling noreturn functions, __builtin_unreachable() and __builtin_trap() @@ -131,7 +129,7 @@ /* gcc version specific checks */ -#if GCC_VERSION >= 40900 && !defined(__CHECKER__) +#if GCC_VERSION >= 40900 /* * __assume_aligned(n, k): Tell the optimizer that the returned * pointer can be assumed to be k modulo n. The second argument is diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 165b1d5683ed..4030a2940d6b 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -357,11 +357,7 @@ static inline void *offset_to_ptr(const int *off) compiletime_assert(__native_word(t), \ "Need native word sized stores/loads for atomicity.") -#ifdef __CHECKER__ -#define __must_be_array(a) 0 -#else /* &a[0] degrades to a pointer: a different type from an array */ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) -#endif #endif /* __LINUX_COMPILER_H */ diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 5ff9cda893f4..a3eceb3ad1b3 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -218,7 +218,7 @@ struct ftrace_likely_data { #define __must_check #endif -#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__) +#if defined(CC_USING_HOTPATCH) #define notrace __attribute__((hotpatch(0, 0))) #else #define notrace __attribute__((__no_instrument_function__)) From 66dbeef915f275dad6c8656b31667ef9640f5639 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 3 Sep 2018 18:34:18 +0200 Subject: [PATCH 168/836] Compiler Attributes: add missing SPDX ID in compiler_types.h Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler_types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index a3eceb3ad1b3..ed7c0e4a180e 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __LINUX_COMPILER_TYPES_H #define __LINUX_COMPILER_TYPES_H From a3f8a30f3f0079c7edfc72e329eee8594fb3e3cb Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Thu, 30 Aug 2018 20:36:59 +0200 Subject: [PATCH 169/836] Compiler Attributes: use feature checks instead of version checks Instead of using version checks per-compiler to define (or not) each attribute, use __has_attribute to test for them, following the cleanup started with commit 815f0ddb346c ("include/linux/compiler*.h: make compiler-*.h mutually exclusive"), which is supported on gcc >= 5, clang >= 2.9 and icc >= 17. In the meantime, to support 4.6 <= gcc < 5, we implement __has_attribute by hand. All the attributes that can be unconditionally defined and directly map to compiler attribute(s) (even if optional) have been moved to a new file include/linux/compiler_attributes.h In an effort to make the file as regular as possible, comments stating the purpose of attributes have been removed. Instead, links to the compiler docs have been added (i.e. to gcc and, if available, to clang as well). In addition, they have been sorted. Finally, if an attribute is optional (i.e. if it is guarded by __has_attribute), the reason has been stated for future reference. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler-clang.h | 4 - include/linux/compiler-gcc.h | 51 ------ include/linux/compiler-intel.h | 6 - include/linux/compiler_attributes.h | 244 ++++++++++++++++++++++++++++ include/linux/compiler_types.h | 74 ++------- 5 files changed, 254 insertions(+), 125 deletions(-) create mode 100644 include/linux/compiler_attributes.h diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index fa9532f8d885..3e7dafb3ea80 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -21,8 +21,6 @@ #define __SANITIZE_ADDRESS__ #endif -#define __no_sanitize_address __attribute__((__no_sanitize__("address"))) - /* * Not all versions of clang implement the the type-generic versions * of the builtin overflow checkers. Fortunately, clang implements @@ -41,5 +39,3 @@ * compilers, like ICC. */ #define barrier() __asm__ __volatile__("" : : : "memory") -#define __assume_aligned(a, ...) \ - __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 1ca6a51cfaa9..cfac027e1625 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -108,9 +108,6 @@ __builtin_unreachable(); \ } while (0) -/* Mark a function definition as prohibited from being cloned. */ -#define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) - #if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) #define __randomize_layout __attribute__((randomize_layout)) #define __no_randomize_layout __attribute__((no_randomize_layout)) @@ -119,32 +116,6 @@ #define randomized_struct_fields_end } __randomize_layout; #endif -/* - * When used with Link Time Optimization, gcc can optimize away C functions or - * variables which are referenced only from assembly code. __visible tells the - * optimizer that something else uses this function or variable, thus preventing - * this. - */ -#define __visible __attribute__((__externally_visible__)) - -/* gcc version specific checks */ - -#if GCC_VERSION >= 40900 -/* - * __assume_aligned(n, k): Tell the optimizer that the returned - * pointer can be assumed to be k modulo n. The second argument is - * optional (default 0), so we use a variadic macro to make the - * shorthand. - * - * Beware: Do not apply this to functions which may return - * ERR_PTRs. Also, it is probably unwise to apply it to functions - * returning extra information in the low bits (but in that case the - * compiler should see some alignment anyway, when the return value is - * massaged by 'flags = ptr & 3; ptr &= ~3;'). - */ -#define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) -#endif - /* * GCC 'asm goto' miscompiles certain code sequences: * @@ -176,32 +147,10 @@ #define KASAN_ABI_VERSION 3 #endif -#if GCC_VERSION >= 40902 -/* - * Tell the compiler that address safety instrumentation (KASAN) - * should not be applied to that function. - * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 - */ -#define __no_sanitize_address __attribute__((__no_sanitize_address__)) -#endif - #if GCC_VERSION >= 50100 -/* - * Mark structures as requiring designated initializers. - * https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html - */ -#define __designated_init __attribute__((__designated_init__)) #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 #endif -#if !defined(__noclone) -#define __noclone /* not needed */ -#endif - -#if !defined(__no_sanitize_address) -#define __no_sanitize_address -#endif - /* * Turn individual warnings and errors on and off locally, depending * on version. diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index 6004b4588bd4..517bd14e1222 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -34,9 +34,3 @@ /* icc has this, but it's called _bswap16 */ #define __HAVE_BUILTIN_BSWAP16__ #define __builtin_bswap16 _bswap16 - -/* The following are for compatibility with GCC, from compiler-gcc.h, - * and may be redefined here because they should not be shared with other - * compilers, like clang. - */ -#define __visible __attribute__((__externally_visible__)) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h new file mode 100644 index 000000000000..f0f9fc398440 --- /dev/null +++ b/include/linux/compiler_attributes.h @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_COMPILER_ATTRIBUTES_H +#define __LINUX_COMPILER_ATTRIBUTES_H + +/* + * The attributes in this file are unconditionally defined and they directly + * map to compiler attribute(s) -- except those that are optional. + * + * Any other "attributes" (i.e. those that depend on a configuration option, + * on a compiler, on an architecture, on plugins, on other attributes...) + * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h). + * + * This file is meant to be sorted (by actual attribute name, + * not by #define identifier). Use the __attribute__((__name__)) syntax + * (i.e. with underscores) to avoid future collisions with other macros. + * If an attribute is optional, state the reason in the comment. + */ + +/* + * To check for optional attributes, we use __has_attribute, which is supported + * on gcc >= 5, clang >= 2.9 and icc >= 17. In the meantime, to support + * 4.6 <= gcc < 5, we implement __has_attribute by hand. + * + * sparse does not support __has_attribute (yet) and defines __GNUC_MINOR__ + * depending on the compiler used to build it; however, these attributes have + * no semantic effects for sparse, so it does not matter. Also note that, + * in order to avoid sparse's warnings, even the unsupported ones must be + * defined to 0. + */ +#ifndef __has_attribute +# define __has_attribute(x) __GCC4_has_attribute_##x +# define __GCC4_has_attribute___assume_aligned__ (__GNUC_MINOR__ >= 9) +# define __GCC4_has_attribute___designated_init__ 0 +# define __GCC4_has_attribute___externally_visible__ 1 +# define __GCC4_has_attribute___noclone__ 1 +# define __GCC4_has_attribute___optimize__ 1 +# define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alias-function-attribute + */ +#define __alias(symbol) __attribute__((__alias__(#symbol))) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-aligned-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute + */ +#define __aligned(x) __attribute__((__aligned__(x))) +#define __aligned_largest __attribute__((__aligned__)) + +/* + * Note: users of __always_inline currently do not write "inline" themselves, + * which seems to be required by gcc to apply the attribute according + * to its docs (and also "warning: always_inline function might not be + * inlinable [-Wattributes]" is emitted). + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute + * clang: mentioned + */ +#define __always_inline inline __attribute__((__always_inline__)) + +/* + * The second argument is optional (default 0), so we use a variadic macro + * to make the shorthand. + * + * Beware: Do not apply this to functions which may return + * ERR_PTRs. Also, it is probably unwise to apply it to functions + * returning extra information in the low bits (but in that case the + * compiler should see some alignment anyway, when the return value is + * massaged by 'flags = ptr & 3; ptr &= ~3;'). + * + * Optional: only supported since gcc >= 4.9 + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#assume-aligned + */ +#if __has_attribute(__assume_aligned__) +# define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) +#else +# define __assume_aligned(a, ...) +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute + */ +#define __cold __attribute__((__cold__)) + +/* + * Note the long name. + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute + */ +#define __attribute_const__ __attribute__((__const__)) + +/* + * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated' + * attribute warnings entirely and for good") for more information. + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#deprecated + */ +#define __deprecated + +/* + * Optional: only supported since gcc >= 5.1 + * Optional: not supported by clang + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute + */ +#if __has_attribute(__designated_init__) +# define __designated_init __attribute__((__designated_init__)) +#else +# define __designated_init +#endif + +/* + * Optional: not supported by clang + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-externally_005fvisible-function-attribute + */ +#if __has_attribute(__externally_visible__) +# define __visible __attribute__((__externally_visible__)) +#else +# define __visible +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-format-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#format + */ +#define __printf(a, b) __attribute__((__format__(printf, a, b))) +#define __scanf(a, b) __attribute__((__format__(scanf, a, b))) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-gnu_005finline-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#gnu-inline + */ +#define __gnu_inline __attribute__((__gnu_inline__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute + */ +#define __malloc __attribute__((__malloc__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-mode-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-mode-variable-attribute + */ +#define __mode(x) __attribute__((__mode__(x))) + +/* + * Optional: not supported by clang + * Note: icc does not recognize gcc's no-tracer + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noclone-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-optimize-function-attribute + */ +#if __has_attribute(__noclone__) +# if __has_attribute(__optimize__) +# define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) +# else +# define __noclone __attribute__((__noclone__)) +# endif +#else +# define __noclone +#endif + +/* + * Note the missing underscores. + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute + * clang: mentioned + */ +#define noinline __attribute__((__noinline__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#noreturn + * clang: https://clang.llvm.org/docs/AttributeReference.html#id1 + */ +#define __noreturn __attribute__((__noreturn__)) + +/* + * Optional: only supported since gcc >= 4.8 + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fsanitize_005faddress-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#no-sanitize-address-no-address-safety-analysis + */ +#if __has_attribute(__no_sanitize_address__) +# define __no_sanitize_address __attribute__((__no_sanitize_address__)) +#else +# define __no_sanitize_address +#endif + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute + * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute + */ +#define __packed __attribute__((__packed__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute + */ +#define __pure __attribute__((__pure__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate + */ +#define __section(S) __attribute__((__section__(#S))) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#maybe-unused-unused + */ +#define __always_unused __attribute__((__unused__)) +#define __maybe_unused __attribute__((__unused__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute + */ +#define __used __attribute__((__used__)) + +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute + */ +#define __weak __attribute__((__weak__)) + +#endif /* __LINUX_COMPILER_ATTRIBUTES_H */ diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index ed7c0e4a180e..3439d7d0249a 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -55,6 +55,9 @@ extern void __chk_io_ptr(const volatile void __iomem *); #ifdef __KERNEL__ +/* Attributes */ +#include + /* Compiler specific macros. */ #ifdef __clang__ #include @@ -79,12 +82,6 @@ extern void __chk_io_ptr(const volatile void __iomem *); #include #endif -/* - * Generic compiler-independent macros required for kernel - * build go below this comment. Actual compiler/compiler version - * specific implementations come from the above header files - */ - struct ftrace_branch_data { const char *func; const char *file; @@ -107,9 +104,6 @@ struct ftrace_likely_data { unsigned long constant; }; -/* Don't. Just don't. */ -#define __deprecated - #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ @@ -119,10 +113,6 @@ struct ftrace_likely_data { * compilers. We don't consider that to be an error, so set them to nothing. * For example, some of them are for compiler specific plugins. */ -#ifndef __designated_init -# define __designated_init -#endif - #ifndef __latent_entropy # define __latent_entropy #endif @@ -140,17 +130,6 @@ struct ftrace_likely_data { # define randomized_struct_fields_end #endif -#ifndef __visible -#define __visible -#endif - -/* - * Assume alignment of return value. - */ -#ifndef __assume_aligned -#define __assume_aligned(a, ...) -#endif - /* Are two types/vars the same type (ignoring qualifiers)? */ #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) @@ -159,10 +138,6 @@ struct ftrace_likely_data { (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) -#ifndef __noclone -#define __noclone -#endif - /* Helpers for emitting diagnostics in pragmas. */ #ifndef __diag #define __diag(string) @@ -182,37 +157,6 @@ struct ftrace_likely_data { #define __diag_error(compiler, version, option, comment) \ __diag_ ## compiler(version, error, option) -/* - * From the GCC manual: - * - * Many functions have no effects except the return value and their - * return value depends only on the parameters and/or global - * variables. Such a function can be subject to common subexpression - * elimination and loop optimization just as an arithmetic operator - * would be. - * [...] - */ -#define __pure __attribute__((__pure__)) -#define __attribute_const__ __attribute__((__const__)) -#define __aligned(x) __attribute__((__aligned__(x))) -#define __aligned_largest __attribute__((__aligned__)) -#define __printf(a, b) __attribute__((__format__(printf, a, b))) -#define __scanf(a, b) __attribute__((__format__(scanf, a, b))) -#define __maybe_unused __attribute__((__unused__)) -#define __always_unused __attribute__((__unused__)) -#define __mode(x) __attribute__((__mode__(x))) -#define __malloc __attribute__((__malloc__)) -#define __used __attribute__((__used__)) -#define __noreturn __attribute__((__noreturn__)) -#define __packed __attribute__((__packed__)) -#define __weak __attribute__((__weak__)) -#define __alias(symbol) __attribute__((__alias__(#symbol))) -#define __cold __attribute__((__cold__)) -#define __section(S) __attribute__((__section__(#S))) -#define __always_inline inline __attribute__((__always_inline__)) -#define __gnu_inline __attribute__((__gnu_inline__)) - - #ifdef CONFIG_ENABLE_MUST_CHECK #define __must_check __attribute__((__warn_unused_result__)) #else @@ -246,18 +190,20 @@ struct ftrace_likely_data { * semantics rather than c99. This prevents multiple symbol definition errors * of extern inline functions at link time. * A lot of inline functions can cause havoc with function tracing. + * Do not use __always_inline here, since currently it expands to inline again + * (which would break users of __always_inline). */ #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ !defined(CONFIG_OPTIMIZE_INLINING) -#define inline \ - inline __attribute__((__always_inline__, __unused__)) notrace __gnu_inline +#define inline inline __attribute__((__always_inline__)) __gnu_inline \ + __maybe_unused notrace #else -#define inline inline __attribute__((__unused__)) notrace __gnu_inline +#define inline inline __gnu_inline \ + __maybe_unused notrace #endif #define __inline__ inline -#define __inline inline -#define noinline __attribute__((__noinline__)) +#define __inline inline /* * Rather then using noinline to prevent stack consumption, use From 06e3727e02f9ee9cf571692cd5c74fc5a8a2af52 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 3 Sep 2018 19:22:13 +0200 Subject: [PATCH 170/836] Compiler Attributes: KENTRY used twice the "used" attribute Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 4030a2940d6b..17ee9165ca51 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -146,7 +146,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, extern typeof(sym) sym; \ static const unsigned long __kentry_##sym \ __used \ - __attribute__((__section__("___kentry" "+" #sym ), used)) \ + __attribute__((__section__("___kentry" "+" #sym ))) \ = (unsigned long)&sym; #endif From e04462fb82f8dd98288c0e7ab1eec79c92537d25 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 3 Sep 2018 19:17:50 +0200 Subject: [PATCH 171/836] Compiler Attributes: remove uses of __attribute__ from compiler.h Suggested-by: Nick Desaulniers Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 17ee9165ca51..b5fb034fa6fa 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -23,8 +23,8 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, #define __branch_check__(x, expect, is_constant) ({ \ long ______r; \ static struct ftrace_likely_data \ - __attribute__((__aligned__(4))) \ - __attribute__((__section__("_ftrace_annotated_branch"))) \ + __aligned(4) \ + __section("_ftrace_annotated_branch") \ ______f = { \ .data.func = __func__, \ .data.file = __FILE__, \ @@ -59,8 +59,8 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, ({ \ int ______r; \ static struct ftrace_branch_data \ - __attribute__((__aligned__(4))) \ - __attribute__((__section__("_ftrace_branch"))) \ + __aligned(4) \ + __section("_ftrace_branch") \ ______f = { \ .func = __func__, \ .file = __FILE__, \ @@ -146,7 +146,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, extern typeof(sym) sym; \ static const unsigned long __kentry_##sym \ __used \ - __attribute__((__section__("___kentry" "+" #sym ))) \ + __section("___kentry" "+" #sym ) \ = (unsigned long)&sym; #endif @@ -287,7 +287,7 @@ unsigned long read_word_at_a_time(const void *addr) * visible to the compiler. */ #define __ADDRESSABLE(sym) \ - static void * __attribute__((__section__(".discard.addressable"), used)) \ + static void * __section(".discard.addressable") __used \ __PASTE(__addressable_##sym, __LINE__) = (void *)&sym; /** From 303d22c5fc37cebe2bd0b3c15ac3db6950db60c6 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Mon, 3 Sep 2018 18:32:11 +0200 Subject: [PATCH 172/836] Compiler Attributes: add Doc/process/programming-language.rst Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- Documentation/process/index.rst | 1 + .../process/programming-language.rst | 45 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 Documentation/process/programming-language.rst diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst index 9ae3e317bddf..00558b6d2649 100644 --- a/Documentation/process/index.rst +++ b/Documentation/process/index.rst @@ -23,6 +23,7 @@ Below are the essential guides that every developer should read. code-of-conduct development-process submitting-patches + programming-language coding-style maintainer-pgp-guide email-clients diff --git a/Documentation/process/programming-language.rst b/Documentation/process/programming-language.rst new file mode 100644 index 000000000000..e5f5f065dc24 --- /dev/null +++ b/Documentation/process/programming-language.rst @@ -0,0 +1,45 @@ +.. _programming_language: + +Programming Language +==================== + +The kernel is written in the C programming language [c-language]_. +More precisely, the kernel is typically compiled with ``gcc`` [gcc]_ +under ``-std=gnu89`` [gcc-c-dialect-options]_: the GNU dialect of ISO C90 +(including some C99 features). + +This dialect contains many extensions to the language [gnu-extensions]_, +and many of them are used within the kernel as a matter of course. + +There is some support for compiling the kernel with ``clang`` [clang]_ +and ``icc`` [icc]_ for several of the architectures, although at the time +of writing it is not completed, requiring third-party patches. + +Attributes +---------- + +One of the common extensions used throughout the kernel are attributes +[gcc-attribute-syntax]_. Attributes allow to introduce +implementation-defined semantics to language entities (like variables, +functions or types) without having to make significant syntactic changes +to the language (e.g. adding a new keyword) [n2049]_. + +In some cases, attributes are optional (i.e. a compiler not supporting them +should still produce proper code, even if it is slower or does not perform +as many compile-time checks/diagnostics). + +The kernel defines pseudo-keywords (e.g. ``__pure``) instead of using +directly the GNU attribute syntax (e.g. ``__attribute__((__pure__))``) +in order to feature detect which ones can be used and/or to shorten the code. + +Please refer to ``include/linux/compiler_attributes.h`` for more information. + +.. [c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards +.. [gcc] https://gcc.gnu.org +.. [clang] https://clang.llvm.org +.. [icc] https://software.intel.com/en-us/c-compilers +.. [gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html +.. [gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html +.. [gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html +.. [n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf + From 5fc4a13b66b4643b7a564cc79c2453889c8665d7 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 8 Sep 2018 22:53:57 +0200 Subject: [PATCH 173/836] Compiler Attributes: add MAINTAINERS entry Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b22e7fdfd2ea..e4980d675584 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3722,6 +3722,11 @@ L: platform-driver-x86@vger.kernel.org S: Maintained F: drivers/platform/x86/compal-laptop.c +COMPILER ATTRIBUTES +M: Miguel Ojeda +S: Maintained +F: include/linux/compiler_attributes.h + CONEXANT ACCESSRUNNER USB DRIVER L: accessrunner-general@lists.sourceforge.net W: http://accessrunner.sourceforge.net/ From 92676236917d8e2e0de1d8612686d3d04a6a245b Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 19 Sep 2018 01:06:24 +0200 Subject: [PATCH 174/836] Compiler Attributes: add support for __nonstring (gcc >= 8) From the GCC manual: nonstring The nonstring variable attribute specifies that an object or member declaration with type array of char, signed char, or unsigned char, or pointer to such a type is intended to store character arrays that do not necessarily contain a terminating NUL. This is useful in detecting uses of such arrays or pointers with functions that expect NUL-terminated strings, and to avoid warnings when such an array or pointer is used as an argument to a bounded string manipulation function such as strncpy. https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html This attribute can be used for documentation purposes (i.e. replacing comments), but it is most helpful when the following warnings are enabled: -Wstringop-overflow Warn for calls to string manipulation functions such as memcpy and strcpy that are determined to overflow the destination buffer. [...] -Wstringop-truncation Warn for calls to bounded string manipulation functions such as strncat, strncpy, and stpncpy that may either truncate the copied string or leave the destination unchanged. [...] In situations where a character array is intended to store a sequence of bytes with no terminating NUL such an array may be annotated with attribute nonstring to avoid this warning. Such arrays, however, are not suitable arguments to functions that expect NUL-terminated strings. To help detect accidental misuses of such arrays GCC issues warnings unless it can prove that the use is safe. https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Kees Cook Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- include/linux/compiler_attributes.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index f0f9fc398440..6b28c1b7310c 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -34,6 +34,7 @@ # define __GCC4_has_attribute___externally_visible__ 1 # define __GCC4_has_attribute___noclone__ 1 # define __GCC4_has_attribute___optimize__ 1 +# define __GCC4_has_attribute___nonstring__ 0 # define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) #endif @@ -181,6 +182,19 @@ */ #define noinline __attribute__((__noinline__)) +/* + * Optional: only supported since gcc >= 8 + * Optional: not supported by clang + * Optional: not supported by icc + * + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute + */ +#if __has_attribute(__nonstring__) +# define __nonstring __attribute__((__nonstring__)) +#else +# define __nonstring +#endif + /* * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute * clang: https://clang.llvm.org/docs/AttributeReference.html#noreturn From 23066c3f4e2146da8c7d1505729f4409f4d93d28 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 19 Sep 2018 02:31:58 +0200 Subject: [PATCH 175/836] Compiler Attributes: enable -Wstringop-truncation on W=1 (gcc >= 8) Commit 217c3e019675 ("disable stringop truncation warnings for now") disabled -Wstringop-truncation since it was too noisy. Having __nonstring available allows us to let GCC know that a string is not meant to be NUL-terminated, which helps suppressing some -Wstringop-truncation warnings. Note that using __nonstring actually triggers other warnings (-Wstringop-overflow, which is on by default) which may be real problems. Therefore, cleaning up -Wstringop-truncation warnings also buys us the ability to uncover further potential problems. To encourage the use of __nonstring, we put the warning back at W=1. In the future, if we end up with a fairly warning-free tree, we might want to enable it by default. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Kees Cook Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- scripts/Makefile.extrawarn | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index 8d5357053f86..b8f36f5f43f2 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -29,6 +29,7 @@ warning-1 += $(call cc-option, -Wmissing-include-dirs) warning-1 += $(call cc-option, -Wunused-but-set-variable) warning-1 += $(call cc-option, -Wunused-const-variable) warning-1 += $(call cc-option, -Wpacked-not-aligned) +warning-1 += $(call cc-option, -Wstringop-truncation) warning-1 += $(call cc-disable-warning, missing-field-initializers) warning-1 += $(call cc-disable-warning, sign-compare) From 98cade0a08ba339cd11d6e89b0df5d1d2fa21202 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Tue, 14 Aug 2018 21:38:26 +0200 Subject: [PATCH 176/836] Compiler Attributes: auxdisplay: panel: use __nonstring Let gcc know these arrays are not meant to be NUL-terminated by annotating them with the new __nonstring variable attribute; and remove the comment since it conveys the same information. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- drivers/auxdisplay/panel.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c index 3b25a643058c..21b9b2f2470a 100644 --- a/drivers/auxdisplay/panel.c +++ b/drivers/auxdisplay/panel.c @@ -155,10 +155,9 @@ struct logical_input { int release_data; } std; struct { /* valid when type == INPUT_TYPE_KBD */ - /* strings can be non null-terminated */ - char press_str[sizeof(void *) + sizeof(int)]; - char repeat_str[sizeof(void *) + sizeof(int)]; - char release_str[sizeof(void *) + sizeof(int)]; + char press_str[sizeof(void *) + sizeof(int)] __nonstring; + char repeat_str[sizeof(void *) + sizeof(int)] __nonstring; + char release_str[sizeof(void *) + sizeof(int)] __nonstring; } kbd; } u; }; From f0604f63033d4020f019d2aaee805c1075b1077b Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 19 Sep 2018 01:41:21 +0200 Subject: [PATCH 177/836] Compiler Attributes: ext4: remove local __nonstring definition Commit 072ebb3bffe6 ("ext4: add nonstring annotations to ext4.h") introduced a local definition of __nonstring to suppress some false positives in gcc 8's -Wstringop-truncation. Since now we support __nonstring for everyone, remove it. Tested-by: Sedat Dilek # on top of v4.19-rc5, clang 7 Reviewed-by: Nick Desaulniers Reviewed-by: Luc Van Oostenryck Signed-off-by: Miguel Ojeda --- fs/ext4/ext4.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index caff935fbeb8..2acdfdad3d3f 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -45,15 +45,6 @@ #include -/* Until this gets included into linux/compiler-gcc.h */ -#ifndef __nonstring -#if defined(GCC_VERSION) && (GCC_VERSION >= 80000) -#define __nonstring __attribute__((nonstring)) -#else -#define __nonstring -#endif -#endif - /* * The fourth extended filesystem constants/structures */ From 69e34551152a286f827d54dcb5700da6aeaac1fb Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:04 +0200 Subject: [PATCH 178/836] fuse: allow caching readdir This patch just adds the cache filling functions, which are invoked if FOPEN_CACHE_DIR flag is set in the OPENDIR reply. Cache reading and cache invalidation are added by subsequent patches. The directory cache uses the page cache. Directory entries are packed into a page in the same format as in the READDIR reply. A page only contains whole entries, the space at the end of the page is cleared. The page is locked while being modified. Multiple parallel readdirs on the same directory can fill the cache; the only constraint is that continuity must be maintained (d_off of last entry points to position of current entry). Signed-off-by: Miklos Szeredi --- fs/fuse/fuse_i.h | 15 ++++++++ fs/fuse/inode.c | 4 +++ fs/fuse/readdir.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index dfe10c2df6a9..d2fa7588533e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -103,6 +103,21 @@ struct fuse_inode { /** List of writepage requestst (pending or sent) */ struct list_head writepages; + /* readdir cache */ + struct { + /* true if fully cached */ + bool cached; + + /* size of cache */ + loff_t size; + + /* position at end of cache (position of next entry) */ + loff_t pos; + + /* protects above fields */ + spinlock_t lock; + } rdc; + /** Miscellaneous bits describing inode state */ unsigned long state; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 9383b47b3d9b..892efe6351eb 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -100,6 +100,10 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) INIT_LIST_HEAD(&fi->queued_writes); INIT_LIST_HEAD(&fi->writepages); init_waitqueue_head(&fi->page_waitq); + spin_lock_init(&fi->rdc.lock); + fi->rdc.cached = false; + fi->rdc.size = 0; + fi->rdc.pos = 0; mutex_init(&fi->mutex); fi->forget = fuse_alloc_forget(); if (!fi->forget) { diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 65336c93c1f4..6c5ada164f7e 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -9,6 +9,8 @@ #include "fuse_i.h" #include +#include +#include static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) { @@ -26,9 +28,91 @@ static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) return false; } +static void fuse_add_dirent_to_cache(struct file *file, + struct fuse_dirent *dirent, loff_t pos) +{ + struct fuse_inode *fi = get_fuse_inode(file_inode(file)); + size_t reclen = FUSE_DIRENT_SIZE(dirent); + pgoff_t index; + struct page *page; + loff_t size; + unsigned int offset; + void *addr; + + spin_lock(&fi->rdc.lock); + /* + * Is cache already completed? Or this entry does not go at the end of + * cache? + */ + if (fi->rdc.cached || pos != fi->rdc.pos) { + spin_unlock(&fi->rdc.lock); + return; + } + size = fi->rdc.size; + offset = size & ~PAGE_MASK; + index = size >> PAGE_SHIFT; + /* Dirent doesn't fit in current page? Jump to next page. */ + if (offset + reclen > PAGE_SIZE) { + index++; + offset = 0; + } + spin_unlock(&fi->rdc.lock); + + if (offset) { + page = find_lock_page(file->f_mapping, index); + } else { + page = find_or_create_page(file->f_mapping, index, + mapping_gfp_mask(file->f_mapping)); + } + if (!page) + return; + + spin_lock(&fi->rdc.lock); + /* Raced with another readdir */ + if (fi->rdc.size != size || WARN_ON(fi->rdc.pos != pos)) + goto unlock; + + addr = kmap_atomic(page); + if (!offset) + clear_page(addr); + memcpy(addr + offset, dirent, reclen); + kunmap_atomic(addr); + fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen; + fi->rdc.pos = dirent->off; +unlock: + spin_unlock(&fi->rdc.lock); + unlock_page(page); + put_page(page); +} + +static void fuse_readdir_cache_end(struct file *file, loff_t pos) +{ + struct fuse_inode *fi = get_fuse_inode(file_inode(file)); + loff_t end; + + spin_lock(&fi->rdc.lock); + /* does cache end position match current position? */ + if (fi->rdc.pos != pos) { + spin_unlock(&fi->rdc.lock); + return; + } + + fi->rdc.cached = true; + end = ALIGN(fi->rdc.size, PAGE_SIZE); + spin_unlock(&fi->rdc.lock); + + /* truncate unused tail of cache */ + truncate_inode_pages(file->f_mapping, end); +} + static bool fuse_emit(struct file *file, struct dir_context *ctx, struct fuse_dirent *dirent) { + struct fuse_file *ff = file->private_data; + + if (ff->open_flags & FOPEN_CACHE_DIR) + fuse_add_dirent_to_cache(file, dirent, ctx->pos); + return dir_emit(ctx, dirent->name, dirent->namelen, dirent->ino, dirent->type); } @@ -249,7 +333,12 @@ int fuse_readdir(struct file *file, struct dir_context *ctx) err = req->out.h.error; fuse_put_request(fc, req); if (!err) { - if (plus) { + if (!nbytes) { + struct fuse_file *ff = file->private_data; + + if (ff->open_flags & FOPEN_CACHE_DIR) + fuse_readdir_cache_end(file, ctx->pos); + } else if (plus) { err = parse_dirplusfile(page_address(page), nbytes, file, ctx, attr_version); } else { From 5d7bc7e8680c7ca4c8a4f139ce2a54ccb8131ef0 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:04 +0200 Subject: [PATCH 179/836] fuse: allow using readdir cache The cache is only used if it's completed, not while it's still being filled; this constraint could be lifted later, if it turns out to be useful. Introduce state in struct fuse_file that indicates the position within the cache. After a seek, reset the position to the beginning of the cache and search the cache for the current position. If the current position is not found in the cache, then fall back to uncached readdir. It can also happen that page(s) disappear from the cache, in which case we must also fall back to uncached readdir. Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 2 + fs/fuse/fuse_i.h | 15 +++++ fs/fuse/readdir.c | 148 ++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 161 insertions(+), 4 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index d15c14912e72..e10c0443c56f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -59,6 +59,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) } INIT_LIST_HEAD(&ff->write_entry); + mutex_init(&ff->readdir.lock); refcount_set(&ff->count, 1); RB_CLEAR_NODE(&ff->polled_node); init_waitqueue_head(&ff->poll_wait); @@ -73,6 +74,7 @@ struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) void fuse_file_free(struct fuse_file *ff) { fuse_request_free(ff->reserved_req); + mutex_destroy(&ff->readdir.lock); kfree(ff); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d2fa7588533e..49e42635e3ac 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -163,6 +163,21 @@ struct fuse_file { /** Entry on inode's write_files list */ struct list_head write_entry; + /* Readdir related */ + struct { + /* + * Protects below fields against (crazy) parallel readdir on + * same open file. Uncontended in the normal case. + */ + struct mutex lock; + + /* Dir stream position */ + loff_t pos; + + /* Offset in cache */ + loff_t cache_off; + } readdir; + /** RB node to be linked on fuse_conn->polled_files */ struct rb_node polled_node; diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 6c5ada164f7e..5bdc0b945d72 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -289,7 +289,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, return 0; } -int fuse_readdir(struct file *file, struct dir_context *ctx) +static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx) { int plus, err; size_t nbytes; @@ -300,9 +300,6 @@ int fuse_readdir(struct file *file, struct dir_context *ctx) u64 attr_version = 0; bool locked; - if (is_bad_inode(inode)) - return -EIO; - req = fuse_get_req(fc, 1); if (IS_ERR(req)) return PTR_ERR(req); @@ -351,3 +348,146 @@ int fuse_readdir(struct file *file, struct dir_context *ctx) fuse_invalidate_atime(inode); return err; } + +enum fuse_parse_result { + FOUND_ERR = -1, + FOUND_NONE = 0, + FOUND_SOME, + FOUND_ALL, +}; + +static enum fuse_parse_result fuse_parse_cache(struct fuse_file *ff, + void *addr, unsigned int size, + struct dir_context *ctx) +{ + unsigned int offset = ff->readdir.cache_off & ~PAGE_MASK; + enum fuse_parse_result res = FOUND_NONE; + + WARN_ON(offset >= size); + + for (;;) { + struct fuse_dirent *dirent = addr + offset; + unsigned int nbytes = size - offset; + size_t reclen = FUSE_DIRENT_SIZE(dirent); + + if (nbytes < FUSE_NAME_OFFSET || !dirent->namelen) + break; + + if (WARN_ON(dirent->namelen > FUSE_NAME_MAX)) + return FOUND_ERR; + if (WARN_ON(reclen > nbytes)) + return FOUND_ERR; + if (WARN_ON(memchr(dirent->name, '/', dirent->namelen) != NULL)) + return FOUND_ERR; + + if (ff->readdir.pos == ctx->pos) { + res = FOUND_SOME; + if (!dir_emit(ctx, dirent->name, dirent->namelen, + dirent->ino, dirent->type)) + return FOUND_ALL; + ctx->pos = dirent->off; + } + ff->readdir.pos = dirent->off; + ff->readdir.cache_off += reclen; + + offset += reclen; + } + + return res; +} + +#define UNCACHED 1 + +static int fuse_readdir_cached(struct file *file, struct dir_context *ctx) +{ + struct fuse_file *ff = file->private_data; + struct inode *inode = file_inode(file); + struct fuse_inode *fi = get_fuse_inode(inode); + enum fuse_parse_result res; + pgoff_t index; + unsigned int size; + struct page *page; + void *addr; + + /* Seeked? If so, reset the cache stream */ + if (ff->readdir.pos != ctx->pos) { + ff->readdir.pos = 0; + ff->readdir.cache_off = 0; + } + +retry: + spin_lock(&fi->rdc.lock); + if (!fi->rdc.cached) { + spin_unlock(&fi->rdc.lock); + return UNCACHED; + } + WARN_ON(fi->rdc.size < ff->readdir.cache_off); + + index = ff->readdir.cache_off >> PAGE_SHIFT; + + if (index == (fi->rdc.size >> PAGE_SHIFT)) + size = fi->rdc.size & ~PAGE_MASK; + else + size = PAGE_SIZE; + spin_unlock(&fi->rdc.lock); + + /* EOF? */ + if ((ff->readdir.cache_off & ~PAGE_MASK) == size) + return 0; + + page = find_get_page_flags(file->f_mapping, index, + FGP_ACCESSED | FGP_LOCK); + if (!page) { + /* + * Uh-oh: page gone missing, cache is useless + */ + return UNCACHED; + } + + addr = kmap(page); + res = fuse_parse_cache(ff, addr, size, ctx); + kunmap(page); + unlock_page(page); + put_page(page); + + if (res == FOUND_ERR) + return -EIO; + + if (res == FOUND_ALL) + return 0; + + if (size == PAGE_SIZE) { + /* We hit end of page: skip to next page. */ + ff->readdir.cache_off = ALIGN(ff->readdir.cache_off, PAGE_SIZE); + goto retry; + } + + /* + * End of cache reached. If found position, then we are done, otherwise + * need to fall back to uncached, since the position we were looking for + * wasn't in the cache. + */ + return res == FOUND_SOME ? 0 : UNCACHED; +} + +int fuse_readdir(struct file *file, struct dir_context *ctx) +{ + struct fuse_file *ff = file->private_data; + struct inode *inode = file_inode(file); + int err; + + if (is_bad_inode(inode)) + return -EIO; + + mutex_lock(&ff->readdir.lock); + + err = UNCACHED; + if (ff->open_flags & FOPEN_CACHE_DIR) + err = fuse_readdir_cached(file, ctx); + if (err == UNCACHED) + err = fuse_readdir_uncached(file, ctx); + + mutex_unlock(&ff->readdir.lock); + + return err; +} From 3494927e090bf511e54eecaf33a8e56e5c0463db Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:04 +0200 Subject: [PATCH 180/836] fuse: add readdir cache version Allow the cache to be invalidated when page(s) have gone missing. In this case increment the version of the cache and reset to an empty state. Add a version number to the directory stream in struct fuse_file as well, indicating the version of the cache it's supposed to be reading. If the cache version doesn't match the stream's version, then reset the stream to the beginning of the cache. Signed-off-by: Miklos Szeredi --- fs/fuse/fuse_i.h | 7 +++++++ fs/fuse/inode.c | 1 + fs/fuse/readdir.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 49e42635e3ac..8b24805e62ee 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -114,6 +114,9 @@ struct fuse_inode { /* position at end of cache (position of next entry) */ loff_t pos; + /* version of the cache */ + u64 version; + /* protects above fields */ spinlock_t lock; } rdc; @@ -176,6 +179,10 @@ struct fuse_file { /* Offset in cache */ loff_t cache_off; + + /* Version of cache we are reading */ + u64 version; + } readdir; /** RB node to be linked on fuse_conn->polled_files */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 892efe6351eb..eef2ae713f75 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -104,6 +104,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) fi->rdc.cached = false; fi->rdc.size = 0; fi->rdc.pos = 0; + fi->rdc.version = 0; mutex_init(&fi->mutex); fi->forget = fuse_alloc_forget(); if (!fi->forget) { diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 5bdc0b945d72..18318cc31c05 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -36,6 +36,7 @@ static void fuse_add_dirent_to_cache(struct file *file, pgoff_t index; struct page *page; loff_t size; + u64 version; unsigned int offset; void *addr; @@ -48,6 +49,7 @@ static void fuse_add_dirent_to_cache(struct file *file, spin_unlock(&fi->rdc.lock); return; } + version = fi->rdc.version; size = fi->rdc.size; offset = size & ~PAGE_MASK; index = size >> PAGE_SHIFT; @@ -69,7 +71,8 @@ static void fuse_add_dirent_to_cache(struct file *file, spin_lock(&fi->rdc.lock); /* Raced with another readdir */ - if (fi->rdc.size != size || WARN_ON(fi->rdc.pos != pos)) + if (fi->rdc.version != version || fi->rdc.size != size || + WARN_ON(fi->rdc.pos != pos)) goto unlock; addr = kmap_atomic(page); @@ -396,6 +399,14 @@ static enum fuse_parse_result fuse_parse_cache(struct fuse_file *ff, return res; } +static void fuse_rdc_reset(struct fuse_inode *fi) +{ + fi->rdc.cached = false; + fi->rdc.version++; + fi->rdc.size = 0; + fi->rdc.pos = 0; +} + #define UNCACHED 1 static int fuse_readdir_cached(struct file *file, struct dir_context *ctx) @@ -421,6 +432,21 @@ retry: spin_unlock(&fi->rdc.lock); return UNCACHED; } + /* + * If cache version changed since the last getdents() call, then reset + * the cache stream. + */ + if (ff->readdir.version != fi->rdc.version) { + ff->readdir.pos = 0; + ff->readdir.cache_off = 0; + } + /* + * If at the beginning of the cache, than reset version to + * current. + */ + if (ff->readdir.pos == 0) + ff->readdir.version = fi->rdc.version; + WARN_ON(fi->rdc.size < ff->readdir.cache_off); index = ff->readdir.cache_off >> PAGE_SHIFT; @@ -437,13 +463,30 @@ retry: page = find_get_page_flags(file->f_mapping, index, FGP_ACCESSED | FGP_LOCK); + spin_lock(&fi->rdc.lock); if (!page) { /* * Uh-oh: page gone missing, cache is useless */ + if (fi->rdc.version == ff->readdir.version) + fuse_rdc_reset(fi); + spin_unlock(&fi->rdc.lock); return UNCACHED; } + /* Make sure it's still the same version after getting the page. */ + if (ff->readdir.version != fi->rdc.version) { + spin_unlock(&fi->rdc.lock); + unlock_page(page); + put_page(page); + goto retry; + } + spin_unlock(&fi->rdc.lock); + + /* + * Contents of the page are now protected against changing by holding + * the page lock. + */ addr = kmap(page); res = fuse_parse_cache(ff, addr, size, ctx); kunmap(page); From 7118883b44b8edfea732aadeb0d4424da3f152b2 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:04 +0200 Subject: [PATCH 181/836] fuse: use mtime for readdir cache verification Store the modification time of the directory in the cache, obtained before starting to fill the cache. When reading the cache, verify that the directory hasn't changed, by checking if current modification time is the same as the one stored in the cache. This only needs to be done when the current file position is at the beginning of the directory, as mandated by POSIX. Signed-off-by: Miklos Szeredi --- fs/fuse/fuse_i.h | 3 +++ fs/fuse/readdir.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 8b24805e62ee..3deb013a289e 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -117,6 +117,9 @@ struct fuse_inode { /* version of the cache */ u64 version; + /* modification time of directory when cache was started */ + struct timespec64 mtime; + /* protects above fields */ spinlock_t lock; } rdc; diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 18318cc31c05..dafd6543cca2 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -399,8 +399,10 @@ static enum fuse_parse_result fuse_parse_cache(struct fuse_file *ff, return res; } -static void fuse_rdc_reset(struct fuse_inode *fi) +static void fuse_rdc_reset(struct inode *inode) { + struct fuse_inode *fi = get_fuse_inode(inode); + fi->rdc.cached = false; fi->rdc.version++; fi->rdc.size = 0; @@ -413,6 +415,7 @@ static int fuse_readdir_cached(struct file *file, struct dir_context *ctx) { struct fuse_file *ff = file->private_data; struct inode *inode = file_inode(file); + struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_inode *fi = get_fuse_inode(inode); enum fuse_parse_result res; pgoff_t index; @@ -426,12 +429,40 @@ static int fuse_readdir_cached(struct file *file, struct dir_context *ctx) ff->readdir.cache_off = 0; } + /* + * We're just about to start reading into the cache or reading the + * cache; both cases require an up-to-date mtime value. + */ + if (!ctx->pos && fc->auto_inval_data) { + int err = fuse_update_attributes(inode, file); + + if (err) + return err; + } + retry: spin_lock(&fi->rdc.lock); +retry_locked: if (!fi->rdc.cached) { + /* Starting cache? Set cache mtime. */ + if (!ctx->pos && !fi->rdc.size) { + fi->rdc.mtime = inode->i_mtime; + } spin_unlock(&fi->rdc.lock); return UNCACHED; } + /* + * When at the beginning of the directory (i.e. just after opendir(3) or + * rewinddir(3)), then need to check whether directory contents have + * changed, and reset the cache if so. + */ + if (!ctx->pos) { + if (!timespec64_equal(&fi->rdc.mtime, &inode->i_mtime)) { + fuse_rdc_reset(inode); + goto retry_locked; + } + } + /* * If cache version changed since the last getdents() call, then reset * the cache stream. @@ -469,9 +500,8 @@ retry: * Uh-oh: page gone missing, cache is useless */ if (fi->rdc.version == ff->readdir.version) - fuse_rdc_reset(fi); - spin_unlock(&fi->rdc.lock); - return UNCACHED; + fuse_rdc_reset(inode); + goto retry_locked; } /* Make sure it's still the same version after getting the page. */ From 261aaba72fdba17b74a3a434d9f925b43d90e958 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:05 +0200 Subject: [PATCH 182/836] fuse: use iversion for readdir cache verification Use the internal iversion counter to make sure modifications of the directory through this filesystem are not missed by the mtime check (due to mtime granularity). Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 21 ++++++++++++++------- fs/fuse/fuse_i.h | 3 +++ fs/fuse/readdir.c | 5 ++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 3a333b0ea9ad..6800fdc3e730 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -14,6 +14,7 @@ #include #include #include +#include #include static void fuse_advise_use_readdirplus(struct inode *dir) @@ -89,6 +90,12 @@ void fuse_invalidate_attr(struct inode *inode) get_fuse_inode(inode)->i_time = 0; } +static void fuse_dir_changed(struct inode *dir) +{ + fuse_invalidate_attr(dir); + inode_maybe_inc_iversion(dir, false); +} + /** * Mark the attributes as stale due to an atime change. Avoid the invalidate if * atime is not used. @@ -447,7 +454,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, kfree(forget); d_instantiate(entry, inode); fuse_change_entry_timeout(entry, &outentry); - fuse_invalidate_attr(dir); + fuse_dir_changed(dir); err = finish_open(file, entry, generic_file_open); if (err) { fuse_sync_release(ff, flags); @@ -561,7 +568,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, } else { fuse_change_entry_timeout(entry, &outarg); } - fuse_invalidate_attr(dir); + fuse_dir_changed(dir); return 0; out_put_forget_req: @@ -671,7 +678,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) drop_nlink(inode); spin_unlock(&fc->lock); fuse_invalidate_attr(inode); - fuse_invalidate_attr(dir); + fuse_dir_changed(dir); fuse_invalidate_entry_cache(entry); fuse_update_ctime(inode); } else if (err == -EINTR) @@ -693,7 +700,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) err = fuse_simple_request(fc, &args); if (!err) { clear_nlink(d_inode(entry)); - fuse_invalidate_attr(dir); + fuse_dir_changed(dir); fuse_invalidate_entry_cache(entry); } else if (err == -EINTR) fuse_invalidate_entry(entry); @@ -732,9 +739,9 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, fuse_update_ctime(d_inode(newent)); } - fuse_invalidate_attr(olddir); + fuse_dir_changed(olddir); if (olddir != newdir) - fuse_invalidate_attr(newdir); + fuse_dir_changed(newdir); /* newent will end up negative */ if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) { @@ -967,7 +974,7 @@ int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid, if (!entry) goto unlock; - fuse_invalidate_attr(parent); + fuse_dir_changed(parent); fuse_invalidate_entry(entry); if (child_nodeid != 0 && d_really_is_positive(entry)) { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 3deb013a289e..d9d1ea78efa6 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -120,6 +120,9 @@ struct fuse_inode { /* modification time of directory when cache was started */ struct timespec64 mtime; + /* iversion of directory when cache was started */ + u64 iversion; + /* protects above fields */ spinlock_t lock; } rdc; diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index dafd6543cca2..ab18b78f4755 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -8,6 +8,7 @@ #include "fuse_i.h" +#include #include #include #include @@ -447,6 +448,7 @@ retry_locked: /* Starting cache? Set cache mtime. */ if (!ctx->pos && !fi->rdc.size) { fi->rdc.mtime = inode->i_mtime; + fi->rdc.iversion = inode_query_iversion(inode); } spin_unlock(&fi->rdc.lock); return UNCACHED; @@ -457,7 +459,8 @@ retry_locked: * changed, and reset the cache if so. */ if (!ctx->pos) { - if (!timespec64_equal(&fi->rdc.mtime, &inode->i_mtime)) { + if (inode_peek_iversion(inode) != fi->rdc.iversion || + !timespec64_equal(&fi->rdc.mtime, &inode->i_mtime)) { fuse_rdc_reset(inode); goto retry_locked; } From ab2257e9941b9ef28d4a4a451e4b146d40a21e18 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:05 +0200 Subject: [PATCH 183/836] fuse: reduce size of struct fuse_inode Do this by grouping fields used for cached writes and putting them into a union with fileds used for cached readdir (with obviously no overlap, since we don't have hybrid objects). Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 13 +++++++++- fs/fuse/file.c | 8 +++++++ fs/fuse/fuse_i.h | 62 ++++++++++++++++++++++++++---------------------- fs/fuse/inode.c | 16 ++++--------- 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 6800fdc3e730..d1b2f42d746e 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1414,8 +1414,11 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, file = NULL; } - if (attr->ia_valid & ATTR_SIZE) + if (attr->ia_valid & ATTR_SIZE) { + if (WARN_ON(!S_ISREG(inode->i_mode))) + return -EIO; is_truncate = true; + } if (is_truncate) { fuse_set_nowrite(inode); @@ -1619,8 +1622,16 @@ void fuse_init_common(struct inode *inode) void fuse_init_dir(struct inode *inode) { + struct fuse_inode *fi = get_fuse_inode(inode); + inode->i_op = &fuse_dir_inode_operations; inode->i_fop = &fuse_dir_operations; + + spin_lock_init(&fi->rdc.lock); + fi->rdc.cached = false; + fi->rdc.size = 0; + fi->rdc.pos = 0; + fi->rdc.version = 0; } void fuse_init_symlink(struct inode *inode) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index e10c0443c56f..b10d14baeb1f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3143,6 +3143,14 @@ static const struct address_space_operations fuse_file_aops = { void fuse_init_file_inode(struct inode *inode) { + struct fuse_inode *fi = get_fuse_inode(inode); + inode->i_fop = &fuse_file_operations; inode->i_data.a_ops = &fuse_file_aops; + + INIT_LIST_HEAD(&fi->write_files); + INIT_LIST_HEAD(&fi->queued_writes); + fi->writectr = 0; + init_waitqueue_head(&fi->page_waitq); + INIT_LIST_HEAD(&fi->writepages); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index d9d1ea78efa6..f5bdce84e766 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -87,45 +87,51 @@ struct fuse_inode { /** Version of last attribute change */ u64 attr_version; - /** Files usable in writepage. Protected by fc->lock */ - struct list_head write_files; + union { + /* Write related fields (regular file only) */ + struct { + /* Files usable in writepage. Protected by fc->lock */ + struct list_head write_files; - /** Writepages pending on truncate or fsync */ - struct list_head queued_writes; + /* Writepages pending on truncate or fsync */ + struct list_head queued_writes; - /** Number of sent writes, a negative bias (FUSE_NOWRITE) - * means more writes are blocked */ - int writectr; + /* Number of sent writes, a negative bias + * (FUSE_NOWRITE) means more writes are blocked */ + int writectr; - /** Waitq for writepage completion */ - wait_queue_head_t page_waitq; + /* Waitq for writepage completion */ + wait_queue_head_t page_waitq; - /** List of writepage requestst (pending or sent) */ - struct list_head writepages; + /* List of writepage requestst (pending or sent) */ + struct list_head writepages; + }; - /* readdir cache */ - struct { - /* true if fully cached */ - bool cached; + /* readdir cache (directory only) */ + struct { + /* true if fully cached */ + bool cached; - /* size of cache */ - loff_t size; + /* size of cache */ + loff_t size; - /* position at end of cache (position of next entry) */ - loff_t pos; + /* position at end of cache (position of next entry) */ + loff_t pos; - /* version of the cache */ - u64 version; + /* version of the cache */ + u64 version; - /* modification time of directory when cache was started */ - struct timespec64 mtime; + /* modification time of directory when cache was + * started */ + struct timespec64 mtime; - /* iversion of directory when cache was started */ - u64 iversion; + /* iversion of directory when cache was started */ + u64 iversion; - /* protects above fields */ - spinlock_t lock; - } rdc; + /* protects above fields */ + spinlock_t lock; + } rdc; + }; /** Miscellaneous bits describing inode state */ unsigned long state; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index eef2ae713f75..82db1ab53420 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -93,18 +93,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) fi->nodeid = 0; fi->nlookup = 0; fi->attr_version = 0; - fi->writectr = 0; fi->orig_ino = 0; fi->state = 0; - INIT_LIST_HEAD(&fi->write_files); - INIT_LIST_HEAD(&fi->queued_writes); - INIT_LIST_HEAD(&fi->writepages); - init_waitqueue_head(&fi->page_waitq); - spin_lock_init(&fi->rdc.lock); - fi->rdc.cached = false; - fi->rdc.size = 0; - fi->rdc.pos = 0; - fi->rdc.version = 0; mutex_init(&fi->mutex); fi->forget = fuse_alloc_forget(); if (!fi->forget) { @@ -124,8 +114,10 @@ static void fuse_i_callback(struct rcu_head *head) static void fuse_destroy_inode(struct inode *inode) { struct fuse_inode *fi = get_fuse_inode(inode); - BUG_ON(!list_empty(&fi->write_files)); - BUG_ON(!list_empty(&fi->queued_writes)); + if (S_ISREG(inode->i_mode)) { + WARN_ON(!list_empty(&fi->write_files)); + WARN_ON(!list_empty(&fi->queued_writes)); + } mutex_destroy(&fi->mutex); kfree(fi->forget); call_rcu(&inode->i_rcu, fuse_i_callback); From 8a7aa286ab67d7dfac8abbefab899597b5977c9a Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:05 +0200 Subject: [PATCH 184/836] fuse: allocate page array more efficiently When allocating page array for a request the array for the page pointers and the array for page descriptors are allocated by two separate kmalloc() calls. Merge these into one allocation. Also instead of initializing the request and the page arrays with memset(), use the zeroing allocation variants. Reserved requests never carry pages (page array size is zero). Make that explicit by initializing the page array pointers to NULL and make sure the assumption remains true by adding a WARN_ON(). Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 91b4ecf85dc7..fefb9dd8a2f4 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -44,9 +44,6 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages, struct fuse_page_desc *page_descs, unsigned npages) { - memset(req, 0, sizeof(*req)); - memset(pages, 0, sizeof(*pages) * npages); - memset(page_descs, 0, sizeof(*page_descs) * npages); INIT_LIST_HEAD(&req->list); INIT_LIST_HEAD(&req->intr_entry); init_waitqueue_head(&req->waitq); @@ -59,28 +56,22 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages, static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) { - struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, flags); + struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags); if (req) { - struct page **pages; - struct fuse_page_desc *page_descs; + struct page **pages = NULL; + struct fuse_page_desc *page_descs = NULL; - if (npages <= FUSE_REQ_INLINE_PAGES) { + if (npages > FUSE_REQ_INLINE_PAGES) { + pages = kzalloc(npages * (sizeof(*pages) + + sizeof(*page_descs)), flags); + if (!pages) { + kmem_cache_free(fuse_req_cachep, req); + return NULL; + } + page_descs = (void *) pages + npages * sizeof(*pages); + } else if (npages) { pages = req->inline_pages; page_descs = req->inline_page_descs; - } else { - pages = kmalloc_array(npages, sizeof(struct page *), - flags); - page_descs = - kmalloc_array(npages, - sizeof(struct fuse_page_desc), - flags); - } - - if (!pages || !page_descs) { - kfree(pages); - kfree(page_descs); - kmem_cache_free(fuse_req_cachep, req); - return NULL; } fuse_request_init(req, pages, page_descs, npages); @@ -101,10 +92,9 @@ struct fuse_req *fuse_request_alloc_nofs(unsigned npages) void fuse_request_free(struct fuse_req *req) { - if (req->pages != req->inline_pages) { + if (req->pages != req->inline_pages) kfree(req->pages); - kfree(req->page_descs); - } + kmem_cache_free(fuse_req_cachep, req); } @@ -239,8 +229,10 @@ static void put_reserved_req(struct fuse_conn *fc, struct fuse_req *req) struct file *file = req->stolen_file; struct fuse_file *ff = file->private_data; + WARN_ON(req->max_pages); spin_lock(&fc->lock); - fuse_request_init(req, req->pages, req->page_descs, req->max_pages); + memset(req, 0, sizeof(*req)); + fuse_request_init(req, NULL, NULL, 0); BUG_ON(ff->reserved_req); ff->reserved_req = req; wake_up_all(&fc->reserved_req_waitq); From 5da784cce4308ae10a79e3c8c41b13fb9568e4e0 Mon Sep 17 00:00:00 2001 From: Constantine Shulyupin Date: Thu, 6 Sep 2018 15:37:06 +0300 Subject: [PATCH 185/836] fuse: add max_pages to init_out Replace FUSE_MAX_PAGES_PER_REQ with the configurable parameter max_pages to improve performance. Old RFC with detailed description of the problem and many fixes by Mitsuo Hayasaka (mitsuo.hayasaka.hu@hitachi.com): - https://lkml.org/lkml/2012/7/5/136 We've encountered performance degradation and fixed it on a big and complex virtual environment. Environment to reproduce degradation and improvement: 1. Add lag to user mode FUSE Add nanosleep(&(struct timespec){ 0, 1000 }, NULL); to xmp_write_buf in passthrough_fh.c 2. patch UM fuse with configurable max_pages parameter. The patch will be provided latter. 3. run test script and perform test on tmpfs fuse_test() { cd /tmp mkdir -p fusemnt passthrough_fh -o max_pages=$1 /tmp/fusemnt grep fuse /proc/self/mounts dd conv=fdatasync oflag=dsync if=/dev/zero of=fusemnt/tmp/tmp \ count=1K bs=1M 2>&1 | grep -v records rm fusemnt/tmp/tmp killall passthrough_fh } Test results: passthrough_fh /tmp/fusemnt fuse.passthrough_fh \ rw,nosuid,nodev,relatime,user_id=0,group_id=0 0 0 1073741824 bytes (1.1 GB) copied, 1.73867 s, 618 MB/s passthrough_fh /tmp/fusemnt fuse.passthrough_fh \ rw,nosuid,nodev,relatime,user_id=0,group_id=0,max_pages=256 0 0 1073741824 bytes (1.1 GB) copied, 1.15643 s, 928 MB/s Obviously with bigger lag the difference between 'before' and 'after' will be more significant. Mitsuo Hayasaka, in 2012 (https://lkml.org/lkml/2012/7/5/136), observed improvement from 400-550 to 520-740. Signed-off-by: Constantine Shulyupin Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 5 ++-- fs/fuse/file.c | 59 ++++++++++++++++++++------------------- fs/fuse/fuse_i.h | 10 +++++-- fs/fuse/inode.c | 8 +++++- include/uapi/linux/fuse.h | 7 ++++- 5 files changed, 54 insertions(+), 35 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index fefb9dd8a2f4..69d4df78a417 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -61,6 +61,7 @@ static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) struct page **pages = NULL; struct fuse_page_desc *page_descs = NULL; + WARN_ON(npages > FUSE_MAX_MAX_PAGES); if (npages > FUSE_REQ_INLINE_PAGES) { pages = kzalloc(npages * (sizeof(*pages) + sizeof(*page_descs)), flags); @@ -1674,7 +1675,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, unsigned int num; unsigned int offset; size_t total_len = 0; - int num_pages; + unsigned int num_pages; offset = outarg->offset & ~PAGE_MASK; file_size = i_size_read(inode); @@ -1686,7 +1687,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, num = file_size - outarg->offset; num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; - num_pages = min(num_pages, FUSE_MAX_PAGES_PER_REQ); + num_pages = min(num_pages, fc->max_pages); req = fuse_get_req(fc, num_pages); if (IS_ERR(req)) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index b10d14baeb1f..035843b501fe 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -850,11 +850,11 @@ static int fuse_readpages_fill(void *_data, struct page *page) fuse_wait_on_page_writeback(inode, page->index); if (req->num_pages && - (req->num_pages == FUSE_MAX_PAGES_PER_REQ || + (req->num_pages == fc->max_pages || (req->num_pages + 1) * PAGE_SIZE > fc->max_read || req->pages[req->num_pages - 1]->index + 1 != page->index)) { - int nr_alloc = min_t(unsigned, data->nr_pages, - FUSE_MAX_PAGES_PER_REQ); + unsigned int nr_alloc = min_t(unsigned int, data->nr_pages, + fc->max_pages); fuse_send_readpages(req, data->file); if (fc->async_read) req = fuse_get_req_for_background(fc, nr_alloc); @@ -889,7 +889,7 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_fill_data data; int err; - int nr_alloc = min_t(unsigned, nr_pages, FUSE_MAX_PAGES_PER_REQ); + unsigned int nr_alloc = min_t(unsigned int, nr_pages, fc->max_pages); err = -EIO; if (is_bad_inode(inode)) @@ -1104,12 +1104,13 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req, return count > 0 ? count : err; } -static inline unsigned fuse_wr_pages(loff_t pos, size_t len) +static inline unsigned int fuse_wr_pages(loff_t pos, size_t len, + unsigned int max_pages) { - return min_t(unsigned, + return min_t(unsigned int, ((pos + len - 1) >> PAGE_SHIFT) - (pos >> PAGE_SHIFT) + 1, - FUSE_MAX_PAGES_PER_REQ); + max_pages); } static ssize_t fuse_perform_write(struct kiocb *iocb, @@ -1131,7 +1132,8 @@ static ssize_t fuse_perform_write(struct kiocb *iocb, do { struct fuse_req *req; ssize_t count; - unsigned nr_pages = fuse_wr_pages(pos, iov_iter_count(ii)); + unsigned int nr_pages = fuse_wr_pages(pos, iov_iter_count(ii), + fc->max_pages); req = fuse_get_req(fc, nr_pages); if (IS_ERR(req)) { @@ -1321,11 +1323,6 @@ static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii, return ret < 0 ? ret : 0; } -static inline int fuse_iter_npages(const struct iov_iter *ii_p) -{ - return iov_iter_npages(ii_p, FUSE_MAX_PAGES_PER_REQ); -} - ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, loff_t *ppos, int flags) { @@ -1345,9 +1342,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, int err = 0; if (io->async) - req = fuse_get_req_for_background(fc, fuse_iter_npages(iter)); + req = fuse_get_req_for_background(fc, iov_iter_npages(iter, + fc->max_pages)); else - req = fuse_get_req(fc, fuse_iter_npages(iter)); + req = fuse_get_req(fc, iov_iter_npages(iter, fc->max_pages)); if (IS_ERR(req)) return PTR_ERR(req); @@ -1392,9 +1390,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, fuse_put_request(fc, req); if (io->async) req = fuse_get_req_for_background(fc, - fuse_iter_npages(iter)); + iov_iter_npages(iter, fc->max_pages)); else - req = fuse_get_req(fc, fuse_iter_npages(iter)); + req = fuse_get_req(fc, iov_iter_npages(iter, + fc->max_pages)); if (IS_ERR(req)) break; } @@ -1823,7 +1822,7 @@ static int fuse_writepages_fill(struct page *page, is_writeback = fuse_page_is_writeback(inode, page->index); if (req && req->num_pages && - (is_writeback || req->num_pages == FUSE_MAX_PAGES_PER_REQ || + (is_writeback || req->num_pages == fc->max_pages || (req->num_pages + 1) * PAGE_SIZE > fc->max_write || data->orig_pages[req->num_pages - 1]->index + 1 != page->index)) { fuse_writepages_send(data); @@ -1851,7 +1850,7 @@ static int fuse_writepages_fill(struct page *page, struct fuse_inode *fi = get_fuse_inode(inode); err = -ENOMEM; - req = fuse_request_alloc_nofs(FUSE_MAX_PAGES_PER_REQ); + req = fuse_request_alloc_nofs(fc->max_pages); if (!req) { __free_page(tmp_page); goto out_unlock; @@ -1908,6 +1907,7 @@ static int fuse_writepages(struct address_space *mapping, struct writeback_control *wbc) { struct inode *inode = mapping->host; + struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_fill_wb_data data; int err; @@ -1920,7 +1920,7 @@ static int fuse_writepages(struct address_space *mapping, data.ff = NULL; err = -ENOMEM; - data.orig_pages = kcalloc(FUSE_MAX_PAGES_PER_REQ, + data.orig_pages = kcalloc(fc->max_pages, sizeof(struct page *), GFP_NOFS); if (!data.orig_pages) @@ -2391,10 +2391,11 @@ static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src, } /* Make sure iov_length() won't overflow */ -static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) +static int fuse_verify_ioctl_iov(struct fuse_conn *fc, struct iovec *iov, + size_t count) { size_t n; - u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; + u32 max = fc->max_pages << PAGE_SHIFT; for (n = 0; n < count; n++, iov++) { if (iov->iov_len > (size_t) max) @@ -2518,7 +2519,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); err = -ENOMEM; - pages = kcalloc(FUSE_MAX_PAGES_PER_REQ, sizeof(pages[0]), GFP_KERNEL); + pages = kcalloc(fc->max_pages, sizeof(pages[0]), GFP_KERNEL); iov_page = (struct iovec *) __get_free_page(GFP_KERNEL); if (!pages || !iov_page) goto out; @@ -2557,7 +2558,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, /* make sure there are enough buffer pages and init request with them */ err = -ENOMEM; - if (max_pages > FUSE_MAX_PAGES_PER_REQ) + if (max_pages > fc->max_pages) goto out; while (num_pages < max_pages) { pages[num_pages] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM); @@ -2644,11 +2645,11 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, in_iov = iov_page; out_iov = in_iov + in_iovs; - err = fuse_verify_ioctl_iov(in_iov, in_iovs); + err = fuse_verify_ioctl_iov(fc, in_iov, in_iovs); if (err) goto out; - err = fuse_verify_ioctl_iov(out_iov, out_iovs); + err = fuse_verify_ioctl_iov(fc, out_iov, out_iovs); if (err) goto out; @@ -2839,9 +2840,9 @@ static void fuse_do_truncate(struct file *file) fuse_do_setattr(file_dentry(file), &attr, file); } -static inline loff_t fuse_round_up(loff_t off) +static inline loff_t fuse_round_up(struct fuse_conn *fc, loff_t off) { - return round_up(off, FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT); + return round_up(off, fc->max_pages << PAGE_SHIFT); } static ssize_t @@ -2870,7 +2871,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) if (async_dio && iov_iter_rw(iter) != WRITE && offset + count > i_size) { if (offset >= i_size) return 0; - iov_iter_truncate(iter, fuse_round_up(i_size - offset)); + iov_iter_truncate(iter, fuse_round_up(ff->fc, i_size - offset)); count = iov_iter_count(iter); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index f5bdce84e766..3d578745c852 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -28,8 +28,11 @@ #include #include -/** Max number of pages that can be used in a single read request */ -#define FUSE_MAX_PAGES_PER_REQ 32 +/** Default max number of pages that can be used in a single read request */ +#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32 + +/** Maximum of max_pages received in init_out */ +#define FUSE_MAX_MAX_PAGES 256 /** Bias for fi->writectr, meaning new writepages must not be sent */ #define FUSE_NOWRITE INT_MIN @@ -525,6 +528,9 @@ struct fuse_conn { /** Maximum write size */ unsigned max_write; + /** Maxmum number of pages that can be used in a single request */ + unsigned int max_pages; + /** Input queue */ struct fuse_iqueue iq; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 82db1ab53420..8cebf4d5f51b 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -928,6 +928,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) } if (arg->flags & FUSE_ABORT_ERROR) fc->abort_err = 1; + if (arg->flags & FUSE_MAX_PAGES) { + fc->max_pages = + min_t(unsigned int, FUSE_MAX_MAX_PAGES, + max_t(unsigned int, arg->max_pages, 1)); + } } else { ra_pages = fc->max_read / PAGE_SIZE; fc->no_lock = 1; @@ -959,7 +964,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL | - FUSE_ABORT_ERROR; + FUSE_ABORT_ERROR | FUSE_MAX_PAGES; req->in.h.opcode = FUSE_INIT; req->in.numargs = 1; req->in.args[0].size = sizeof(*arg); @@ -1152,6 +1157,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) fc->user_id = d.user_id; fc->group_id = d.group_id; fc->max_read = max_t(unsigned, 4096, d.max_read); + fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ; /* Used by get_root_inode() */ sb->s_fs_info = fc; diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index 31a504f1ee60..76f46f159992 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -120,6 +120,7 @@ * 7.28 * - add FUSE_COPY_FILE_RANGE * - add FOPEN_CACHE_DIR + * - add FUSE_MAX_PAGES, add max_pages to init_out */ #ifndef _LINUX_FUSE_H @@ -255,6 +256,7 @@ struct fuse_file_lock { * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc * FUSE_POSIX_ACL: filesystem supports posix acls * FUSE_ABORT_ERROR: reading the device after abort returns ECONNABORTED + * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -278,6 +280,7 @@ struct fuse_file_lock { #define FUSE_HANDLE_KILLPRIV (1 << 19) #define FUSE_POSIX_ACL (1 << 20) #define FUSE_ABORT_ERROR (1 << 21) +#define FUSE_MAX_PAGES (1 << 22) /** * CUSE INIT request/reply flags @@ -617,7 +620,9 @@ struct fuse_init_out { uint16_t congestion_threshold; uint32_t max_write; uint32_t time_gran; - uint32_t unused[9]; + uint16_t max_pages; + uint16_t padding; + uint32_t unused[8]; }; #define CUSE_INIT_INFO_MAX 4096 From e52a8250480acd3b26534793c61816e30d85fbb6 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 1 Oct 2018 10:07:06 +0200 Subject: [PATCH 186/836] fuse: realloc page array Writeback caching currently allocates requests with the maximum number of possible pages, while the actual number of pages per request depends on a couple of factors that cannot be determined when the request is allocated (whether page is already under writeback, whether page is contiguous with previous pages already added to a request). This patch allows such requests to start with no page allocation (all pages inline) and grow the page array on demand. If the max_pages tunable remains the default value, then this will mean just one allocation that is the same size as before. If the tunable is larger, then this adds at most 3 additional memory allocations (which is generously compensated by the improved performance from the larger request). Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 49 ++++++++++++++++++++++++++++++++++++++++++++---- fs/fuse/file.c | 8 +++++++- fs/fuse/fuse_i.h | 4 ++++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 69d4df78a417..ae813e609932 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -54,6 +54,18 @@ static void fuse_request_init(struct fuse_req *req, struct page **pages, __set_bit(FR_PENDING, &req->flags); } +static struct page **fuse_req_pages_alloc(unsigned int npages, gfp_t flags, + struct fuse_page_desc **desc) +{ + struct page **pages; + + pages = kzalloc(npages * (sizeof(struct page *) + + sizeof(struct fuse_page_desc)), flags); + *desc = (void *) pages + npages * sizeof(struct page *); + + return pages; +} + static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) { struct fuse_req *req = kmem_cache_zalloc(fuse_req_cachep, flags); @@ -63,13 +75,12 @@ static struct fuse_req *__fuse_request_alloc(unsigned npages, gfp_t flags) WARN_ON(npages > FUSE_MAX_MAX_PAGES); if (npages > FUSE_REQ_INLINE_PAGES) { - pages = kzalloc(npages * (sizeof(*pages) + - sizeof(*page_descs)), flags); + pages = fuse_req_pages_alloc(npages, flags, + &page_descs); if (!pages) { kmem_cache_free(fuse_req_cachep, req); return NULL; } - page_descs = (void *) pages + npages * sizeof(*pages); } else if (npages) { pages = req->inline_pages; page_descs = req->inline_page_descs; @@ -91,11 +102,41 @@ struct fuse_req *fuse_request_alloc_nofs(unsigned npages) return __fuse_request_alloc(npages, GFP_NOFS); } -void fuse_request_free(struct fuse_req *req) +static void fuse_req_pages_free(struct fuse_req *req) { if (req->pages != req->inline_pages) kfree(req->pages); +} +bool fuse_req_realloc_pages(struct fuse_conn *fc, struct fuse_req *req, + gfp_t flags) +{ + struct page **pages; + struct fuse_page_desc *page_descs; + unsigned int npages = min_t(unsigned int, + max_t(unsigned int, req->max_pages * 2, + FUSE_DEFAULT_MAX_PAGES_PER_REQ), + fc->max_pages); + WARN_ON(npages <= req->max_pages); + + pages = fuse_req_pages_alloc(npages, flags, &page_descs); + if (!pages) + return false; + + memcpy(pages, req->pages, sizeof(struct page *) * req->max_pages); + memcpy(page_descs, req->page_descs, + sizeof(struct fuse_page_desc) * req->max_pages); + fuse_req_pages_free(req); + req->pages = pages; + req->page_descs = page_descs; + req->max_pages = npages; + + return true; +} + +void fuse_request_free(struct fuse_req *req) +{ + fuse_req_pages_free(req); kmem_cache_free(fuse_req_cachep, req); } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 035843b501fe..f5507198ea00 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1827,7 +1827,13 @@ static int fuse_writepages_fill(struct page *page, data->orig_pages[req->num_pages - 1]->index + 1 != page->index)) { fuse_writepages_send(data); data->req = NULL; + } else if (req && req->num_pages == req->max_pages) { + if (!fuse_req_realloc_pages(fc, req, GFP_NOFS)) { + fuse_writepages_send(data); + req = data->req = NULL; + } } + err = -ENOMEM; tmp_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); if (!tmp_page) @@ -1850,7 +1856,7 @@ static int fuse_writepages_fill(struct page *page, struct fuse_inode *fi = get_fuse_inode(inode); err = -ENOMEM; - req = fuse_request_alloc_nofs(fc->max_pages); + req = fuse_request_alloc_nofs(FUSE_REQ_INLINE_PAGES); if (!req) { __free_page(tmp_page); goto out_unlock; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 3d578745c852..b7d96e7b5e0f 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -879,6 +879,10 @@ struct fuse_req *fuse_request_alloc(unsigned npages); struct fuse_req *fuse_request_alloc_nofs(unsigned npages); +bool fuse_req_realloc_pages(struct fuse_conn *fc, struct fuse_req *req, + gfp_t flags); + + /** * Free a request */ From c3828949a21d95326f08f02d97fea97172319300 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 12 Sep 2018 15:40:17 +0200 Subject: [PATCH 187/836] clk: mvebu: use SPDX-License-Identifier Convert the remaining files to SPDX license description. Signed-off-by: Gregory CLEMENT Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 4 +--- drivers/clk/mvebu/armada-370.c | 4 +--- drivers/clk/mvebu/armada-375.c | 4 +--- drivers/clk/mvebu/armada-37xx-tbg.c | 5 +---- drivers/clk/mvebu/armada-37xx-xtal.c | 4 +--- drivers/clk/mvebu/armada-38x.c | 4 +--- drivers/clk/mvebu/armada-39x.c | 4 +--- drivers/clk/mvebu/armada-xp.c | 4 +--- drivers/clk/mvebu/clk-corediv.c | 4 +--- drivers/clk/mvebu/clk-cpu.c | 4 +--- drivers/clk/mvebu/common.c | 4 +--- drivers/clk/mvebu/common.h | 4 +--- drivers/clk/mvebu/cp110-system-controller.c | 4 +--- drivers/clk/mvebu/dove.c | 4 +--- drivers/clk/mvebu/kirkwood.c | 4 +--- drivers/clk/mvebu/mv98dx3236.c | 4 +--- drivers/clk/mvebu/orion.c | 4 +--- 17 files changed, 17 insertions(+), 52 deletions(-) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index fa2fbd2cef4a..9fbec3eb725f 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada AP806 System Controller * @@ -5,9 +6,6 @@ * * Thomas Petazzoni * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #define pr_fmt(fmt) "ap806-system-controller: " fmt diff --git a/drivers/clk/mvebu/armada-370.c b/drivers/clk/mvebu/armada-370.c index 2c7c1085f883..7dedfaa6e152 100644 --- a/drivers/clk/mvebu/armada-370.c +++ b/drivers/clk/mvebu/armada-370.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada 370 SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/armada-375.c b/drivers/clk/mvebu/armada-375.c index c7af2242b796..a7157c690238 100644 --- a/drivers/clk/mvebu/armada-375.c +++ b/drivers/clk/mvebu/armada-375.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada 375 SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c index 7ff041f73b55..71f30149e80e 100644 --- a/drivers/clk/mvebu/armada-37xx-tbg.c +++ b/drivers/clk/mvebu/armada-37xx-tbg.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Marvell Armada 37xx SoC Time Base Generator clocks * * Copyright (C) 2016 Marvell * * Gregory CLEMENT - * - * This file is licensed under the terms of the GNU General Public - * License version 2 or later. This program is licensed "as is" - * without any warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/armada-37xx-xtal.c b/drivers/clk/mvebu/armada-37xx-xtal.c index 612d65ede10a..e9e306d4e9af 100644 --- a/drivers/clk/mvebu/armada-37xx-xtal.c +++ b/drivers/clk/mvebu/armada-37xx-xtal.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada 37xx SoC xtal clocks * @@ -5,9 +6,6 @@ * * Gregory CLEMENT * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c index 9ff4ea63932d..ef2ab81f087d 100644 --- a/drivers/clk/mvebu/armada-38x.c +++ b/drivers/clk/mvebu/armada-38x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada 380/385 SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/armada-39x.c b/drivers/clk/mvebu/armada-39x.c index 4fdfd32247a9..674ccfd6236e 100644 --- a/drivers/clk/mvebu/armada-39x.c +++ b/drivers/clk/mvebu/armada-39x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada 39x SoC clocks * @@ -8,9 +9,6 @@ * Andrew Lunn * Thomas Petazzoni * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c index 0ec44ae9a2a2..e8f03293ec83 100644 --- a/drivers/clk/mvebu/armada-xp.c +++ b/drivers/clk/mvebu/armada-xp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada XP SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c index 68f05c53d40e..1fc84b0e72ee 100644 --- a/drivers/clk/mvebu/clk-corediv.c +++ b/drivers/clk/mvebu/clk-corediv.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MVEBU Core divider clock * @@ -5,9 +6,6 @@ * * Ezequiel Garcia * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 072aa38374ce..d1a715767364 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell MVEBU CPU clock handling. * @@ -5,9 +6,6 @@ * * Gregory CLEMENT * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include #include diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 472c88b90256..6ab3c2e627c7 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell EBU SoC common clock handling * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/common.h b/drivers/clk/mvebu/common.h index f0de6c8a494a..d1ab79b43105 100644 --- a/drivers/clk/mvebu/common.h +++ b/drivers/clk/mvebu/common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Marvell EBU SoC common clock handling * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #ifndef __CLK_MVEBU_COMMON_H_ diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index 75bf7b8f282f..9781b1bf5998 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Armada CP110 System Controller * @@ -5,9 +6,6 @@ * * Thomas Petazzoni * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ /* diff --git a/drivers/clk/mvebu/dove.c b/drivers/clk/mvebu/dove.c index 59fad9546c84..e0dd99f36bf4 100644 --- a/drivers/clk/mvebu/dove.c +++ b/drivers/clk/mvebu/dove.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Dove SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index a2a8d614039d..6f784167bda4 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Kirkwood SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/mv98dx3236.c b/drivers/clk/mvebu/mv98dx3236.c index 6e203af73cac..0a74cf7a7725 100644 --- a/drivers/clk/mvebu/mv98dx3236.c +++ b/drivers/clk/mvebu/mv98dx3236.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell MV98DX3236 SoC clocks * @@ -7,9 +8,6 @@ * Sebastian Hesselbarth * Andrew Lunn * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include diff --git a/drivers/clk/mvebu/orion.c b/drivers/clk/mvebu/orion.c index a6e5bee23385..f681a65be20a 100644 --- a/drivers/clk/mvebu/orion.c +++ b/drivers/clk/mvebu/orion.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Marvell Orion SoC clocks * @@ -5,9 +6,6 @@ * * Thomas Petazzoni * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include From 6ffeddd6bca4cb838623d0bf4134c0eb06ad7485 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 12 Sep 2018 17:35:49 +0200 Subject: [PATCH 188/836] clk: mvebu: ap806: Remove superfluous of_clk_add_provider While applying the commit a8309cedcdce ("clk: apn806: Add eMMC clock to system controller driver"), of_clk_add_provider was added wheres it was already present in the probe function. This extraneous call is harmless but not useful so remove it. Signed-off-by: Gregory CLEMENT Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index fa2fbd2cef4a..cfc6b82d2448 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -155,7 +155,6 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, goto fail4; } - of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); if (ret) goto fail_clk_add; From e3aaadb0f0d64153674b9f81e3c12f95fa420e6d Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Thu, 21 Jun 2018 09:37:04 +0200 Subject: [PATCH 189/836] clk: davinci: kill davinci_clk_reset_assert/deassert() This code is no longer used. Remove it. Signed-off-by: Bartosz Golaszewski Reviewed-by: David Lechner Signed-off-by: Stephen Boyd --- arch/arm/mach-davinci/include/mach/clock.h | 21 --------------------- drivers/clk/davinci/psc.c | 18 ------------------ 2 files changed, 39 deletions(-) delete mode 100644 arch/arm/mach-davinci/include/mach/clock.h diff --git a/arch/arm/mach-davinci/include/mach/clock.h b/arch/arm/mach-davinci/include/mach/clock.h deleted file mode 100644 index 42ed4f2f5ce4..000000000000 --- a/arch/arm/mach-davinci/include/mach/clock.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/arm/mach-davinci/include/mach/clock.h - * - * Clock control driver for DaVinci - header file - * - * Authors: Vladimir Barinov - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#ifndef __ASM_ARCH_DAVINCI_CLOCK_H -#define __ASM_ARCH_DAVINCI_CLOCK_H - -struct clk; - -int davinci_clk_reset_assert(struct clk *c); -int davinci_clk_reset_deassert(struct clk *c); - -#endif diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index fffbed5e263b..5b69e24a224f 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -303,24 +303,6 @@ static int davinci_lpsc_clk_reset(struct clk *clk, bool reset) return 0; } -/* - * REVISIT: These exported functions can be removed after a non-DT lookup is - * added to the reset controller framework and the davinci-rproc driver is - * updated to use the generic reset controller framework. - */ - -int davinci_clk_reset_assert(struct clk *clk) -{ - return davinci_lpsc_clk_reset(clk, true); -} -EXPORT_SYMBOL(davinci_clk_reset_assert); - -int davinci_clk_reset_deassert(struct clk *clk) -{ - return davinci_lpsc_clk_reset(clk, false); -} -EXPORT_SYMBOL(davinci_clk_reset_deassert); - static int davinci_psc_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { From d2266bbfa9e3e32e3b642965088ca461bd24a94f Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 3 Oct 2018 00:49:21 +0800 Subject: [PATCH 190/836] x86/earlyprintk: Add a force option for pciserial device The "pciserial" earlyprintk variant helps much on many modern x86 platforms, but unfortunately there are still some platforms with PCI UART devices which have the wrong PCI class code. In that case, the current class code check does not allow for them to be used for logging. Add a sub-option "force" which overrides the class code check and thus the use of such device can be enforced. [ bp: massage formulations. ] Suggested-by: Borislav Petkov Signed-off-by: Feng Tang Signed-off-by: Borislav Petkov Cc: "H. Peter Anvin" Cc: "Stuart R . Anderson" Cc: Bjorn Helgaas Cc: David Rientjes Cc: Feng Tang Cc: Frederic Weisbecker Cc: Greg Kroah-Hartman Cc: H Peter Anvin Cc: Ingo Molnar Cc: Jiri Kosina Cc: Jonathan Corbet Cc: Kai-Heng Feng Cc: Kate Stewart Cc: Konrad Rzeszutek Wilk Cc: Peter Zijlstra Cc: Philippe Ombredanne Cc: Thomas Gleixner Cc: Thymo van Beers Cc: alan@linux.intel.com Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20181002164921.25833-1-feng.tang@intel.com --- .../admin-guide/kernel-parameters.txt | 6 +++- arch/x86/kernel/early_printk.c | 29 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 92eb1f42240d..34e6800dea0e 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1063,7 +1063,7 @@ earlyprintk=serial[,0x...[,baudrate]] earlyprintk=ttySn[,baudrate] earlyprintk=dbgp[debugController#] - earlyprintk=pciserial,bus:device.function[,baudrate] + earlyprintk=pciserial[,force],bus:device.function[,baudrate] earlyprintk=xdbc[xhciController#] earlyprintk is useful when the kernel crashes before @@ -1095,6 +1095,10 @@ The sclp output can only be used on s390. + The optional "force" to "pciserial" enables use of a + PCI device even when its classcode is not of the + UART class. + edac_report= [HW,EDAC] Control how to report EDAC event Format: {"on" | "off" | "force"} on: enable EDAC to report H/W event. May be overridden diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 5e801c8c8ce7..374a52fa5296 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -213,8 +213,9 @@ static unsigned int mem32_serial_in(unsigned long addr, int offset) * early_pci_serial_init() * * This function is invoked when the early_printk param starts with "pciserial" - * The rest of the param should be ",B:D.F,baud" where B, D & F describe the - * location of a PCI device that must be a UART device. + * The rest of the param should be "[force],B:D.F,baud", where B, D & F describe + * the location of a PCI device that must be a UART device. "force" is optional + * and overrides the use of an UART device with a wrong PCI class code. */ static __init void early_pci_serial_init(char *s) { @@ -224,17 +225,23 @@ static __init void early_pci_serial_init(char *s) u32 classcode, bar0; u16 cmdreg; char *e; + int force = 0; - - /* - * First, part the param to get the BDF values - */ if (*s == ',') ++s; if (*s == 0) return; + /* Force the use of an UART device with wrong class code */ + if (!strncmp(s, "force,", 6)) { + force = 1; + s += 6; + } + + /* + * Part the param to get the BDF values + */ bus = (u8)simple_strtoul(s, &e, 16); s = e; if (*s != ':') @@ -253,7 +260,7 @@ static __init void early_pci_serial_init(char *s) s++; /* - * Second, find the device from the BDF + * Find the device from the BDF */ cmdreg = read_pci_config(bus, slot, func, PCI_COMMAND); classcode = read_pci_config(bus, slot, func, PCI_CLASS_REVISION); @@ -264,8 +271,10 @@ static __init void early_pci_serial_init(char *s) */ if (((classcode >> 16 != PCI_CLASS_COMMUNICATION_MODEM) && (classcode >> 16 != PCI_CLASS_COMMUNICATION_SERIAL)) || - (((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ - return; + (((classcode >> 8) & 0xff) != 0x02)) /* 16550 I/F at BAR0 */ { + if (!force) + return; + } /* * Determine if it is IO or memory mapped @@ -289,7 +298,7 @@ static __init void early_pci_serial_init(char *s) } /* - * Lastly, initialize the hardware + * Initialize the hardware */ if (*s) { if (strcmp(s, "nocfg") == 0) From 2f149e6e14bcb5e581e49307b54aafcd6f74a74f Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 27 Aug 2018 19:50:56 -0500 Subject: [PATCH 191/836] clk: keystone: Enable TISCI clocks if K3_ARCH K3_ARCH uses TISCI for clocks as well. Enable the same for the driver support. Signed-off-by: Nishanth Menon Acked-by: Santosh Shilimkar Signed-off-by: Stephen Boyd --- drivers/clk/Makefile | 1 + drivers/clk/keystone/Kconfig | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index a84c5573cabe..ed344eb717cc 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -73,6 +73,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ obj-$(CONFIG_ARCH_MXC) += imx/ obj-$(CONFIG_MACH_INGENIC) += ingenic/ +obj-$(CONFIG_ARCH_K3) += keystone/ obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(CONFIG_MACH_LOONGSON32) += loongson1/ obj-y += mediatek/ diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig index 7e9f0176578a..b04927d06cd1 100644 --- a/drivers/clk/keystone/Kconfig +++ b/drivers/clk/keystone/Kconfig @@ -7,7 +7,7 @@ config COMMON_CLK_KEYSTONE config TI_SCI_CLK tristate "TI System Control Interface clock drivers" - depends on (ARCH_KEYSTONE || COMPILE_TEST) && OF + depends on (ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST) && OF depends on TI_SCI_PROTOCOL default ARCH_KEYSTONE ---help--- From 2991cc22966a712706c053ca3d3b03bd1ae384ae Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 2 Oct 2018 23:16:42 +0200 Subject: [PATCH 192/836] firmware: dcdbas: include linux/io.h memremap() is declared in linux/io.h, not in asm/io.h, so we should include that header to avoid build errors: drivers/platform/x86/dcdbas.c: In function 'dcdbas_check_wsmt': drivers/platform/x86/dcdbas.c:572:15: error: implicit declaration of function 'memremap'; did you mean 'ioremap'? [-Werror=implicit-function-declaration] eps_buffer = memremap(eps->smm_comm_buff_addr, remap_size, MEMREMAP_WB); ^~~~~~~~ ioremap drivers/platform/x86/dcdbas.c:572:61: error: 'MEMREMAP_WB' undeclared (first use in this function) eps_buffer = memremap(eps->smm_comm_buff_addr, remap_size, MEMREMAP_WB); ^~~~~~~~~~~ drivers/platform/x86/dcdbas.c:572:61: note: each undeclared identifier is reported only once for each function it appears in drivers/platform/x86/dcdbas.c: In function 'dcdbas_exit': drivers/platform/x86/dcdbas.c:748:3: error: implicit declaration of function 'memunmap'; did you mean 'vm_munmap'? [-Werror=implicit-function-declaration] Fixes: 12c956c4f32e ("firmware: dcdbas: Add support for WSMT ACPI table") Signed-off-by: Arnd Bergmann Reported-by: Randy Dunlap Signed-off-by: Andy Shevchenko --- drivers/platform/x86/dcdbas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/dcdbas.c b/drivers/platform/x86/dcdbas.c index ae28e48ff7dc..88bd7efafe14 100644 --- a/drivers/platform/x86/dcdbas.c +++ b/drivers/platform/x86/dcdbas.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include "dcdbas.h" From e358cf2e6efce1312f1b5bc97543f40dfd319633 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 31 Aug 2018 17:38:57 +0300 Subject: [PATCH 193/836] dt-bindings: clock: am33xx: add clkctrl indices for new data layout The new data layout will be split based on clockdomain boundaries, instead of CM boundaries. This introduces a few new clkctrl providers, that have different indices for the clkctrl data. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- include/dt-bindings/clock/am3.h | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/include/dt-bindings/clock/am3.h b/include/dt-bindings/clock/am3.h index b396f00e481d..86a8806e2140 100644 --- a/include/dt-bindings/clock/am3.h +++ b/include/dt-bindings/clock/am3.h @@ -16,6 +16,8 @@ #define AM3_CLKCTRL_OFFSET 0x0 #define AM3_CLKCTRL_INDEX(offset) ((offset) - AM3_CLKCTRL_OFFSET) +/* XXX: Compatibility part begin, remove this once compatibility support is no longer needed */ + /* l4_per clocks */ #define AM3_L4_PER_CLKCTRL_OFFSET 0x14 #define AM3_L4_PER_CLKCTRL_INDEX(offset) ((offset) - AM3_L4_PER_CLKCTRL_OFFSET) @@ -105,4 +107,121 @@ #define AM3_L4_CEFUSE_CLKCTRL_INDEX(offset) ((offset) - AM3_L4_CEFUSE_CLKCTRL_OFFSET) #define AM3_CEFUSE_CLKCTRL AM3_L4_CEFUSE_CLKCTRL_INDEX(0x20) +/* XXX: Compatibility part end */ + +/* l4ls clocks */ +#define AM3_L4LS_CLKCTRL_OFFSET 0x38 +#define AM3_L4LS_CLKCTRL_INDEX(offset) ((offset) - AM3_L4LS_CLKCTRL_OFFSET) +#define AM3_L4LS_UART6_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x38) +#define AM3_L4LS_MMC1_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x3c) +#define AM3_L4LS_ELM_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x40) +#define AM3_L4LS_I2C3_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x44) +#define AM3_L4LS_I2C2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x48) +#define AM3_L4LS_SPI0_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x4c) +#define AM3_L4LS_SPI1_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x50) +#define AM3_L4LS_L4_LS_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x60) +#define AM3_L4LS_UART2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x6c) +#define AM3_L4LS_UART3_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x70) +#define AM3_L4LS_UART4_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x74) +#define AM3_L4LS_UART5_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x78) +#define AM3_L4LS_TIMER7_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x7c) +#define AM3_L4LS_TIMER2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x80) +#define AM3_L4LS_TIMER3_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x84) +#define AM3_L4LS_TIMER4_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x88) +#define AM3_L4LS_RNG_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x90) +#define AM3_L4LS_GPIO2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xac) +#define AM3_L4LS_GPIO3_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xb0) +#define AM3_L4LS_GPIO4_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xb4) +#define AM3_L4LS_D_CAN0_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xc0) +#define AM3_L4LS_D_CAN1_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xc4) +#define AM3_L4LS_EPWMSS1_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xcc) +#define AM3_L4LS_EPWMSS0_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xd4) +#define AM3_L4LS_EPWMSS2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xd8) +#define AM3_L4LS_TIMER5_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xec) +#define AM3_L4LS_TIMER6_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xf0) +#define AM3_L4LS_MMC2_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0xf4) +#define AM3_L4LS_SPINLOCK_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x10c) +#define AM3_L4LS_MAILBOX_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x110) +#define AM3_L4LS_OCPWP_CLKCTRL AM3_L4LS_CLKCTRL_INDEX(0x130) + +/* l3s clocks */ +#define AM3_L3S_CLKCTRL_OFFSET 0x1c +#define AM3_L3S_CLKCTRL_INDEX(offset) ((offset) - AM3_L3S_CLKCTRL_OFFSET) +#define AM3_L3S_USB_OTG_HS_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0x1c) +#define AM3_L3S_GPMC_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0x30) +#define AM3_L3S_MCASP0_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0x34) +#define AM3_L3S_MCASP1_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0x68) +#define AM3_L3S_MMC3_CLKCTRL AM3_L3S_CLKCTRL_INDEX(0xf8) + +/* l3 clocks */ +#define AM3_L3_CLKCTRL_OFFSET 0x24 +#define AM3_L3_CLKCTRL_INDEX(offset) ((offset) - AM3_L3_CLKCTRL_OFFSET) +#define AM3_L3_TPTC0_CLKCTRL AM3_L3_CLKCTRL_INDEX(0x24) +#define AM3_L3_EMIF_CLKCTRL AM3_L3_CLKCTRL_INDEX(0x28) +#define AM3_L3_OCMCRAM_CLKCTRL AM3_L3_CLKCTRL_INDEX(0x2c) +#define AM3_L3_AES_CLKCTRL AM3_L3_CLKCTRL_INDEX(0x94) +#define AM3_L3_SHAM_CLKCTRL AM3_L3_CLKCTRL_INDEX(0xa0) +#define AM3_L3_TPCC_CLKCTRL AM3_L3_CLKCTRL_INDEX(0xbc) +#define AM3_L3_L3_INSTR_CLKCTRL AM3_L3_CLKCTRL_INDEX(0xdc) +#define AM3_L3_L3_MAIN_CLKCTRL AM3_L3_CLKCTRL_INDEX(0xe0) +#define AM3_L3_TPTC1_CLKCTRL AM3_L3_CLKCTRL_INDEX(0xfc) +#define AM3_L3_TPTC2_CLKCTRL AM3_L3_CLKCTRL_INDEX(0x100) + +/* l4hs clocks */ +#define AM3_L4HS_CLKCTRL_OFFSET 0x120 +#define AM3_L4HS_CLKCTRL_INDEX(offset) ((offset) - AM3_L4HS_CLKCTRL_OFFSET) +#define AM3_L4HS_L4_HS_CLKCTRL AM3_L4HS_CLKCTRL_INDEX(0x120) + +/* pruss_ocp clocks */ +#define AM3_PRUSS_OCP_CLKCTRL_OFFSET 0xe8 +#define AM3_PRUSS_OCP_CLKCTRL_INDEX(offset) ((offset) - AM3_PRUSS_OCP_CLKCTRL_OFFSET) +#define AM3_PRUSS_OCP_PRUSS_CLKCTRL AM3_PRUSS_OCP_CLKCTRL_INDEX(0xe8) + +/* cpsw_125mhz clocks */ +#define AM3_CPSW_125MHZ_CPGMAC0_CLKCTRL AM3_CLKCTRL_INDEX(0x14) + +/* lcdc clocks */ +#define AM3_LCDC_CLKCTRL_OFFSET 0x18 +#define AM3_LCDC_CLKCTRL_INDEX(offset) ((offset) - AM3_LCDC_CLKCTRL_OFFSET) +#define AM3_LCDC_LCDC_CLKCTRL AM3_LCDC_CLKCTRL_INDEX(0x18) + +/* clk_24mhz clocks */ +#define AM3_CLK_24MHZ_CLKCTRL_OFFSET 0x14c +#define AM3_CLK_24MHZ_CLKCTRL_INDEX(offset) ((offset) - AM3_CLK_24MHZ_CLKCTRL_OFFSET) +#define AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL AM3_CLK_24MHZ_CLKCTRL_INDEX(0x14c) + +/* l4_wkup clocks */ +#define AM3_L4_WKUP_CONTROL_CLKCTRL AM3_CLKCTRL_INDEX(0x4) +#define AM3_L4_WKUP_GPIO1_CLKCTRL AM3_CLKCTRL_INDEX(0x8) +#define AM3_L4_WKUP_L4_WKUP_CLKCTRL AM3_CLKCTRL_INDEX(0xc) +#define AM3_L4_WKUP_UART1_CLKCTRL AM3_CLKCTRL_INDEX(0xb4) +#define AM3_L4_WKUP_I2C1_CLKCTRL AM3_CLKCTRL_INDEX(0xb8) +#define AM3_L4_WKUP_ADC_TSC_CLKCTRL AM3_CLKCTRL_INDEX(0xbc) +#define AM3_L4_WKUP_SMARTREFLEX0_CLKCTRL AM3_CLKCTRL_INDEX(0xc0) +#define AM3_L4_WKUP_TIMER1_CLKCTRL AM3_CLKCTRL_INDEX(0xc4) +#define AM3_L4_WKUP_SMARTREFLEX1_CLKCTRL AM3_CLKCTRL_INDEX(0xc8) +#define AM3_L4_WKUP_WD_TIMER2_CLKCTRL AM3_CLKCTRL_INDEX(0xd4) + +/* l3_aon clocks */ +#define AM3_L3_AON_CLKCTRL_OFFSET 0x14 +#define AM3_L3_AON_CLKCTRL_INDEX(offset) ((offset) - AM3_L3_AON_CLKCTRL_OFFSET) +#define AM3_L3_AON_DEBUGSS_CLKCTRL AM3_L3_AON_CLKCTRL_INDEX(0x14) + +/* l4_wkup_aon clocks */ +#define AM3_L4_WKUP_AON_CLKCTRL_OFFSET 0xb0 +#define AM3_L4_WKUP_AON_CLKCTRL_INDEX(offset) ((offset) - AM3_L4_WKUP_AON_CLKCTRL_OFFSET) +#define AM3_L4_WKUP_AON_WKUP_M3_CLKCTRL AM3_L4_WKUP_AON_CLKCTRL_INDEX(0xb0) + +/* mpu clocks */ +#define AM3_MPU_MPU_CLKCTRL AM3_CLKCTRL_INDEX(0x4) + +/* l4_rtc clocks */ +#define AM3_L4_RTC_RTC_CLKCTRL AM3_CLKCTRL_INDEX(0x0) + +/* gfx_l3 clocks */ +#define AM3_GFX_L3_GFX_CLKCTRL AM3_CLKCTRL_INDEX(0x4) + +/* l4_cefuse clocks */ +#define AM3_L4_CEFUSE_CEFUSE_CLKCTRL AM3_CLKCTRL_INDEX(0x20) + #endif From 8cfbdbd9694ea41a33f991c608fce5d43b8b1cce Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 31 Aug 2018 17:42:31 +0300 Subject: [PATCH 194/836] dt-bindings: clock: am43xx: add clkctrl indices for new data layout The new data layout will be split based on clockdomain boundaries, instead of CM boundaries. This introduces a few new clkctrl providers, that have different indices for the clkctrl data. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- include/dt-bindings/clock/am4.h | 132 ++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/include/dt-bindings/clock/am4.h b/include/dt-bindings/clock/am4.h index d21df00b3270..0f545b5afd60 100644 --- a/include/dt-bindings/clock/am4.h +++ b/include/dt-bindings/clock/am4.h @@ -16,6 +16,8 @@ #define AM4_CLKCTRL_OFFSET 0x20 #define AM4_CLKCTRL_INDEX(offset) ((offset) - AM4_CLKCTRL_OFFSET) +/* XXX: Compatibility part begin, remove this once compatibility support is no longer needed */ + /* l4_wkup clocks */ #define AM4_ADC_TSC_CLKCTRL AM4_CLKCTRL_INDEX(0x120) #define AM4_L4_WKUP_CLKCTRL AM4_CLKCTRL_INDEX(0x220) @@ -110,4 +112,134 @@ #define AM4_DSS_CORE_CLKCTRL AM4_CLKCTRL_INDEX(0xa20) #define AM4_CPGMAC0_CLKCTRL AM4_CLKCTRL_INDEX(0xb20) +/* XXX: Compatibility part end. */ + +/* l3s_tsc clocks */ +#define AM4_L3S_TSC_CLKCTRL_OFFSET 0x120 +#define AM4_L3S_TSC_CLKCTRL_INDEX(offset) ((offset) - AM4_L3S_TSC_CLKCTRL_OFFSET) +#define AM4_L3S_TSC_ADC_TSC_CLKCTRL AM4_L3S_TSC_CLKCTRL_INDEX(0x120) + +/* l4_wkup_aon clocks */ +#define AM4_L4_WKUP_AON_CLKCTRL_OFFSET 0x228 +#define AM4_L4_WKUP_AON_CLKCTRL_INDEX(offset) ((offset) - AM4_L4_WKUP_AON_CLKCTRL_OFFSET) +#define AM4_L4_WKUP_AON_WKUP_M3_CLKCTRL AM4_L4_WKUP_AON_CLKCTRL_INDEX(0x228) +#define AM4_L4_WKUP_AON_COUNTER_32K_CLKCTRL AM4_L4_WKUP_AON_CLKCTRL_INDEX(0x230) + +/* l4_wkup clocks */ +#define AM4_L4_WKUP_CLKCTRL_OFFSET 0x220 +#define AM4_L4_WKUP_CLKCTRL_INDEX(offset) ((offset) - AM4_L4_WKUP_CLKCTRL_OFFSET) +#define AM4_L4_WKUP_L4_WKUP_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x220) +#define AM4_L4_WKUP_TIMER1_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x328) +#define AM4_L4_WKUP_WD_TIMER2_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x338) +#define AM4_L4_WKUP_I2C1_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x340) +#define AM4_L4_WKUP_UART1_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x348) +#define AM4_L4_WKUP_SMARTREFLEX0_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x350) +#define AM4_L4_WKUP_SMARTREFLEX1_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x358) +#define AM4_L4_WKUP_CONTROL_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x360) +#define AM4_L4_WKUP_GPIO1_CLKCTRL AM4_L4_WKUP_CLKCTRL_INDEX(0x368) + +/* mpu clocks */ +#define AM4_MPU_MPU_CLKCTRL AM4_CLKCTRL_INDEX(0x20) + +/* gfx_l3 clocks */ +#define AM4_GFX_L3_GFX_CLKCTRL AM4_CLKCTRL_INDEX(0x20) + +/* l4_rtc clocks */ +#define AM4_L4_RTC_RTC_CLKCTRL AM4_CLKCTRL_INDEX(0x20) + +/* l3 clocks */ +#define AM4_L3_L3_MAIN_CLKCTRL AM4_CLKCTRL_INDEX(0x20) +#define AM4_L3_AES_CLKCTRL AM4_CLKCTRL_INDEX(0x28) +#define AM4_L3_DES_CLKCTRL AM4_CLKCTRL_INDEX(0x30) +#define AM4_L3_L3_INSTR_CLKCTRL AM4_CLKCTRL_INDEX(0x40) +#define AM4_L3_OCMCRAM_CLKCTRL AM4_CLKCTRL_INDEX(0x50) +#define AM4_L3_SHAM_CLKCTRL AM4_CLKCTRL_INDEX(0x58) +#define AM4_L3_TPCC_CLKCTRL AM4_CLKCTRL_INDEX(0x78) +#define AM4_L3_TPTC0_CLKCTRL AM4_CLKCTRL_INDEX(0x80) +#define AM4_L3_TPTC1_CLKCTRL AM4_CLKCTRL_INDEX(0x88) +#define AM4_L3_TPTC2_CLKCTRL AM4_CLKCTRL_INDEX(0x90) +#define AM4_L3_L4_HS_CLKCTRL AM4_CLKCTRL_INDEX(0xa0) + +/* l3s clocks */ +#define AM4_L3S_CLKCTRL_OFFSET 0x68 +#define AM4_L3S_CLKCTRL_INDEX(offset) ((offset) - AM4_L3S_CLKCTRL_OFFSET) +#define AM4_L3S_VPFE0_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x68) +#define AM4_L3S_VPFE1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x70) +#define AM4_L3S_GPMC_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x220) +#define AM4_L3S_MCASP0_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x238) +#define AM4_L3S_MCASP1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x240) +#define AM4_L3S_MMC3_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x248) +#define AM4_L3S_QSPI_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x258) +#define AM4_L3S_USB_OTG_SS0_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x260) +#define AM4_L3S_USB_OTG_SS1_CLKCTRL AM4_L3S_CLKCTRL_INDEX(0x268) + +/* pruss_ocp clocks */ +#define AM4_PRUSS_OCP_CLKCTRL_OFFSET 0x320 +#define AM4_PRUSS_OCP_CLKCTRL_INDEX(offset) ((offset) - AM4_PRUSS_OCP_CLKCTRL_OFFSET) +#define AM4_PRUSS_OCP_PRUSS_CLKCTRL AM4_PRUSS_OCP_CLKCTRL_INDEX(0x320) + +/* l4ls clocks */ +#define AM4_L4LS_CLKCTRL_OFFSET 0x420 +#define AM4_L4LS_CLKCTRL_INDEX(offset) ((offset) - AM4_L4LS_CLKCTRL_OFFSET) +#define AM4_L4LS_L4_LS_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x420) +#define AM4_L4LS_D_CAN0_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x428) +#define AM4_L4LS_D_CAN1_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x430) +#define AM4_L4LS_EPWMSS0_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x438) +#define AM4_L4LS_EPWMSS1_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x440) +#define AM4_L4LS_EPWMSS2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x448) +#define AM4_L4LS_EPWMSS3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x450) +#define AM4_L4LS_EPWMSS4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x458) +#define AM4_L4LS_EPWMSS5_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x460) +#define AM4_L4LS_ELM_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x468) +#define AM4_L4LS_GPIO2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x478) +#define AM4_L4LS_GPIO3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x480) +#define AM4_L4LS_GPIO4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x488) +#define AM4_L4LS_GPIO5_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x490) +#define AM4_L4LS_GPIO6_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x498) +#define AM4_L4LS_HDQ1W_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4a0) +#define AM4_L4LS_I2C2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4a8) +#define AM4_L4LS_I2C3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4b0) +#define AM4_L4LS_MAILBOX_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4b8) +#define AM4_L4LS_MMC1_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4c0) +#define AM4_L4LS_MMC2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4c8) +#define AM4_L4LS_RNG_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x4e0) +#define AM4_L4LS_SPI0_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x500) +#define AM4_L4LS_SPI1_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x508) +#define AM4_L4LS_SPI2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x510) +#define AM4_L4LS_SPI3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x518) +#define AM4_L4LS_SPI4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x520) +#define AM4_L4LS_SPINLOCK_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x528) +#define AM4_L4LS_TIMER2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x530) +#define AM4_L4LS_TIMER3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x538) +#define AM4_L4LS_TIMER4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x540) +#define AM4_L4LS_TIMER5_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x548) +#define AM4_L4LS_TIMER6_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x550) +#define AM4_L4LS_TIMER7_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x558) +#define AM4_L4LS_TIMER8_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x560) +#define AM4_L4LS_TIMER9_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x568) +#define AM4_L4LS_TIMER10_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x570) +#define AM4_L4LS_TIMER11_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x578) +#define AM4_L4LS_UART2_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x580) +#define AM4_L4LS_UART3_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x588) +#define AM4_L4LS_UART4_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x590) +#define AM4_L4LS_UART5_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x598) +#define AM4_L4LS_UART6_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x5a0) +#define AM4_L4LS_OCP2SCP0_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x5b8) +#define AM4_L4LS_OCP2SCP1_CLKCTRL AM4_L4LS_CLKCTRL_INDEX(0x5c0) + +/* emif clocks */ +#define AM4_EMIF_CLKCTRL_OFFSET 0x720 +#define AM4_EMIF_CLKCTRL_INDEX(offset) ((offset) - AM4_EMIF_CLKCTRL_OFFSET) +#define AM4_EMIF_EMIF_CLKCTRL AM4_EMIF_CLKCTRL_INDEX(0x720) + +/* dss clocks */ +#define AM4_DSS_CLKCTRL_OFFSET 0xa20 +#define AM4_DSS_CLKCTRL_INDEX(offset) ((offset) - AM4_DSS_CLKCTRL_OFFSET) +#define AM4_DSS_DSS_CORE_CLKCTRL AM4_DSS_CLKCTRL_INDEX(0xa20) + +/* cpsw_125mhz clocks */ +#define AM4_CPSW_125MHZ_CLKCTRL_OFFSET 0xb20 +#define AM4_CPSW_125MHZ_CLKCTRL_INDEX(offset) ((offset) - AM4_CPSW_125MHZ_CLKCTRL_OFFSET) +#define AM4_CPSW_125MHZ_CPGMAC0_CLKCTRL AM4_CPSW_125MHZ_CLKCTRL_INDEX(0xb20) + #endif From 8fa45095791813b0438c2604567e7e213804e66c Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 31 Aug 2018 17:44:09 +0300 Subject: [PATCH 195/836] dt-bindings: clock: dra7xx: add clkctrl indices for new data layout The new data layout will be split based on clockdomain boundaries, instead of CM boundaries. This introduces a few new clkctrl providers, that have different indices for the clkctrl data. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- include/dt-bindings/clock/dra7.h | 326 ++++++++++++++++++++++++------- 1 file changed, 258 insertions(+), 68 deletions(-) diff --git a/include/dt-bindings/clock/dra7.h b/include/dt-bindings/clock/dra7.h index d7549c57cac3..ec969b5aeb25 100644 --- a/include/dt-bindings/clock/dra7.h +++ b/include/dt-bindings/clock/dra7.h @@ -16,19 +16,21 @@ #define DRA7_CLKCTRL_OFFSET 0x20 #define DRA7_CLKCTRL_INDEX(offset) ((offset) - DRA7_CLKCTRL_OFFSET) +/* XXX: Compatibility part begin, remove this once compatibility support is no longer needed */ + /* mpu clocks */ #define DRA7_MPU_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) /* ipu clocks */ -#define DRA7_IPU_CLKCTRL_OFFSET 0x40 -#define DRA7_IPU_CLKCTRL_INDEX(offset) ((offset) - DRA7_IPU_CLKCTRL_OFFSET) -#define DRA7_MCASP1_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x50) -#define DRA7_TIMER5_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x58) -#define DRA7_TIMER6_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x60) -#define DRA7_TIMER7_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x68) -#define DRA7_TIMER8_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x70) -#define DRA7_I2C5_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x78) -#define DRA7_UART6_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x80) +#define _DRA7_IPU_CLKCTRL_OFFSET 0x40 +#define _DRA7_IPU_CLKCTRL_INDEX(offset) ((offset) - _DRA7_IPU_CLKCTRL_OFFSET) +#define DRA7_MCASP1_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x50) +#define DRA7_TIMER5_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x58) +#define DRA7_TIMER6_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x60) +#define DRA7_TIMER7_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x68) +#define DRA7_TIMER8_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x70) +#define DRA7_I2C5_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x78) +#define DRA7_UART6_CLKCTRL _DRA7_IPU_CLKCTRL_INDEX(0x80) /* rtc clocks */ #define DRA7_RTC_CLKCTRL_OFFSET 0x40 @@ -99,65 +101,65 @@ #define DRA7_USB_OTG_SS1_CLKCTRL DRA7_CLKCTRL_INDEX(0xf0) /* l4per clocks */ -#define DRA7_L4PER_CLKCTRL_OFFSET 0x0 -#define DRA7_L4PER_CLKCTRL_INDEX(offset) ((offset) - DRA7_L4PER_CLKCTRL_OFFSET) -#define DRA7_L4_PER2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xc) -#define DRA7_L4_PER3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x14) -#define DRA7_TIMER10_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x28) -#define DRA7_TIMER11_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x30) -#define DRA7_TIMER2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x38) -#define DRA7_TIMER3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x40) -#define DRA7_TIMER4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x48) -#define DRA7_TIMER9_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x50) -#define DRA7_ELM_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x58) -#define DRA7_GPIO2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x60) -#define DRA7_GPIO3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x68) -#define DRA7_GPIO4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x70) -#define DRA7_GPIO5_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x78) -#define DRA7_GPIO6_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x80) -#define DRA7_HDQ1W_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x88) -#define DRA7_EPWMSS1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x90) -#define DRA7_EPWMSS2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x98) -#define DRA7_I2C1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xa0) -#define DRA7_I2C2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xa8) -#define DRA7_I2C3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xb0) -#define DRA7_I2C4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xb8) -#define DRA7_L4_PER1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xc0) -#define DRA7_EPWMSS0_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xc4) -#define DRA7_TIMER13_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xc8) -#define DRA7_TIMER14_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xd0) -#define DRA7_TIMER15_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xd8) -#define DRA7_MCSPI1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xf0) -#define DRA7_MCSPI2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xf8) -#define DRA7_MCSPI3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x100) -#define DRA7_MCSPI4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x108) -#define DRA7_GPIO7_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x110) -#define DRA7_GPIO8_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x118) -#define DRA7_MMC3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x120) -#define DRA7_MMC4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x128) -#define DRA7_TIMER16_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x130) -#define DRA7_QSPI_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x138) -#define DRA7_UART1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x140) -#define DRA7_UART2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x148) -#define DRA7_UART3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x150) -#define DRA7_UART4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x158) -#define DRA7_MCASP2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x160) -#define DRA7_MCASP3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x168) -#define DRA7_UART5_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x170) -#define DRA7_MCASP5_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x178) -#define DRA7_MCASP8_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x190) -#define DRA7_MCASP4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x198) -#define DRA7_AES1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1a0) -#define DRA7_AES2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1a8) -#define DRA7_DES_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1b0) -#define DRA7_RNG_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1c0) -#define DRA7_SHAM_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1c8) -#define DRA7_UART7_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1d0) -#define DRA7_UART8_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1e0) -#define DRA7_UART9_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1e8) -#define DRA7_DCAN2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x1f0) -#define DRA7_MCASP6_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x204) -#define DRA7_MCASP7_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x208) +#define _DRA7_L4PER_CLKCTRL_OFFSET 0x0 +#define _DRA7_L4PER_CLKCTRL_INDEX(offset) ((offset) - _DRA7_L4PER_CLKCTRL_OFFSET) +#define DRA7_L4_PER2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xc) +#define DRA7_L4_PER3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x14) +#define DRA7_TIMER10_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x28) +#define DRA7_TIMER11_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x30) +#define DRA7_TIMER2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x38) +#define DRA7_TIMER3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x40) +#define DRA7_TIMER4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x48) +#define DRA7_TIMER9_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x50) +#define DRA7_ELM_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x58) +#define DRA7_GPIO2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x60) +#define DRA7_GPIO3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x68) +#define DRA7_GPIO4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x70) +#define DRA7_GPIO5_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x78) +#define DRA7_GPIO6_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x80) +#define DRA7_HDQ1W_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x88) +#define DRA7_EPWMSS1_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x90) +#define DRA7_EPWMSS2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x98) +#define DRA7_I2C1_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xa0) +#define DRA7_I2C2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xa8) +#define DRA7_I2C3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xb0) +#define DRA7_I2C4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xb8) +#define DRA7_L4_PER1_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xc0) +#define DRA7_EPWMSS0_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xc4) +#define DRA7_TIMER13_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xc8) +#define DRA7_TIMER14_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xd0) +#define DRA7_TIMER15_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xd8) +#define DRA7_MCSPI1_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xf0) +#define DRA7_MCSPI2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0xf8) +#define DRA7_MCSPI3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x100) +#define DRA7_MCSPI4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x108) +#define DRA7_GPIO7_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x110) +#define DRA7_GPIO8_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x118) +#define DRA7_MMC3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x120) +#define DRA7_MMC4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x128) +#define DRA7_TIMER16_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x130) +#define DRA7_QSPI_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x138) +#define DRA7_UART1_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x140) +#define DRA7_UART2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x148) +#define DRA7_UART3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x150) +#define DRA7_UART4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x158) +#define DRA7_MCASP2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x160) +#define DRA7_MCASP3_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x168) +#define DRA7_UART5_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x170) +#define DRA7_MCASP5_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x178) +#define DRA7_MCASP8_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x190) +#define DRA7_MCASP4_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x198) +#define DRA7_AES1_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1a0) +#define DRA7_AES2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1a8) +#define DRA7_DES_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1b0) +#define DRA7_RNG_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1c0) +#define DRA7_SHAM_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1c8) +#define DRA7_UART7_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1d0) +#define DRA7_UART8_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1e0) +#define DRA7_UART9_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1e8) +#define DRA7_DCAN2_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x1f0) +#define DRA7_MCASP6_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x204) +#define DRA7_MCASP7_CLKCTRL _DRA7_L4PER_CLKCTRL_INDEX(0x208) /* wkupaon clocks */ #define DRA7_L4_WKUP_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) @@ -170,4 +172,192 @@ #define DRA7_DCAN1_CLKCTRL DRA7_CLKCTRL_INDEX(0x88) #define DRA7_ADC_CLKCTRL DRA7_CLKCTRL_INDEX(0xa0) +/* XXX: Compatibility part end. */ + +/* mpu clocks */ +#define DRA7_MPU_MPU_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* dsp1 clocks */ +#define DRA7_DSP1_MMU0_DSP1_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* ipu1 clocks */ +#define DRA7_IPU1_MMU_IPU1_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* ipu clocks */ +#define DRA7_IPU_CLKCTRL_OFFSET 0x50 +#define DRA7_IPU_CLKCTRL_INDEX(offset) ((offset) - DRA7_IPU_CLKCTRL_OFFSET) +#define DRA7_IPU_MCASP1_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x50) +#define DRA7_IPU_TIMER5_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x58) +#define DRA7_IPU_TIMER6_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x60) +#define DRA7_IPU_TIMER7_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x68) +#define DRA7_IPU_TIMER8_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x70) +#define DRA7_IPU_I2C5_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x78) +#define DRA7_IPU_UART6_CLKCTRL DRA7_IPU_CLKCTRL_INDEX(0x80) + +/* dsp2 clocks */ +#define DRA7_DSP2_MMU0_DSP2_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* rtc clocks */ +#define DRA7_RTC_RTCSS_CLKCTRL DRA7_CLKCTRL_INDEX(0x44) + +/* coreaon clocks */ +#define DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL DRA7_CLKCTRL_INDEX(0x28) +#define DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL DRA7_CLKCTRL_INDEX(0x38) + +/* l3main1 clocks */ +#define DRA7_L3MAIN1_L3_MAIN_1_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) +#define DRA7_L3MAIN1_GPMC_CLKCTRL DRA7_CLKCTRL_INDEX(0x28) +#define DRA7_L3MAIN1_TPCC_CLKCTRL DRA7_CLKCTRL_INDEX(0x70) +#define DRA7_L3MAIN1_TPTC0_CLKCTRL DRA7_CLKCTRL_INDEX(0x78) +#define DRA7_L3MAIN1_TPTC1_CLKCTRL DRA7_CLKCTRL_INDEX(0x80) +#define DRA7_L3MAIN1_VCP1_CLKCTRL DRA7_CLKCTRL_INDEX(0x88) +#define DRA7_L3MAIN1_VCP2_CLKCTRL DRA7_CLKCTRL_INDEX(0x90) + +/* ipu2 clocks */ +#define DRA7_IPU2_MMU_IPU2_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* dma clocks */ +#define DRA7_DMA_DMA_SYSTEM_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* emif clocks */ +#define DRA7_EMIF_DMM_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) + +/* atl clocks */ +#define DRA7_ATL_CLKCTRL_OFFSET 0x0 +#define DRA7_ATL_CLKCTRL_INDEX(offset) ((offset) - DRA7_ATL_CLKCTRL_OFFSET) +#define DRA7_ATL_ATL_CLKCTRL DRA7_ATL_CLKCTRL_INDEX(0x0) + +/* l4cfg clocks */ +#define DRA7_L4CFG_L4_CFG_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) +#define DRA7_L4CFG_SPINLOCK_CLKCTRL DRA7_CLKCTRL_INDEX(0x28) +#define DRA7_L4CFG_MAILBOX1_CLKCTRL DRA7_CLKCTRL_INDEX(0x30) +#define DRA7_L4CFG_MAILBOX2_CLKCTRL DRA7_CLKCTRL_INDEX(0x48) +#define DRA7_L4CFG_MAILBOX3_CLKCTRL DRA7_CLKCTRL_INDEX(0x50) +#define DRA7_L4CFG_MAILBOX4_CLKCTRL DRA7_CLKCTRL_INDEX(0x58) +#define DRA7_L4CFG_MAILBOX5_CLKCTRL DRA7_CLKCTRL_INDEX(0x60) +#define DRA7_L4CFG_MAILBOX6_CLKCTRL DRA7_CLKCTRL_INDEX(0x68) +#define DRA7_L4CFG_MAILBOX7_CLKCTRL DRA7_CLKCTRL_INDEX(0x70) +#define DRA7_L4CFG_MAILBOX8_CLKCTRL DRA7_CLKCTRL_INDEX(0x78) +#define DRA7_L4CFG_MAILBOX9_CLKCTRL DRA7_CLKCTRL_INDEX(0x80) +#define DRA7_L4CFG_MAILBOX10_CLKCTRL DRA7_CLKCTRL_INDEX(0x88) +#define DRA7_L4CFG_MAILBOX11_CLKCTRL DRA7_CLKCTRL_INDEX(0x90) +#define DRA7_L4CFG_MAILBOX12_CLKCTRL DRA7_CLKCTRL_INDEX(0x98) +#define DRA7_L4CFG_MAILBOX13_CLKCTRL DRA7_CLKCTRL_INDEX(0xa0) + +/* l3instr clocks */ +#define DRA7_L3INSTR_L3_MAIN_2_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) +#define DRA7_L3INSTR_L3_INSTR_CLKCTRL DRA7_CLKCTRL_INDEX(0x28) + +/* dss clocks */ +#define DRA7_DSS_DSS_CORE_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) +#define DRA7_DSS_BB2D_CLKCTRL DRA7_CLKCTRL_INDEX(0x30) + +/* l3init clocks */ +#define DRA7_L3INIT_MMC1_CLKCTRL DRA7_CLKCTRL_INDEX(0x28) +#define DRA7_L3INIT_MMC2_CLKCTRL DRA7_CLKCTRL_INDEX(0x30) +#define DRA7_L3INIT_USB_OTG_SS2_CLKCTRL DRA7_CLKCTRL_INDEX(0x40) +#define DRA7_L3INIT_USB_OTG_SS3_CLKCTRL DRA7_CLKCTRL_INDEX(0x48) +#define DRA7_L3INIT_USB_OTG_SS4_CLKCTRL DRA7_CLKCTRL_INDEX(0x50) +#define DRA7_L3INIT_SATA_CLKCTRL DRA7_CLKCTRL_INDEX(0x88) +#define DRA7_L3INIT_OCP2SCP1_CLKCTRL DRA7_CLKCTRL_INDEX(0xe0) +#define DRA7_L3INIT_OCP2SCP3_CLKCTRL DRA7_CLKCTRL_INDEX(0xe8) +#define DRA7_L3INIT_USB_OTG_SS1_CLKCTRL DRA7_CLKCTRL_INDEX(0xf0) + +/* pcie clocks */ +#define DRA7_PCIE_CLKCTRL_OFFSET 0xb0 +#define DRA7_PCIE_CLKCTRL_INDEX(offset) ((offset) - DRA7_PCIE_CLKCTRL_OFFSET) +#define DRA7_PCIE_PCIE1_CLKCTRL DRA7_PCIE_CLKCTRL_INDEX(0xb0) +#define DRA7_PCIE_PCIE2_CLKCTRL DRA7_PCIE_CLKCTRL_INDEX(0xb8) + +/* gmac clocks */ +#define DRA7_GMAC_CLKCTRL_OFFSET 0xd0 +#define DRA7_GMAC_CLKCTRL_INDEX(offset) ((offset) - DRA7_GMAC_CLKCTRL_OFFSET) +#define DRA7_GMAC_GMAC_CLKCTRL DRA7_GMAC_CLKCTRL_INDEX(0xd0) + +/* l4per clocks */ +#define DRA7_L4PER_CLKCTRL_OFFSET 0x28 +#define DRA7_L4PER_CLKCTRL_INDEX(offset) ((offset) - DRA7_L4PER_CLKCTRL_OFFSET) +#define DRA7_L4PER_TIMER10_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x28) +#define DRA7_L4PER_TIMER11_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x30) +#define DRA7_L4PER_TIMER2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x38) +#define DRA7_L4PER_TIMER3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x40) +#define DRA7_L4PER_TIMER4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x48) +#define DRA7_L4PER_TIMER9_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x50) +#define DRA7_L4PER_ELM_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x58) +#define DRA7_L4PER_GPIO2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x60) +#define DRA7_L4PER_GPIO3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x68) +#define DRA7_L4PER_GPIO4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x70) +#define DRA7_L4PER_GPIO5_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x78) +#define DRA7_L4PER_GPIO6_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x80) +#define DRA7_L4PER_HDQ1W_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x88) +#define DRA7_L4PER_I2C1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xa0) +#define DRA7_L4PER_I2C2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xa8) +#define DRA7_L4PER_I2C3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xb0) +#define DRA7_L4PER_I2C4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xb8) +#define DRA7_L4PER_L4_PER1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xc0) +#define DRA7_L4PER_MCSPI1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xf0) +#define DRA7_L4PER_MCSPI2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0xf8) +#define DRA7_L4PER_MCSPI3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x100) +#define DRA7_L4PER_MCSPI4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x108) +#define DRA7_L4PER_GPIO7_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x110) +#define DRA7_L4PER_GPIO8_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x118) +#define DRA7_L4PER_MMC3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x120) +#define DRA7_L4PER_MMC4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x128) +#define DRA7_L4PER_UART1_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x140) +#define DRA7_L4PER_UART2_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x148) +#define DRA7_L4PER_UART3_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x150) +#define DRA7_L4PER_UART4_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x158) +#define DRA7_L4PER_UART5_CLKCTRL DRA7_L4PER_CLKCTRL_INDEX(0x170) + +/* l4sec clocks */ +#define DRA7_L4SEC_CLKCTRL_OFFSET 0x1a0 +#define DRA7_L4SEC_CLKCTRL_INDEX(offset) ((offset) - DRA7_L4SEC_CLKCTRL_OFFSET) +#define DRA7_L4SEC_AES1_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1a0) +#define DRA7_L4SEC_AES2_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1a8) +#define DRA7_L4SEC_DES_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1b0) +#define DRA7_L4SEC_RNG_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1c0) +#define DRA7_L4SEC_SHAM_CLKCTRL DRA7_L4SEC_CLKCTRL_INDEX(0x1c8) + +/* l4per2 clocks */ +#define DRA7_L4PER2_CLKCTRL_OFFSET 0xc +#define DRA7_L4PER2_CLKCTRL_INDEX(offset) ((offset) - DRA7_L4PER2_CLKCTRL_OFFSET) +#define DRA7_L4PER2_L4_PER2_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0xc) +#define DRA7_L4PER2_PRUSS1_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x18) +#define DRA7_L4PER2_PRUSS2_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x20) +#define DRA7_L4PER2_EPWMSS1_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x90) +#define DRA7_L4PER2_EPWMSS2_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x98) +#define DRA7_L4PER2_EPWMSS0_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0xc4) +#define DRA7_L4PER2_QSPI_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x138) +#define DRA7_L4PER2_MCASP2_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x160) +#define DRA7_L4PER2_MCASP3_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x168) +#define DRA7_L4PER2_MCASP5_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x178) +#define DRA7_L4PER2_MCASP8_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x190) +#define DRA7_L4PER2_MCASP4_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x198) +#define DRA7_L4PER2_UART7_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x1d0) +#define DRA7_L4PER2_UART8_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x1e0) +#define DRA7_L4PER2_UART9_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x1e8) +#define DRA7_L4PER2_DCAN2_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x1f0) +#define DRA7_L4PER2_MCASP6_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x204) +#define DRA7_L4PER2_MCASP7_CLKCTRL DRA7_L4PER2_CLKCTRL_INDEX(0x208) + +/* l4per3 clocks */ +#define DRA7_L4PER3_CLKCTRL_OFFSET 0x14 +#define DRA7_L4PER3_CLKCTRL_INDEX(offset) ((offset) - DRA7_L4PER3_CLKCTRL_OFFSET) +#define DRA7_L4PER3_L4_PER3_CLKCTRL DRA7_L4PER3_CLKCTRL_INDEX(0x14) +#define DRA7_L4PER3_TIMER13_CLKCTRL DRA7_L4PER3_CLKCTRL_INDEX(0xc8) +#define DRA7_L4PER3_TIMER14_CLKCTRL DRA7_L4PER3_CLKCTRL_INDEX(0xd0) +#define DRA7_L4PER3_TIMER15_CLKCTRL DRA7_L4PER3_CLKCTRL_INDEX(0xd8) +#define DRA7_L4PER3_TIMER16_CLKCTRL DRA7_L4PER3_CLKCTRL_INDEX(0x130) + +/* wkupaon clocks */ +#define DRA7_WKUPAON_L4_WKUP_CLKCTRL DRA7_CLKCTRL_INDEX(0x20) +#define DRA7_WKUPAON_WD_TIMER2_CLKCTRL DRA7_CLKCTRL_INDEX(0x30) +#define DRA7_WKUPAON_GPIO1_CLKCTRL DRA7_CLKCTRL_INDEX(0x38) +#define DRA7_WKUPAON_TIMER1_CLKCTRL DRA7_CLKCTRL_INDEX(0x40) +#define DRA7_WKUPAON_TIMER12_CLKCTRL DRA7_CLKCTRL_INDEX(0x48) +#define DRA7_WKUPAON_COUNTER_32K_CLKCTRL DRA7_CLKCTRL_INDEX(0x50) +#define DRA7_WKUPAON_UART10_CLKCTRL DRA7_CLKCTRL_INDEX(0x80) +#define DRA7_WKUPAON_DCAN1_CLKCTRL DRA7_CLKCTRL_INDEX(0x88) +#define DRA7_WKUPAON_ADC_CLKCTRL DRA7_CLKCTRL_INDEX(0xa0) + #endif From 47b00dcf141172c4c1c583701ec91923672cec39 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 10 Aug 2018 11:29:09 +0300 Subject: [PATCH 196/836] clk: ti: clkctrl: support multiple clkctrl nodes under a cm node Currently, only one clkctrl node can be added under a specific CM node due to limitation with the implementation. Modify the code to pick-up clockdomain name from the clkctrl node instead of CM node if provided. Also, add a new flag to the TI clock driver so that both modes can be supported simultaneously. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/clk.c | 7 +++-- drivers/clk/ti/clkctrl.c | 61 +++++++++++++++++++++++++++++----------- drivers/clk/ti/clock.h | 2 ++ include/linux/clk/ti.h | 1 + 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 27e0979b3158..8b89be18e39e 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -34,7 +34,7 @@ struct ti_clk_ll_ops *ti_clk_ll_ops; static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS]; -static struct ti_clk_features ti_clk_features; +struct ti_clk_features ti_clk_features; struct clk_iomap { struct regmap *regmap; @@ -140,6 +140,9 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) int ret; static bool clkctrl_nodes_missing; static bool has_clkctrl_data; + static bool compat_mode; + + compat_mode = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT; for (c = oclks; c->node_name != NULL; c++) { strcpy(buf, c->node_name); @@ -164,7 +167,7 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[]) continue; node = of_find_node_by_name(NULL, buf); - if (num_args) { + if (num_args && compat_mode) { parent = node; node = of_get_child_by_name(parent, "clk"); of_node_put(parent); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 421b05392220..9bff57f0345d 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -259,8 +259,13 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, struct omap_clkctrl_clk *clkctrl_clk; int ret = 0; - init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name, - node->name, offset, bit); + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", + node->parent->name, node->name, offset, + bit); + else + init.name = kasprintf(GFP_KERNEL, "%s:%04x:%d", node->name, + offset, bit); clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); if (!init.name || !clkctrl_clk) { ret = -ENOMEM; @@ -441,6 +446,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) u32 addr; int ret; + if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) && + !strcmp(node->name, "clk")) + ti_clk_features.flags |= TI_CLK_CLKCTRL_COMPAT; + addrp = of_get_address(node, 0, NULL, NULL); addr = (u32)of_translate_address(node, addrp); @@ -492,19 +501,35 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) provider->base = of_iomap(node, 0); - provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3, - GFP_KERNEL); - if (!provider->clkdm_name) { - kfree(provider); - return; + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) { + provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3, + GFP_KERNEL); + if (!provider->clkdm_name) { + kfree(provider); + return; + } + + /* + * Create default clkdm name, replace _cm from end of parent + * node name with _clkdm + */ + strcpy(provider->clkdm_name, node->parent->name); + provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0; + } else { + provider->clkdm_name = kmalloc(strlen(node->name), GFP_KERNEL); + if (!provider->clkdm_name) { + kfree(provider); + return; + } + + /* + * Create default clkdm name, replace _clkctrl from end of + * node name with _clkdm + */ + strcpy(provider->clkdm_name, node->name); + provider->clkdm_name[strlen(provider->clkdm_name) - 7] = 0; } - /* - * Create default clkdm name, replace _cm from end of parent node - * name with _clkdm - */ - strcpy(provider->clkdm_name, node->parent->name); - provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0; strcat(provider->clkdm_name, "clkdm"); INIT_LIST_HEAD(&provider->clocks); @@ -539,9 +564,13 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) init.flags = 0; if (reg_data->flags & CLKF_SET_RATE_PARENT) init.flags |= CLK_SET_RATE_PARENT; - init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", - node->parent->name, node->name, - reg_data->offset, 0); + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", + node->parent->name, node->name, + reg_data->offset, 0); + else + init.name = kasprintf(GFP_KERNEL, "%s:%04x:%d", + node->name, reg_data->offset, 0); clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); if (!init.name || !clkctrl_clk) goto cleanup; diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index b58278077226..ce4aad6c4c7c 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -233,6 +233,8 @@ extern const struct clk_ops ti_clk_divider_ops; extern const struct clk_ops ti_clk_mux_ops; extern const struct clk_ops omap_gate_clk_ops; +extern struct ti_clk_features ti_clk_features; + void omap2_init_clk_clkdm(struct clk_hw *hw); int omap2_clkops_enable_clkdm(struct clk_hw *hw); void omap2_clkops_disable_clkdm(struct clk_hw *hw); diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index a8faa38b1ed6..3301bd025a2c 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -290,6 +290,7 @@ struct ti_clk_features { #define TI_CLK_DPLL4_DENY_REPROGRAM BIT(1) #define TI_CLK_DISABLE_CLKDM_CONTROL BIT(2) #define TI_CLK_ERRATA_I810 BIT(3) +#define TI_CLK_CLKCTRL_COMPAT BIT(4) void ti_clk_setup_features(struct ti_clk_features *features); const struct ti_clk_features *ti_clk_get_features(void); From 1dc88f78da594042b549f1ea70de2fb721990e3c Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 30 Aug 2018 09:58:31 +0300 Subject: [PATCH 197/836] clk: ti: clkctrl: replace dashes from clkdm name with underscore The change in the DTS data node naming prevents using underscore within the node names and force usage of dash instead. On the other hand, clockdomains use underscore instead of dash, so this must be replaced within the driver code so that the mapping between the two can be done properly. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/clkctrl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 9bff57f0345d..e4b431b63e6b 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -445,6 +445,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) const __be32 *addrp; u32 addr; int ret; + char *c; if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) && !strcmp(node->name, "clk")) @@ -532,6 +533,15 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) strcat(provider->clkdm_name, "clkdm"); + /* Replace any dash from the clkdm name with underscore */ + c = provider->clkdm_name; + + while (*c) { + if (*c == '-') + *c = '_'; + c++; + } + INIT_LIST_HEAD(&provider->clocks); /* Generate clocks */ From e97017f935fcb3d505d86738817230552f58a19a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 10 Aug 2018 18:22:02 +0300 Subject: [PATCH 198/836] clk: ti: am33xx: rename existing clkctrl data as compat data Rename the existing clkctrl data in preparation of upcoming clkdm based split for it. Once the DT data has transitioned also, the compat data can be removed. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/clk-33xx-compat.c | 218 +++++++++++++++++++++++++++++++ drivers/clk/ti/clk-33xx.c | 196 +-------------------------- drivers/clk/ti/clkctrl.c | 2 +- drivers/clk/ti/clock.h | 3 +- 5 files changed, 224 insertions(+), 198 deletions(-) create mode 100644 drivers/clk/ti/clk-33xx-compat.c diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index 5ab295d2a3cb..0ff5a2538a8f 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -6,7 +6,8 @@ clk-common = dpll.o composite.o divider.o gate.o \ fixed-factor.o mux.o apll.o \ clkt_dpll.o clkt_iclk.o clkt_dflt.o \ clkctrl.o -obj-$(CONFIG_SOC_AM33XX) += $(clk-common) clk-33xx.o dpll3xxx.o +obj-$(CONFIG_SOC_AM33XX) += $(clk-common) clk-33xx.o dpll3xxx.o \ + clk-33xx-compat.o obj-$(CONFIG_SOC_TI81XX) += $(clk-common) fapll.o clk-814x.o clk-816x.o obj-$(CONFIG_ARCH_OMAP2) += $(clk-common) interface.o clk-2xxx.o obj-$(CONFIG_ARCH_OMAP3) += $(clk-common) interface.o \ diff --git a/drivers/clk/ti/clk-33xx-compat.c b/drivers/clk/ti/clk-33xx-compat.c new file mode 100644 index 000000000000..3e07f127912a --- /dev/null +++ b/drivers/clk/ti/clk-33xx-compat.c @@ -0,0 +1,218 @@ +/* + * AM33XX Clock init + * + * 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 as + * published by the Free Software Foundation version 2. + * + * 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 +#include +#include +#include +#include +#include + +#include "clock.h" + +static const char * const am3_gpio1_dbclk_parents[] __initconst = { + "l4_per_cm:clk:0138:0", + NULL, +}; + +static const struct omap_clkctrl_bit_data am3_gpio2_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am3_gpio3_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = { + { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, + { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" }, + { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" }, + { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" }, + { AM3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, + { AM3_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" }, + { AM3_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM3_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" }, + { AM3_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, + { AM3_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, + { AM3_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, + { AM3_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, + { AM3_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, + { AM3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" }, + { AM3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_GPIO2_CLKCTRL, am3_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_GPIO3_CLKCTRL, am3_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_GPIO4_CLKCTRL, am3_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, + { AM3_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, + { AM3_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" }, + { AM3_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, + { AM3_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, + { AM3_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM3_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" }, + { AM3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM3_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l4hs_clkdm" }, + { AM3_OCPWP_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_CLKDIV32K_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ck", "clk_24mhz_clkdm" }, + { 0 }, +}; + +static const char * const am3_gpio0_dbclk_parents[] __initconst = { + "gpio0_dbclk_mux_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am3_gpio1_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio0_dbclk_parents, NULL }, + { 0 }, +}; + +static const char * const am3_dbg_sysclk_ck_parents[] __initconst = { + "sys_clkin_ck", + NULL, +}; + +static const char * const am3_trace_pmd_clk_mux_ck_parents[] __initconst = { + "l4_wkup_cm:clk:0010:19", + "l4_wkup_cm:clk:0010:30", + NULL, +}; + +static const char * const am3_trace_clk_div_ck_parents[] __initconst = { + "l4_wkup_cm:clk:0010:20", + NULL, +}; + +static const struct omap_clkctrl_div_data am3_trace_clk_div_ck_data __initconst = { + .max_div = 64, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const char * const am3_stm_clk_div_ck_parents[] __initconst = { + "l4_wkup_cm:clk:0010:22", + NULL, +}; + +static const struct omap_clkctrl_div_data am3_stm_clk_div_ck_data __initconst = { + .max_div = 64, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const char * const am3_dbg_clka_ck_parents[] __initconst = { + "dpll_core_m4_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am3_debugss_bit_data[] __initconst = { + { 19, TI_CLK_GATE, am3_dbg_sysclk_ck_parents, NULL }, + { 20, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL }, + { 22, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL }, + { 24, TI_CLK_DIVIDER, am3_trace_clk_div_ck_parents, &am3_trace_clk_div_ck_data }, + { 27, TI_CLK_DIVIDER, am3_stm_clk_div_ck_parents, &am3_stm_clk_div_ck_data }, + { 30, TI_CLK_GATE, am3_dbg_clka_ck_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_wkup_clkctrl_regs[] __initconst = { + { AM3_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, + { AM3_GPIO1_CLKCTRL, am3_gpio1_bit_data, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, + { AM3_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, + { AM3_DEBUGSS_CLKCTRL, am3_debugss_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0010:24", "l3_aon_clkdm" }, + { AM3_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "dpll_core_m4_div2_ck", "l4_wkup_aon_clkdm" }, + { AM3_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, + { AM3_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, + { AM3_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" }, + { AM3_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" }, + { AM3_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" }, + { AM3_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" }, + { AM3_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_mpu_clkctrl_regs[] __initconst = { + { AM3_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = { + { AM3_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = { + { AM3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_cefuse_clkctrl_regs[] __initconst = { + { AM3_CEFUSE_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, + { 0 }, +}; + +const struct omap_clkctrl_data am3_clkctrl_compat_data[] __initconst = { + { 0x44e00014, am3_l4_per_clkctrl_regs }, + { 0x44e00404, am3_l4_wkup_clkctrl_regs }, + { 0x44e00604, am3_mpu_clkctrl_regs }, + { 0x44e00800, am3_l4_rtc_clkctrl_regs }, + { 0x44e00904, am3_gfx_l3_clkctrl_regs }, + { 0x44e00a20, am3_l4_cefuse_clkctrl_regs }, + { 0 }, +}; + +struct ti_dt_clk am33xx_compat_clks[] = { + DT_CLK(NULL, "timer_32k_ck", "l4_per_cm:0138:0"), + DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), + DT_CLK(NULL, "clkdiv32k_ick", "l4_per_cm:0138:0"), + DT_CLK(NULL, "dbg_clka_ck", "l4_wkup_cm:0010:30"), + DT_CLK(NULL, "dbg_sysclk_ck", "l4_wkup_cm:0010:19"), + DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0004:18"), + DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0098:18"), + DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:009c:18"), + DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:00a0:18"), + DT_CLK(NULL, "stm_clk_div_ck", "l4_wkup_cm:0010:27"), + DT_CLK(NULL, "stm_pmd_clock_mux_ck", "l4_wkup_cm:0010:22"), + DT_CLK(NULL, "trace_clk_div_ck", "l4_wkup_cm:0010:24"), + DT_CLK(NULL, "trace_pmd_clk_mux_ck", "l4_wkup_cm:0010:20"), + { .node_name = NULL }, +}; diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index 12e0a2d19911..b43c00392bdc 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c @@ -23,200 +23,6 @@ #include "clock.h" -static const char * const am3_gpio1_dbclk_parents[] __initconst = { - "l4_per_cm:clk:0138:0", - NULL, -}; - -static const struct omap_clkctrl_bit_data am3_gpio2_bit_data[] __initconst = { - { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am3_gpio3_bit_data[] __initconst = { - { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = { - { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am3_l4_per_clkctrl_regs[] __initconst = { - { AM3_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, - { AM3_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk", "lcdc_clkdm" }, - { AM3_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck", "l3s_clkdm" }, - { AM3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck", "l3_clkdm" }, - { AM3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, - { AM3_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" }, - { AM3_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, - { AM3_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" }, - { AM3_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM3_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, - { AM3_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, - { AM3_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, - { AM3_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, - { AM3_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, - { AM3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" }, - { AM3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_GPIO2_CLKCTRL, am3_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_GPIO3_CLKCTRL, am3_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_GPIO4_CLKCTRL, am3_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, - { AM3_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, - { AM3_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" }, - { AM3_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, - { AM3_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, - { AM3_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, - { AM3_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" }, - { AM3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM3_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l4hs_clkdm" }, - { AM3_OCPWP_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM3_CLKDIV32K_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ck", "clk_24mhz_clkdm" }, - { 0 }, -}; - -static const char * const am3_gpio0_dbclk_parents[] __initconst = { - "gpio0_dbclk_mux_ck", - NULL, -}; - -static const struct omap_clkctrl_bit_data am3_gpio1_bit_data[] __initconst = { - { 18, TI_CLK_GATE, am3_gpio0_dbclk_parents, NULL }, - { 0 }, -}; - -static const char * const am3_dbg_sysclk_ck_parents[] __initconst = { - "sys_clkin_ck", - NULL, -}; - -static const char * const am3_trace_pmd_clk_mux_ck_parents[] __initconst = { - "l4_wkup_cm:clk:0010:19", - "l4_wkup_cm:clk:0010:30", - NULL, -}; - -static const char * const am3_trace_clk_div_ck_parents[] __initconst = { - "l4_wkup_cm:clk:0010:20", - NULL, -}; - -static const struct omap_clkctrl_div_data am3_trace_clk_div_ck_data __initconst = { - .max_div = 64, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const char * const am3_stm_clk_div_ck_parents[] __initconst = { - "l4_wkup_cm:clk:0010:22", - NULL, -}; - -static const struct omap_clkctrl_div_data am3_stm_clk_div_ck_data __initconst = { - .max_div = 64, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const char * const am3_dbg_clka_ck_parents[] __initconst = { - "dpll_core_m4_ck", - NULL, -}; - -static const struct omap_clkctrl_bit_data am3_debugss_bit_data[] __initconst = { - { 19, TI_CLK_GATE, am3_dbg_sysclk_ck_parents, NULL }, - { 20, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL }, - { 22, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL }, - { 24, TI_CLK_DIVIDER, am3_trace_clk_div_ck_parents, &am3_trace_clk_div_ck_data }, - { 27, TI_CLK_DIVIDER, am3_stm_clk_div_ck_parents, &am3_stm_clk_div_ck_data }, - { 30, TI_CLK_GATE, am3_dbg_clka_ck_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am3_l4_wkup_clkctrl_regs[] __initconst = { - { AM3_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, - { AM3_GPIO1_CLKCTRL, am3_gpio1_bit_data, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, - { AM3_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, - { AM3_DEBUGSS_CLKCTRL, am3_debugss_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0010:24", "l3_aon_clkdm" }, - { AM3_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "dpll_core_m4_div2_ck", "l4_wkup_aon_clkdm" }, - { AM3_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, - { AM3_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, - { AM3_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" }, - { AM3_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" }, - { AM3_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" }, - { AM3_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" }, - { AM3_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am3_mpu_clkctrl_regs[] __initconst = { - { AM3_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = { - { AM3_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = { - { AM3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am3_l4_cefuse_clkctrl_regs[] __initconst = { - { AM3_CEFUSE_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, - { 0 }, -}; - -const struct omap_clkctrl_data am3_clkctrl_data[] __initconst = { - { 0x44e00014, am3_l4_per_clkctrl_regs }, - { 0x44e00404, am3_l4_wkup_clkctrl_regs }, - { 0x44e00604, am3_mpu_clkctrl_regs }, - { 0x44e00800, am3_l4_rtc_clkctrl_regs }, - { 0x44e00904, am3_gfx_l3_clkctrl_regs }, - { 0x44e00a20, am3_l4_cefuse_clkctrl_regs }, - { 0 }, -}; - -static struct ti_dt_clk am33xx_clks[] = { - DT_CLK(NULL, "timer_32k_ck", "l4_per_cm:0138:0"), - DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), - DT_CLK(NULL, "clkdiv32k_ick", "l4_per_cm:0138:0"), - DT_CLK(NULL, "dbg_clka_ck", "l4_wkup_cm:0010:30"), - DT_CLK(NULL, "dbg_sysclk_ck", "l4_wkup_cm:0010:19"), - DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0004:18"), - DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0098:18"), - DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:009c:18"), - DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:00a0:18"), - DT_CLK(NULL, "stm_clk_div_ck", "l4_wkup_cm:0010:27"), - DT_CLK(NULL, "stm_pmd_clock_mux_ck", "l4_wkup_cm:0010:22"), - DT_CLK(NULL, "trace_clk_div_ck", "l4_wkup_cm:0010:24"), - DT_CLK(NULL, "trace_pmd_clk_mux_ck", "l4_wkup_cm:0010:20"), - { .node_name = NULL }, -}; - static const char *enable_init_clks[] = { "dpll_ddr_m2_ck", "dpll_mpu_m2_ck", @@ -232,7 +38,7 @@ int __init am33xx_dt_clk_init(void) { struct clk *clk1, *clk2; - ti_dt_clocks_register(am33xx_clks); + ti_dt_clocks_register(am33xx_compat_clks); omap2_clk_disable_autoidle_all(); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index e4b431b63e6b..82c53034b82c 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -468,7 +468,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) #endif #ifdef CONFIG_SOC_AM33XX if (of_machine_is_compatible("ti,am33xx")) - data = am3_clkctrl_data; + data = am3_clkctrl_compat_data; #endif #ifdef CONFIG_SOC_AM43XX if (of_machine_is_compatible("ti,am4372")) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index ce4aad6c4c7c..b614f76e66f5 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -184,7 +184,8 @@ struct omap_clkctrl_data { extern const struct omap_clkctrl_data omap4_clkctrl_data[]; extern const struct omap_clkctrl_data omap5_clkctrl_data[]; extern const struct omap_clkctrl_data dra7_clkctrl_data[]; -extern const struct omap_clkctrl_data am3_clkctrl_data[]; +extern const struct omap_clkctrl_data am3_clkctrl_compat_data[]; +extern struct ti_dt_clk am33xx_compat_clks[]; extern const struct omap_clkctrl_data am4_clkctrl_data[]; extern const struct omap_clkctrl_data am438x_clkctrl_data[]; extern const struct omap_clkctrl_data dm814_clkctrl_data[]; From 296e583e9987e9f8e24dbc4e96692f987cfd6d95 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 10 Aug 2018 18:35:03 +0300 Subject: [PATCH 199/836] clk: ti: am33xx: add new clkctrl data for am33xx The new clkctrl data layout for am33xx is split based on clockdomain boundaries. Previously the split was based on CM boundaries. This patch adds the new data as separate data entity, retaining the compatibility data also for now. The compatibility data can be removed once no longer needed. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/clk-33xx.c | 244 +++++++++++++++++++++++++++++++++++++- drivers/clk/ti/clkctrl.c | 8 +- drivers/clk/ti/clock.h | 1 + 3 files changed, 250 insertions(+), 3 deletions(-) diff --git a/drivers/clk/ti/clk-33xx.c b/drivers/clk/ti/clk-33xx.c index b43c00392bdc..a360d3109555 100644 --- a/drivers/clk/ti/clk-33xx.c +++ b/drivers/clk/ti/clk-33xx.c @@ -23,6 +23,245 @@ #include "clock.h" +static const char * const am3_gpio1_dbclk_parents[] __initconst = { + "clk-24mhz-clkctrl:0000:0", + NULL, +}; + +static const struct omap_clkctrl_bit_data am3_gpio2_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am3_gpio3_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am3_gpio4_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4ls_clkctrl_regs[] __initconst = { + { AM3_L4LS_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM3_L4LS_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM3_L4LS_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, + { AM3_L4LS_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, + { AM3_L4LS_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, + { AM3_L4LS_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, + { AM3_L4LS_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, + { AM3_L4LS_GPIO2_CLKCTRL, am3_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_GPIO3_CLKCTRL, am3_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_GPIO4_CLKCTRL, am3_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, + { AM3_L4LS_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, + { AM3_L4LS_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, + { AM3_L4LS_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, + { AM3_L4LS_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM3_L4LS_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM3_L4LS_OCPWP_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l3s_clkctrl_regs[] __initconst = { + { AM3_L3S_USB_OTG_HS_CLKCTRL, NULL, CLKF_SW_SUP, "usbotg_fck" }, + { AM3_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, + { AM3_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" }, + { AM3_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" }, + { AM3_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l3_clkctrl_regs[] __initconst = { + { AM3_L3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_div2_ck" }, + { AM3_L3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck" }, + { AM3_L3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM3_L3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4hs_clkctrl_regs[] __initconst = { + { AM3_L4HS_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_pruss_ocp_clkctrl_regs[] __initconst = { + { AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_cpsw_125mhz_clkctrl_regs[] __initconst = { + { AM3_CPSW_125MHZ_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_lcdc_clkctrl_regs[] __initconst = { + { AM3_LCDC_LCDC_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "lcd_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_clk_24mhz_clkctrl_regs[] __initconst = { + { AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ck" }, + { 0 }, +}; + +static const char * const am3_gpio0_dbclk_parents[] __initconst = { + "gpio0_dbclk_mux_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am3_gpio1_bit_data[] __initconst = { + { 18, TI_CLK_GATE, am3_gpio0_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_wkup_clkctrl_regs[] __initconst = { + { AM3_L4_WKUP_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, + { AM3_L4_WKUP_GPIO1_CLKCTRL, am3_gpio1_bit_data, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, + { AM3_L4_WKUP_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_m4_div2_ck" }, + { AM3_L4_WKUP_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, + { AM3_L4_WKUP_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, + { AM3_L4_WKUP_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" }, + { AM3_L4_WKUP_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" }, + { AM3_L4_WKUP_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" }, + { AM3_L4_WKUP_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" }, + { AM3_L4_WKUP_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" }, + { 0 }, +}; + +static const char * const am3_dbg_sysclk_ck_parents[] __initconst = { + "sys_clkin_ck", + NULL, +}; + +static const char * const am3_trace_pmd_clk_mux_ck_parents[] __initconst = { + "l3-aon-clkctrl:0000:19", + "l3-aon-clkctrl:0000:30", + NULL, +}; + +static const char * const am3_trace_clk_div_ck_parents[] __initconst = { + "l3-aon-clkctrl:0000:20", + NULL, +}; + +static const struct omap_clkctrl_div_data am3_trace_clk_div_ck_data __initconst = { + .max_div = 64, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const char * const am3_stm_clk_div_ck_parents[] __initconst = { + "l3-aon-clkctrl:0000:22", + NULL, +}; + +static const struct omap_clkctrl_div_data am3_stm_clk_div_ck_data __initconst = { + .max_div = 64, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const char * const am3_dbg_clka_ck_parents[] __initconst = { + "dpll_core_m4_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am3_debugss_bit_data[] __initconst = { + { 19, TI_CLK_GATE, am3_dbg_sysclk_ck_parents, NULL }, + { 20, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL }, + { 22, TI_CLK_MUX, am3_trace_pmd_clk_mux_ck_parents, NULL }, + { 24, TI_CLK_DIVIDER, am3_trace_clk_div_ck_parents, &am3_trace_clk_div_ck_data }, + { 27, TI_CLK_DIVIDER, am3_stm_clk_div_ck_parents, &am3_stm_clk_div_ck_data }, + { 30, TI_CLK_GATE, am3_dbg_clka_ck_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l3_aon_clkctrl_regs[] __initconst = { + { AM3_L3_AON_DEBUGSS_CLKCTRL, am3_debugss_bit_data, CLKF_SW_SUP, "l3-aon-clkctrl:0000:24" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_wkup_aon_clkctrl_regs[] __initconst = { + { AM3_L4_WKUP_AON_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "dpll_core_m4_div2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_mpu_clkctrl_regs[] __initconst = { + { AM3_MPU_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = { + { AM3_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = { + { AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am3_l4_cefuse_clkctrl_regs[] __initconst = { + { AM3_L4_CEFUSE_CEFUSE_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, + { 0 }, +}; + +const struct omap_clkctrl_data am3_clkctrl_data[] __initconst = { + { 0x44e00038, am3_l4ls_clkctrl_regs }, + { 0x44e0001c, am3_l3s_clkctrl_regs }, + { 0x44e00024, am3_l3_clkctrl_regs }, + { 0x44e00120, am3_l4hs_clkctrl_regs }, + { 0x44e000e8, am3_pruss_ocp_clkctrl_regs }, + { 0x44e00000, am3_cpsw_125mhz_clkctrl_regs }, + { 0x44e00018, am3_lcdc_clkctrl_regs }, + { 0x44e0014c, am3_clk_24mhz_clkctrl_regs }, + { 0x44e00400, am3_l4_wkup_clkctrl_regs }, + { 0x44e00414, am3_l3_aon_clkctrl_regs }, + { 0x44e004b0, am3_l4_wkup_aon_clkctrl_regs }, + { 0x44e00600, am3_mpu_clkctrl_regs }, + { 0x44e00800, am3_l4_rtc_clkctrl_regs }, + { 0x44e00900, am3_gfx_l3_clkctrl_regs }, + { 0x44e00a00, am3_l4_cefuse_clkctrl_regs }, + { 0 }, +}; + +static struct ti_dt_clk am33xx_clks[] = { + DT_CLK(NULL, "timer_32k_ck", "clk-24mhz-clkctrl:0000:0"), + DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), + DT_CLK(NULL, "clkdiv32k_ick", "clk-24mhz-clkctrl:0000:0"), + DT_CLK(NULL, "dbg_clka_ck", "l3-aon-clkctrl:0000:30"), + DT_CLK(NULL, "dbg_sysclk_ck", "l3-aon-clkctrl:0000:19"), + DT_CLK(NULL, "gpio0_dbclk", "l4-wkup-clkctrl:0008:18"), + DT_CLK(NULL, "gpio1_dbclk", "l4ls-clkctrl:0074:18"), + DT_CLK(NULL, "gpio2_dbclk", "l4ls-clkctrl:0078:18"), + DT_CLK(NULL, "gpio3_dbclk", "l4ls-clkctrl:007c:18"), + DT_CLK(NULL, "stm_clk_div_ck", "l3-aon-clkctrl:0000:27"), + DT_CLK(NULL, "stm_pmd_clock_mux_ck", "l3-aon-clkctrl:0000:22"), + DT_CLK(NULL, "trace_clk_div_ck", "l3-aon-clkctrl:0000:24"), + DT_CLK(NULL, "trace_pmd_clk_mux_ck", "l3-aon-clkctrl:0000:20"), + { .node_name = NULL }, +}; + static const char *enable_init_clks[] = { "dpll_ddr_m2_ck", "dpll_mpu_m2_ck", @@ -38,7 +277,10 @@ int __init am33xx_dt_clk_init(void) { struct clk *clk1, *clk2; - ti_dt_clocks_register(am33xx_compat_clks); + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + ti_dt_clocks_register(am33xx_compat_clks); + else + ti_dt_clocks_register(am33xx_clks); omap2_clk_disable_autoidle_all(); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 82c53034b82c..1d78d6c6e8fc 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -467,8 +467,12 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) data = dra7_clkctrl_data; #endif #ifdef CONFIG_SOC_AM33XX - if (of_machine_is_compatible("ti,am33xx")) - data = am3_clkctrl_compat_data; + if (of_machine_is_compatible("ti,am33xx")) { + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + data = am3_clkctrl_compat_data; + else + data = am3_clkctrl_data; + } #endif #ifdef CONFIG_SOC_AM43XX if (of_machine_is_compatible("ti,am4372")) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index b614f76e66f5..c4c6c787ed43 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -184,6 +184,7 @@ struct omap_clkctrl_data { extern const struct omap_clkctrl_data omap4_clkctrl_data[]; extern const struct omap_clkctrl_data omap5_clkctrl_data[]; extern const struct omap_clkctrl_data dra7_clkctrl_data[]; +extern const struct omap_clkctrl_data am3_clkctrl_data[]; extern const struct omap_clkctrl_data am3_clkctrl_compat_data[]; extern struct ti_dt_clk am33xx_compat_clks[]; extern const struct omap_clkctrl_data am4_clkctrl_data[]; From 131ee08f3fba48fd39ceca9c785a908c37276667 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 13 Aug 2018 10:38:40 +0300 Subject: [PATCH 200/836] clk: ti: am43xx: rename existing clkctrl data as compat data Rename the existing clkctrl data in preparation of upcoming clkdm based split for it. Once the DT data has transitioned also, the compat data can be removed. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/clk-43xx-compat.c | 225 +++++++++++++++++++++++++++++++ drivers/clk/ti/clk-43xx.c | 203 +--------------------------- drivers/clk/ti/clkctrl.c | 4 +- drivers/clk/ti/clock.h | 5 +- 5 files changed, 233 insertions(+), 207 deletions(-) create mode 100644 drivers/clk/ti/clk-43xx-compat.c diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index 0ff5a2538a8f..5f2385d9a2e9 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -18,7 +18,8 @@ obj-$(CONFIG_SOC_OMAP5) += $(clk-common) clk-54xx.o \ dpll3xxx.o dpll44xx.o obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o \ clk-dra7-atl.o dpll3xxx.o dpll44xx.o -obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o +obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o \ + clk-43xx-compat.o endif # CONFIG_ARCH_OMAP2PLUS diff --git a/drivers/clk/ti/clk-43xx-compat.c b/drivers/clk/ti/clk-43xx-compat.c new file mode 100644 index 000000000000..513039843392 --- /dev/null +++ b/drivers/clk/ti/clk-43xx-compat.c @@ -0,0 +1,225 @@ +/* + * AM43XX Clock init + * + * 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 as + * published by the Free Software Foundation version 2. + * + * 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 +#include +#include +#include +#include +#include + +#include "clock.h" + +static const char * const am4_synctimer_32kclk_parents[] __initconst = { + "mux_synctimer32k_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_counter_32k_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_synctimer_32kclk_parents, NULL }, + { 0 }, +}; + +static const char * const am4_gpio0_dbclk_parents[] __initconst = { + "gpio0_dbclk_mux_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_gpio1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio0_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4_wkup_clkctrl_regs[] __initconst = { + { AM4_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck", "l3s_tsc_clkdm" }, + { AM4_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" }, + { AM4_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "sys_clkin_ck" }, + { AM4_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0210:8" }, + { AM4_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck", "l4_wkup_clkdm" }, + { AM4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck", "l4_wkup_clkdm" }, + { AM4_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" }, + { AM4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" }, + { AM4_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck", "l4_wkup_clkdm" }, + { AM4_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck", "l4_wkup_clkdm" }, + { AM4_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" }, + { AM4_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = { + { AM4_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = { + { AM4_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = { + { AM4_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, + { 0 }, +}; + +static const char * const am4_usb_otg_ss0_refclk960m_parents[] __initconst = { + "dpll_per_clkdcoldo", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_usb_otg_ss0_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_usb_otg_ss1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, + { 0 }, +}; + +static const char * const am4_gpio1_dbclk_parents[] __initconst = { + "clkdiv32k_ick", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_gpio2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio3_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio4_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio5_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio6_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst = { + { AM4_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" }, + { AM4_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" }, + { AM4_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" }, + { AM4_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, + { AM4_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l3_clkdm" }, + { AM4_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, + { AM4_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" }, + { AM4_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" }, + { AM4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" }, + { AM4_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, + { AM4_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, + { AM4_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, + { AM4_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" }, + { AM4_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, + { AM4_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, + { AM4_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" }, + { AM4_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM4_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM4_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, + { AM4_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, + { AM4_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, + { AM4_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, + { AM4_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, + { AM4_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, + { AM4_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, + { AM4_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" }, + { AM4_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" }, + { AM4_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" }, + { AM4_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" }, + { AM4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" }, + { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" }, + { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, + { 0 }, +}; + +const struct omap_clkctrl_data am4_clkctrl_compat_data[] __initconst = { + { 0x44df2820, am4_l4_wkup_clkctrl_regs }, + { 0x44df8320, am4_mpu_clkctrl_regs }, + { 0x44df8420, am4_gfx_l3_clkctrl_regs }, + { 0x44df8520, am4_l4_rtc_clkctrl_regs }, + { 0x44df8820, am4_l4_per_clkctrl_regs }, + { 0 }, +}; + +const struct omap_clkctrl_data am438x_clkctrl_compat_data[] __initconst = { + { 0x44df2820, am4_l4_wkup_clkctrl_regs }, + { 0x44df8320, am4_mpu_clkctrl_regs }, + { 0x44df8420, am4_gfx_l3_clkctrl_regs }, + { 0x44df8820, am4_l4_per_clkctrl_regs }, + { 0 }, +}; + +struct ti_dt_clk am43xx_compat_clks[] = { + DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"), + DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), + DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0348:8"), + DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0458:8"), + DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:0460:8"), + DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:0468:8"), + DT_CLK(NULL, "gpio4_dbclk", "l4_per_cm:0470:8"), + DT_CLK(NULL, "gpio5_dbclk", "l4_per_cm:0478:8"), + DT_CLK(NULL, "synctimer_32kclk", "l4_wkup_cm:0210:8"), + DT_CLK(NULL, "usb_otg_ss0_refclk960m", "l4_per_cm:0240:8"), + DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l4_per_cm:0248:8"), + { .node_name = NULL }, +}; diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index 63c5ddb50187..dc3ccdc29ee8 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -23,212 +23,11 @@ #include "clock.h" -static const char * const am4_synctimer_32kclk_parents[] __initconst = { - "mux_synctimer32k_ck", - NULL, -}; - -static const struct omap_clkctrl_bit_data am4_counter_32k_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_synctimer_32kclk_parents, NULL }, - { 0 }, -}; - -static const char * const am4_gpio0_dbclk_parents[] __initconst = { - "gpio0_dbclk_mux_ck", - NULL, -}; - -static const struct omap_clkctrl_bit_data am4_gpio1_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_gpio0_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am4_l4_wkup_clkctrl_regs[] __initconst = { - { AM4_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck", "l3s_tsc_clkdm" }, - { AM4_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" }, - { AM4_WKUP_M3_CLKCTRL, NULL, CLKF_NO_IDLEST, "sys_clkin_ck" }, - { AM4_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4_wkup_cm:clk:0210:8" }, - { AM4_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck", "l4_wkup_clkdm" }, - { AM4_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck", "l4_wkup_clkdm" }, - { AM4_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" }, - { AM4_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck", "l4_wkup_clkdm" }, - { AM4_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck", "l4_wkup_clkdm" }, - { AM4_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck", "l4_wkup_clkdm" }, - { AM4_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" }, - { AM4_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck", "l4_wkup_clkdm" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = { - { AM4_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = { - { AM4_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = { - { AM4_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, - { 0 }, -}; - -static const char * const am4_usb_otg_ss0_refclk960m_parents[] __initconst = { - "dpll_per_clkdcoldo", - NULL, -}; - -static const struct omap_clkctrl_bit_data am4_usb_otg_ss0_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am4_usb_otg_ss1_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, - { 0 }, -}; - -static const char * const am4_gpio1_dbclk_parents[] __initconst = { - "clkdiv32k_ick", - NULL, -}; - -static const struct omap_clkctrl_bit_data am4_gpio2_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am4_gpio3_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am4_gpio4_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am4_gpio5_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data am4_gpio6_bit_data[] __initconst = { - { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data am4_l4_per_clkctrl_regs[] __initconst = { - { AM4_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck", "l3_clkdm" }, - { AM4_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" }, - { AM4_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3s_clkdm" }, - { AM4_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk", "l3_clkdm" }, - { AM4_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk", "l3_clkdm" }, - { AM4_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, - { AM4_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck", "l3s_clkdm" }, - { AM4_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck", "l3s_clkdm" }, - { AM4_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk", "l3s_clkdm" }, - { AM4_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, - { AM4_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, - { AM4_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk", "l3s_clkdm" }, - { AM4_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk", "pruss_ocp_clkdm" }, - { AM4_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, - { AM4_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, - { AM4_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" }, - { AM4_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, - { AM4_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, - { AM4_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, - { AM4_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, - { AM4_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, - { AM4_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, - { AM4_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, - { AM4_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, - { AM4_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, - { AM4_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" }, - { AM4_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" }, - { AM4_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" }, - { AM4_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" }, - { AM4_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, - { AM4_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, - { AM4_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck", "emif_clkdm" }, - { AM4_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk", "dss_clkdm" }, - { AM4_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk", "cpsw_125mhz_clkdm" }, - { 0 }, -}; - -const struct omap_clkctrl_data am4_clkctrl_data[] __initconst = { - { 0x44df2820, am4_l4_wkup_clkctrl_regs }, - { 0x44df8320, am4_mpu_clkctrl_regs }, - { 0x44df8420, am4_gfx_l3_clkctrl_regs }, - { 0x44df8520, am4_l4_rtc_clkctrl_regs }, - { 0x44df8820, am4_l4_per_clkctrl_regs }, - { 0 }, -}; - -const struct omap_clkctrl_data am438x_clkctrl_data[] __initconst = { - { 0x44df2820, am4_l4_wkup_clkctrl_regs }, - { 0x44df8320, am4_mpu_clkctrl_regs }, - { 0x44df8420, am4_gfx_l3_clkctrl_regs }, - { 0x44df8820, am4_l4_per_clkctrl_regs }, - { 0 }, -}; - -static struct ti_dt_clk am43xx_clks[] = { - DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"), - DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), - DT_CLK(NULL, "gpio0_dbclk", "l4_wkup_cm:0348:8"), - DT_CLK(NULL, "gpio1_dbclk", "l4_per_cm:0458:8"), - DT_CLK(NULL, "gpio2_dbclk", "l4_per_cm:0460:8"), - DT_CLK(NULL, "gpio3_dbclk", "l4_per_cm:0468:8"), - DT_CLK(NULL, "gpio4_dbclk", "l4_per_cm:0470:8"), - DT_CLK(NULL, "gpio5_dbclk", "l4_per_cm:0478:8"), - DT_CLK(NULL, "synctimer_32kclk", "l4_wkup_cm:0210:8"), - DT_CLK(NULL, "usb_otg_ss0_refclk960m", "l4_per_cm:0240:8"), - DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l4_per_cm:0248:8"), - { .node_name = NULL }, -}; - int __init am43xx_dt_clk_init(void) { struct clk *clk1, *clk2; - ti_dt_clocks_register(am43xx_clks); + ti_dt_clocks_register(am43xx_compat_clks); omap2_clk_disable_autoidle_all(); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 1d78d6c6e8fc..57f352ac9371 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -476,9 +476,9 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) #endif #ifdef CONFIG_SOC_AM43XX if (of_machine_is_compatible("ti,am4372")) - data = am4_clkctrl_data; + data = am4_clkctrl_compat_data; if (of_machine_is_compatible("ti,am438x")) - data = am438x_clkctrl_data; + data = am438x_clkctrl_compat_data; #endif #ifdef CONFIG_SOC_TI81XX if (of_machine_is_compatible("ti,dm814")) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index c4c6c787ed43..01b3c4ed7f3a 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -187,8 +187,9 @@ extern const struct omap_clkctrl_data dra7_clkctrl_data[]; extern const struct omap_clkctrl_data am3_clkctrl_data[]; extern const struct omap_clkctrl_data am3_clkctrl_compat_data[]; extern struct ti_dt_clk am33xx_compat_clks[]; -extern const struct omap_clkctrl_data am4_clkctrl_data[]; -extern const struct omap_clkctrl_data am438x_clkctrl_data[]; +extern const struct omap_clkctrl_data am4_clkctrl_compat_data[]; +extern struct ti_dt_clk am43xx_compat_clks[]; +extern const struct omap_clkctrl_data am438x_clkctrl_compat_data[]; extern const struct omap_clkctrl_data dm814_clkctrl_data[]; extern const struct omap_clkctrl_data dm816_clkctrl_data[]; From 76a1049b84dd57bad6260b51455bbd17053b2eb4 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 13 Aug 2018 10:48:52 +0300 Subject: [PATCH 201/836] clk: ti: am43xx: add new clkctrl data for am43xx The new clkctrl data layout for am43xx is split based on clockdomain boundaries. Previously the split was based on CM boundaries. This patch adds the new data as separate data entity, retaining the compatibility data also for now. The compatibility data can be removed once no longer needed. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/clk-43xx.c | 254 +++++++++++++++++++++++++++++++++++++- drivers/clk/ti/clkctrl.c | 17 ++- drivers/clk/ti/clock.h | 2 + 3 files changed, 268 insertions(+), 5 deletions(-) diff --git a/drivers/clk/ti/clk-43xx.c b/drivers/clk/ti/clk-43xx.c index dc3ccdc29ee8..2782d91838ac 100644 --- a/drivers/clk/ti/clk-43xx.c +++ b/drivers/clk/ti/clk-43xx.c @@ -23,11 +23,263 @@ #include "clock.h" +static const struct omap_clkctrl_reg_data am4_l3s_tsc_clkctrl_regs[] __initconst = { + { AM4_L3S_TSC_ADC_TSC_CLKCTRL, NULL, CLKF_SW_SUP, "adc_tsc_fck" }, + { 0 }, +}; + +static const char * const am4_synctimer_32kclk_parents[] __initconst = { + "mux_synctimer32k_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_counter_32k_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_synctimer_32kclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4_wkup_aon_clkctrl_regs[] __initconst = { + { AM4_L4_WKUP_AON_WKUP_M3_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "sys_clkin_ck" }, + { AM4_L4_WKUP_AON_COUNTER_32K_CLKCTRL, am4_counter_32k_bit_data, CLKF_SW_SUP, "l4-wkup-aon-clkctrl:0008:8" }, + { 0 }, +}; + +static const char * const am4_gpio0_dbclk_parents[] __initconst = { + "gpio0_dbclk_mux_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_gpio1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio0_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4_wkup_clkctrl_regs[] __initconst = { + { AM4_L4_WKUP_L4_WKUP_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, + { AM4_L4_WKUP_TIMER1_CLKCTRL, NULL, CLKF_SW_SUP, "timer1_fck" }, + { AM4_L4_WKUP_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "wdt1_fck" }, + { AM4_L4_WKUP_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, + { AM4_L4_WKUP_UART1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_wkupdm_ck" }, + { AM4_L4_WKUP_SMARTREFLEX0_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex0_fck" }, + { AM4_L4_WKUP_SMARTREFLEX1_CLKCTRL, NULL, CLKF_SW_SUP, "smartreflex1_fck" }, + { AM4_L4_WKUP_CONTROL_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin_ck" }, + { AM4_L4_WKUP_GPIO1_CLKCTRL, am4_gpio1_bit_data, CLKF_SW_SUP, "sys_clkin_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = { + { AM4_MPU_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_mpu_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = { + { AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = { + { AM4_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l3_clkctrl_regs[] __initconst = { + { AM4_L3_L3_MAIN_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_AES_CLKCTRL, NULL, CLKF_SW_SUP, "aes0_fck" }, + { AM4_L3_DES_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_L3_INSTR_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_OCMCRAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_SHAM_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_TPCC_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_TPTC0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_TPTC1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_TPTC2_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3_L4_HS_CLKCTRL, NULL, CLKF_SW_SUP, "l4hs_gclk" }, + { 0 }, +}; + +static const char * const am4_usb_otg_ss0_refclk960m_parents[] __initconst = { + "dpll_per_clkdcoldo", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_usb_otg_ss0_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_usb_otg_ss1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_usb_otg_ss0_refclk960m_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = { + { AM4_L3S_VPFE0_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3S_VPFE1_CLKCTRL, NULL, CLKF_SW_SUP, "l3_gclk" }, + { AM4_L3S_GPMC_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, + { AM4_L3S_MCASP0_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp0_fck" }, + { AM4_L3S_MCASP1_CLKCTRL, NULL, CLKF_SW_SUP, "mcasp1_fck" }, + { AM4_L3S_MMC3_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM4_L3S_QSPI_CLKCTRL, NULL, CLKF_SW_SUP, "l3s_gclk" }, + { AM4_L3S_USB_OTG_SS0_CLKCTRL, am4_usb_otg_ss0_bit_data, CLKF_SW_SUP, "l3s_gclk" }, + { AM4_L3S_USB_OTG_SS1_CLKCTRL, am4_usb_otg_ss1_bit_data, CLKF_SW_SUP, "l3s_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_pruss_ocp_clkctrl_regs[] __initconst = { + { AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" }, + { 0 }, +}; + +static const char * const am4_gpio1_dbclk_parents[] __initconst = { + "clkdiv32k_ick", + NULL, +}; + +static const struct omap_clkctrl_bit_data am4_gpio2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio3_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio4_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio5_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data am4_gpio6_bit_data[] __initconst = { + { 8, TI_CLK_GATE, am4_gpio1_dbclk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_l4ls_clkctrl_regs[] __initconst = { + { AM4_L4LS_L4_LS_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_D_CAN0_CLKCTRL, NULL, CLKF_SW_SUP, "dcan0_fck" }, + { AM4_L4LS_D_CAN1_CLKCTRL, NULL, CLKF_SW_SUP, "dcan1_fck" }, + { AM4_L4LS_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_EPWMSS3_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_EPWMSS4_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_EPWMSS5_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_ELM_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_GPIO2_CLKCTRL, am4_gpio2_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_GPIO3_CLKCTRL, am4_gpio3_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_GPIO4_CLKCTRL, am4_gpio4_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_GPIO5_CLKCTRL, am4_gpio5_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_GPIO6_CLKCTRL, am4_gpio6_bit_data, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_clk" }, + { AM4_L4LS_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_MAILBOX_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_MMC1_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM4_L4LS_MMC2_CLKCTRL, NULL, CLKF_SW_SUP, "mmc_clk" }, + { AM4_L4LS_RNG_CLKCTRL, NULL, CLKF_SW_SUP, "rng_fck" }, + { AM4_L4LS_SPI0_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_SPI1_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_SPI2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_SPI3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_SPI4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_SPINLOCK_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "timer2_fck" }, + { AM4_L4LS_TIMER3_CLKCTRL, NULL, CLKF_SW_SUP, "timer3_fck" }, + { AM4_L4LS_TIMER4_CLKCTRL, NULL, CLKF_SW_SUP, "timer4_fck" }, + { AM4_L4LS_TIMER5_CLKCTRL, NULL, CLKF_SW_SUP, "timer5_fck" }, + { AM4_L4LS_TIMER6_CLKCTRL, NULL, CLKF_SW_SUP, "timer6_fck" }, + { AM4_L4LS_TIMER7_CLKCTRL, NULL, CLKF_SW_SUP, "timer7_fck" }, + { AM4_L4LS_TIMER8_CLKCTRL, NULL, CLKF_SW_SUP, "timer8_fck" }, + { AM4_L4LS_TIMER9_CLKCTRL, NULL, CLKF_SW_SUP, "timer9_fck" }, + { AM4_L4LS_TIMER10_CLKCTRL, NULL, CLKF_SW_SUP, "timer10_fck" }, + { AM4_L4LS_TIMER11_CLKCTRL, NULL, CLKF_SW_SUP, "timer11_fck" }, + { AM4_L4LS_UART2_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_UART3_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_UART4_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_UART5_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_UART6_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_per_m2_div4_ck" }, + { AM4_L4LS_OCP2SCP0_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { AM4_L4LS_OCP2SCP1_CLKCTRL, NULL, CLKF_SW_SUP, "l4ls_gclk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_emif_clkctrl_regs[] __initconst = { + { AM4_EMIF_EMIF_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_ddr_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_dss_clkctrl_regs[] __initconst = { + { AM4_DSS_DSS_CORE_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_SET_RATE_PARENT, "disp_clk" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data am4_cpsw_125mhz_clkctrl_regs[] __initconst = { + { AM4_CPSW_125MHZ_CPGMAC0_CLKCTRL, NULL, CLKF_SW_SUP, "cpsw_125mhz_gclk" }, + { 0 }, +}; + +const struct omap_clkctrl_data am4_clkctrl_data[] __initconst = { + { 0x44df2920, am4_l3s_tsc_clkctrl_regs }, + { 0x44df2a28, am4_l4_wkup_aon_clkctrl_regs }, + { 0x44df2a20, am4_l4_wkup_clkctrl_regs }, + { 0x44df8320, am4_mpu_clkctrl_regs }, + { 0x44df8420, am4_gfx_l3_clkctrl_regs }, + { 0x44df8520, am4_l4_rtc_clkctrl_regs }, + { 0x44df8820, am4_l3_clkctrl_regs }, + { 0x44df8868, am4_l3s_clkctrl_regs }, + { 0x44df8b20, am4_pruss_ocp_clkctrl_regs }, + { 0x44df8c20, am4_l4ls_clkctrl_regs }, + { 0x44df8f20, am4_emif_clkctrl_regs }, + { 0x44df9220, am4_dss_clkctrl_regs }, + { 0x44df9320, am4_cpsw_125mhz_clkctrl_regs }, + { 0 }, +}; + +const struct omap_clkctrl_data am438x_clkctrl_data[] __initconst = { + { 0x44df2920, am4_l3s_tsc_clkctrl_regs }, + { 0x44df2a28, am4_l4_wkup_aon_clkctrl_regs }, + { 0x44df2a20, am4_l4_wkup_clkctrl_regs }, + { 0x44df8320, am4_mpu_clkctrl_regs }, + { 0x44df8420, am4_gfx_l3_clkctrl_regs }, + { 0x44df8820, am4_l3_clkctrl_regs }, + { 0x44df8868, am4_l3s_clkctrl_regs }, + { 0x44df8b20, am4_pruss_ocp_clkctrl_regs }, + { 0x44df8c20, am4_l4ls_clkctrl_regs }, + { 0x44df8f20, am4_emif_clkctrl_regs }, + { 0x44df9220, am4_dss_clkctrl_regs }, + { 0x44df9320, am4_cpsw_125mhz_clkctrl_regs }, + { 0 }, +}; + +static struct ti_dt_clk am43xx_clks[] = { + DT_CLK(NULL, "timer_32k_ck", "clkdiv32k_ick"), + DT_CLK(NULL, "timer_sys_ck", "sys_clkin_ck"), + DT_CLK(NULL, "gpio0_dbclk", "l4-wkup-clkctrl:0148:8"), + DT_CLK(NULL, "gpio1_dbclk", "l4ls-clkctrl:0058:8"), + DT_CLK(NULL, "gpio2_dbclk", "l4ls-clkctrl:0060:8"), + DT_CLK(NULL, "gpio3_dbclk", "l4ls-clkctrl:0068:8"), + DT_CLK(NULL, "gpio4_dbclk", "l4ls-clkctrl:0070:8"), + DT_CLK(NULL, "gpio5_dbclk", "l4ls-clkctrl:0078:8"), + DT_CLK(NULL, "synctimer_32kclk", "l4-wkup-aon-clkctrl:0008:8"), + DT_CLK(NULL, "usb_otg_ss0_refclk960m", "l3s-clkctrl:01f8:8"), + DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3s-clkctrl:0200:8"), + { .node_name = NULL }, +}; + int __init am43xx_dt_clk_init(void) { struct clk *clk1, *clk2; - ti_dt_clocks_register(am43xx_compat_clks); + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + ti_dt_clocks_register(am43xx_compat_clks); + else + ti_dt_clocks_register(am43xx_clks); omap2_clk_disable_autoidle_all(); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 57f352ac9371..6fe10a9f3116 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -475,10 +475,19 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) } #endif #ifdef CONFIG_SOC_AM43XX - if (of_machine_is_compatible("ti,am4372")) - data = am4_clkctrl_compat_data; - if (of_machine_is_compatible("ti,am438x")) - data = am438x_clkctrl_compat_data; + if (of_machine_is_compatible("ti,am4372")) { + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + data = am4_clkctrl_compat_data; + else + data = am4_clkctrl_data; + } + + if (of_machine_is_compatible("ti,am438x")) { + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + data = am438x_clkctrl_compat_data; + else + data = am438x_clkctrl_data; + } #endif #ifdef CONFIG_SOC_TI81XX if (of_machine_is_compatible("ti,dm814")) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index 01b3c4ed7f3a..11348de507fc 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -187,8 +187,10 @@ extern const struct omap_clkctrl_data dra7_clkctrl_data[]; extern const struct omap_clkctrl_data am3_clkctrl_data[]; extern const struct omap_clkctrl_data am3_clkctrl_compat_data[]; extern struct ti_dt_clk am33xx_compat_clks[]; +extern const struct omap_clkctrl_data am4_clkctrl_data[]; extern const struct omap_clkctrl_data am4_clkctrl_compat_data[]; extern struct ti_dt_clk am43xx_compat_clks[]; +extern const struct omap_clkctrl_data am438x_clkctrl_data[]; extern const struct omap_clkctrl_data am438x_clkctrl_compat_data[]; extern const struct omap_clkctrl_data dm814_clkctrl_data[]; extern const struct omap_clkctrl_data dm816_clkctrl_data[]; From 43c56e046cd8229315a466b079c53f4ab0f8dcf2 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 13 Aug 2018 11:11:33 +0300 Subject: [PATCH 202/836] clk: ti: dra7xx: rename existing clkctrl data as compat data Rename the existing clkctrl data in preparation of upcoming clkdm based split for it. Once the DT data has transitioned also, the compat data can be removed. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/Makefile | 3 +- drivers/clk/ti/clk-7xx-compat.c | 823 ++++++++++++++++++++++++++++++++ drivers/clk/ti/clk-7xx.c | 802 +------------------------------ drivers/clk/ti/clkctrl.c | 2 +- drivers/clk/ti/clock.h | 3 +- 5 files changed, 829 insertions(+), 804 deletions(-) create mode 100644 drivers/clk/ti/clk-7xx-compat.c diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index 5f2385d9a2e9..5ca1e39dd88a 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -17,7 +17,8 @@ obj-$(CONFIG_ARCH_OMAP4) += $(clk-common) clk-44xx.o \ obj-$(CONFIG_SOC_OMAP5) += $(clk-common) clk-54xx.o \ dpll3xxx.o dpll44xx.o obj-$(CONFIG_SOC_DRA7XX) += $(clk-common) clk-7xx.o \ - clk-dra7-atl.o dpll3xxx.o dpll44xx.o + clk-dra7-atl.o dpll3xxx.o \ + dpll44xx.o clk-7xx-compat.o obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o \ clk-43xx-compat.o diff --git a/drivers/clk/ti/clk-7xx-compat.c b/drivers/clk/ti/clk-7xx-compat.c new file mode 100644 index 000000000000..e3cb7f0b03ae --- /dev/null +++ b/drivers/clk/ti/clk-7xx-compat.c @@ -0,0 +1,823 @@ +/* + * DRA7 Clock init + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "clock.h" + +#define DRA7_DPLL_GMAC_DEFFREQ 1000000000 +#define DRA7_DPLL_USB_DEFFREQ 960000000 + +static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = { + { DRA7_MPU_CLKCTRL, NULL, 0, "dpll_mpu_m2_ck" }, + { 0 }, +}; + +static const char * const dra7_mcasp1_aux_gfclk_mux_parents[] __initconst = { + "per_abe_x1_gfclk2_div", + "video1_clk2_div", + "video2_clk2_div", + "hdmi_clk2_div", + NULL, +}; + +static const char * const dra7_mcasp1_ahclkx_mux_parents[] __initconst = { + "abe_24m_fclk", + "abe_sys_clk_div", + "func_24m_clk", + "atl_clkin3_ck", + "atl_clkin2_ck", + "atl_clkin1_ck", + "atl_clkin0_ck", + "sys_clkin2", + "ref_clkin0_ck", + "ref_clkin1_ck", + "ref_clkin2_ck", + "ref_clkin3_ck", + "mlb_clk", + "mlbp_clk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp1_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_timer5_gfclk_mux_parents[] __initconst = { + "timer_sys_clk_div", + "sys_32k_ck", + "sys_clkin2", + "ref_clkin0_ck", + "ref_clkin1_ck", + "ref_clkin2_ck", + "ref_clkin3_ck", + "abe_giclk_div", + "video1_div_clk", + "video2_div_clk", + "hdmi_div_clk", + "clkoutmux0_clk_mux", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_timer5_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer6_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer7_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer8_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_uart6_gfclk_mux_parents[] __initconst = { + "func_48m_fclk", + "dpll_per_m2x2_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_uart6_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = { + { DRA7_MCASP1_CLKCTRL, dra7_mcasp1_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0010:22" }, + { DRA7_TIMER5_CLKCTRL, dra7_timer5_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0018:24" }, + { DRA7_TIMER6_CLKCTRL, dra7_timer6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0020:24" }, + { DRA7_TIMER7_CLKCTRL, dra7_timer7_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0028:24" }, + { DRA7_TIMER8_CLKCTRL, dra7_timer8_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0030:24" }, + { DRA7_I2C5_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_UART6_CLKCTRL, dra7_uart6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0040:24" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst = { + { DRA7_RTCSS_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = { + { DRA7_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, + { DRA7_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initconst = { + { DRA7_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_TPCC_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_TPTC0_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_TPTC1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_VCP1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_VCP2_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_dma_clkctrl_regs[] __initconst = { + { DRA7_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_emif_clkctrl_regs[] __initconst = { + { DRA7_DMM_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const char * const dra7_atl_dpll_clk_mux_parents[] __initconst = { + "sys_32k_ck", + "video1_clkin_ck", + "video2_clkin_ck", + "hdmi_clkin_ck", + NULL, +}; + +static const char * const dra7_atl_gfclk_mux_parents[] __initconst = { + "l3_iclk_div", + "dpll_abe_m2_ck", + "atl_cm:clk:0000:24", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_atl_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_atl_dpll_clk_mux_parents, NULL }, + { 26, TI_CLK_MUX, dra7_atl_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_atl_clkctrl_regs[] __initconst = { + { DRA7_ATL_CLKCTRL, dra7_atl_bit_data, CLKF_SW_SUP, "atl_cm:clk:0000:26" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4cfg_clkctrl_regs[] __initconst = { + { DRA7_L4_CFG_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_SPINLOCK_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX2_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX3_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX4_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX5_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX6_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX7_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX8_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX9_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX10_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX11_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX12_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_MAILBOX13_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l3instr_clkctrl_regs[] __initconst = { + { DRA7_L3_MAIN_2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { 0 }, +}; + +static const char * const dra7_dss_dss_clk_parents[] __initconst = { + "dpll_per_h12x2_ck", + NULL, +}; + +static const char * const dra7_dss_48mhz_clk_parents[] __initconst = { + "func_48m_fclk", + NULL, +}; + +static const char * const dra7_dss_hdmi_clk_parents[] __initconst = { + "hdmi_dpll_clk_mux", + NULL, +}; + +static const char * const dra7_dss_32khz_clk_parents[] __initconst = { + "sys_32k_ck", + NULL, +}; + +static const char * const dra7_dss_video1_clk_parents[] __initconst = { + "video1_dpll_clk_mux", + NULL, +}; + +static const char * const dra7_dss_video2_clk_parents[] __initconst = { + "video2_dpll_clk_mux", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_dss_core_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_dss_clk_parents, NULL }, + { 9, TI_CLK_GATE, dra7_dss_48mhz_clk_parents, NULL }, + { 10, TI_CLK_GATE, dra7_dss_hdmi_clk_parents, NULL }, + { 11, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 12, TI_CLK_GATE, dra7_dss_video1_clk_parents, NULL }, + { 13, TI_CLK_GATE, dra7_dss_video2_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst = { + { DRA7_DSS_CORE_CLKCTRL, dra7_dss_core_bit_data, CLKF_SW_SUP, "dss_cm:clk:0000:8" }, + { DRA7_BB2D_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_h24x2_ck" }, + { 0 }, +}; + +static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = { + "func_128m_clk", + "dpll_per_m2x2_ck", + NULL, +}; + +static const char * const dra7_mmc1_fclk_div_parents[] __initconst = { + "l3init_cm:clk:0008:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc1_fclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc1_fclk_div_parents, &dra7_mmc1_fclk_div_data }, + { 0 }, +}; + +static const char * const dra7_mmc2_fclk_div_parents[] __initconst = { + "l3init_cm:clk:0010:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc2_fclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc2_fclk_div_parents, &dra7_mmc2_fclk_div_data }, + { 0 }, +}; + +static const char * const dra7_usb_otg_ss2_refclk960m_parents[] __initconst = { + "l3init_960m_gfclk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_usb_otg_ss2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_sata_ref_clk_parents[] __initconst = { + "sys_clkin1", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_sata_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_sata_ref_clk_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_optfclk_pciephy1_clk_parents[] __initconst = { + "apll_pcie_ck", + NULL, +}; + +static const char * const dra7_optfclk_pciephy1_div_clk_parents[] __initconst = { + "optfclk_pciephy_div", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_pcie1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL }, + { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_pcie2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL }, + { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_rmii_50mhz_clk_mux_parents[] __initconst = { + "dpll_gmac_h11x2_ck", + "rmii_clk_ck", + NULL, +}; + +static const char * const dra7_gmac_rft_clk_mux_parents[] __initconst = { + "video1_clkin_ck", + "video2_clkin_ck", + "dpll_abe_m2_ck", + "hdmi_clkin_ck", + "l3_iclk_div", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_rmii_50mhz_clk_mux_parents, NULL }, + { 25, TI_CLK_MUX, dra7_gmac_rft_clk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_usb_otg_ss1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst = { + { DRA7_MMC1_CLKCTRL, dra7_mmc1_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0008:25" }, + { DRA7_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" }, + { DRA7_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { DRA7_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { DRA7_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { DRA7_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" }, + { DRA7_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" }, + { DRA7_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck", "gmac_clkdm" }, + { DRA7_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, + { DRA7_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, + { DRA7_USB_OTG_SS1_CLKCTRL, dra7_usb_otg_ss1_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { 0 }, +}; + +static const char * const dra7_timer10_gfclk_mux_parents[] __initconst = { + "timer_sys_clk_div", + "sys_32k_ck", + "sys_clkin2", + "ref_clkin0_ck", + "ref_clkin1_ck", + "ref_clkin2_ck", + "ref_clkin3_ck", + "abe_giclk_div", + "video1_div_clk", + "video2_div_clk", + "hdmi_div_clk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_timer10_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer11_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer2_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer3_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer4_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer9_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio3_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio4_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio5_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio6_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer13_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer14_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer15_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio7_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio8_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_mmc3_gfclk_div_parents[] __initconst = { + "l4per_cm:clk:0120:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc3_gfclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc3_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc3_gfclk_div_parents, &dra7_mmc3_gfclk_div_data }, + { 0 }, +}; + +static const char * const dra7_mmc4_gfclk_div_parents[] __initconst = { + "l4per_cm:clk:0128:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc4_gfclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc4_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc4_gfclk_div_parents, &dra7_mmc4_gfclk_div_data }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer16_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_qspi_gfclk_mux_parents[] __initconst = { + "func_128m_clk", + "dpll_per_h13x2_ck", + NULL, +}; + +static const char * const dra7_qspi_gfclk_div_parents[] __initconst = { + "l4per_cm:clk:0138:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_qspi_gfclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_qspi_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_qspi_gfclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_qspi_gfclk_div_parents, &dra7_qspi_gfclk_div_data }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart2_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart3_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart4_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp2_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp3_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart5_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp5_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp8_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp4_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart7_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart8_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart9_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp6_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp7_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst = { + { DRA7_L4_PER2_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per2_clkdm" }, + { DRA7_L4_PER3_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per3_clkdm" }, + { DRA7_TIMER10_CLKCTRL, dra7_timer10_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0028:24" }, + { DRA7_TIMER11_CLKCTRL, dra7_timer11_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0030:24" }, + { DRA7_TIMER2_CLKCTRL, dra7_timer2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0038:24" }, + { DRA7_TIMER3_CLKCTRL, dra7_timer3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0040:24" }, + { DRA7_TIMER4_CLKCTRL, dra7_timer4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0048:24" }, + { DRA7_TIMER9_CLKCTRL, dra7_timer9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0050:24" }, + { DRA7_ELM_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_GPIO2_CLKCTRL, dra7_gpio2_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_GPIO3_CLKCTRL, dra7_gpio3_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_GPIO4_CLKCTRL, dra7_gpio4_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_GPIO5_CLKCTRL, dra7_gpio5_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_GPIO6_CLKCTRL, dra7_gpio6_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" }, + { DRA7_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" }, + { DRA7_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" }, + { DRA7_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_L4_PER1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" }, + { DRA7_TIMER13_CLKCTRL, dra7_timer13_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00c8:24", "l4per3_clkdm" }, + { DRA7_TIMER14_CLKCTRL, dra7_timer14_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d0:24", "l4per3_clkdm" }, + { DRA7_TIMER15_CLKCTRL, dra7_timer15_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d8:24", "l4per3_clkdm" }, + { DRA7_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_GPIO7_CLKCTRL, dra7_gpio7_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_GPIO8_CLKCTRL, dra7_gpio8_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_MMC3_CLKCTRL, dra7_mmc3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0120:25" }, + { DRA7_MMC4_CLKCTRL, dra7_mmc4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0128:25" }, + { DRA7_TIMER16_CLKCTRL, dra7_timer16_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0130:24", "l4per3_clkdm" }, + { DRA7_QSPI_CLKCTRL, dra7_qspi_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0138:25", "l4per2_clkdm" }, + { DRA7_UART1_CLKCTRL, dra7_uart1_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0140:24" }, + { DRA7_UART2_CLKCTRL, dra7_uart2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0148:24" }, + { DRA7_UART3_CLKCTRL, dra7_uart3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0150:24" }, + { DRA7_UART4_CLKCTRL, dra7_uart4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0158:24" }, + { DRA7_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0160:22", "l4per2_clkdm" }, + { DRA7_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0168:22", "l4per2_clkdm" }, + { DRA7_UART5_CLKCTRL, dra7_uart5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0170:24" }, + { DRA7_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0178:22", "l4per2_clkdm" }, + { DRA7_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0190:24", "l4per2_clkdm" }, + { DRA7_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0198:22", "l4per2_clkdm" }, + { DRA7_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, + { DRA7_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, + { DRA7_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, + { DRA7_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, + { DRA7_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, + { DRA7_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01d0:24", "l4per2_clkdm" }, + { DRA7_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e0:24", "l4per2_clkdm" }, + { DRA7_UART9_CLKCTRL, dra7_uart9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e8:24", "l4per2_clkdm" }, + { DRA7_DCAN2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin1", "l4per2_clkdm" }, + { DRA7_MCASP6_CLKCTRL, dra7_mcasp6_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0204:22", "l4per2_clkdm" }, + { DRA7_MCASP7_CLKCTRL, dra7_mcasp7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0208:22", "l4per2_clkdm" }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart10_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_dcan1_sys_clk_mux_parents[] __initconst = { + "sys_clkin1", + "sys_clkin2", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_dcan1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_dcan1_sys_clk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initconst = { + { DRA7_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, + { DRA7_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, + { DRA7_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" }, + { DRA7_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" }, + { DRA7_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" }, + { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, + { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" }, + { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" }, + { DRA7_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk"}, + { 0 }, +}; + +const struct omap_clkctrl_data dra7_clkctrl_compat_data[] __initconst = { + { 0x4a005320, dra7_mpu_clkctrl_regs }, + { 0x4a005540, dra7_ipu_clkctrl_regs }, + { 0x4a005740, dra7_rtc_clkctrl_regs }, + { 0x4a008620, dra7_coreaon_clkctrl_regs }, + { 0x4a008720, dra7_l3main1_clkctrl_regs }, + { 0x4a008a20, dra7_dma_clkctrl_regs }, + { 0x4a008b20, dra7_emif_clkctrl_regs }, + { 0x4a008c00, dra7_atl_clkctrl_regs }, + { 0x4a008d20, dra7_l4cfg_clkctrl_regs }, + { 0x4a008e20, dra7_l3instr_clkctrl_regs }, + { 0x4a009120, dra7_dss_clkctrl_regs }, + { 0x4a009320, dra7_l3init_clkctrl_regs }, + { 0x4a009700, dra7_l4per_clkctrl_regs }, + { 0x4ae07820, dra7_wkupaon_clkctrl_regs }, + { 0 }, +}; + +struct ti_dt_clk dra7xx_compat_clks[] = { + DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), + DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"), + DT_CLK(NULL, "sys_clkin", "sys_clkin1"), + DT_CLK(NULL, "atl_dpll_clk_mux", "atl_cm:0000:24"), + DT_CLK(NULL, "atl_gfclk_mux", "atl_cm:0000:26"), + DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon_cm:0068:24"), + DT_CLK(NULL, "dss_32khz_clk", "dss_cm:0000:11"), + DT_CLK(NULL, "dss_48mhz_clk", "dss_cm:0000:9"), + DT_CLK(NULL, "dss_dss_clk", "dss_cm:0000:8"), + DT_CLK(NULL, "dss_hdmi_clk", "dss_cm:0000:10"), + DT_CLK(NULL, "dss_video1_clk", "dss_cm:0000:12"), + DT_CLK(NULL, "dss_video2_clk", "dss_cm:0000:13"), + DT_CLK(NULL, "gmac_rft_clk_mux", "l3init_cm:00b0:25"), + DT_CLK(NULL, "gpio1_dbclk", "wkupaon_cm:0018:8"), + DT_CLK(NULL, "gpio2_dbclk", "l4per_cm:0060:8"), + DT_CLK(NULL, "gpio3_dbclk", "l4per_cm:0068:8"), + DT_CLK(NULL, "gpio4_dbclk", "l4per_cm:0070:8"), + DT_CLK(NULL, "gpio5_dbclk", "l4per_cm:0078:8"), + DT_CLK(NULL, "gpio6_dbclk", "l4per_cm:0080:8"), + DT_CLK(NULL, "gpio7_dbclk", "l4per_cm:0110:8"), + DT_CLK(NULL, "gpio8_dbclk", "l4per_cm:0118:8"), + DT_CLK(NULL, "mcasp1_ahclkr_mux", "ipu_cm:0010:28"), + DT_CLK(NULL, "mcasp1_ahclkx_mux", "ipu_cm:0010:24"), + DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "ipu_cm:0010:22"), + DT_CLK(NULL, "mcasp2_ahclkr_mux", "l4per_cm:0160:28"), + DT_CLK(NULL, "mcasp2_ahclkx_mux", "l4per_cm:0160:24"), + DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "l4per_cm:0160:22"), + DT_CLK(NULL, "mcasp3_ahclkx_mux", "l4per_cm:0168:24"), + DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "l4per_cm:0168:22"), + DT_CLK(NULL, "mcasp4_ahclkx_mux", "l4per_cm:0198:24"), + DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "l4per_cm:0198:22"), + DT_CLK(NULL, "mcasp5_ahclkx_mux", "l4per_cm:0178:24"), + DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "l4per_cm:0178:22"), + DT_CLK(NULL, "mcasp6_ahclkx_mux", "l4per_cm:0204:24"), + DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per_cm:0204:22"), + DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per_cm:0208:24"), + DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per_cm:0208:22"), + DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per_cm:0190:22"), + DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per_cm:0190:24"), + DT_CLK(NULL, "mmc1_clk32k", "l3init_cm:0008:8"), + DT_CLK(NULL, "mmc1_fclk_div", "l3init_cm:0008:25"), + DT_CLK(NULL, "mmc1_fclk_mux", "l3init_cm:0008:24"), + DT_CLK(NULL, "mmc2_clk32k", "l3init_cm:0010:8"), + DT_CLK(NULL, "mmc2_fclk_div", "l3init_cm:0010:25"), + DT_CLK(NULL, "mmc2_fclk_mux", "l3init_cm:0010:24"), + DT_CLK(NULL, "mmc3_clk32k", "l4per_cm:0120:8"), + DT_CLK(NULL, "mmc3_gfclk_div", "l4per_cm:0120:25"), + DT_CLK(NULL, "mmc3_gfclk_mux", "l4per_cm:0120:24"), + DT_CLK(NULL, "mmc4_clk32k", "l4per_cm:0128:8"), + DT_CLK(NULL, "mmc4_gfclk_div", "l4per_cm:0128:25"), + DT_CLK(NULL, "mmc4_gfclk_mux", "l4per_cm:0128:24"), + DT_CLK(NULL, "optfclk_pciephy1_32khz", "l3init_cm:0090:8"), + DT_CLK(NULL, "optfclk_pciephy1_clk", "l3init_cm:0090:9"), + DT_CLK(NULL, "optfclk_pciephy1_div_clk", "l3init_cm:0090:10"), + DT_CLK(NULL, "optfclk_pciephy2_32khz", "l3init_cm:0098:8"), + DT_CLK(NULL, "optfclk_pciephy2_clk", "l3init_cm:0098:9"), + DT_CLK(NULL, "optfclk_pciephy2_div_clk", "l3init_cm:0098:10"), + DT_CLK(NULL, "qspi_gfclk_div", "l4per_cm:0138:25"), + DT_CLK(NULL, "qspi_gfclk_mux", "l4per_cm:0138:24"), + DT_CLK(NULL, "rmii_50mhz_clk_mux", "l3init_cm:00b0:24"), + DT_CLK(NULL, "sata_ref_clk", "l3init_cm:0068:8"), + DT_CLK(NULL, "timer10_gfclk_mux", "l4per_cm:0028:24"), + DT_CLK(NULL, "timer11_gfclk_mux", "l4per_cm:0030:24"), + DT_CLK(NULL, "timer13_gfclk_mux", "l4per_cm:00c8:24"), + DT_CLK(NULL, "timer14_gfclk_mux", "l4per_cm:00d0:24"), + DT_CLK(NULL, "timer15_gfclk_mux", "l4per_cm:00d8:24"), + DT_CLK(NULL, "timer16_gfclk_mux", "l4per_cm:0130:24"), + DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon_cm:0020:24"), + DT_CLK(NULL, "timer2_gfclk_mux", "l4per_cm:0038:24"), + DT_CLK(NULL, "timer3_gfclk_mux", "l4per_cm:0040:24"), + DT_CLK(NULL, "timer4_gfclk_mux", "l4per_cm:0048:24"), + DT_CLK(NULL, "timer5_gfclk_mux", "ipu_cm:0018:24"), + DT_CLK(NULL, "timer6_gfclk_mux", "ipu_cm:0020:24"), + DT_CLK(NULL, "timer7_gfclk_mux", "ipu_cm:0028:24"), + DT_CLK(NULL, "timer8_gfclk_mux", "ipu_cm:0030:24"), + DT_CLK(NULL, "timer9_gfclk_mux", "l4per_cm:0050:24"), + DT_CLK(NULL, "uart10_gfclk_mux", "wkupaon_cm:0060:24"), + DT_CLK(NULL, "uart1_gfclk_mux", "l4per_cm:0140:24"), + DT_CLK(NULL, "uart2_gfclk_mux", "l4per_cm:0148:24"), + DT_CLK(NULL, "uart3_gfclk_mux", "l4per_cm:0150:24"), + DT_CLK(NULL, "uart4_gfclk_mux", "l4per_cm:0158:24"), + DT_CLK(NULL, "uart5_gfclk_mux", "l4per_cm:0170:24"), + DT_CLK(NULL, "uart6_gfclk_mux", "ipu_cm:0040:24"), + DT_CLK(NULL, "uart7_gfclk_mux", "l4per_cm:01d0:24"), + DT_CLK(NULL, "uart8_gfclk_mux", "l4per_cm:01e0:24"), + DT_CLK(NULL, "uart9_gfclk_mux", "l4per_cm:01e8:24"), + DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3init_cm:00d0:8"), + DT_CLK(NULL, "usb_otg_ss2_refclk960m", "l3init_cm:0020:8"), + { .node_name = NULL }, +}; diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index 71a122b2dc67..6f989f8b6881 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -22,812 +22,12 @@ #define DRA7_DPLL_GMAC_DEFFREQ 1000000000 #define DRA7_DPLL_USB_DEFFREQ 960000000 -static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = { - { DRA7_MPU_CLKCTRL, NULL, 0, "dpll_mpu_m2_ck" }, - { 0 }, -}; - -static const char * const dra7_mcasp1_aux_gfclk_mux_parents[] __initconst = { - "per_abe_x1_gfclk2_div", - "video1_clk2_div", - "video2_clk2_div", - "hdmi_clk2_div", - NULL, -}; - -static const char * const dra7_mcasp1_ahclkx_mux_parents[] __initconst = { - "abe_24m_fclk", - "abe_sys_clk_div", - "func_24m_clk", - "atl_clkin3_ck", - "atl_clkin2_ck", - "atl_clkin1_ck", - "atl_clkin0_ck", - "sys_clkin2", - "ref_clkin0_ck", - "ref_clkin1_ck", - "ref_clkin2_ck", - "ref_clkin3_ck", - "mlb_clk", - "mlbp_clk", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp1_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_timer5_gfclk_mux_parents[] __initconst = { - "timer_sys_clk_div", - "sys_32k_ck", - "sys_clkin2", - "ref_clkin0_ck", - "ref_clkin1_ck", - "ref_clkin2_ck", - "ref_clkin3_ck", - "abe_giclk_div", - "video1_div_clk", - "video2_div_clk", - "hdmi_div_clk", - "clkoutmux0_clk_mux", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_timer5_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer6_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer7_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer8_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_uart6_gfclk_mux_parents[] __initconst = { - "func_48m_fclk", - "dpll_per_m2x2_ck", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_uart6_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = { - { DRA7_MCASP1_CLKCTRL, dra7_mcasp1_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0010:22" }, - { DRA7_TIMER5_CLKCTRL, dra7_timer5_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0018:24" }, - { DRA7_TIMER6_CLKCTRL, dra7_timer6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0020:24" }, - { DRA7_TIMER7_CLKCTRL, dra7_timer7_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0028:24" }, - { DRA7_TIMER8_CLKCTRL, dra7_timer8_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0030:24" }, - { DRA7_I2C5_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { DRA7_UART6_CLKCTRL, dra7_uart6_bit_data, CLKF_SW_SUP, "ipu_cm:clk:0040:24" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst = { - { DRA7_RTCSS_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = { - { DRA7_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, - { DRA7_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initconst = { - { DRA7_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_TPCC_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_TPTC0_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_TPTC1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_VCP1_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_VCP2_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_dma_clkctrl_regs[] __initconst = { - { DRA7_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_emif_clkctrl_regs[] __initconst = { - { DRA7_DMM_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { 0 }, -}; - -static const char * const dra7_atl_dpll_clk_mux_parents[] __initconst = { - "sys_32k_ck", - "video1_clkin_ck", - "video2_clkin_ck", - "hdmi_clkin_ck", - NULL, -}; - -static const char * const dra7_atl_gfclk_mux_parents[] __initconst = { - "l3_iclk_div", - "dpll_abe_m2_ck", - "atl_cm:clk:0000:24", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_atl_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_atl_dpll_clk_mux_parents, NULL }, - { 26, TI_CLK_MUX, dra7_atl_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_atl_clkctrl_regs[] __initconst = { - { DRA7_ATL_CLKCTRL, dra7_atl_bit_data, CLKF_SW_SUP, "atl_cm:clk:0000:26" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_l4cfg_clkctrl_regs[] __initconst = { - { DRA7_L4_CFG_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_SPINLOCK_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX1_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX2_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX3_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX4_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX5_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX6_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX7_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX8_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX9_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX10_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX11_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX12_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_MAILBOX13_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_l3instr_clkctrl_regs[] __initconst = { - { DRA7_L3_MAIN_2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, - { 0 }, -}; - -static const char * const dra7_dss_dss_clk_parents[] __initconst = { - "dpll_per_h12x2_ck", - NULL, -}; - -static const char * const dra7_dss_48mhz_clk_parents[] __initconst = { - "func_48m_fclk", - NULL, -}; - -static const char * const dra7_dss_hdmi_clk_parents[] __initconst = { - "hdmi_dpll_clk_mux", - NULL, -}; - -static const char * const dra7_dss_32khz_clk_parents[] __initconst = { - "sys_32k_ck", - NULL, -}; - -static const char * const dra7_dss_video1_clk_parents[] __initconst = { - "video1_dpll_clk_mux", - NULL, -}; - -static const char * const dra7_dss_video2_clk_parents[] __initconst = { - "video2_dpll_clk_mux", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_dss_core_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_dss_clk_parents, NULL }, - { 9, TI_CLK_GATE, dra7_dss_48mhz_clk_parents, NULL }, - { 10, TI_CLK_GATE, dra7_dss_hdmi_clk_parents, NULL }, - { 11, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 12, TI_CLK_GATE, dra7_dss_video1_clk_parents, NULL }, - { 13, TI_CLK_GATE, dra7_dss_video2_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst = { - { DRA7_DSS_CORE_CLKCTRL, dra7_dss_core_bit_data, CLKF_SW_SUP, "dss_cm:clk:0000:8" }, - { DRA7_BB2D_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_h24x2_ck" }, - { 0 }, -}; - -static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = { - "func_128m_clk", - "dpll_per_m2x2_ck", - NULL, -}; - -static const char * const dra7_mmc1_fclk_div_parents[] __initconst = { - "l3init_cm:clk:0008:24", - NULL, -}; - -static const struct omap_clkctrl_div_data dra7_mmc1_fclk_div_data __initconst = { - .max_div = 4, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const struct omap_clkctrl_bit_data dra7_mmc1_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL }, - { 25, TI_CLK_DIVIDER, dra7_mmc1_fclk_div_parents, &dra7_mmc1_fclk_div_data }, - { 0 }, -}; - -static const char * const dra7_mmc2_fclk_div_parents[] __initconst = { - "l3init_cm:clk:0010:24", - NULL, -}; - -static const struct omap_clkctrl_div_data dra7_mmc2_fclk_div_data __initconst = { - .max_div = 4, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const struct omap_clkctrl_bit_data dra7_mmc2_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL }, - { 25, TI_CLK_DIVIDER, dra7_mmc2_fclk_div_parents, &dra7_mmc2_fclk_div_data }, - { 0 }, -}; - -static const char * const dra7_usb_otg_ss2_refclk960m_parents[] __initconst = { - "l3init_960m_gfclk", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_usb_otg_ss2_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_sata_ref_clk_parents[] __initconst = { - "sys_clkin1", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_sata_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_sata_ref_clk_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_optfclk_pciephy1_clk_parents[] __initconst = { - "apll_pcie_ck", - NULL, -}; - -static const char * const dra7_optfclk_pciephy1_div_clk_parents[] __initconst = { - "optfclk_pciephy_div", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_pcie1_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL }, - { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_pcie2_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL }, - { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_rmii_50mhz_clk_mux_parents[] __initconst = { - "dpll_gmac_h11x2_ck", - "rmii_clk_ck", - NULL, -}; - -static const char * const dra7_gmac_rft_clk_mux_parents[] __initconst = { - "video1_clkin_ck", - "video2_clkin_ck", - "dpll_abe_m2_ck", - "hdmi_clkin_ck", - "l3_iclk_div", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_rmii_50mhz_clk_mux_parents, NULL }, - { 25, TI_CLK_MUX, dra7_gmac_rft_clk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_usb_otg_ss1_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst = { - { DRA7_MMC1_CLKCTRL, dra7_mmc1_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0008:25" }, - { DRA7_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init_cm:clk:0010:25" }, - { DRA7_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, - { DRA7_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, - { DRA7_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, - { DRA7_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" }, - { DRA7_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" }, - { DRA7_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div", "pcie_clkdm" }, - { DRA7_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck", "gmac_clkdm" }, - { DRA7_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, - { DRA7_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, - { DRA7_USB_OTG_SS1_CLKCTRL, dra7_usb_otg_ss1_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, - { 0 }, -}; - -static const char * const dra7_timer10_gfclk_mux_parents[] __initconst = { - "timer_sys_clk_div", - "sys_32k_ck", - "sys_clkin2", - "ref_clkin0_ck", - "ref_clkin1_ck", - "ref_clkin2_ck", - "ref_clkin3_ck", - "abe_giclk_div", - "video1_div_clk", - "video2_div_clk", - "hdmi_div_clk", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_timer10_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer11_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer2_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer3_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer4_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer9_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio2_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio3_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio4_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio5_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio6_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer13_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer14_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer15_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio7_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio8_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_mmc3_gfclk_div_parents[] __initconst = { - "l4per_cm:clk:0120:24", - NULL, -}; - -static const struct omap_clkctrl_div_data dra7_mmc3_gfclk_div_data __initconst = { - .max_div = 4, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const struct omap_clkctrl_bit_data dra7_mmc3_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 25, TI_CLK_DIVIDER, dra7_mmc3_gfclk_div_parents, &dra7_mmc3_gfclk_div_data }, - { 0 }, -}; - -static const char * const dra7_mmc4_gfclk_div_parents[] __initconst = { - "l4per_cm:clk:0128:24", - NULL, -}; - -static const struct omap_clkctrl_div_data dra7_mmc4_gfclk_div_data __initconst = { - .max_div = 4, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const struct omap_clkctrl_bit_data dra7_mmc4_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 25, TI_CLK_DIVIDER, dra7_mmc4_gfclk_div_parents, &dra7_mmc4_gfclk_div_data }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer16_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_qspi_gfclk_mux_parents[] __initconst = { - "func_128m_clk", - "dpll_per_h13x2_ck", - NULL, -}; - -static const char * const dra7_qspi_gfclk_div_parents[] __initconst = { - "l4per_cm:clk:0138:24", - NULL, -}; - -static const struct omap_clkctrl_div_data dra7_qspi_gfclk_div_data __initconst = { - .max_div = 4, - .flags = CLK_DIVIDER_POWER_OF_TWO, -}; - -static const struct omap_clkctrl_bit_data dra7_qspi_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_qspi_gfclk_mux_parents, NULL }, - { 25, TI_CLK_DIVIDER, dra7_qspi_gfclk_div_parents, &dra7_qspi_gfclk_div_data }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart1_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart2_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart3_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart4_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp2_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp3_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart5_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp5_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp8_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp4_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart7_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart8_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart9_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp6_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_mcasp7_bit_data[] __initconst = { - { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, - { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst = { - { DRA7_L4_PER2_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per2_clkdm" }, - { DRA7_L4_PER3_CLKCTRL, NULL, 0, "l3_iclk_div", "l4per3_clkdm" }, - { DRA7_TIMER10_CLKCTRL, dra7_timer10_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0028:24" }, - { DRA7_TIMER11_CLKCTRL, dra7_timer11_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0030:24" }, - { DRA7_TIMER2_CLKCTRL, dra7_timer2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0038:24" }, - { DRA7_TIMER3_CLKCTRL, dra7_timer3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0040:24" }, - { DRA7_TIMER4_CLKCTRL, dra7_timer4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0048:24" }, - { DRA7_TIMER9_CLKCTRL, dra7_timer9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0050:24" }, - { DRA7_ELM_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_GPIO2_CLKCTRL, dra7_gpio2_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_GPIO3_CLKCTRL, dra7_gpio3_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_GPIO4_CLKCTRL, dra7_gpio4_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_GPIO5_CLKCTRL, dra7_gpio5_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_GPIO6_CLKCTRL, dra7_gpio6_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" }, - { DRA7_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" }, - { DRA7_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" }, - { DRA7_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { DRA7_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { DRA7_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { DRA7_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, - { DRA7_L4_PER1_CLKCTRL, NULL, 0, "l3_iclk_div" }, - { DRA7_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div", "l4per2_clkdm" }, - { DRA7_TIMER13_CLKCTRL, dra7_timer13_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00c8:24", "l4per3_clkdm" }, - { DRA7_TIMER14_CLKCTRL, dra7_timer14_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d0:24", "l4per3_clkdm" }, - { DRA7_TIMER15_CLKCTRL, dra7_timer15_bit_data, CLKF_SW_SUP, "l4per_cm:clk:00d8:24", "l4per3_clkdm" }, - { DRA7_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { DRA7_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { DRA7_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { DRA7_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, - { DRA7_GPIO7_CLKCTRL, dra7_gpio7_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_GPIO8_CLKCTRL, dra7_gpio8_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, - { DRA7_MMC3_CLKCTRL, dra7_mmc3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0120:25" }, - { DRA7_MMC4_CLKCTRL, dra7_mmc4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0128:25" }, - { DRA7_TIMER16_CLKCTRL, dra7_timer16_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0130:24", "l4per3_clkdm" }, - { DRA7_QSPI_CLKCTRL, dra7_qspi_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0138:25", "l4per2_clkdm" }, - { DRA7_UART1_CLKCTRL, dra7_uart1_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0140:24" }, - { DRA7_UART2_CLKCTRL, dra7_uart2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0148:24" }, - { DRA7_UART3_CLKCTRL, dra7_uart3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0150:24" }, - { DRA7_UART4_CLKCTRL, dra7_uart4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0158:24" }, - { DRA7_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0160:22", "l4per2_clkdm" }, - { DRA7_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0168:22", "l4per2_clkdm" }, - { DRA7_UART5_CLKCTRL, dra7_uart5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0170:24" }, - { DRA7_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0178:22", "l4per2_clkdm" }, - { DRA7_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0190:24", "l4per2_clkdm" }, - { DRA7_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0198:22", "l4per2_clkdm" }, - { DRA7_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, - { DRA7_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, - { DRA7_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, - { DRA7_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, - { DRA7_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div", "l4sec_clkdm" }, - { DRA7_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01d0:24", "l4per2_clkdm" }, - { DRA7_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e0:24", "l4per2_clkdm" }, - { DRA7_UART9_CLKCTRL, dra7_uart9_bit_data, CLKF_SW_SUP, "l4per_cm:clk:01e8:24", "l4per2_clkdm" }, - { DRA7_DCAN2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin1", "l4per2_clkdm" }, - { DRA7_MCASP6_CLKCTRL, dra7_mcasp6_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0204:22", "l4per2_clkdm" }, - { DRA7_MCASP7_CLKCTRL, dra7_mcasp7_bit_data, CLKF_SW_SUP, "l4per_cm:clk:0208:22", "l4per2_clkdm" }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_gpio1_bit_data[] __initconst = { - { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_timer1_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_bit_data dra7_uart10_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, - { 0 }, -}; - -static const char * const dra7_dcan1_sys_clk_mux_parents[] __initconst = { - "sys_clkin1", - "sys_clkin2", - NULL, -}; - -static const struct omap_clkctrl_bit_data dra7_dcan1_bit_data[] __initconst = { - { 24, TI_CLK_MUX, dra7_dcan1_sys_clk_mux_parents, NULL }, - { 0 }, -}; - -static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initconst = { - { DRA7_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, - { DRA7_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, - { DRA7_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" }, - { DRA7_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0020:24" }, - { DRA7_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" }, - { DRA7_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, - { DRA7_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0060:24" }, - { DRA7_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon_cm:clk:0068:24" }, - { DRA7_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk"}, - { 0 }, -}; - -const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = { - { 0x4a005320, dra7_mpu_clkctrl_regs }, - { 0x4a005540, dra7_ipu_clkctrl_regs }, - { 0x4a005740, dra7_rtc_clkctrl_regs }, - { 0x4a008620, dra7_coreaon_clkctrl_regs }, - { 0x4a008720, dra7_l3main1_clkctrl_regs }, - { 0x4a008a20, dra7_dma_clkctrl_regs }, - { 0x4a008b20, dra7_emif_clkctrl_regs }, - { 0x4a008c00, dra7_atl_clkctrl_regs }, - { 0x4a008d20, dra7_l4cfg_clkctrl_regs }, - { 0x4a008e20, dra7_l3instr_clkctrl_regs }, - { 0x4a009120, dra7_dss_clkctrl_regs }, - { 0x4a009320, dra7_l3init_clkctrl_regs }, - { 0x4a009700, dra7_l4per_clkctrl_regs }, - { 0x4ae07820, dra7_wkupaon_clkctrl_regs }, - { 0 }, -}; - -static struct ti_dt_clk dra7xx_clks[] = { - DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), - DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"), - DT_CLK(NULL, "sys_clkin", "sys_clkin1"), - DT_CLK(NULL, "atl_dpll_clk_mux", "atl_cm:0000:24"), - DT_CLK(NULL, "atl_gfclk_mux", "atl_cm:0000:26"), - DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon_cm:0068:24"), - DT_CLK(NULL, "dss_32khz_clk", "dss_cm:0000:11"), - DT_CLK(NULL, "dss_48mhz_clk", "dss_cm:0000:9"), - DT_CLK(NULL, "dss_dss_clk", "dss_cm:0000:8"), - DT_CLK(NULL, "dss_hdmi_clk", "dss_cm:0000:10"), - DT_CLK(NULL, "dss_video1_clk", "dss_cm:0000:12"), - DT_CLK(NULL, "dss_video2_clk", "dss_cm:0000:13"), - DT_CLK(NULL, "gmac_rft_clk_mux", "l3init_cm:00b0:25"), - DT_CLK(NULL, "gpio1_dbclk", "wkupaon_cm:0018:8"), - DT_CLK(NULL, "gpio2_dbclk", "l4per_cm:0060:8"), - DT_CLK(NULL, "gpio3_dbclk", "l4per_cm:0068:8"), - DT_CLK(NULL, "gpio4_dbclk", "l4per_cm:0070:8"), - DT_CLK(NULL, "gpio5_dbclk", "l4per_cm:0078:8"), - DT_CLK(NULL, "gpio6_dbclk", "l4per_cm:0080:8"), - DT_CLK(NULL, "gpio7_dbclk", "l4per_cm:0110:8"), - DT_CLK(NULL, "gpio8_dbclk", "l4per_cm:0118:8"), - DT_CLK(NULL, "mcasp1_ahclkr_mux", "ipu_cm:0010:28"), - DT_CLK(NULL, "mcasp1_ahclkx_mux", "ipu_cm:0010:24"), - DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "ipu_cm:0010:22"), - DT_CLK(NULL, "mcasp2_ahclkr_mux", "l4per_cm:0160:28"), - DT_CLK(NULL, "mcasp2_ahclkx_mux", "l4per_cm:0160:24"), - DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "l4per_cm:0160:22"), - DT_CLK(NULL, "mcasp3_ahclkx_mux", "l4per_cm:0168:24"), - DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "l4per_cm:0168:22"), - DT_CLK(NULL, "mcasp4_ahclkx_mux", "l4per_cm:0198:24"), - DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "l4per_cm:0198:22"), - DT_CLK(NULL, "mcasp5_ahclkx_mux", "l4per_cm:0178:24"), - DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "l4per_cm:0178:22"), - DT_CLK(NULL, "mcasp6_ahclkx_mux", "l4per_cm:0204:24"), - DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per_cm:0204:22"), - DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per_cm:0208:24"), - DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per_cm:0208:22"), - DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per_cm:0190:22"), - DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per_cm:0190:24"), - DT_CLK(NULL, "mmc1_clk32k", "l3init_cm:0008:8"), - DT_CLK(NULL, "mmc1_fclk_div", "l3init_cm:0008:25"), - DT_CLK(NULL, "mmc1_fclk_mux", "l3init_cm:0008:24"), - DT_CLK(NULL, "mmc2_clk32k", "l3init_cm:0010:8"), - DT_CLK(NULL, "mmc2_fclk_div", "l3init_cm:0010:25"), - DT_CLK(NULL, "mmc2_fclk_mux", "l3init_cm:0010:24"), - DT_CLK(NULL, "mmc3_clk32k", "l4per_cm:0120:8"), - DT_CLK(NULL, "mmc3_gfclk_div", "l4per_cm:0120:25"), - DT_CLK(NULL, "mmc3_gfclk_mux", "l4per_cm:0120:24"), - DT_CLK(NULL, "mmc4_clk32k", "l4per_cm:0128:8"), - DT_CLK(NULL, "mmc4_gfclk_div", "l4per_cm:0128:25"), - DT_CLK(NULL, "mmc4_gfclk_mux", "l4per_cm:0128:24"), - DT_CLK(NULL, "optfclk_pciephy1_32khz", "l3init_cm:0090:8"), - DT_CLK(NULL, "optfclk_pciephy1_clk", "l3init_cm:0090:9"), - DT_CLK(NULL, "optfclk_pciephy1_div_clk", "l3init_cm:0090:10"), - DT_CLK(NULL, "optfclk_pciephy2_32khz", "l3init_cm:0098:8"), - DT_CLK(NULL, "optfclk_pciephy2_clk", "l3init_cm:0098:9"), - DT_CLK(NULL, "optfclk_pciephy2_div_clk", "l3init_cm:0098:10"), - DT_CLK(NULL, "qspi_gfclk_div", "l4per_cm:0138:25"), - DT_CLK(NULL, "qspi_gfclk_mux", "l4per_cm:0138:24"), - DT_CLK(NULL, "rmii_50mhz_clk_mux", "l3init_cm:00b0:24"), - DT_CLK(NULL, "sata_ref_clk", "l3init_cm:0068:8"), - DT_CLK(NULL, "timer10_gfclk_mux", "l4per_cm:0028:24"), - DT_CLK(NULL, "timer11_gfclk_mux", "l4per_cm:0030:24"), - DT_CLK(NULL, "timer13_gfclk_mux", "l4per_cm:00c8:24"), - DT_CLK(NULL, "timer14_gfclk_mux", "l4per_cm:00d0:24"), - DT_CLK(NULL, "timer15_gfclk_mux", "l4per_cm:00d8:24"), - DT_CLK(NULL, "timer16_gfclk_mux", "l4per_cm:0130:24"), - DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon_cm:0020:24"), - DT_CLK(NULL, "timer2_gfclk_mux", "l4per_cm:0038:24"), - DT_CLK(NULL, "timer3_gfclk_mux", "l4per_cm:0040:24"), - DT_CLK(NULL, "timer4_gfclk_mux", "l4per_cm:0048:24"), - DT_CLK(NULL, "timer5_gfclk_mux", "ipu_cm:0018:24"), - DT_CLK(NULL, "timer6_gfclk_mux", "ipu_cm:0020:24"), - DT_CLK(NULL, "timer7_gfclk_mux", "ipu_cm:0028:24"), - DT_CLK(NULL, "timer8_gfclk_mux", "ipu_cm:0030:24"), - DT_CLK(NULL, "timer9_gfclk_mux", "l4per_cm:0050:24"), - DT_CLK(NULL, "uart10_gfclk_mux", "wkupaon_cm:0060:24"), - DT_CLK(NULL, "uart1_gfclk_mux", "l4per_cm:0140:24"), - DT_CLK(NULL, "uart2_gfclk_mux", "l4per_cm:0148:24"), - DT_CLK(NULL, "uart3_gfclk_mux", "l4per_cm:0150:24"), - DT_CLK(NULL, "uart4_gfclk_mux", "l4per_cm:0158:24"), - DT_CLK(NULL, "uart5_gfclk_mux", "l4per_cm:0170:24"), - DT_CLK(NULL, "uart6_gfclk_mux", "ipu_cm:0040:24"), - DT_CLK(NULL, "uart7_gfclk_mux", "l4per_cm:01d0:24"), - DT_CLK(NULL, "uart8_gfclk_mux", "l4per_cm:01e0:24"), - DT_CLK(NULL, "uart9_gfclk_mux", "l4per_cm:01e8:24"), - DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3init_cm:00d0:8"), - DT_CLK(NULL, "usb_otg_ss2_refclk960m", "l3init_cm:0020:8"), - { .node_name = NULL }, -}; - int __init dra7xx_dt_clk_init(void) { int rc; struct clk *dpll_ck, *hdcp_ck; - ti_dt_clocks_register(dra7xx_clks); + ti_dt_clocks_register(dra7xx_compat_clks); omap2_clk_disable_autoidle_all(); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 6fe10a9f3116..c1fbb3d20155 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -464,7 +464,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) #endif #ifdef CONFIG_SOC_DRA7XX if (of_machine_is_compatible("ti,dra7")) - data = dra7_clkctrl_data; + data = dra7_clkctrl_compat_data; #endif #ifdef CONFIG_SOC_AM33XX if (of_machine_is_compatible("ti,am33xx")) { diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index 11348de507fc..c729f87c4feb 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -183,7 +183,8 @@ struct omap_clkctrl_data { extern const struct omap_clkctrl_data omap4_clkctrl_data[]; extern const struct omap_clkctrl_data omap5_clkctrl_data[]; -extern const struct omap_clkctrl_data dra7_clkctrl_data[]; +extern const struct omap_clkctrl_data dra7_clkctrl_compat_data[]; +extern struct ti_dt_clk dra7xx_compat_clks[]; extern const struct omap_clkctrl_data am3_clkctrl_data[]; extern const struct omap_clkctrl_data am3_clkctrl_compat_data[]; extern struct ti_dt_clk am33xx_compat_clks[]; From dffa9051d54672a7d7f5951e074c4393672c03e9 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 13 Aug 2018 14:30:49 +0300 Subject: [PATCH 203/836] clk: ti: dra7: add new clkctrl data The new clkctrl data layout for dra7xx is split based on clockdomain boundaries. Previously the split was based on CM boundaries. This patch adds the new data as separate data entity, retaining the compatibility data also for now. The compatibility data can be removed once no longer needed. Signed-off-by: Tero Kristo Tested-by: Tony Lindgren --- drivers/clk/ti/clk-7xx.c | 868 ++++++++++++++++++++++++++++++++++++++- drivers/clk/ti/clkctrl.c | 8 +- drivers/clk/ti/clock.h | 1 + 3 files changed, 874 insertions(+), 3 deletions(-) diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index 6f989f8b6881..597fb4a59318 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -22,12 +22,878 @@ #define DRA7_DPLL_GMAC_DEFFREQ 1000000000 #define DRA7_DPLL_USB_DEFFREQ 960000000 +static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst = { + { DRA7_MPU_MPU_CLKCTRL, NULL, 0, "dpll_mpu_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_dsp1_clkctrl_regs[] __initconst = { + { DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" }, + { 0 }, +}; + +static const char * const dra7_ipu1_gfclk_mux_parents[] __initconst = { + "dpll_abe_m2x2_ck", + "dpll_core_h22x2_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_mmu_ipu1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_ipu1_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_ipu1_clkctrl_regs[] __initconst = { + { DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP, "ipu1-clkctrl:0000:24" }, + { 0 }, +}; + +static const char * const dra7_mcasp1_aux_gfclk_mux_parents[] __initconst = { + "per_abe_x1_gfclk2_div", + "video1_clk2_div", + "video2_clk2_div", + "hdmi_clk2_div", + NULL, +}; + +static const char * const dra7_mcasp1_ahclkx_mux_parents[] __initconst = { + "abe_24m_fclk", + "abe_sys_clk_div", + "func_24m_clk", + "atl_clkin3_ck", + "atl_clkin2_ck", + "atl_clkin1_ck", + "atl_clkin0_ck", + "sys_clkin2", + "ref_clkin0_ck", + "ref_clkin1_ck", + "ref_clkin2_ck", + "ref_clkin3_ck", + "mlb_clk", + "mlbp_clk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp1_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_timer5_gfclk_mux_parents[] __initconst = { + "timer_sys_clk_div", + "sys_32k_ck", + "sys_clkin2", + "ref_clkin0_ck", + "ref_clkin1_ck", + "ref_clkin2_ck", + "ref_clkin3_ck", + "abe_giclk_div", + "video1_div_clk", + "video2_div_clk", + "hdmi_div_clk", + "clkoutmux0_clk_mux", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_timer5_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer6_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer7_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer8_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer5_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_uart6_gfclk_mux_parents[] __initconst = { + "func_48m_fclk", + "dpll_per_m2x2_ck", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_uart6_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst = { + { DRA7_IPU_MCASP1_CLKCTRL, dra7_mcasp1_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0000:22" }, + { DRA7_IPU_TIMER5_CLKCTRL, dra7_timer5_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0008:24" }, + { DRA7_IPU_TIMER6_CLKCTRL, dra7_timer6_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0010:24" }, + { DRA7_IPU_TIMER7_CLKCTRL, dra7_timer7_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0018:24" }, + { DRA7_IPU_TIMER8_CLKCTRL, dra7_timer8_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0020:24" }, + { DRA7_IPU_I2C5_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_IPU_UART6_CLKCTRL, dra7_uart6_bit_data, CLKF_SW_SUP, "ipu-clkctrl:0030:24" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_dsp2_clkctrl_regs[] __initconst = { + { DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst = { + { DRA7_RTC_RTCSS_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = { + { DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, + { DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initconst = { + { DRA7_L3MAIN1_L3_MAIN_1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L3MAIN1_GPMC_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L3MAIN1_TPCC_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L3MAIN1_TPTC0_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L3MAIN1_TPTC1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L3MAIN1_VCP1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L3MAIN1_VCP2_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_ipu2_clkctrl_regs[] __initconst = { + { DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_dma_clkctrl_regs[] __initconst = { + { DRA7_DMA_DMA_SYSTEM_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_emif_clkctrl_regs[] __initconst = { + { DRA7_EMIF_DMM_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const char * const dra7_atl_dpll_clk_mux_parents[] __initconst = { + "sys_32k_ck", + "video1_clkin_ck", + "video2_clkin_ck", + "hdmi_clkin_ck", + NULL, +}; + +static const char * const dra7_atl_gfclk_mux_parents[] __initconst = { + "l3_iclk_div", + "dpll_abe_m2_ck", + "atl-clkctrl:0000:24", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_atl_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_atl_dpll_clk_mux_parents, NULL }, + { 26, TI_CLK_MUX, dra7_atl_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_atl_clkctrl_regs[] __initconst = { + { DRA7_ATL_ATL_CLKCTRL, dra7_atl_bit_data, CLKF_SW_SUP, "atl-clkctrl:0000:26" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4cfg_clkctrl_regs[] __initconst = { + { DRA7_L4CFG_L4_CFG_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_SPINLOCK_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX2_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX3_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX4_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX5_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX6_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX7_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX8_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX9_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX10_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX11_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX12_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4CFG_MAILBOX13_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l3instr_clkctrl_regs[] __initconst = { + { DRA7_L3INSTR_L3_MAIN_2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L3INSTR_L3_INSTR_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { 0 }, +}; + +static const char * const dra7_dss_dss_clk_parents[] __initconst = { + "dpll_per_h12x2_ck", + NULL, +}; + +static const char * const dra7_dss_48mhz_clk_parents[] __initconst = { + "func_48m_fclk", + NULL, +}; + +static const char * const dra7_dss_hdmi_clk_parents[] __initconst = { + "hdmi_dpll_clk_mux", + NULL, +}; + +static const char * const dra7_dss_32khz_clk_parents[] __initconst = { + "sys_32k_ck", + NULL, +}; + +static const char * const dra7_dss_video1_clk_parents[] __initconst = { + "video1_dpll_clk_mux", + NULL, +}; + +static const char * const dra7_dss_video2_clk_parents[] __initconst = { + "video2_dpll_clk_mux", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_dss_core_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_dss_clk_parents, NULL }, + { 9, TI_CLK_GATE, dra7_dss_48mhz_clk_parents, NULL }, + { 10, TI_CLK_GATE, dra7_dss_hdmi_clk_parents, NULL }, + { 11, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 12, TI_CLK_GATE, dra7_dss_video1_clk_parents, NULL }, + { 13, TI_CLK_GATE, dra7_dss_video2_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst = { + { DRA7_DSS_DSS_CORE_CLKCTRL, dra7_dss_core_bit_data, CLKF_SW_SUP, "dss-clkctrl:0000:8" }, + { DRA7_DSS_BB2D_CLKCTRL, NULL, CLKF_SW_SUP, "dpll_core_h24x2_ck" }, + { 0 }, +}; + +static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = { + "func_128m_clk", + "dpll_per_m2x2_ck", + NULL, +}; + +static const char * const dra7_mmc1_fclk_div_parents[] __initconst = { + "l3init-clkctrl:0008:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc1_fclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc1_fclk_div_parents, &dra7_mmc1_fclk_div_data }, + { 0 }, +}; + +static const char * const dra7_mmc2_fclk_div_parents[] __initconst = { + "l3init-clkctrl:0010:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc2_fclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mmc1_fclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc2_fclk_div_parents, &dra7_mmc2_fclk_div_data }, + { 0 }, +}; + +static const char * const dra7_usb_otg_ss2_refclk960m_parents[] __initconst = { + "l3init_960m_gfclk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_usb_otg_ss2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_sata_ref_clk_parents[] __initconst = { + "sys_clkin1", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_sata_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_sata_ref_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_usb_otg_ss1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_usb_otg_ss2_refclk960m_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l3init_clkctrl_regs[] __initconst = { + { DRA7_L3INIT_MMC1_CLKCTRL, dra7_mmc1_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0008:25" }, + { DRA7_L3INIT_MMC2_CLKCTRL, dra7_mmc2_bit_data, CLKF_SW_SUP, "l3init-clkctrl:0010:25" }, + { DRA7_L3INIT_USB_OTG_SS2_CLKCTRL, dra7_usb_otg_ss2_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { DRA7_L3INIT_USB_OTG_SS3_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { DRA7_L3INIT_USB_OTG_SS4_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { DRA7_L3INIT_SATA_CLKCTRL, dra7_sata_bit_data, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_L3INIT_OCP2SCP1_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, + { DRA7_L3INIT_OCP2SCP3_CLKCTRL, NULL, CLKF_HW_SUP, "l4_root_clk_div" }, + { DRA7_L3INIT_USB_OTG_SS1_CLKCTRL, dra7_usb_otg_ss1_bit_data, CLKF_HW_SUP, "dpll_core_h13x2_ck" }, + { 0 }, +}; + +static const char * const dra7_optfclk_pciephy1_clk_parents[] __initconst = { + "apll_pcie_ck", + NULL, +}; + +static const char * const dra7_optfclk_pciephy1_div_clk_parents[] __initconst = { + "optfclk_pciephy_div", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_pcie1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL }, + { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_pcie2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 9, TI_CLK_GATE, dra7_optfclk_pciephy1_clk_parents, NULL }, + { 10, TI_CLK_GATE, dra7_optfclk_pciephy1_div_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_pcie_clkctrl_regs[] __initconst = { + { DRA7_PCIE_PCIE1_CLKCTRL, dra7_pcie1_bit_data, CLKF_SW_SUP, "l4_root_clk_div" }, + { DRA7_PCIE_PCIE2_CLKCTRL, dra7_pcie2_bit_data, CLKF_SW_SUP, "l4_root_clk_div" }, + { 0 }, +}; + +static const char * const dra7_rmii_50mhz_clk_mux_parents[] __initconst = { + "dpll_gmac_h11x2_ck", + "rmii_clk_ck", + NULL, +}; + +static const char * const dra7_gmac_rft_clk_mux_parents[] __initconst = { + "video1_clkin_ck", + "video2_clkin_ck", + "dpll_abe_m2_ck", + "hdmi_clkin_ck", + "l3_iclk_div", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_rmii_50mhz_clk_mux_parents, NULL }, + { 25, TI_CLK_MUX, dra7_gmac_rft_clk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_gmac_clkctrl_regs[] __initconst = { + { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck" }, + { 0 }, +}; + +static const char * const dra7_timer10_gfclk_mux_parents[] __initconst = { + "timer_sys_clk_div", + "sys_32k_ck", + "sys_clkin2", + "ref_clkin0_ck", + "ref_clkin1_ck", + "ref_clkin2_ck", + "ref_clkin3_ck", + "abe_giclk_div", + "video1_div_clk", + "video2_div_clk", + "hdmi_div_clk", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_timer10_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer11_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer2_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer3_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer4_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer9_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio2_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio3_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio4_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio5_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio6_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio7_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio8_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_mmc3_gfclk_div_parents[] __initconst = { + "l4per-clkctrl:00f8:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc3_gfclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc3_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc3_gfclk_div_parents, &dra7_mmc3_gfclk_div_data }, + { 0 }, +}; + +static const char * const dra7_mmc4_gfclk_div_parents[] __initconst = { + "l4per-clkctrl:0100:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_mmc4_gfclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_mmc4_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_mmc4_gfclk_div_parents, &dra7_mmc4_gfclk_div_data }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart2_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart3_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart4_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart5_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4per_clkctrl_regs[] __initconst = { + { DRA7_L4PER_TIMER10_CLKCTRL, dra7_timer10_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0000:24" }, + { DRA7_L4PER_TIMER11_CLKCTRL, dra7_timer11_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0008:24" }, + { DRA7_L4PER_TIMER2_CLKCTRL, dra7_timer2_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0010:24" }, + { DRA7_L4PER_TIMER3_CLKCTRL, dra7_timer3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0018:24" }, + { DRA7_L4PER_TIMER4_CLKCTRL, dra7_timer4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0020:24" }, + { DRA7_L4PER_TIMER9_CLKCTRL, dra7_timer9_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0028:24" }, + { DRA7_L4PER_ELM_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4PER_GPIO2_CLKCTRL, dra7_gpio2_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_GPIO3_CLKCTRL, dra7_gpio3_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_GPIO4_CLKCTRL, dra7_gpio4_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_GPIO5_CLKCTRL, dra7_gpio5_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_GPIO6_CLKCTRL, dra7_gpio6_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_HDQ1W_CLKCTRL, NULL, CLKF_SW_SUP, "func_12m_fclk" }, + { DRA7_L4PER_I2C1_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_L4PER_I2C2_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_L4PER_I2C3_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_L4PER_I2C4_CLKCTRL, NULL, CLKF_SW_SUP, "func_96m_fclk" }, + { DRA7_L4PER_L4_PER1_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4PER_MCSPI1_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_L4PER_MCSPI2_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_L4PER_MCSPI3_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_L4PER_MCSPI4_CLKCTRL, NULL, CLKF_SW_SUP, "func_48m_fclk" }, + { DRA7_L4PER_GPIO7_CLKCTRL, dra7_gpio7_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_GPIO8_CLKCTRL, dra7_gpio8_bit_data, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4PER_MMC3_CLKCTRL, dra7_mmc3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:00f8:25" }, + { DRA7_L4PER_MMC4_CLKCTRL, dra7_mmc4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0100:25" }, + { DRA7_L4PER_UART1_CLKCTRL, dra7_uart1_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0118:24" }, + { DRA7_L4PER_UART2_CLKCTRL, dra7_uart2_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0120:24" }, + { DRA7_L4PER_UART3_CLKCTRL, dra7_uart3_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0128:24" }, + { DRA7_L4PER_UART4_CLKCTRL, dra7_uart4_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0130:24" }, + { DRA7_L4PER_UART5_CLKCTRL, dra7_uart5_bit_data, CLKF_SW_SUP, "l4per-clkctrl:0148:24" }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4sec_clkctrl_regs[] __initconst = { + { DRA7_L4SEC_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4SEC_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4SEC_DES_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { DRA7_L4SEC_RNG_CLKCTRL, NULL, CLKF_HW_SUP, "" }, + { DRA7_L4SEC_SHAM_CLKCTRL, NULL, CLKF_HW_SUP, "l3_iclk_div" }, + { 0 }, +}; + +static const char * const dra7_qspi_gfclk_mux_parents[] __initconst = { + "func_128m_clk", + "dpll_per_h13x2_ck", + NULL, +}; + +static const char * const dra7_qspi_gfclk_div_parents[] __initconst = { + "l4per2-clkctrl:012c:24", + NULL, +}; + +static const struct omap_clkctrl_div_data dra7_qspi_gfclk_div_data __initconst = { + .max_div = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, +}; + +static const struct omap_clkctrl_bit_data dra7_qspi_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_qspi_gfclk_mux_parents, NULL }, + { 25, TI_CLK_DIVIDER, dra7_qspi_gfclk_div_parents, &dra7_qspi_gfclk_div_data }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp2_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 28, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp3_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp5_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp8_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp4_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart7_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart8_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart9_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp6_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_mcasp7_bit_data[] __initconst = { + { 22, TI_CLK_MUX, dra7_mcasp1_aux_gfclk_mux_parents, NULL }, + { 24, TI_CLK_MUX, dra7_mcasp1_ahclkx_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4per2_clkctrl_regs[] __initconst = { + { DRA7_L4PER2_L4_PER2_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4PER2_PRUSS1_CLKCTRL, NULL, CLKF_SW_SUP, "" }, + { DRA7_L4PER2_PRUSS2_CLKCTRL, NULL, CLKF_SW_SUP, "" }, + { DRA7_L4PER2_EPWMSS1_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" }, + { DRA7_L4PER2_EPWMSS2_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" }, + { DRA7_L4PER2_EPWMSS0_CLKCTRL, NULL, CLKF_SW_SUP, "l4_root_clk_div" }, + { DRA7_L4PER2_QSPI_CLKCTRL, dra7_qspi_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:012c:25" }, + { DRA7_L4PER2_MCASP2_CLKCTRL, dra7_mcasp2_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0154:22" }, + { DRA7_L4PER2_MCASP3_CLKCTRL, dra7_mcasp3_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:015c:22" }, + { DRA7_L4PER2_MCASP5_CLKCTRL, dra7_mcasp5_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:016c:22" }, + { DRA7_L4PER2_MCASP8_CLKCTRL, dra7_mcasp8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:0184:24" }, + { DRA7_L4PER2_MCASP4_CLKCTRL, dra7_mcasp4_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:018c:22" }, + { DRA7_L4PER2_UART7_CLKCTRL, dra7_uart7_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01c4:24" }, + { DRA7_L4PER2_UART8_CLKCTRL, dra7_uart8_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01d4:24" }, + { DRA7_L4PER2_UART9_CLKCTRL, dra7_uart9_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01dc:24" }, + { DRA7_L4PER2_DCAN2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_clkin1" }, + { DRA7_L4PER2_MCASP6_CLKCTRL, dra7_mcasp6_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01f8:22" }, + { DRA7_L4PER2_MCASP7_CLKCTRL, dra7_mcasp7_bit_data, CLKF_SW_SUP, "l4per2-clkctrl:01fc:22" }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer13_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer14_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer15_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer16_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_l4per3_clkctrl_regs[] __initconst = { + { DRA7_L4PER3_L4_PER3_CLKCTRL, NULL, 0, "l3_iclk_div" }, + { DRA7_L4PER3_TIMER13_CLKCTRL, dra7_timer13_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:00b4:24" }, + { DRA7_L4PER3_TIMER14_CLKCTRL, dra7_timer14_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:00bc:24" }, + { DRA7_L4PER3_TIMER15_CLKCTRL, dra7_timer15_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:00c4:24" }, + { DRA7_L4PER3_TIMER16_CLKCTRL, dra7_timer16_bit_data, CLKF_SW_SUP, "l4per3-clkctrl:011c:24" }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_gpio1_bit_data[] __initconst = { + { 8, TI_CLK_GATE, dra7_dss_32khz_clk_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_timer1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_timer10_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_bit_data dra7_uart10_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_uart6_gfclk_mux_parents, NULL }, + { 0 }, +}; + +static const char * const dra7_dcan1_sys_clk_mux_parents[] __initconst = { + "sys_clkin1", + "sys_clkin2", + NULL, +}; + +static const struct omap_clkctrl_bit_data dra7_dcan1_bit_data[] __initconst = { + { 24, TI_CLK_MUX, dra7_dcan1_sys_clk_mux_parents, NULL }, + { 0 }, +}; + +static const struct omap_clkctrl_reg_data dra7_wkupaon_clkctrl_regs[] __initconst = { + { DRA7_WKUPAON_L4_WKUP_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, + { DRA7_WKUPAON_WD_TIMER2_CLKCTRL, NULL, CLKF_SW_SUP, "sys_32k_ck" }, + { DRA7_WKUPAON_GPIO1_CLKCTRL, dra7_gpio1_bit_data, CLKF_HW_SUP, "wkupaon_iclk_mux" }, + { DRA7_WKUPAON_TIMER1_CLKCTRL, dra7_timer1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0020:24" }, + { DRA7_WKUPAON_TIMER12_CLKCTRL, NULL, 0, "secure_32k_clk_src_ck" }, + { DRA7_WKUPAON_COUNTER_32K_CLKCTRL, NULL, 0, "wkupaon_iclk_mux" }, + { DRA7_WKUPAON_UART10_CLKCTRL, dra7_uart10_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0060:24" }, + { DRA7_WKUPAON_DCAN1_CLKCTRL, dra7_dcan1_bit_data, CLKF_SW_SUP, "wkupaon-clkctrl:0068:24" }, + { DRA7_WKUPAON_ADC_CLKCTRL, NULL, CLKF_SW_SUP, "mcan_clk" }, + { 0 }, +}; + +const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = { + { 0x4a005320, dra7_mpu_clkctrl_regs }, + { 0x4a005420, dra7_dsp1_clkctrl_regs }, + { 0x4a005520, dra7_ipu1_clkctrl_regs }, + { 0x4a005550, dra7_ipu_clkctrl_regs }, + { 0x4a005620, dra7_dsp2_clkctrl_regs }, + { 0x4a005720, dra7_rtc_clkctrl_regs }, + { 0x4a008620, dra7_coreaon_clkctrl_regs }, + { 0x4a008720, dra7_l3main1_clkctrl_regs }, + { 0x4a008920, dra7_ipu2_clkctrl_regs }, + { 0x4a008a20, dra7_dma_clkctrl_regs }, + { 0x4a008b20, dra7_emif_clkctrl_regs }, + { 0x4a008c00, dra7_atl_clkctrl_regs }, + { 0x4a008d20, dra7_l4cfg_clkctrl_regs }, + { 0x4a008e20, dra7_l3instr_clkctrl_regs }, + { 0x4a009120, dra7_dss_clkctrl_regs }, + { 0x4a009320, dra7_l3init_clkctrl_regs }, + { 0x4a0093b0, dra7_pcie_clkctrl_regs }, + { 0x4a0093d0, dra7_gmac_clkctrl_regs }, + { 0x4a009728, dra7_l4per_clkctrl_regs }, + { 0x4a0098a0, dra7_l4sec_clkctrl_regs }, + { 0x4a00970c, dra7_l4per2_clkctrl_regs }, + { 0x4a009714, dra7_l4per3_clkctrl_regs }, + { 0x4ae07820, dra7_wkupaon_clkctrl_regs }, + { 0 }, +}; + +static struct ti_dt_clk dra7xx_clks[] = { + DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), + DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"), + DT_CLK(NULL, "sys_clkin", "sys_clkin1"), + DT_CLK(NULL, "atl_dpll_clk_mux", "atl-clkctrl:0000:24"), + DT_CLK(NULL, "atl_gfclk_mux", "atl-clkctrl:0000:26"), + DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon-clkctrl:0068:24"), + DT_CLK(NULL, "dss_32khz_clk", "dss-clkctrl:0000:11"), + DT_CLK(NULL, "dss_48mhz_clk", "dss-clkctrl:0000:9"), + DT_CLK(NULL, "dss_dss_clk", "dss-clkctrl:0000:8"), + DT_CLK(NULL, "dss_hdmi_clk", "dss-clkctrl:0000:10"), + DT_CLK(NULL, "dss_video1_clk", "dss-clkctrl:0000:12"), + DT_CLK(NULL, "dss_video2_clk", "dss-clkctrl:0000:13"), + DT_CLK(NULL, "gmac_rft_clk_mux", "gmac-clkctrl:0000:25"), + DT_CLK(NULL, "gpio1_dbclk", "wkupaon-clkctrl:0018:8"), + DT_CLK(NULL, "gpio2_dbclk", "l4per-clkctrl:0038:8"), + DT_CLK(NULL, "gpio3_dbclk", "l4per-clkctrl:0040:8"), + DT_CLK(NULL, "gpio4_dbclk", "l4per-clkctrl:0048:8"), + DT_CLK(NULL, "gpio5_dbclk", "l4per-clkctrl:0050:8"), + DT_CLK(NULL, "gpio6_dbclk", "l4per-clkctrl:0058:8"), + DT_CLK(NULL, "gpio7_dbclk", "l4per-clkctrl:00e8:8"), + DT_CLK(NULL, "gpio8_dbclk", "l4per-clkctrl:00f0:8"), + DT_CLK(NULL, "ipu1_gfclk_mux", "ipu1-clkctrl:0000:24"), + DT_CLK(NULL, "mcasp1_ahclkr_mux", "ipu-clkctrl:0000:28"), + DT_CLK(NULL, "mcasp1_ahclkx_mux", "ipu-clkctrl:0000:24"), + DT_CLK(NULL, "mcasp1_aux_gfclk_mux", "ipu-clkctrl:0000:22"), + DT_CLK(NULL, "mcasp2_ahclkr_mux", "l4per2-clkctrl:0154:28"), + DT_CLK(NULL, "mcasp2_ahclkx_mux", "l4per2-clkctrl:0154:24"), + DT_CLK(NULL, "mcasp2_aux_gfclk_mux", "l4per2-clkctrl:0154:22"), + DT_CLK(NULL, "mcasp3_ahclkx_mux", "l4per2-clkctrl:015c:24"), + DT_CLK(NULL, "mcasp3_aux_gfclk_mux", "l4per2-clkctrl:015c:22"), + DT_CLK(NULL, "mcasp4_ahclkx_mux", "l4per2-clkctrl:018c:24"), + DT_CLK(NULL, "mcasp4_aux_gfclk_mux", "l4per2-clkctrl:018c:22"), + DT_CLK(NULL, "mcasp5_ahclkx_mux", "l4per2-clkctrl:016c:24"), + DT_CLK(NULL, "mcasp5_aux_gfclk_mux", "l4per2-clkctrl:016c:22"), + DT_CLK(NULL, "mcasp6_ahclkx_mux", "l4per2-clkctrl:01f8:24"), + DT_CLK(NULL, "mcasp6_aux_gfclk_mux", "l4per2-clkctrl:01f8:22"), + DT_CLK(NULL, "mcasp7_ahclkx_mux", "l4per2-clkctrl:01fc:24"), + DT_CLK(NULL, "mcasp7_aux_gfclk_mux", "l4per2-clkctrl:01fc:22"), + DT_CLK(NULL, "mcasp8_ahclkx_mux", "l4per2-clkctrl:0184:22"), + DT_CLK(NULL, "mcasp8_aux_gfclk_mux", "l4per2-clkctrl:0184:24"), + DT_CLK(NULL, "mmc1_clk32k", "l3init-clkctrl:0008:8"), + DT_CLK(NULL, "mmc1_fclk_div", "l3init-clkctrl:0008:25"), + DT_CLK(NULL, "mmc1_fclk_mux", "l3init-clkctrl:0008:24"), + DT_CLK(NULL, "mmc2_clk32k", "l3init-clkctrl:0010:8"), + DT_CLK(NULL, "mmc2_fclk_div", "l3init-clkctrl:0010:25"), + DT_CLK(NULL, "mmc2_fclk_mux", "l3init-clkctrl:0010:24"), + DT_CLK(NULL, "mmc3_clk32k", "l4per-clkctrl:00f8:8"), + DT_CLK(NULL, "mmc3_gfclk_div", "l4per-clkctrl:00f8:25"), + DT_CLK(NULL, "mmc3_gfclk_mux", "l4per-clkctrl:00f8:24"), + DT_CLK(NULL, "mmc4_clk32k", "l4per-clkctrl:0100:8"), + DT_CLK(NULL, "mmc4_gfclk_div", "l4per-clkctrl:0100:25"), + DT_CLK(NULL, "mmc4_gfclk_mux", "l4per-clkctrl:0100:24"), + DT_CLK(NULL, "optfclk_pciephy1_32khz", "pcie-clkctrl:0000:8"), + DT_CLK(NULL, "optfclk_pciephy1_clk", "pcie-clkctrl:0000:9"), + DT_CLK(NULL, "optfclk_pciephy1_div_clk", "pcie-clkctrl:0000:10"), + DT_CLK(NULL, "optfclk_pciephy2_32khz", "pcie-clkctrl:0008:8"), + DT_CLK(NULL, "optfclk_pciephy2_clk", "pcie-clkctrl:0008:9"), + DT_CLK(NULL, "optfclk_pciephy2_div_clk", "pcie-clkctrl:0008:10"), + DT_CLK(NULL, "qspi_gfclk_div", "l4per2-clkctrl:012c:25"), + DT_CLK(NULL, "qspi_gfclk_mux", "l4per2-clkctrl:012c:24"), + DT_CLK(NULL, "rmii_50mhz_clk_mux", "gmac-clkctrl:0000:24"), + DT_CLK(NULL, "sata_ref_clk", "l3init-clkctrl:0068:8"), + DT_CLK(NULL, "timer10_gfclk_mux", "l4per-clkctrl:0000:24"), + DT_CLK(NULL, "timer11_gfclk_mux", "l4per-clkctrl:0008:24"), + DT_CLK(NULL, "timer13_gfclk_mux", "l4per3-clkctrl:00b4:24"), + DT_CLK(NULL, "timer14_gfclk_mux", "l4per3-clkctrl:00bc:24"), + DT_CLK(NULL, "timer15_gfclk_mux", "l4per3-clkctrl:00c4:24"), + DT_CLK(NULL, "timer16_gfclk_mux", "l4per3-clkctrl:011c:24"), + DT_CLK(NULL, "timer1_gfclk_mux", "wkupaon-clkctrl:0020:24"), + DT_CLK(NULL, "timer2_gfclk_mux", "l4per-clkctrl:0010:24"), + DT_CLK(NULL, "timer3_gfclk_mux", "l4per-clkctrl:0018:24"), + DT_CLK(NULL, "timer4_gfclk_mux", "l4per-clkctrl:0020:24"), + DT_CLK(NULL, "timer5_gfclk_mux", "ipu-clkctrl:0008:24"), + DT_CLK(NULL, "timer6_gfclk_mux", "ipu-clkctrl:0010:24"), + DT_CLK(NULL, "timer7_gfclk_mux", "ipu-clkctrl:0018:24"), + DT_CLK(NULL, "timer8_gfclk_mux", "ipu-clkctrl:0020:24"), + DT_CLK(NULL, "timer9_gfclk_mux", "l4per-clkctrl:0028:24"), + DT_CLK(NULL, "uart10_gfclk_mux", "wkupaon-clkctrl:0060:24"), + DT_CLK(NULL, "uart1_gfclk_mux", "l4per-clkctrl:0118:24"), + DT_CLK(NULL, "uart2_gfclk_mux", "l4per-clkctrl:0120:24"), + DT_CLK(NULL, "uart3_gfclk_mux", "l4per-clkctrl:0128:24"), + DT_CLK(NULL, "uart4_gfclk_mux", "l4per-clkctrl:0130:24"), + DT_CLK(NULL, "uart5_gfclk_mux", "l4per-clkctrl:0148:24"), + DT_CLK(NULL, "uart6_gfclk_mux", "ipu-clkctrl:0030:24"), + DT_CLK(NULL, "uart7_gfclk_mux", "l4per2-clkctrl:01c4:24"), + DT_CLK(NULL, "uart8_gfclk_mux", "l4per2-clkctrl:01d4:24"), + DT_CLK(NULL, "uart9_gfclk_mux", "l4per2-clkctrl:01dc:24"), + DT_CLK(NULL, "usb_otg_ss1_refclk960m", "l3init-clkctrl:00d0:8"), + DT_CLK(NULL, "usb_otg_ss2_refclk960m", "l3init-clkctrl:0020:8"), + { .node_name = NULL }, +}; + int __init dra7xx_dt_clk_init(void) { int rc; struct clk *dpll_ck, *hdcp_ck; - ti_dt_clocks_register(dra7xx_compat_clks); + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + ti_dt_clocks_register(dra7xx_compat_clks); + else + ti_dt_clocks_register(dra7xx_clks); omap2_clk_disable_autoidle_all(); diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index c1fbb3d20155..955f2e26ab00 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -463,8 +463,12 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) data = omap5_clkctrl_data; #endif #ifdef CONFIG_SOC_DRA7XX - if (of_machine_is_compatible("ti,dra7")) - data = dra7_clkctrl_compat_data; + if (of_machine_is_compatible("ti,dra7")) { + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) + data = dra7_clkctrl_compat_data; + else + data = dra7_clkctrl_data; + } #endif #ifdef CONFIG_SOC_AM33XX if (of_machine_is_compatible("ti,am33xx")) { diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index c729f87c4feb..5a781067a0e7 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -183,6 +183,7 @@ struct omap_clkctrl_data { extern const struct omap_clkctrl_data omap4_clkctrl_data[]; extern const struct omap_clkctrl_data omap5_clkctrl_data[]; +extern const struct omap_clkctrl_data dra7_clkctrl_data[]; extern const struct omap_clkctrl_data dra7_clkctrl_compat_data[]; extern struct ti_dt_clk dra7xx_compat_clks[]; extern const struct omap_clkctrl_data am3_clkctrl_data[]; From 8b95d1ce3300c411728954473316bd04d0ba9883 Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Tue, 4 Sep 2018 12:19:35 +0530 Subject: [PATCH 204/836] clk: Add functions to save/restore clock context en-masse Deep enough power saving mode can result into losing context of the clock registers also, and they need to be restored once coming back from the power saving mode. Hence add functions to save/restore clock context. Signed-off-by: Keerthy Signed-off-by: Russ Dill Acked-by: Tony Lindgren Signed-off-by: Tero Kristo --- drivers/clk/clk.c | 74 ++++++++++++++++++++++++++++++++++++ include/linux/clk-provider.h | 7 ++++ include/linux/clk.h | 25 ++++++++++++ 3 files changed, 106 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index d31055ae6ec6..8a0254a1c303 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -923,6 +923,80 @@ static int clk_core_enable_lock(struct clk_core *core) return ret; } +static int _clk_save_context(struct clk_core *clk) +{ + struct clk_core *child; + int ret = 0; + + hlist_for_each_entry(child, &clk->children, child_node) { + ret = _clk_save_context(child); + if (ret < 0) + return ret; + } + + if (clk->ops && clk->ops->save_context) + ret = clk->ops->save_context(clk->hw); + + return ret; +} + +static void _clk_restore_context(struct clk_core *clk) +{ + struct clk_core *child; + + if (clk->ops && clk->ops->restore_context) + clk->ops->restore_context(clk->hw); + + hlist_for_each_entry(child, &clk->children, child_node) + _clk_restore_context(child); +} + +/** + * clk_save_context - save clock context for poweroff + * + * Saves the context of the clock register for powerstates in which the + * contents of the registers will be lost. Occurs deep within the suspend + * code. Returns 0 on success. + */ +int clk_save_context(void) +{ + struct clk_core *clk; + int ret; + + hlist_for_each_entry(clk, &clk_root_list, child_node) { + ret = _clk_save_context(clk); + if (ret < 0) + return ret; + } + + hlist_for_each_entry(clk, &clk_orphan_list, child_node) { + ret = _clk_save_context(clk); + if (ret < 0) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(clk_save_context); + +/** + * clk_restore_context - restore clock context after poweroff + * + * Restore the saved clock context upon resume. + * + */ +void clk_restore_context(void) +{ + struct clk_core *clk; + + hlist_for_each_entry(clk, &clk_root_list, child_node) + _clk_restore_context(clk); + + hlist_for_each_entry(clk, &clk_orphan_list, child_node) + _clk_restore_context(clk); +} +EXPORT_SYMBOL_GPL(clk_restore_context); + /** * clk_enable - ungate a clock * @clk: the clk being ungated diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 08b1aa70a38d..df7379da6269 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -119,6 +119,11 @@ struct clk_duty { * Called with enable_lock held. This function must not * sleep. * + * @save_context: Save the context of the clock in prepration for poweroff. + * + * @restore_context: Restore the context of the clock after a restoration + * of power. + * * @recalc_rate Recalculate the rate of this clock, by querying hardware. The * parent rate is an input parameter. It is up to the caller to * ensure that the prepare_mutex is held across this call. @@ -223,6 +228,8 @@ struct clk_ops { void (*disable)(struct clk_hw *hw); int (*is_enabled)(struct clk_hw *hw); void (*disable_unused)(struct clk_hw *hw); + int (*save_context)(struct clk_hw *hw); + void (*restore_context)(struct clk_hw *hw); unsigned long (*recalc_rate)(struct clk_hw *hw, unsigned long parent_rate); long (*round_rate)(struct clk_hw *hw, unsigned long rate, diff --git a/include/linux/clk.h b/include/linux/clk.h index 4f750c481b82..7da754d79f9d 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -629,6 +629,23 @@ struct clk *clk_get_parent(struct clk *clk); */ struct clk *clk_get_sys(const char *dev_id, const char *con_id); +/** + * clk_save_context - save clock context for poweroff + * + * Saves the context of the clock register for powerstates in which the + * contents of the registers will be lost. Occurs deep within the suspend + * code so locking is not necessary. + */ +int clk_save_context(void); + +/** + * clk_restore_context - restore clock context after poweroff + * + * This occurs with all clocks enabled. Occurs deep within the resume code + * so locking is not necessary. + */ +void clk_restore_context(void); + #else /* !CONFIG_HAVE_CLK */ static inline struct clk *clk_get(struct device *dev, const char *id) @@ -728,6 +745,14 @@ static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id) { return NULL; } + +static inline int clk_save_context(void) +{ + return 0; +} + +static inline void clk_restore_context(void) {} + #endif /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ From 435365485f40cf12747d1daa2253a4f4b46b8148 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Tue, 4 Sep 2018 12:19:36 +0530 Subject: [PATCH 205/836] clk: clk: Add clk_gate_restore_context function The clock gate restore context function enables or disables the gate clocks based on the enable_count. This is done in cases where the clock context is lost and based on the enable_count the clock either needs to be enabled/disabled. Signed-off-by: Keerthy Acked-by: Tony Lindgren Signed-off-by: Tero Kristo --- drivers/clk/clk.c | 19 +++++++++++++++++++ include/linux/clk-provider.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 8a0254a1c303..dd775771a7cc 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -923,6 +923,25 @@ static int clk_core_enable_lock(struct clk_core *core) return ret; } +/** + * clk_gate_restore_context - restore context for poweroff + * @hw: the clk_hw pointer of clock whose state is to be restored + * + * The clock gate restore context function enables or disables + * the gate clocks based on the enable_count. This is done in cases + * where the clock context is lost and based on the enable_count + * the clock either needs to be enabled/disabled. This + * helps restore the state of gate clocks. + */ +void clk_gate_restore_context(struct clk_hw *hw) +{ + if (hw->clk->core->enable_count) + hw->clk->core->ops->enable(hw); + else + hw->clk->core->ops->disable(hw); +} +EXPORT_SYMBOL_GPL(clk_gate_restore_context); + static int _clk_save_context(struct clk_core *clk) { struct clk_core *child; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index df7379da6269..60c51871b04b 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -1018,5 +1018,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg) #endif /* platform dependent I/O accessors */ +void clk_gate_restore_context(struct clk_hw *hw); + #endif /* CONFIG_COMMON_CLK */ #endif /* CLK_PROVIDER_H */ From d6e7bbc148f9fbec8a0117b0d0f420c9710e6d81 Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Tue, 4 Sep 2018 12:19:37 +0530 Subject: [PATCH 206/836] clk: ti: Add functions to save/restore clk context SoCs like AM43XX lose clock registers context during RTC-only suspend. Hence add functions to save/restore the clock registers context. Signed-off-by: Keerthy Signed-off-by: Russ Dill Acked-by: Tony Lindgren Signed-off-by: Tero Kristo --- drivers/clk/ti/clock.h | 2 + drivers/clk/ti/divider.c | 36 +++++++++++ drivers/clk/ti/dpll.c | 6 ++ drivers/clk/ti/dpll3xxx.c | 124 ++++++++++++++++++++++++++++++++++++++ drivers/clk/ti/gate.c | 3 + drivers/clk/ti/mux.c | 29 +++++++++ include/linux/clk/ti.h | 6 ++ 7 files changed, 206 insertions(+) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index 5a781067a0e7..9f312a219510 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -24,6 +24,7 @@ struct clk_omap_divider { u8 flags; s8 latch; const struct clk_div_table *table; + u32 context; }; #define to_clk_omap_divider(_hw) container_of(_hw, struct clk_omap_divider, hw) @@ -36,6 +37,7 @@ struct clk_omap_mux { u8 shift; s8 latch; u8 flags; + u8 saved_parent; }; #define to_clk_omap_mux(_hw) container_of(_hw, struct clk_omap_mux, hw) diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index ccfb4d9a152a..373f620f49cb 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -268,10 +268,46 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } +/** + * 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(÷r->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(÷r->reg); + val &= ~(div_mask(divider) << divider->shift); + val |= divider->context << divider->shift; + ti_clk_ll_ops->clk_writel(val, ÷r->reg); +} + 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, + .save_context = clk_divider_save_context, + .restore_context = clk_divider_restore_context, }; static struct clk *_register_divider(struct device *dev, const char *name, diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index dc86d07d0921..25d86d5ebb36 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -39,6 +39,8 @@ static const struct clk_ops dpll_m4xen_ck_ops = { .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, .determine_rate = &omap4_dpll_regm4xen_determine_rate, .get_parent = &omap2_init_dpll_parent, + .save_context = &omap3_core_dpll_save_context, + .restore_context = &omap3_core_dpll_restore_context, }; #else static const struct clk_ops dpll_m4xen_ck_ops = {}; @@ -62,6 +64,8 @@ static const struct clk_ops dpll_ck_ops = { .set_rate_and_parent = &omap3_noncore_dpll_set_rate_and_parent, .determine_rate = &omap3_noncore_dpll_determine_rate, .get_parent = &omap2_init_dpll_parent, + .save_context = &omap3_noncore_dpll_save_context, + .restore_context = &omap3_noncore_dpll_restore_context, }; static const struct clk_ops dpll_no_gate_ck_ops = { @@ -72,6 +76,8 @@ static const struct clk_ops dpll_no_gate_ck_ops = { .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, + .save_context = &omap3_noncore_dpll_save_context, + .restore_context = &omap3_noncore_dpll_restore_context }; #else static const struct clk_ops dpll_core_ck_ops = {}; diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index 4534de2ef455..44b6b6403753 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -782,6 +782,130 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw, return rate; } +/** + * omap3_core_dpll_save_context - Save the m and n values of the divider + * @hw: pointer struct clk_hw + * + * Before the dpll registers are lost save the last rounded rate m and n + * and the enable mask. + */ +int omap3_core_dpll_save_context(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct dpll_data *dd; + u32 v; + + dd = clk->dpll_data; + + v = ti_clk_ll_ops->clk_readl(&dd->control_reg); + clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask); + + if (clk->context == DPLL_LOCKED) { + v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); + dd->last_rounded_m = (v & dd->mult_mask) >> + __ffs(dd->mult_mask); + dd->last_rounded_n = ((v & dd->div1_mask) >> + __ffs(dd->div1_mask)) + 1; + } + + return 0; +} + +/** + * omap3_core_dpll_restore_context - restore the m and n values of the divider + * @hw: pointer struct clk_hw + * + * Restore the last rounded rate m and n + * and the enable mask. + */ +void omap3_core_dpll_restore_context(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + const struct dpll_data *dd; + u32 v; + + dd = clk->dpll_data; + + if (clk->context == DPLL_LOCKED) { + _omap3_dpll_write_clken(clk, 0x4); + _omap3_wait_dpll_status(clk, 0); + + v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); + v &= ~(dd->mult_mask | dd->div1_mask); + v |= dd->last_rounded_m << __ffs(dd->mult_mask); + v |= (dd->last_rounded_n - 1) << __ffs(dd->div1_mask); + ti_clk_ll_ops->clk_writel(v, &dd->mult_div1_reg); + + _omap3_dpll_write_clken(clk, DPLL_LOCKED); + _omap3_wait_dpll_status(clk, 1); + } else { + _omap3_dpll_write_clken(clk, clk->context); + } +} + +/** + * omap3_non_core_dpll_save_context - Save the m and n values of the divider + * @hw: pointer struct clk_hw + * + * Before the dpll registers are lost save the last rounded rate m and n + * and the enable mask. + */ +int omap3_noncore_dpll_save_context(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + struct dpll_data *dd; + u32 v; + + dd = clk->dpll_data; + + v = ti_clk_ll_ops->clk_readl(&dd->control_reg); + clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask); + + if (clk->context == DPLL_LOCKED) { + v = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); + dd->last_rounded_m = (v & dd->mult_mask) >> + __ffs(dd->mult_mask); + dd->last_rounded_n = ((v & dd->div1_mask) >> + __ffs(dd->div1_mask)) + 1; + } + + return 0; +} + +/** + * omap3_core_dpll_restore_context - restore the m and n values of the divider + * @hw: pointer struct clk_hw + * + * Restore the last rounded rate m and n + * and the enable mask. + */ +void omap3_noncore_dpll_restore_context(struct clk_hw *hw) +{ + struct clk_hw_omap *clk = to_clk_hw_omap(hw); + const struct dpll_data *dd; + u32 ctrl, mult_div1; + + dd = clk->dpll_data; + + ctrl = ti_clk_ll_ops->clk_readl(&dd->control_reg); + mult_div1 = ti_clk_ll_ops->clk_readl(&dd->mult_div1_reg); + + if (clk->context == ((ctrl & dd->enable_mask) >> + __ffs(dd->enable_mask)) && + dd->last_rounded_m == ((mult_div1 & dd->mult_mask) >> + __ffs(dd->mult_mask)) && + dd->last_rounded_n == ((mult_div1 & dd->div1_mask) >> + __ffs(dd->div1_mask)) + 1) { + /* nothing to be done */ + return; + } + + if (clk->context == DPLL_LOCKED) + omap3_noncore_dpll_program(clk, 0); + else + _omap3_dpll_write_clken(clk, clk->context); +} + /* OMAP3/4 non-CORE DPLL clkops */ const struct clk_hw_omap_ops clkhwops_omap3_dpll = { .allow_idle = omap3_dpll_allow_idle, diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 935b2de5fb88..cf9e9f5fc007 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -33,6 +33,7 @@ static const struct clk_ops omap_gate_clkdm_clk_ops = { .init = &omap2_init_clk_clkdm, .enable = &omap2_clkops_enable_clkdm, .disable = &omap2_clkops_disable_clkdm, + .restore_context = clk_gate_restore_context, }; const struct clk_ops omap_gate_clk_ops = { @@ -40,6 +41,7 @@ const struct clk_ops omap_gate_clk_ops = { .enable = &omap2_dflt_clk_enable, .disable = &omap2_dflt_clk_disable, .is_enabled = &omap2_dflt_clk_is_enabled, + .restore_context = clk_gate_restore_context, }; static const struct clk_ops omap_gate_clk_hsdiv_restore_ops = { @@ -47,6 +49,7 @@ static const struct clk_ops omap_gate_clk_hsdiv_restore_ops = { .enable = &omap36xx_gate_clk_enable_with_hsdiv_restore, .disable = &omap2_dflt_clk_disable, .is_enabled = &omap2_dflt_clk_is_enabled, + .restore_context = clk_gate_restore_context, }; /** diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index 69a4308a5a98..5749b2b4fa61 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -91,10 +91,39 @@ static int ti_clk_mux_set_parent(struct clk_hw *hw, u8 index) return 0; } +/** + * clk_mux_save_context - Save the parent selcted in the mux + * @hw: pointer struct clk_hw + * + * Save the parent mux value. + */ +static int clk_mux_save_context(struct clk_hw *hw) +{ + struct clk_omap_mux *mux = to_clk_omap_mux(hw); + + mux->saved_parent = ti_clk_mux_get_parent(hw); + return 0; +} + +/** + * clk_mux_restore_context - Restore the parent in the mux + * @hw: pointer struct clk_hw + * + * Restore the saved parent mux value. + */ +static void clk_mux_restore_context(struct clk_hw *hw) +{ + struct clk_omap_mux *mux = to_clk_omap_mux(hw); + + ti_clk_mux_set_parent(hw, mux->saved_parent); +} + const struct clk_ops ti_clk_mux_ops = { .get_parent = ti_clk_mux_get_parent, .set_parent = ti_clk_mux_set_parent, .determine_rate = __clk_mux_determine_rate, + .save_context = clk_mux_save_context, + .restore_context = clk_mux_restore_context, }; static struct clk *_register_mux(struct device *dev, const char *name, diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 3301bd025a2c..eacc5df57b99 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -159,6 +159,7 @@ struct clk_hw_omap { const char *clkdm_name; struct clockdomain *clkdm; const struct clk_hw_omap_ops *ops; + u32 context; }; /* @@ -294,6 +295,11 @@ struct ti_clk_features { void ti_clk_setup_features(struct ti_clk_features *features); const struct ti_clk_features *ti_clk_get_features(void); +int omap3_noncore_dpll_save_context(struct clk_hw *hw); +void omap3_noncore_dpll_restore_context(struct clk_hw *hw); + +int omap3_core_dpll_save_context(struct clk_hw *hw); +void omap3_core_dpll_restore_context(struct clk_hw *hw); extern const struct clk_hw_omap_ops clkhwops_omap2xxx_dpll; From 617a629c08bfffb05249131079d9a38322902e5b Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 24 May 2018 13:27:45 -0700 Subject: [PATCH 207/836] apparmor: Add a wildcard secid Reserve a secid value that we can use as a wildcard, allowing us to define policy that's expected to match against all secids. Signed-off-by: Matthew Garrett Signed-off-by: John Johansen --- security/apparmor/include/secid.h | 3 +++ security/apparmor/secid.c | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/security/apparmor/include/secid.h b/security/apparmor/include/secid.h index dee6fa3b6081..fa2062711b63 100644 --- a/security/apparmor/include/secid.h +++ b/security/apparmor/include/secid.h @@ -22,6 +22,9 @@ struct aa_label; /* secid value that will not be allocated */ #define AA_SECID_INVALID 0 +/* secid value that matches any other secid */ +#define AA_SECID_WILDCARD 1 + struct aa_label *aa_secid_to_label(u32 secid); int apparmor_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); int apparmor_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); diff --git a/security/apparmor/secid.c b/security/apparmor/secid.c index f2f22d00db18..8c951c493beb 100644 --- a/security/apparmor/secid.c +++ b/security/apparmor/secid.c @@ -32,8 +32,7 @@ * secids - do not pin labels with a refcount. They rely on the label * properly updating/freeing them */ - -#define AA_FIRST_SECID 1 +#define AA_FIRST_SECID 2 static DEFINE_IDR(aa_secids); static DEFINE_SPINLOCK(secid_lock); From 9caafbe2b4cf4c635826a2832e93cf648605de8b Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 24 May 2018 13:27:46 -0700 Subject: [PATCH 208/836] apparmor: Parse secmark policy Add support for parsing secmark policy provided by userspace, and store that in the overall policy. Signed-off-by: Matthew Garrett Signed-off-by: John Johansen --- security/apparmor/include/net.h | 10 +++++ security/apparmor/include/policy.h | 3 ++ security/apparmor/policy.c | 3 ++ security/apparmor/policy_unpack.c | 61 ++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h index ec7228e857a9..7334ac966d01 100644 --- a/security/apparmor/include/net.h +++ b/security/apparmor/include/net.h @@ -83,6 +83,13 @@ struct aa_sk_ctx { __e; \ }) +struct aa_secmark { + u8 audit; + u8 deny; + u32 secid; + char *label; +}; + extern struct aa_sfs_entry aa_sfs_entry_network[]; void audit_net_cb(struct audit_buffer *ab, void *va); @@ -103,4 +110,7 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk); int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, struct socket *sock); +int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, + u32 secid, struct sock *sk); + #endif /* __AA_NET_H */ diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index ab64c6b5db5a..8e6707c837be 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -155,6 +155,9 @@ struct aa_profile { struct aa_rlimit rlimits; + int secmark_count; + struct aa_secmark *secmark; + struct aa_loaddata *rawdata; unsigned char *hash; char *dirname; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 1590e2de4e84..8d846a747b84 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -231,6 +231,9 @@ void aa_free_profile(struct aa_profile *profile) for (i = 0; i < profile->xattr_count; i++) kzfree(profile->xattrs[i]); kzfree(profile->xattrs); + for (i=0; i < profile->secmark_count; i++) + kzfree(profile->secmark[i].label); + kzfree(profile->secmark); kzfree(profile->dirname); aa_put_dfa(profile->xmatch); aa_put_dfa(profile->policy.dfa); diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 21cb384d712a..379682e2a8d5 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -292,6 +292,19 @@ fail: return 0; } +static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name) +{ + if (unpack_nameX(e, AA_U8, name)) { + if (!inbounds(e, sizeof(u8))) + return 0; + if (data) + *data = get_unaligned((u8 *)e->pos); + e->pos += sizeof(u8); + return 1; + } + return 0; +} + static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name) { if (unpack_nameX(e, AA_U32, name)) { @@ -529,6 +542,49 @@ fail: return 0; } +static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile) +{ + void *pos = e->pos; + int i, size; + + if (unpack_nameX(e, AA_STRUCT, "secmark")) { + size = unpack_array(e, NULL); + + profile->secmark = kcalloc(size, sizeof(struct aa_secmark), + GFP_KERNEL); + if (!profile->secmark) + goto fail; + + profile->secmark_count = size; + + for (i = 0; i < size; i++) { + if (!unpack_u8(e, &profile->secmark[i].audit, NULL)) + goto fail; + if (!unpack_u8(e, &profile->secmark[i].deny, NULL)) + goto fail; + if (!unpack_strdup(e, &profile->secmark[i].label, NULL)) + goto fail; + } + if (!unpack_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + } + + return 1; + +fail: + if (profile->secmark) { + for (i = 0; i < size; i++) + kfree(profile->secmark[i].label); + kfree(profile->secmark); + profile->secmark_count = 0; + } + + e->pos = pos; + return 0; +} + static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) { void *pos = e->pos; @@ -727,6 +783,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } + if (!unpack_secmark(e, profile)) { + info = "failed to unpack profile secmark rules"; + goto fail; + } + if (unpack_nameX(e, AA_STRUCT, "policydb")) { /* generic policy dfa - optional and may be NULL */ info = "failed to unpack policydb"; From ab9f2115081ab7ba63b77a759e0f3eb5d6463d7f Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 24 May 2018 13:27:47 -0700 Subject: [PATCH 209/836] apparmor: Allow filtering based on secmark policy Add support for dropping or accepting packets based on their secmark tags. Signed-off-by: Matthew Garrett Signed-off-by: John Johansen --- security/apparmor/lsm.c | 112 +++++++++++++++++++++++++++++++++++++++- security/apparmor/net.c | 66 +++++++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index f09fea0b4db7..2c842f24821b 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include "include/apparmor.h" @@ -1030,7 +1032,13 @@ static int apparmor_socket_shutdown(struct socket *sock, int how) */ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { - return 0; + struct aa_sk_ctx *ctx = SK_CTX(sk); + + if (!skb->secmark) + return 0; + + return apparmor_secmark_check(ctx->label, OP_RECVMSG, AA_MAY_RECEIVE, + skb->secmark, sk); } @@ -1126,6 +1134,18 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) ctx->label = aa_get_current_label(); } +static int apparmor_inet_conn_request(struct sock *sk, struct sk_buff *skb, + struct request_sock *req) +{ + struct aa_sk_ctx *ctx = SK_CTX(sk); + + if (!skb->secmark) + return 0; + + return apparmor_secmark_check(ctx->label, OP_CONNECT, AA_MAY_CONNECT, + skb->secmark, sk); +} + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), @@ -1183,6 +1203,7 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(socket_getpeersec_dgram, apparmor_socket_getpeersec_dgram), LSM_HOOK_INIT(sock_graft, apparmor_sock_graft), + LSM_HOOK_INIT(inet_conn_request, apparmor_inet_conn_request), LSM_HOOK_INIT(cred_alloc_blank, apparmor_cred_alloc_blank), LSM_HOOK_INIT(cred_free, apparmor_cred_free), @@ -1538,6 +1559,95 @@ static inline int apparmor_init_sysctl(void) } #endif /* CONFIG_SYSCTL */ +static unsigned int apparmor_ip_postroute(void *priv, + struct sk_buff *skb, + const struct nf_hook_state *state) +{ + struct aa_sk_ctx *ctx; + struct sock *sk; + + if (!skb->secmark) + return NF_ACCEPT; + + sk = skb_to_full_sk(skb); + if (sk == NULL) + return NF_ACCEPT; + + ctx = SK_CTX(sk); + if (!apparmor_secmark_check(ctx->label, OP_SENDMSG, AA_MAY_SEND, + skb->secmark, sk)) + return NF_ACCEPT; + + return NF_DROP_ERR(-ECONNREFUSED); + +} + +static unsigned int apparmor_ipv4_postroute(void *priv, + struct sk_buff *skb, + const struct nf_hook_state *state) +{ + return apparmor_ip_postroute(priv, skb, state); +} + +static unsigned int apparmor_ipv6_postroute(void *priv, + struct sk_buff *skb, + const struct nf_hook_state *state) +{ + return apparmor_ip_postroute(priv, skb, state); +} + +static const struct nf_hook_ops apparmor_nf_ops[] = { + { + .hook = apparmor_ipv4_postroute, + .pf = NFPROTO_IPV4, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP_PRI_SELINUX_FIRST, + }, +#if IS_ENABLED(CONFIG_IPV6) + { + .hook = apparmor_ipv6_postroute, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_POST_ROUTING, + .priority = NF_IP6_PRI_SELINUX_FIRST, + }, +#endif +}; + +static int __net_init apparmor_nf_register(struct net *net) +{ + int ret; + + ret = nf_register_net_hooks(net, apparmor_nf_ops, + ARRAY_SIZE(apparmor_nf_ops)); + return ret; +} + +static void __net_exit apparmor_nf_unregister(struct net *net) +{ + nf_unregister_net_hooks(net, apparmor_nf_ops, + ARRAY_SIZE(apparmor_nf_ops)); +} + +static struct pernet_operations apparmor_net_ops = { + .init = apparmor_nf_register, + .exit = apparmor_nf_unregister, +}; + +static int __init apparmor_nf_ip_init(void) +{ + int err; + + if (!apparmor_enabled) + return 0; + + err = register_pernet_subsys(&apparmor_net_ops); + if (err) + panic("Apparmor: register_pernet_subsys: error %d\n", err); + + return 0; +} +__initcall(apparmor_nf_ip_init); + static int __init apparmor_init(void) { int error; diff --git a/security/apparmor/net.c b/security/apparmor/net.c index d5d72dd1ca1f..f9a678ce994f 100644 --- a/security/apparmor/net.c +++ b/security/apparmor/net.c @@ -18,6 +18,7 @@ #include "include/label.h" #include "include/net.h" #include "include/policy.h" +#include "include/secid.h" #include "net_names.h" @@ -188,3 +189,68 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, return aa_label_sk_perm(label, op, request, sock->sk); } + +static int apparmor_secmark_init(struct aa_secmark *secmark) +{ + struct aa_label *label; + + if (secmark->label[0] == '*') { + secmark->secid = AA_SECID_WILDCARD; + return 0; + } + + label = aa_label_strn_parse(&root_ns->unconfined->label, + secmark->label, strlen(secmark->label), + GFP_ATOMIC, false, false); + + if (IS_ERR(label)) + return PTR_ERR(label); + + secmark->secid = label->secid; + + return 0; +} + +static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, + struct common_audit_data *sa, struct sock *sk) +{ + int i, ret; + struct aa_perms perms = { }; + + if (profile->secmark_count == 0) + return 0; + + for (i = 0; i < profile->secmark_count; i++) { + if (!profile->secmark[i].secid) { + ret = apparmor_secmark_init(&profile->secmark[i]); + if (ret) + return ret; + } + + if (profile->secmark[i].secid == secid || + profile->secmark[i].secid == AA_SECID_WILDCARD) { + if (profile->secmark[i].deny) + perms.deny = ALL_PERMS_MASK; + else + perms.allow = ALL_PERMS_MASK; + + if (profile->secmark[i].audit) + perms.audit = ALL_PERMS_MASK; + } + } + + aa_apply_modes_to_perms(profile, &perms); + + return aa_check_perms(profile, &perms, request, sa, audit_net_cb); +} + +int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, + u32 secid, struct sock *sk) +{ + struct aa_profile *profile; + DEFINE_AUDIT_SK(sa, op, sk); + + return fn_for_each_confined(label, profile, + aa_secmark_perm(profile, request, secid, + &sa, sk)); +} From 0fb871cc42537465e322f727bec6abfd375faa83 Mon Sep 17 00:00:00 2001 From: Lance Roy Date: Tue, 2 Oct 2018 22:39:01 -0700 Subject: [PATCH 210/836] apparmor: Replace spin_is_locked() with lockdep lockdep_assert_held() is better suited to checking locking requirements, since it won't get confused when someone else holds the lock. This is also a step towards possibly removing spin_is_locked(). Signed-off-by: Lance Roy Cc: John Johansen Cc: James Morris Cc: "Serge E. Hallyn" Cc: Signed-off-by: John Johansen --- security/apparmor/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/apparmor/file.c b/security/apparmor/file.c index 4285943f7260..d0afed9ebd0e 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c @@ -496,7 +496,7 @@ static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label, /* update caching of label on file_ctx */ spin_lock(&fctx->lock); old = rcu_dereference_protected(fctx->label, - spin_is_locked(&fctx->lock)); + lockdep_is_held(&fctx->lock)); l = aa_label_merge(old, label, GFP_ATOMIC); if (l) { if (l != old) { From ca3fde5214e1d24f78269b337d3f22afd6bf445e Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Sat, 29 Sep 2018 03:49:26 +0200 Subject: [PATCH 211/836] apparmor: don't try to replace stale label in ptraceme check begin_current_label_crit_section() must run in sleepable context because when label_is_stale() is true, aa_replace_current_label() runs, which uses prepare_creds(), which can sleep. Until now, the ptraceme access check (which runs with tasklist_lock held) violated this rule. Fixes: b2d09ae449ced ("apparmor: move ptrace checks to using labels") Reported-by: Cyrill Gorcunov Reported-by: kernel test robot Signed-off-by: Jann Horn Signed-off-by: John Johansen --- security/apparmor/lsm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 2c842f24821b..d08aac05c65a 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -132,11 +132,11 @@ static int apparmor_ptrace_traceme(struct task_struct *parent) struct aa_label *tracer, *tracee; int error; - tracee = begin_current_label_crit_section(); + tracee = __begin_current_label_crit_section(); tracer = aa_get_task_label(parent); error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE); aa_put_label(tracer); - end_current_label_crit_section(tracee); + __end_current_label_crit_section(tracee); return error; } From 250f2da49cb8e582215a65c03f50e8ddf5cd119c Mon Sep 17 00:00:00 2001 From: Zubin Mithra Date: Thu, 27 Sep 2018 14:49:17 -0700 Subject: [PATCH 212/836] apparmor: Fix uninitialized value in aa_split_fqname Syzkaller reported a OOB-read with the stacktrace below. This occurs inside __aa_lookupn_ns as `n` is not initialized. `n` is obtained from aa_splitn_fqname. In cases where `name` is invalid, aa_splitn_fqname returns without initializing `ns_name` and `ns_len`. Fix this by always initializing `ns_name` and `ns_len`. __dump_stack lib/dump_stack.c:77 [inline] dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113 print_address_description.cold.8+0x9/0x1ff mm/kasan/report.c:256 kasan_report_error mm/kasan/report.c:354 [inline] kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412 __asan_report_load1_noabort+0x14/0x20 mm/kasan/report.c:430 memcmp+0xe3/0x160 lib/string.c:861 strnstr+0x4b/0x70 lib/string.c:934 __aa_lookupn_ns+0xc1/0x570 security/apparmor/policy_ns.c:209 aa_lookupn_ns+0x88/0x1e0 security/apparmor/policy_ns.c:240 aa_fqlookupn_profile+0x1b9/0x1010 security/apparmor/policy.c:468 fqlookupn_profile+0x80/0xc0 security/apparmor/label.c:1844 aa_label_strn_parse+0xa3a/0x1230 security/apparmor/label.c:1908 aa_label_parse+0x42/0x50 security/apparmor/label.c:1943 aa_change_profile+0x513/0x3510 security/apparmor/domain.c:1362 apparmor_setprocattr+0xaa4/0x1150 security/apparmor/lsm.c:658 security_setprocattr+0x66/0xc0 security/security.c:1298 proc_pid_attr_write+0x301/0x540 fs/proc/base.c:2555 __vfs_write+0x119/0x9f0 fs/read_write.c:485 vfs_write+0x1fc/0x560 fs/read_write.c:549 ksys_write+0x101/0x260 fs/read_write.c:598 __do_sys_write fs/read_write.c:610 [inline] __se_sys_write fs/read_write.c:607 [inline] __x64_sys_write+0x73/0xb0 fs/read_write.c:607 do_syscall_64+0x1b9/0x820 arch/x86/entry/common.c:290 entry_SYSCALL_64_after_hwframe+0x49/0xbe Fixes: 3b0aaf5866bf ("apparmor: add lib fn to find the "split" for fqnames") Reported-by: syzbot+61e4b490d9d2da591b50@syzkaller.appspotmail.com Signed-off-by: Zubin Mithra Reviewed-by: Kees Cook Signed-off-by: John Johansen --- security/apparmor/lib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 974affe50531..76491e7f4177 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -90,10 +90,12 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, const char *end = fqname + n; const char *name = skipn_spaces(fqname, n); - if (!name) - return NULL; *ns_name = NULL; *ns_len = 0; + + if (!name) + return NULL; + if (name[0] == ':') { char *split = strnchr(&name[1], end - &name[1], ':'); *ns_name = skipn_spaces(&name[1], end - &name[1]); From 5aa389aa29ce0fcdd39fa88245bcad6cea6af57c Mon Sep 17 00:00:00 2001 From: Rajneesh Bhardwaj Date: Wed, 3 Oct 2018 17:21:10 +0530 Subject: [PATCH 213/836] MAINTAINERS: intel_pmc_core: Update MAINTAINERS This removes the entry for pmc_core.h file in the MAINTAINERS as the file is already removed by a previous commit. "platform/x86: intel_pmc_core: Remove unused header file" Reported-by: Joe Perches Signed-off-by: Rajneesh Bhardwaj Signed-off-by: Andy Shevchenko --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2614592f8fa4..257f0aa8af45 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7475,7 +7475,6 @@ M: Rajneesh Bhardwaj M: Vishwanath Somayaji L: platform-driver-x86@vger.kernel.org S: Maintained -F: arch/x86/include/asm/pmc_core.h F: drivers/platform/x86/intel_pmc_core* INTEL PMC/P-Unit IPC DRIVER From ab6ead7d07ca87e3e66e6d524c8aa311732878de Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 2 Oct 2018 11:45:29 +0200 Subject: [PATCH 214/836] ARM: OMAP1: ams-delta: Fix impossible .irq < 0 Since the very beginning, unsigned int .irq member of struct plat_serial8250_port introduced by commit eff443df679e ("OMAP1: AMS_DELTA: add modem support") was statically initialized to a negative value -EINVAL. Moreover, commit 0812db943748 ("ARM: OMAP1: ams-delta: assign MODEM IRQ from GPIO descriptor") has introduced some new code which checks for that member carrying a negative value which is impossible. Use IRQ_NOTCONNECTED instead of -EINVAL. Also, drop the valueless check and let the modem device be registered regardless of .irq value, and the value handled by "serial8250" driver. Fixes: 0812db943748 ("ARM: OMAP1: ams-delta: assign MODEM IRQ from GPIO descriptor") Reported-by: Dan Carpenter Signed-off-by: Janusz Krzysztofik Acked-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 318925ae3ebe..b01b68494cac 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -765,7 +765,7 @@ static struct plat_serial8250_port ams_delta_modem_ports[] = { { .membase = IOMEM(MODEM_VIRT), .mapbase = MODEM_PHYS, - .irq = -EINVAL, /* changed later */ + .irq = IRQ_NOTCONNECTED, /* changed later */ .flags = UPF_BOOT_AUTOCONF, .irqflags = IRQF_TRIGGER_RISING, .iotype = UPIO_MEM, @@ -856,8 +856,7 @@ static int __init modem_nreset_init(void) /* - * This function expects MODEM IRQ number already assigned to the port - * and fails if it's not. + * This function expects MODEM IRQ number already assigned to the port. * The MODEM device requires its RESET# pin kept high during probe. * That requirement can be fulfilled in several ways: * - with a descriptor of already functional modem_nreset regulator @@ -880,9 +879,6 @@ static int __init ams_delta_modem_init(void) if (!machine_is_ams_delta()) return -ENODEV; - if (ams_delta_modem_ports[0].irq < 0) - return ams_delta_modem_ports[0].irq; - omap_cfg_reg(M14_1510_GPIO2); /* Initialize the modem_nreset regulator consumer before use */ From 3773ee423e726e1da2cb505ee3c990073c608968 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:27 +0200 Subject: [PATCH 215/836] clk: samsung: s3c64xx: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. [snawrocki@kernel.org: Whitespace correction] Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-s3c64xx.c | 66 +++---------------------------- 1 file changed, 6 insertions(+), 60 deletions(-) diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 6db01cf5ab83..54916c7bdb06 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -12,7 +12,6 @@ #include #include #include -#include #include @@ -59,10 +58,6 @@ static void __iomem *reg_base; static bool is_s3c6400; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *s3c64xx_save_common; -static struct samsung_clk_reg_dump *s3c64xx_save_soc; - /* * List of controller registers to be saved and restored during * a suspend/resume cycle. @@ -89,60 +84,6 @@ static unsigned long s3c6410_clk_regs[] __initdata = { MEM0_GATE, }; -static int s3c64xx_clk_suspend(void) -{ - samsung_clk_save(reg_base, s3c64xx_save_common, - ARRAY_SIZE(s3c64xx_clk_regs)); - - if (!is_s3c6400) - samsung_clk_save(reg_base, s3c64xx_save_soc, - ARRAY_SIZE(s3c6410_clk_regs)); - - return 0; -} - -static void s3c64xx_clk_resume(void) -{ - samsung_clk_restore(reg_base, s3c64xx_save_common, - ARRAY_SIZE(s3c64xx_clk_regs)); - - if (!is_s3c6400) - samsung_clk_restore(reg_base, s3c64xx_save_soc, - ARRAY_SIZE(s3c6410_clk_regs)); -} - -static struct syscore_ops s3c64xx_clk_syscore_ops = { - .suspend = s3c64xx_clk_suspend, - .resume = s3c64xx_clk_resume, -}; - -static void __init s3c64xx_clk_sleep_init(void) -{ - s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs, - ARRAY_SIZE(s3c64xx_clk_regs)); - if (!s3c64xx_save_common) - goto err_warn; - - if (!is_s3c6400) { - s3c64xx_save_soc = samsung_clk_alloc_reg_dump(s3c6410_clk_regs, - ARRAY_SIZE(s3c6410_clk_regs)); - if (!s3c64xx_save_soc) - goto err_soc; - } - - register_syscore_ops(&s3c64xx_clk_syscore_ops); - return; - -err_soc: - kfree(s3c64xx_save_common); -err_warn: - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); -} -#else -static void __init s3c64xx_clk_sleep_init(void) {} -#endif - /* List of parent clocks common for all S3C64xx SoCs. */ PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" }; PNAME(uart_p) = { "mout_epll", "dout_mpll" }; @@ -508,7 +449,12 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, samsung_clk_register_alias(ctx, s3c64xx_clock_aliases, ARRAY_SIZE(s3c64xx_clock_aliases)); - s3c64xx_clk_sleep_init(); + + samsung_clk_sleep_init(reg_base, s3c64xx_clk_regs, + ARRAY_SIZE(s3c64xx_clk_regs)); + if (!is_s3c6400) + samsung_clk_sleep_init(reg_base, s3c6410_clk_regs, + ARRAY_SIZE(s3c6410_clk_regs)); samsung_clk_of_add_provider(np, ctx); From 3ac0b61578a6e9edcedeb6b4d7c53c6f3c7ae916 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:28 +0200 Subject: [PATCH 216/836] clk: samsung: s5pv210: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-s5pv210.c | 41 ++----------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c index fd2725710a6f..41d2337fe030 100644 --- a/drivers/clk/samsung/clk-s5pv210.c +++ b/drivers/clk/samsung/clk-s5pv210.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "clk.h" #include "clk-pll.h" @@ -83,9 +82,6 @@ enum { static void __iomem *reg_base; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *s5pv210_clk_dump; - /* List of registers that need to be preserved across suspend/resume. */ static unsigned long s5pv210_clk_regs[] __initdata = { CLK_SRC0, @@ -132,40 +128,6 @@ static unsigned long s5pv210_clk_regs[] __initdata = { CLK_OUT, }; -static int s5pv210_clk_suspend(void) -{ - samsung_clk_save(reg_base, s5pv210_clk_dump, - ARRAY_SIZE(s5pv210_clk_regs)); - return 0; -} - -static void s5pv210_clk_resume(void) -{ - samsung_clk_restore(reg_base, s5pv210_clk_dump, - ARRAY_SIZE(s5pv210_clk_regs)); -} - -static struct syscore_ops s5pv210_clk_syscore_ops = { - .suspend = s5pv210_clk_suspend, - .resume = s5pv210_clk_resume, -}; - -static void s5pv210_clk_sleep_init(void) -{ - s5pv210_clk_dump = - samsung_clk_alloc_reg_dump(s5pv210_clk_regs, - ARRAY_SIZE(s5pv210_clk_regs)); - if (!s5pv210_clk_dump) { - pr_warn("%s: Failed to allocate sleep save data\n", __func__); - return; - } - - register_syscore_ops(&s5pv210_clk_syscore_ops); -} -#else -static inline void s5pv210_clk_sleep_init(void) { } -#endif - /* Mux parent lists. */ static const char *const fin_pll_p[] __initconst = { "xxti", @@ -822,7 +784,8 @@ static void __init __s5pv210_clk_init(struct device_node *np, samsung_clk_register_alias(ctx, s5pv210_aliases, ARRAY_SIZE(s5pv210_aliases)); - s5pv210_clk_sleep_init(); + samsung_clk_sleep_init(reg_base, s5pv210_clk_regs, + ARRAY_SIZE(s5pv210_clk_regs)); samsung_clk_of_add_provider(np, ctx); From c41b0ff2f627c654475a287a21b2f455430f0923 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:29 +0200 Subject: [PATCH 217/836] clk: samsung: exynos5250: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5250.c | 42 ++-------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 347fd80c351b..f14139bcb0c1 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "clk.h" #include "clk-cpu.h" @@ -111,9 +110,6 @@ enum exynos5250_plls { static void __iomem *reg_base; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *exynos5250_save; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -172,41 +168,6 @@ static const unsigned long exynos5250_clk_regs[] __initconst = { GATE_IP_ISP1, }; -static int exynos5250_clk_suspend(void) -{ - samsung_clk_save(reg_base, exynos5250_save, - ARRAY_SIZE(exynos5250_clk_regs)); - - return 0; -} - -static void exynos5250_clk_resume(void) -{ - samsung_clk_restore(reg_base, exynos5250_save, - ARRAY_SIZE(exynos5250_clk_regs)); -} - -static struct syscore_ops exynos5250_clk_syscore_ops = { - .suspend = exynos5250_clk_suspend, - .resume = exynos5250_clk_resume, -}; - -static void __init exynos5250_clk_sleep_init(void) -{ - exynos5250_save = samsung_clk_alloc_reg_dump(exynos5250_clk_regs, - ARRAY_SIZE(exynos5250_clk_regs)); - if (!exynos5250_save) { - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); - return; - } - - register_syscore_ops(&exynos5250_clk_syscore_ops); -} -#else -static void __init exynos5250_clk_sleep_init(void) {} -#endif - /* list of all parent clock list */ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; @@ -882,7 +843,8 @@ static void __init exynos5250_clk_init(struct device_node *np) PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO); __raw_writel(tmp, reg_base + PWR_CTRL2); - exynos5250_clk_sleep_init(); + samsung_clk_sleep_init(reg_base, exynos5250_clk_regs, + ARRAY_SIZE(exynos5250_clk_regs)); exynos5_subcmus_init(ctx, 1, &exynos5250_disp_subcmu); samsung_clk_of_add_provider(np, ctx); From 8bf27eaa04a610c622fda45b715f90f1781c2abb Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:30 +0200 Subject: [PATCH 218/836] clk: samsung: Add support for setting registers state before suspend Some registers of clock controller have to be set to certain values before entering system suspend state. Till now drivers did that on their own, but it will be easier to handle it by generic code and let drivers simply to provide the list of registers and their state. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk.c | 23 +++++++++++++---------- drivers/clk/samsung/clk.h | 18 ++++++++++++++++-- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 8634884aa11c..1f6e47cd327d 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -290,9 +290,12 @@ static int samsung_clk_suspend(void) { struct samsung_clock_reg_cache *reg_cache; - list_for_each_entry(reg_cache, &clock_reg_cache_list, node) + list_for_each_entry(reg_cache, &clock_reg_cache_list, node) { samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, reg_cache->rd_num); + samsung_clk_restore(reg_cache->reg_base, reg_cache->rsuspend, + reg_cache->rsuspend_num); + } return 0; } @@ -310,9 +313,11 @@ static struct syscore_ops samsung_clk_syscore_ops = { .resume = samsung_clk_resume, }; -void samsung_clk_sleep_init(void __iomem *reg_base, +void samsung_clk_extended_sleep_init(void __iomem *reg_base, const unsigned long *rdump, - unsigned long nr_rdump) + unsigned long nr_rdump, + const struct samsung_clk_reg_dump *rsuspend, + unsigned long nr_rsuspend) { struct samsung_clock_reg_cache *reg_cache; @@ -330,13 +335,10 @@ void samsung_clk_sleep_init(void __iomem *reg_base, reg_cache->reg_base = reg_base; reg_cache->rd_num = nr_rdump; + reg_cache->rsuspend = rsuspend; + reg_cache->rsuspend_num = nr_rsuspend; list_add_tail(®_cache->node, &clock_reg_cache_list); } - -#else -void samsung_clk_sleep_init(void __iomem *reg_base, - const unsigned long *rdump, - unsigned long nr_rdump) {} #endif /* @@ -380,8 +382,9 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks, cmu->nr_fixed_factor_clks); if (cmu->clk_regs) - samsung_clk_sleep_init(reg_base, cmu->clk_regs, - cmu->nr_clk_regs); + samsung_clk_extended_sleep_init(reg_base, + cmu->clk_regs, cmu->nr_clk_regs, + cmu->suspend_regs, cmu->nr_suspend_regs); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 3880d2f9d582..c3f309d7100d 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -279,6 +279,8 @@ struct samsung_clock_reg_cache { void __iomem *reg_base; struct samsung_clk_reg_dump *rdump; unsigned int rd_num; + const struct samsung_clk_reg_dump *rsuspend; + unsigned int rsuspend_num; }; struct samsung_cmu_info { @@ -358,9 +360,21 @@ extern struct samsung_clk_provider __init *samsung_cmu_register_one( extern unsigned long _get_rate(const char *clk_name); -extern void samsung_clk_sleep_init(void __iomem *reg_base, +#ifdef CONFIG_PM_SLEEP +extern void samsung_clk_extended_sleep_init(void __iomem *reg_base, const unsigned long *rdump, - unsigned long nr_rdump); + unsigned long nr_rdump, + const struct samsung_clk_reg_dump *rsuspend, + unsigned long nr_rsuspend); +#else +static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, + const unsigned long *rdump, + unsigned long nr_rdump, + const struct samsung_clk_reg_dump *rsuspend, + unsigned long nr_rsuspend) {} +#endif +#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ + samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) extern void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, From 9a4d8a8c4d2a4683874d242363f30dbdccd034c9 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:31 +0200 Subject: [PATCH 219/836] clk: samsung: exynos4: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Handling of PLLs is a bit different in generic code, as they are handled in the same way as other clock registers. Such approach was already used on later Exynos SoCs and worked fine. Tests have shown that it works also on Exynos4 SoCs and significantly simplifies the code. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos4.c | 145 +++--------------------------- 1 file changed, 14 insertions(+), 131 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 0421960eb963..d7cfdb0732c8 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "clk.h" #include "clk-cpu.h" @@ -157,14 +156,6 @@ enum exynos4_plls { static void __iomem *reg_base; static enum exynos4_soc exynos4_soc; -/* - * Support for CMU save/restore across system suspends - */ -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *exynos4_save_common; -static struct samsung_clk_reg_dump *exynos4_save_soc; -static struct samsung_clk_reg_dump *exynos4_save_pll; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -192,7 +183,7 @@ static const unsigned long exynos4x12_clk_save[] __initconst = { E4X12_PWR_CTRL2, }; -static const unsigned long exynos4_clk_pll_regs[] __initconst = { +static const unsigned long exynos4_clk_regs[] __initconst = { EPLL_LOCK, VPLL_LOCK, EPLL_CON0, @@ -201,9 +192,6 @@ static const unsigned long exynos4_clk_pll_regs[] __initconst = { VPLL_CON0, VPLL_CON1, VPLL_CON2, -}; - -static const unsigned long exynos4_clk_regs[] __initconst = { SRC_LEFTBUS, DIV_LEFTBUS, GATE_IP_LEFTBUS, @@ -276,6 +264,8 @@ static const unsigned long exynos4_clk_regs[] __initconst = { }; static const struct samsung_clk_reg_dump src_mask_suspend[] = { + { .offset = VPLL_CON0, .value = 0x80600302, }, + { .offset = EPLL_CON0, .value = 0x806F0302, }, { .offset = SRC_MASK_TOP, .value = 0x00000001, }, { .offset = SRC_MASK_CAM, .value = 0x11111111, }, { .offset = SRC_MASK_TV, .value = 0x00000111, }, @@ -291,123 +281,6 @@ static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = { { .offset = E4210_SRC_MASK_LCD1, .value = 0x00001111, }, }; -#define PLL_ENABLED (1 << 31) -#define PLL_LOCKED (1 << 29) - -static void exynos4_clk_enable_pll(u32 reg) -{ - u32 pll_con = readl(reg_base + reg); - pll_con |= PLL_ENABLED; - writel(pll_con, reg_base + reg); - - while (!(pll_con & PLL_LOCKED)) { - cpu_relax(); - pll_con = readl(reg_base + reg); - } -} - -static void exynos4_clk_wait_for_pll(u32 reg) -{ - u32 pll_con; - - pll_con = readl(reg_base + reg); - if (!(pll_con & PLL_ENABLED)) - return; - - while (!(pll_con & PLL_LOCKED)) { - cpu_relax(); - pll_con = readl(reg_base + reg); - } -} - -static int exynos4_clk_suspend(void) -{ - samsung_clk_save(reg_base, exynos4_save_common, - ARRAY_SIZE(exynos4_clk_regs)); - samsung_clk_save(reg_base, exynos4_save_pll, - ARRAY_SIZE(exynos4_clk_pll_regs)); - - exynos4_clk_enable_pll(EPLL_CON0); - exynos4_clk_enable_pll(VPLL_CON0); - - if (exynos4_soc == EXYNOS4210) { - samsung_clk_save(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4210_clk_save)); - samsung_clk_restore(reg_base, src_mask_suspend_e4210, - ARRAY_SIZE(src_mask_suspend_e4210)); - } else { - samsung_clk_save(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4x12_clk_save)); - } - - samsung_clk_restore(reg_base, src_mask_suspend, - ARRAY_SIZE(src_mask_suspend)); - - return 0; -} - -static void exynos4_clk_resume(void) -{ - samsung_clk_restore(reg_base, exynos4_save_pll, - ARRAY_SIZE(exynos4_clk_pll_regs)); - - exynos4_clk_wait_for_pll(EPLL_CON0); - exynos4_clk_wait_for_pll(VPLL_CON0); - - samsung_clk_restore(reg_base, exynos4_save_common, - ARRAY_SIZE(exynos4_clk_regs)); - - if (exynos4_soc == EXYNOS4210) - samsung_clk_restore(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4210_clk_save)); - else - samsung_clk_restore(reg_base, exynos4_save_soc, - ARRAY_SIZE(exynos4x12_clk_save)); -} - -static struct syscore_ops exynos4_clk_syscore_ops = { - .suspend = exynos4_clk_suspend, - .resume = exynos4_clk_resume, -}; - -static void __init exynos4_clk_sleep_init(void) -{ - exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs, - ARRAY_SIZE(exynos4_clk_regs)); - if (!exynos4_save_common) - goto err_warn; - - if (exynos4_soc == EXYNOS4210) - exynos4_save_soc = samsung_clk_alloc_reg_dump( - exynos4210_clk_save, - ARRAY_SIZE(exynos4210_clk_save)); - else - exynos4_save_soc = samsung_clk_alloc_reg_dump( - exynos4x12_clk_save, - ARRAY_SIZE(exynos4x12_clk_save)); - if (!exynos4_save_soc) - goto err_common; - - exynos4_save_pll = samsung_clk_alloc_reg_dump(exynos4_clk_pll_regs, - ARRAY_SIZE(exynos4_clk_pll_regs)); - if (!exynos4_save_pll) - goto err_soc; - - register_syscore_ops(&exynos4_clk_syscore_ops); - return; - -err_soc: - kfree(exynos4_save_soc); -err_common: - kfree(exynos4_save_common); -err_warn: - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); -} -#else -static void __init exynos4_clk_sleep_init(void) {} -#endif - /* list of all parent clock list */ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; @@ -1532,7 +1405,17 @@ static void __init exynos4_clk_init(struct device_node *np, if (soc == EXYNOS4X12) exynos4x12_core_down_clock(); - exynos4_clk_sleep_init(); + + samsung_clk_extended_sleep_init(reg_base, + exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), + src_mask_suspend, ARRAY_SIZE(src_mask_suspend)); + if (exynos4_soc == EXYNOS4210) + samsung_clk_extended_sleep_init(reg_base, + exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save), + src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210)); + else + samsung_clk_sleep_init(reg_base, exynos4x12_clk_save, + ARRAY_SIZE(exynos4x12_clk_save)); samsung_clk_of_add_provider(np, ctx); From 2d77f77c0aaaa77ebfa8c4763816a8018d170111 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 17:55:32 +0200 Subject: [PATCH 220/836] clk: samsung: exynos5420: Use generic helper for handling suspend/resume Replace common suspend/resume handling code by generic helper. Almost no functional change, the only difference is in handling of hypothetical memory allocation failure on boot. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5420.c | 72 +++------------------------- 1 file changed, 6 insertions(+), 66 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 95e1bf69449b..76e7686c6162 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "clk.h" #include "clk-cpu.h" @@ -156,10 +155,6 @@ enum exynos5x_plls { static void __iomem *reg_base; static enum exynos5x_soc exynos5x_soc; -#ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *exynos5x_save; -static struct samsung_clk_reg_dump *exynos5800_save; - /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -283,66 +278,6 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = { { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, }; -static int exynos5420_clk_suspend(void) -{ - samsung_clk_save(reg_base, exynos5x_save, - ARRAY_SIZE(exynos5x_clk_regs)); - - if (exynos5x_soc == EXYNOS5800) - samsung_clk_save(reg_base, exynos5800_save, - ARRAY_SIZE(exynos5800_clk_regs)); - - samsung_clk_restore(reg_base, exynos5420_set_clksrc, - ARRAY_SIZE(exynos5420_set_clksrc)); - - return 0; -} - -static void exynos5420_clk_resume(void) -{ - samsung_clk_restore(reg_base, exynos5x_save, - ARRAY_SIZE(exynos5x_clk_regs)); - - if (exynos5x_soc == EXYNOS5800) - samsung_clk_restore(reg_base, exynos5800_save, - ARRAY_SIZE(exynos5800_clk_regs)); -} - -static struct syscore_ops exynos5420_clk_syscore_ops = { - .suspend = exynos5420_clk_suspend, - .resume = exynos5420_clk_resume, -}; - -static void __init exynos5420_clk_sleep_init(void) -{ - exynos5x_save = samsung_clk_alloc_reg_dump(exynos5x_clk_regs, - ARRAY_SIZE(exynos5x_clk_regs)); - if (!exynos5x_save) { - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); - return; - } - - if (exynos5x_soc == EXYNOS5800) { - exynos5800_save = - samsung_clk_alloc_reg_dump(exynos5800_clk_regs, - ARRAY_SIZE(exynos5800_clk_regs)); - if (!exynos5800_save) - goto err_soc; - } - - register_syscore_ops(&exynos5420_clk_syscore_ops); - return; -err_soc: - kfree(exynos5x_save); - pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", - __func__); - return; -} -#else -static void __init exynos5420_clk_sleep_init(void) {} -#endif - /* list of all parent clocks */ PNAME(mout_mspll_cpu_p) = {"mout_sclk_cpll", "mout_sclk_dpll", "mout_sclk_mpll", "mout_sclk_spll"}; @@ -1540,7 +1475,12 @@ static void __init exynos5x_clk_init(struct device_node *np, mout_kfc_p[0], mout_kfc_p[1], 0x28200, exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0); - exynos5420_clk_sleep_init(); + samsung_clk_extended_sleep_init(reg_base, + exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs), + exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc)); + if (soc == EXYNOS5800) + samsung_clk_sleep_init(reg_base, exynos5800_clk_regs, + ARRAY_SIZE(exynos5800_clk_regs)); exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus), exynos5x_subcmus); From 70da9ee80228e6d98fd68e3c1db124c4461d283c Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 18:02:35 +0200 Subject: [PATCH 221/836] clk: samsung: Use NOIRQ stage for Exynos5433 clocks suspend/resume SoC clock drivers should suspend after every other drivers in the system, which are using clocks and resume before them. The last stage for calling suspend device callbacks is NOIRQ stage and there exists driver, which use that state (dwmmc-exynos), so Exynos5433 clocks driver should also use it. During the same stage, clocks driver will be always suspended after its clients as a direct result of proper device probe order (deferred probe reorders the suspend call sequence). Signed-off-by: Marek Szyprowski Acked-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 162de44df099..426980514e67 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -5630,7 +5630,7 @@ static const struct of_device_id exynos5433_cmu_of_match[] = { static const struct dev_pm_ops exynos5433_cmu_pm_ops = { SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume, NULL) - SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; From a766065279e2fd2c4ee6fe6b48d44386c000c940 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 6 Sep 2018 18:02:36 +0200 Subject: [PATCH 222/836] clk: samsung: exynos5433: Add suspend state for TOP, CPIF & PERIC CMUs Before entering system suspend, one has to ensure that some clocks from TOP, CPIF and PERIC CMUs are enabled. This is needed by the firmware to properly perform system suspend operation. Instead of adding more and more clocks with CRITICAL flag, simply enable those clocks directly in respective CMU registers using 'suspend_regs' feature. Signed-off-by: Marek Szyprowski Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 426980514e67..13384f4911c7 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -177,6 +177,15 @@ static const unsigned long top_clk_regs[] __initconst = { ENABLE_CMU_TOP_DIV_STAT, }; +static const struct samsung_clk_reg_dump top_suspend_regs[] = { + /* force all aclk clocks enabled */ + { ENABLE_ACLK_TOP, 0x67ecffed }, + /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */ + { ISP_PLL_CON0, 0x85cc0502 }, + /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */ + { AUD_PLL_CON0, 0x84830202 }, +}; + /* list of all parent clock list */ PNAME(mout_aud_pll_p) = { "oscclk", "fout_aud_pll", }; PNAME(mout_isp_pll_p) = { "oscclk", "fout_isp_pll", }; @@ -792,6 +801,8 @@ static const struct samsung_cmu_info top_cmu_info __initconst = { .nr_clk_ids = TOP_NR_CLK, .clk_regs = top_clk_regs, .nr_clk_regs = ARRAY_SIZE(top_clk_regs), + .suspend_regs = top_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(top_suspend_regs), }; static void __init exynos5433_cmu_top_init(struct device_node *np) @@ -822,6 +833,13 @@ static const unsigned long cpif_clk_regs[] __initconst = { ENABLE_SCLK_CPIF, }; +static const struct samsung_clk_reg_dump cpif_suspend_regs[] = { + /* force all sclk clocks enabled */ + { ENABLE_SCLK_CPIF, 0x3ff }, + /* MPHY PLL has to be enabled for suspend: reset value + ENABLE bit */ + { MPHY_PLL_CON0, 0x81c70601 }, +}; + /* list of all parent clock list */ PNAME(mout_mphy_pll_p) = { "oscclk", "fout_mphy_pll", }; @@ -862,6 +880,8 @@ static const struct samsung_cmu_info cpif_cmu_info __initconst = { .nr_clk_ids = CPIF_NR_CLK, .clk_regs = cpif_clk_regs, .nr_clk_regs = ARRAY_SIZE(cpif_clk_regs), + .suspend_regs = cpif_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(cpif_suspend_regs), }; static void __init exynos5433_cmu_cpif_init(struct device_node *np) @@ -1547,6 +1567,13 @@ static const unsigned long peric_clk_regs[] __initconst = { ENABLE_IP_PERIC2, }; +static const struct samsung_clk_reg_dump peric_suspend_regs[] = { + /* pclk: sci, pmu, sysreg, gpio_{finger, ese, touch, nfc}, uart2-0 */ + { ENABLE_PCLK_PERIC0, 0xe00ff000 }, + /* sclk: uart2-0 */ + { ENABLE_SCLK_PERIC, 0x7 }, +}; + static const struct samsung_div_clock peric_div_clks[] __initconst = { /* DIV_PERIC */ DIV(CLK_DIV_SCLK_SCI, "div_sclk_sci", "oscclk", DIV_PERIC, 4, 4), @@ -1705,6 +1732,8 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = { .nr_clk_ids = PERIC_NR_CLK, .clk_regs = peric_clk_regs, .nr_clk_regs = ARRAY_SIZE(peric_clk_regs), + .suspend_regs = peric_suspend_regs, + .nr_suspend_regs = ARRAY_SIZE(peric_suspend_regs), }; static void __init exynos5433_cmu_peric_init(struct device_node *np) From fa34efff75d4a853551c8154e0685d44a7a6a6aa Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 11 Oct 2017 11:25:15 +0200 Subject: [PATCH 223/836] clk: samsung: Remove obsolete code for Exynos4412 ISP clocks Exynos4412 ISP clock are provided by separate Exynos4412 ISP clock driver, so support for them in Exynos4-clk driver can be removed. Signed-off-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos4.c | 81 ----------------------------- include/dt-bindings/clock/exynos4.h | 30 ----------- 2 files changed, 111 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index d7cfdb0732c8..59d4d46667ce 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -122,10 +122,6 @@ #define CLKOUT_CMU_CPU 0x14a00 #define PWR_CTRL1 0x15020 #define E4X12_PWR_CTRL2 0x15024 -#define E4X12_DIV_ISP0 0x18300 -#define E4X12_DIV_ISP1 0x18304 -#define E4X12_GATE_ISP0 0x18800 -#define E4X12_GATE_ISP1 0x18804 /* Below definitions are used for PWR_CTRL settings */ #define PWR_CTRL1_CORE2_DOWN_RATIO(x) (((x) & 0x7) << 28) @@ -714,18 +710,6 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = { DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3), }; -static struct samsung_div_clock exynos4x12_isp_div_clks[] = { - DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3, - CLK_GET_RATE_NOCACHE, 0), - DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3, - CLK_GET_RATE_NOCACHE, 0), - DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3), - DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, - 4, 3, CLK_GET_RATE_NOCACHE, 0), - DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, - 8, 3, CLK_GET_RATE_NOCACHE, 0), -}; - /* list of gate clocks supported in all exynos4 soc's */ static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = { GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0), @@ -1023,61 +1007,6 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = { 0), }; -static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = { - GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), - GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, - CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0), -}; - /* * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit * resides in chipid register space, outside of the clock controller memory @@ -1377,8 +1306,6 @@ static void __init exynos4_clk_init(struct device_node *np, e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d), CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1); } else { - struct resource res; - samsung_clk_register_mux(ctx, exynos4x12_mux_clks, ARRAY_SIZE(exynos4x12_mux_clks)); samsung_clk_register_div(ctx, exynos4x12_div_clks, @@ -1389,14 +1316,6 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4x12_fixed_factor_clks, ARRAY_SIZE(exynos4x12_fixed_factor_clks)); - of_address_to_resource(np, 0, &res); - if (resource_size(&res) > 0x18000) { - samsung_clk_register_div(ctx, exynos4x12_isp_div_clks, - ARRAY_SIZE(exynos4x12_isp_div_clks)); - samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks, - ARRAY_SIZE(exynos4x12_isp_gate_clks)); - } - exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk", mout_core_p4x12[0], mout_core_p4x12[1], 0x14200, e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d), diff --git a/include/dt-bindings/clock/exynos4.h b/include/dt-bindings/clock/exynos4.h index e9f9d400c322..f59ea85d77bd 100644 --- a/include/dt-bindings/clock/exynos4.h +++ b/include/dt-bindings/clock/exynos4.h @@ -190,32 +190,6 @@ #define CLK_MIPI_HSI 349 /* Exynos4210 only */ #define CLK_PIXELASYNCM0 351 #define CLK_PIXELASYNCM1 352 -#define CLK_FIMC_LITE0 353 /* Exynos4x12 only */ -#define CLK_FIMC_LITE1 354 /* Exynos4x12 only */ -#define CLK_PPMUISPX 355 /* Exynos4x12 only */ -#define CLK_PPMUISPMX 356 /* Exynos4x12 only */ -#define CLK_FIMC_ISP 357 /* Exynos4x12 only */ -#define CLK_FIMC_DRC 358 /* Exynos4x12 only */ -#define CLK_FIMC_FD 359 /* Exynos4x12 only */ -#define CLK_MCUISP 360 /* Exynos4x12 only */ -#define CLK_GICISP 361 /* Exynos4x12 only */ -#define CLK_SMMU_ISP 362 /* Exynos4x12 only */ -#define CLK_SMMU_DRC 363 /* Exynos4x12 only */ -#define CLK_SMMU_FD 364 /* Exynos4x12 only */ -#define CLK_SMMU_LITE0 365 /* Exynos4x12 only */ -#define CLK_SMMU_LITE1 366 /* Exynos4x12 only */ -#define CLK_MCUCTL_ISP 367 /* Exynos4x12 only */ -#define CLK_MPWM_ISP 368 /* Exynos4x12 only */ -#define CLK_I2C0_ISP 369 /* Exynos4x12 only */ -#define CLK_I2C1_ISP 370 /* Exynos4x12 only */ -#define CLK_MTCADC_ISP 371 /* Exynos4x12 only */ -#define CLK_PWM_ISP 372 /* Exynos4x12 only */ -#define CLK_WDT_ISP 373 /* Exynos4x12 only */ -#define CLK_UART_ISP 374 /* Exynos4x12 only */ -#define CLK_ASYNCAXIM 375 /* Exynos4x12 only */ -#define CLK_SMMU_ISPCX 376 /* Exynos4x12 only */ -#define CLK_SPI0_ISP 377 /* Exynos4x12 only */ -#define CLK_SPI1_ISP 378 /* Exynos4x12 only */ #define CLK_PWM_ISP_SCLK 379 /* Exynos4x12 only */ #define CLK_SPI0_ISP_SCLK 380 /* Exynos4x12 only */ #define CLK_SPI1_ISP_SCLK 381 /* Exynos4x12 only */ @@ -257,10 +231,6 @@ #define CLK_PPMUACP 415 /* div clocks */ -#define CLK_DIV_ISP0 450 /* Exynos4x12 only */ -#define CLK_DIV_ISP1 451 /* Exynos4x12 only */ -#define CLK_DIV_MCUISP0 452 /* Exynos4x12 only */ -#define CLK_DIV_MCUISP1 453 /* Exynos4x12 only */ #define CLK_DIV_ACLK200 454 /* Exynos4x12 only */ #define CLK_DIV_ACLK400_MCUISP 455 /* Exynos4x12 only */ #define CLK_DIV_ACP 456 From defadcc956cacfb36ecf9902bd56dc5a14fdec49 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 12 Sep 2018 15:16:41 +0200 Subject: [PATCH 224/836] clk: samsung: exynos5433: Keep sclk_uart clocks enabled in suspend All sclk_uart clocks in TOP CMU have to be kept enabled for suspend/resume cycle, otherwise TM2(e) boards hangs before entering the suspend mode. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5433.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index 13384f4911c7..751e2c4fb65b 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -180,6 +180,8 @@ static const unsigned long top_clk_regs[] __initconst = { static const struct samsung_clk_reg_dump top_suspend_regs[] = { /* force all aclk clocks enabled */ { ENABLE_ACLK_TOP, 0x67ecffed }, + /* force all sclk_uart clocks enabled */ + { ENABLE_SCLK_TOP_PERIC, 0x38 }, /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */ { ISP_PLL_CON0, 0x85cc0502 }, /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */ From d32dd2a1a0f80edad158c9a1ba5f47650d9504a0 Mon Sep 17 00:00:00 2001 From: Joonyoung Shim Date: Mon, 24 Sep 2018 13:00:56 +0200 Subject: [PATCH 225/836] clk: samsung: exynos5420: Define CLK_SECKEY gate clock only or Exynos5420 The bit of GATE_BUS_PERIS1 for CLK_SECKEY is just reserved on exynos5422/5800, not exynos5420. Define gate clk for exynos5420 to handle the bit only on exynos5420. Signed-off-by: Joonyoung Shim [m.szyprow: rewrote commit subject] Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5420.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 76e7686c6162..a2d6e7f4bcd3 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -568,6 +568,7 @@ static const struct samsung_div_clock exynos5420_div_clks[] __initconst = { }; static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = { + GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0), GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), }; @@ -1097,8 +1098,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = { GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_IP_PERIS, 21, 0, 0), GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_IP_PERIS, 22, 0, 0), - GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0), - /* GEN Block */ GATE(CLK_ROTATOR, "rotator", "mout_user_aclk266", GATE_IP_GEN, 1, 0, 0), GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0), From b33228029d842269e17bba591609e83ed422005d Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Mon, 24 Sep 2018 13:01:20 +0200 Subject: [PATCH 226/836] clk: samsung: exynos5420: Enable PERIS clocks for suspend Ensure that clocks for core SoC modules (including TZPC0..9 modules) are enabled for suspend/resume cycle. This fixes suspend/resume support on Exynos5422-based Odroid XU3/XU4 boards. Suggested-by: Joonyoung Shim Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-exynos5420.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index a2d6e7f4bcd3..34cce3c5898f 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -276,6 +276,7 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = { { .offset = GATE_BUS_TOP, .value = 0xffffffff, }, { .offset = GATE_BUS_DISP1, .value = 0xffffffff, }, { .offset = GATE_IP_PERIC, .value = 0xffffffff, }, + { .offset = GATE_IP_PERIS, .value = 0xffffffff, }, }; /* list of all parent clocks */ From 1da220e3a5d22fccda0bc8542997abc1d1741268 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 2 Oct 2018 13:52:10 +0200 Subject: [PATCH 227/836] clk: samsung: Use clk_hw API for calling clk framework from clk notifiers clk_notifier_register() documentation states, that the provided notifier callbacks associated with the notifier must not re-enter into the clk framework by calling any top-level clk APIs. Fix this by replacing clk_get_rate() calls with clk_hw_get_rate(), which is safe in this context. Signed-off-by: Marek Szyprowski Signed-off-by: Sylwester Nawrocki --- drivers/clk/samsung/clk-cpu.c | 6 +++--- drivers/clk/samsung/clk-cpu.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index d2c99d8916b8..a5fddebbe530 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -152,7 +152,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, struct exynos_cpuclk *cpuclk, void __iomem *base) { const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg; - unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent); + unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent); unsigned long alt_div = 0, alt_div_mask = DIV_MASK; unsigned long div0, div1 = 0, mux_reg; unsigned long flags; @@ -280,7 +280,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, struct exynos_cpuclk *cpuclk, void __iomem *base) { const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg; - unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent); + unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent); unsigned long alt_div = 0, alt_div_mask = DIV_MASK; unsigned long div0, div1 = 0, mux_reg; unsigned long flags; @@ -432,7 +432,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, else cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb; - cpuclk->alt_parent = __clk_lookup(alt_parent); + cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent)); if (!cpuclk->alt_parent) { pr_err("%s: could not lookup alternate parent %s\n", __func__, alt_parent); diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h index d4b6b517fe1b..bd38c6aa3897 100644 --- a/drivers/clk/samsung/clk-cpu.h +++ b/drivers/clk/samsung/clk-cpu.h @@ -49,7 +49,7 @@ struct exynos_cpuclk_cfg_data { */ struct exynos_cpuclk { struct clk_hw hw; - struct clk *alt_parent; + struct clk_hw *alt_parent; void __iomem *ctrl_base; spinlock_t *lock; const struct exynos_cpuclk_cfg_data *cfg; From 9dbcfe1ace4e9c57b819df1054eaeceb9bfd34f5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 27 Sep 2018 19:03:47 +0200 Subject: [PATCH 228/836] dt-bindings: clock: samsung: Add SPDX license identifiers Replace GPL license statements with SPDX license identifiers (GPL-2.0). Signed-off-by: Krzysztof Kozlowski Acked-by: Chanwoo Choi Reviewed-by: Rob Herring Signed-off-by: Sylwester Nawrocki --- include/dt-bindings/clock/exynos3250.h | 5 +---- include/dt-bindings/clock/exynos4.h | 7 ++----- include/dt-bindings/clock/exynos5250.h | 7 ++----- include/dt-bindings/clock/exynos5260-clk.h | 7 ++----- include/dt-bindings/clock/exynos5410.h | 7 ++----- include/dt-bindings/clock/exynos5420.h | 7 ++----- include/dt-bindings/clock/exynos5433.h | 5 +---- include/dt-bindings/clock/exynos7-clk.h | 7 ++----- include/dt-bindings/clock/s3c2410.h | 5 +---- include/dt-bindings/clock/s3c2412.h | 5 +---- include/dt-bindings/clock/s3c2443.h | 5 +---- 11 files changed, 17 insertions(+), 50 deletions(-) diff --git a/include/dt-bindings/clock/exynos3250.h b/include/dt-bindings/clock/exynos3250.h index c796ff02ceeb..fe8214017b46 100644 --- a/include/dt-bindings/clock/exynos3250.h +++ b/include/dt-bindings/clock/exynos3250.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Tomasz Figa * - * 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. - * * Device Tree binding constants for Samsung Exynos3250 clock controllers. */ diff --git a/include/dt-bindings/clock/exynos4.h b/include/dt-bindings/clock/exynos4.h index f59ea85d77bd..a0439ce8e8d3 100644 --- a/include/dt-bindings/clock/exynos4.h +++ b/include/dt-bindings/clock/exynos4.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Samsung Electronics Co., Ltd. * Author: Andrzej Hajda * - * 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. - * * Device Tree binding constants for Exynos4 clock controller. -*/ + */ #ifndef _DT_BINDINGS_CLOCK_EXYNOS_4_H #define _DT_BINDINGS_CLOCK_EXYNOS_4_H diff --git a/include/dt-bindings/clock/exynos5250.h b/include/dt-bindings/clock/exynos5250.h index 15508adcdfde..bc8a3c53a54b 100644 --- a/include/dt-bindings/clock/exynos5250.h +++ b/include/dt-bindings/clock/exynos5250.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Samsung Electronics Co., Ltd. * Author: Andrzej Hajda * - * 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. - * * Device Tree binding constants for Exynos5250 clock controller. -*/ + */ #ifndef _DT_BINDINGS_CLOCK_EXYNOS_5250_H #define _DT_BINDINGS_CLOCK_EXYNOS_5250_H diff --git a/include/dt-bindings/clock/exynos5260-clk.h b/include/dt-bindings/clock/exynos5260-clk.h index a4bac9a1764f..98a58cbd81b2 100644 --- a/include/dt-bindings/clock/exynos5260-clk.h +++ b/include/dt-bindings/clock/exynos5260-clk.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Rahul Sharma * - * 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. - * * Provides Constants for Exynos5260 clocks. -*/ + */ #ifndef _DT_BINDINGS_CLK_EXYNOS5260_H #define _DT_BINDINGS_CLK_EXYNOS5260_H diff --git a/include/dt-bindings/clock/exynos5410.h b/include/dt-bindings/clock/exynos5410.h index 6cb4e90f81fc..f179eabbcdb7 100644 --- a/include/dt-bindings/clock/exynos5410.h +++ b/include/dt-bindings/clock/exynos5410.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd. * Copyright (c) 2016 Krzysztof Kozlowski * - * 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. - * * Device Tree binding constants for Exynos5421 clock controller. -*/ + */ #ifndef _DT_BINDINGS_CLOCK_EXYNOS_5410_H #define _DT_BINDINGS_CLOCK_EXYNOS_5410_H diff --git a/include/dt-bindings/clock/exynos5420.h b/include/dt-bindings/clock/exynos5420.h index 2740ae0424a9..355f469943f1 100644 --- a/include/dt-bindings/clock/exynos5420.h +++ b/include/dt-bindings/clock/exynos5420.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Samsung Electronics Co., Ltd. * Author: Andrzej Hajda * - * 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. - * * Device Tree binding constants for Exynos5420 clock controller. -*/ + */ #ifndef _DT_BINDINGS_CLOCK_EXYNOS_5420_H #define _DT_BINDINGS_CLOCK_EXYNOS_5420_H diff --git a/include/dt-bindings/clock/exynos5433.h b/include/dt-bindings/clock/exynos5433.h index be39d23e6a32..98bd85ce1e45 100644 --- a/include/dt-bindings/clock/exynos5433.h +++ b/include/dt-bindings/clock/exynos5433.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Chanwoo Choi - * - * 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. */ #ifndef _DT_BINDINGS_CLOCK_EXYNOS5433_H diff --git a/include/dt-bindings/clock/exynos7-clk.h b/include/dt-bindings/clock/exynos7-clk.h index 10c558611085..fce33c7050c8 100644 --- a/include/dt-bindings/clock/exynos7-clk.h +++ b/include/dt-bindings/clock/exynos7-clk.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2014 Samsung Electronics Co., Ltd. * Author: Naveen Krishna Ch - * - * 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. -*/ + */ #ifndef _DT_BINDINGS_CLOCK_EXYNOS7_H #define _DT_BINDINGS_CLOCK_EXYNOS7_H diff --git a/include/dt-bindings/clock/s3c2410.h b/include/dt-bindings/clock/s3c2410.h index 352a7673fc69..0fb65c3f2f59 100644 --- a/include/dt-bindings/clock/s3c2410.h +++ b/include/dt-bindings/clock/s3c2410.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Heiko Stuebner * - * 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. - * * Device Tree binding constants clock controllers of Samsung S3C2410 and later. */ diff --git a/include/dt-bindings/clock/s3c2412.h b/include/dt-bindings/clock/s3c2412.h index aac1dcfda81c..b4656156cc0f 100644 --- a/include/dt-bindings/clock/s3c2412.h +++ b/include/dt-bindings/clock/s3c2412.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Heiko Stuebner * - * 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. - * * Device Tree binding constants clock controllers of Samsung S3C2412. */ diff --git a/include/dt-bindings/clock/s3c2443.h b/include/dt-bindings/clock/s3c2443.h index f3ba68a25ecb..a9d2f105d536 100644 --- a/include/dt-bindings/clock/s3c2443.h +++ b/include/dt-bindings/clock/s3c2443.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2013 Heiko Stuebner * - * 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. - * * Device Tree binding constants clock controllers of Samsung S3C2443 and later. */ From 9e6dbc3d5cfc1afec5aefe87a7fffd5b9d44f09a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 5 Oct 2018 18:11:15 +0200 Subject: [PATCH 229/836] clk: keystone: add missing MODULE_LICENSE A randconfig build showed that two clk modules have no license tag: WARNING: modpost: missing MODULE_LICENSE() in drivers/clk/keystone/gate.o see include/linux/module.h for more information WARNING: modpost: missing MODULE_LICENSE() in drivers/clk/keystone/pll.o see include/linux/module.h for more information Add the appropriate information from the comment at the start of the two files. Signed-off-by: Arnd Bergmann Acked-by: Santosh Shilimkar Signed-off-by: Stephen Boyd --- drivers/clk/keystone/gate.c | 5 +++++ drivers/clk/keystone/pll.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c index aed5af23895b..b02a262d69cd 100644 --- a/drivers/clk/keystone/gate.c +++ b/drivers/clk/keystone/gate.c @@ -266,3 +266,8 @@ static void __init of_keystone_psc_clk_init(struct device_node *node) } CLK_OF_DECLARE(keystone_gate_clk, "ti,keystone,psc-clock", of_keystone_psc_clk_init); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Clock driver for Keystone 2 based devices"); +MODULE_AUTHOR("Murali Karicheri "); +MODULE_AUTHOR("Santosh Shilimkar "); diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c index e7e840fb74ea..19c9dc37c58f 100644 --- a/drivers/clk/keystone/pll.c +++ b/drivers/clk/keystone/pll.c @@ -338,3 +338,8 @@ static void __init of_pll_mux_clk_init(struct device_node *node) pr_err("%s: error registering mux %s\n", __func__, clk_name); } CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PLL clock driver for Keystone devices"); +MODULE_AUTHOR("Murali Karicheri "); +MODULE_AUTHOR("Santosh Shilimkar "); From ad4366ad4831f9a42d86f19c43a482c7cb04cecb Mon Sep 17 00:00:00 2001 From: Jia-Ju Bai Date: Mon, 8 Oct 2018 12:57:34 +0200 Subject: [PATCH 230/836] video: fbdev: add the dependency of broadsheetfb in Kconfig broadsheetfb is a platform driver and it should not be used on x86. It should be used only by single ARM PXA board so add the dependency in Kconfig. Signed-off-by: Jia-Ju Bai Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 591a13a59787..d9ffb13cc87a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2240,7 +2240,7 @@ config FB_MX3 config FB_BROADSHEET tristate "E-Ink Broadsheet/Epson S1D13521 controller support" - depends on FB + depends on FB && (ARCH_PXA || COMPILE_TEST) select FB_SYS_FILLRECT select FB_SYS_COPYAREA select FB_SYS_IMAGEBLIT From 68a958a915ca912b8ce71b9eea7445996f6e681e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 8 Oct 2018 12:57:34 +0200 Subject: [PATCH 231/836] udlfb: handle unplug properly The udlfb driver maintained an open count and cleaned up itself when the count reached zero. But the console is also counted in the reference count - so, if the user unplugged the device, the open count would not drop to zero and the driver stayed loaded with console attached. If the user re-plugged the adapter, it would create a device /dev/fb1, show green screen and the access to the console would be lost. The framebuffer subsystem has reference counting on its own - in order to fix the unplug bug, we rely the framebuffer reference counting. When the user unplugs the adapter, we call unregister_framebuffer unconditionally. unregister_framebuffer will unbind the console, wait until all users stop using the framebuffer and then call the fb_destroy method. The fb_destroy cleans up the USB driver. This patch makes the following changes: * Drop dlfb->kref and rely on implicit framebuffer reference counting instead. * dlfb_usb_disconnect calls unregister_framebuffer, the rest of driver cleanup is done in the function dlfb_ops_destroy. dlfb_ops_destroy will be called by the framebuffer subsystem when no processes have the framebuffer open or mapped. * We don't use workqueue during initialization, but initialize directly from dlfb_usb_probe. The workqueue could race with dlfb_usb_disconnect and this racing would produce various kinds of memory corruption. * We use usb_get_dev and usb_put_dev to make sure that the USB subsystem doesn't free the device under us. Signed-off-by: Mikulas Patocka cc: Dave Airlie Cc: Bernie Thompson , Cc: Ladislav Michl Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/udlfb.c | 143 ++++++++++-------------------------- include/video/udlfb.h | 3 - 2 files changed, 38 insertions(+), 108 deletions(-) diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index afbd6101c78e..070026a7e55a 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -916,8 +916,6 @@ static int dlfb_ops_open(struct fb_info *info, int user) dlfb->fb_count++; - kref_get(&dlfb->kref); - if (fb_defio && (info->fbdefio == NULL)) { /* enable defio at last moment if not disabled by client */ @@ -940,14 +938,17 @@ static int dlfb_ops_open(struct fb_info *info, int user) return 0; } -/* - * Called when all client interfaces to start transactions have been disabled, - * and all references to our device instance (dlfb_data) are released. - * Every transaction must have a reference, so we know are fully spun down - */ -static void dlfb_free(struct kref *kref) +static void dlfb_ops_destroy(struct fb_info *info) { - struct dlfb_data *dlfb = container_of(kref, struct dlfb_data, kref); + struct dlfb_data *dlfb = info->par; + + if (info->cmap.len != 0) + fb_dealloc_cmap(&info->cmap); + if (info->monspecs.modedb) + fb_destroy_modedb(info->monspecs.modedb); + vfree(info->screen_base); + + fb_destroy_modelist(&info->modelist); while (!list_empty(&dlfb->deferred_free)) { struct dlfb_deferred_free *d = list_entry(dlfb->deferred_free.next, struct dlfb_deferred_free, list); @@ -957,40 +958,13 @@ static void dlfb_free(struct kref *kref) } vfree(dlfb->backing_buffer); kfree(dlfb->edid); + usb_put_dev(dlfb->udev); kfree(dlfb); + + /* Assume info structure is freed after this point */ + framebuffer_release(info); } -static void dlfb_free_framebuffer(struct dlfb_data *dlfb) -{ - struct fb_info *info = dlfb->info; - - if (info) { - unregister_framebuffer(info); - - if (info->cmap.len != 0) - fb_dealloc_cmap(&info->cmap); - if (info->monspecs.modedb) - fb_destroy_modedb(info->monspecs.modedb); - vfree(info->screen_base); - - fb_destroy_modelist(&info->modelist); - - dlfb->info = NULL; - - /* Assume info structure is freed after this point */ - framebuffer_release(info); - } - - /* ref taken in probe() as part of registering framebfufer */ - kref_put(&dlfb->kref, dlfb_free); -} - -static void dlfb_free_framebuffer_work(struct work_struct *work) -{ - struct dlfb_data *dlfb = container_of(work, struct dlfb_data, - free_framebuffer_work.work); - dlfb_free_framebuffer(dlfb); -} /* * Assumes caller is holding info->lock mutex (for open and release at least) */ @@ -1000,10 +974,6 @@ static int dlfb_ops_release(struct fb_info *info, int user) dlfb->fb_count--; - /* We can't free fb_info here - fbmem will touch it when we return */ - if (dlfb->virtualized && (dlfb->fb_count == 0)) - schedule_delayed_work(&dlfb->free_framebuffer_work, HZ); - if ((dlfb->fb_count == 0) && (info->fbdefio)) { fb_deferred_io_cleanup(info); kfree(info->fbdefio); @@ -1013,8 +983,6 @@ static int dlfb_ops_release(struct fb_info *info, int user) dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count); - kref_put(&dlfb->kref, dlfb_free); - return 0; } @@ -1172,6 +1140,7 @@ static struct fb_ops dlfb_ops = { .fb_blank = dlfb_ops_blank, .fb_check_var = dlfb_ops_check_var, .fb_set_par = dlfb_ops_set_par, + .fb_destroy = dlfb_ops_destroy, }; @@ -1615,12 +1584,13 @@ success: return true; } -static void dlfb_init_framebuffer_work(struct work_struct *work); - static int dlfb_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { + int i; + const struct device_attribute *attr; struct dlfb_data *dlfb; + struct fb_info *info; int retval = -ENOMEM; struct usb_device *usbdev = interface_to_usbdev(intf); @@ -1631,10 +1601,9 @@ static int dlfb_usb_probe(struct usb_interface *intf, goto error; } - kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */ INIT_LIST_HEAD(&dlfb->deferred_free); - dlfb->udev = usbdev; + dlfb->udev = usb_get_dev(usbdev); usb_set_intfdata(intf, dlfb); dev_dbg(&intf->dev, "console enable=%d\n", console); @@ -1657,42 +1626,6 @@ static int dlfb_usb_probe(struct usb_interface *intf, } - if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { - retval = -ENOMEM; - dev_err(&intf->dev, "unable to allocate urb list\n"); - goto error; - } - - kref_get(&dlfb->kref); /* matching kref_put in free_framebuffer_work */ - - /* We don't register a new USB class. Our client interface is dlfbev */ - - /* Workitem keep things fast & simple during USB enumeration */ - INIT_DELAYED_WORK(&dlfb->init_framebuffer_work, - dlfb_init_framebuffer_work); - schedule_delayed_work(&dlfb->init_framebuffer_work, 0); - - return 0; - -error: - if (dlfb) { - - kref_put(&dlfb->kref, dlfb_free); /* last ref from kref_init */ - - /* dev has been deallocated. Do not dereference */ - } - - return retval; -} - -static void dlfb_init_framebuffer_work(struct work_struct *work) -{ - int i, retval; - struct fb_info *info; - const struct device_attribute *attr; - struct dlfb_data *dlfb = container_of(work, struct dlfb_data, - init_framebuffer_work.work); - /* allocates framebuffer driver structure, not framebuffer memory */ info = framebuffer_alloc(0, &dlfb->udev->dev); if (!info) { @@ -1706,17 +1639,22 @@ static void dlfb_init_framebuffer_work(struct work_struct *work) dlfb->ops = dlfb_ops; info->fbops = &dlfb->ops; + INIT_LIST_HEAD(&info->modelist); + + if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) { + retval = -ENOMEM; + dev_err(&intf->dev, "unable to allocate urb list\n"); + goto error; + } + + /* We don't register a new USB class. Our client interface is dlfbev */ + retval = fb_alloc_cmap(&info->cmap, 256, 0); if (retval < 0) { dev_err(info->device, "cmap allocation failed: %d\n", retval); goto error; } - INIT_DELAYED_WORK(&dlfb->free_framebuffer_work, - dlfb_free_framebuffer_work); - - INIT_LIST_HEAD(&info->modelist); - retval = dlfb_setup_modes(dlfb, info, NULL, 0); if (retval != 0) { dev_err(info->device, @@ -1760,10 +1698,16 @@ static void dlfb_init_framebuffer_work(struct work_struct *work) dev_name(info->dev), info->var.xres, info->var.yres, ((dlfb->backing_buffer) ? info->fix.smem_len * 2 : info->fix.smem_len) >> 10); - return; + return 0; error: - dlfb_free_framebuffer(dlfb); + if (dlfb->info) { + dlfb_ops_destroy(dlfb->info); + } else if (dlfb) { + usb_put_dev(dlfb->udev); + kfree(dlfb); + } + return retval; } static void dlfb_usb_disconnect(struct usb_interface *intf) @@ -1791,20 +1735,9 @@ static void dlfb_usb_disconnect(struct usb_interface *intf) for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) device_remove_file(info->dev, &fb_device_attrs[i]); device_remove_bin_file(info->dev, &edid_attr); - unlink_framebuffer(info); } - usb_set_intfdata(intf, NULL); - dlfb->udev = NULL; - - /* if clients still have us open, will be freed on last close */ - if (dlfb->fb_count == 0) - schedule_delayed_work(&dlfb->free_framebuffer_work, 0); - - /* release reference taken by kref_init in probe() */ - kref_put(&dlfb->kref, dlfb_free); - - /* consider dlfb_data freed */ + unregister_framebuffer(info); } static struct usb_driver dlfb_driver = { diff --git a/include/video/udlfb.h b/include/video/udlfb.h index 3abd327bada6..7d09e54ae54e 100644 --- a/include/video/udlfb.h +++ b/include/video/udlfb.h @@ -36,12 +36,9 @@ struct dlfb_data { struct usb_device *udev; struct fb_info *info; struct urb_list urbs; - struct kref kref; char *backing_buffer; int fb_count; bool virtualized; /* true when physical usb device not present */ - struct delayed_work init_framebuffer_work; - struct delayed_work free_framebuffer_work; atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */ atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */ char *edid; /* null until we read edid from hw or get from sysfs */ From ceadddde8875bda7af3824244de3d93e386d08c1 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 8 Oct 2018 12:57:34 +0200 Subject: [PATCH 232/836] mach64: detect the dot clock divider correctly on sparc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Sun Ultra 5, it happens that the dot clock is not set up properly for some videomodes. For example, if we set the videomode "r1024x768x60" in the firmware, Linux would incorrectly set a videomode with refresh rate 180Hz when booting (suprisingly, my LCD monitor can display it, although display quality is very low). The reason is this: Older mach64 cards set the divider in the register VCLK_POST_DIV. The register has four 2-bit fields (the field that is actually used is specified in the lowest two bits of the register CLOCK_CNTL). The 2 bits select divider "1, 2, 4, 8". On newer mach64 cards, there's another bit added - the top four bits of PLL_EXT_CNTL extend the divider selection, so we have possible dividers "1, 2, 4, 8, 3, 5, 6, 12". The Linux driver clears the top four bits of PLL_EXT_CNTL and never sets them, so it can work regardless if the card supports them. However, the sparc64 firmware may set these extended dividers during boot - and the mach64 driver detects incorrect dot clock in this case. This patch makes the driver read the additional divider bit from PLL_EXT_CNTL and calculate the initial refresh rate properly. Signed-off-by: Mikulas Patocka Acked-by: David S. Miller Reviewed-by: Ville Syrjälä Cc: stable@vger.kernel.org Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/aty/atyfb.h | 3 ++- drivers/video/fbdev/aty/atyfb_base.c | 7 ++++--- drivers/video/fbdev/aty/mach64_ct.c | 10 +++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h index 8235b285dbb2..d09bab3bf224 100644 --- a/drivers/video/fbdev/aty/atyfb.h +++ b/drivers/video/fbdev/aty/atyfb.h @@ -333,6 +333,8 @@ extern const struct aty_pll_ops aty_pll_ct; /* Integrated */ extern void aty_set_pll_ct(const struct fb_info *info, const union aty_pll *pll); extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); +extern const u8 aty_postdividers[8]; + /* * Hardware cursor support @@ -359,7 +361,6 @@ static inline void wait_for_idle(struct atyfb_par *par) extern void aty_reset_engine(const struct atyfb_par *par); extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); -extern u8 aty_ld_pll_ct(int offset, const struct atyfb_par *par); void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index a9a8272f7a6e..05111e90f168 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -3087,17 +3087,18 @@ static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, /* * PLL Reference Divider M: */ - M = pll_regs[2]; + M = pll_regs[PLL_REF_DIV]; /* * PLL Feedback Divider N (Dependent on CLOCK_CNTL): */ - N = pll_regs[7 + (clock_cntl & 3)]; + N = pll_regs[VCLK0_FB_DIV + (clock_cntl & 3)]; /* * PLL Post Divider P (Dependent on CLOCK_CNTL): */ - P = 1 << (pll_regs[6] >> ((clock_cntl & 3) << 1)); + P = aty_postdividers[((pll_regs[VCLK_POST_DIV] >> ((clock_cntl & 3) << 1)) & 3) | + ((pll_regs[PLL_EXT_CNTL] >> (2 + (clock_cntl & 3))) & 4)]; /* * PLL Divider Q: diff --git a/drivers/video/fbdev/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c index 74a62aa193c0..f87cc81f4fa2 100644 --- a/drivers/video/fbdev/aty/mach64_ct.c +++ b/drivers/video/fbdev/aty/mach64_ct.c @@ -115,7 +115,7 @@ static void aty_st_pll_ct(int offset, u8 val, const struct atyfb_par *par) */ #define Maximum_DSP_PRECISION 7 -static u8 postdividers[] = {1,2,4,8,3}; +const u8 aty_postdividers[8] = {1,2,4,8,3,5,6,12}; static int aty_dsp_gt(const struct fb_info *info, u32 bpp, struct pll_ct *pll) { @@ -222,7 +222,7 @@ static int aty_valid_pll_ct(const struct fb_info *info, u32 vclk_per, struct pll pll->vclk_post_div += (q < 64*8); pll->vclk_post_div += (q < 32*8); } - pll->vclk_post_div_real = postdividers[pll->vclk_post_div]; + pll->vclk_post_div_real = aty_postdividers[pll->vclk_post_div]; // pll->vclk_post_div <<= 6; pll->vclk_fb_div = q * pll->vclk_post_div_real / 8; pllvclk = (1000000 * 2 * pll->vclk_fb_div) / @@ -513,7 +513,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll) u8 mclk_fb_div, pll_ext_cntl; pll->ct.pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par); pll_ext_cntl = aty_ld_pll_ct(PLL_EXT_CNTL, par); - pll->ct.xclk_post_div_real = postdividers[pll_ext_cntl & 0x07]; + pll->ct.xclk_post_div_real = aty_postdividers[pll_ext_cntl & 0x07]; mclk_fb_div = aty_ld_pll_ct(MCLK_FB_DIV, par); if (pll_ext_cntl & PLL_MFB_TIMES_4_2B) mclk_fb_div <<= 1; @@ -535,7 +535,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll) xpost_div += (q < 64*8); xpost_div += (q < 32*8); } - pll->ct.xclk_post_div_real = postdividers[xpost_div]; + pll->ct.xclk_post_div_real = aty_postdividers[xpost_div]; pll->ct.mclk_fb_div = q * pll->ct.xclk_post_div_real / 8; #ifdef CONFIG_PPC @@ -584,7 +584,7 @@ static int aty_init_pll_ct(const struct fb_info *info, union aty_pll *pll) mpost_div += (q < 64*8); mpost_div += (q < 32*8); } - sclk_post_div_real = postdividers[mpost_div]; + sclk_post_div_real = aty_postdividers[mpost_div]; pll->ct.sclk_fb_div = q * sclk_post_div_real / 8; pll->ct.spll_cntl2 = mpost_div << 4; #ifdef DEBUG From 3c6c6a7878d00a3ac997a779c5b9861ff25dfcc8 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 8 Oct 2018 12:57:34 +0200 Subject: [PATCH 233/836] mach64: fix display corruption on big endian machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code for manual bit triple is not endian-clean. It builds the variable "hostdword" using byte accesses, therefore we must read the variable with "le32_to_cpu". The patch also enables (hardware or software) bit triple only if the image is monochrome (image->depth). If we want to blit full-color image, we shouldn't use the triple code. Signed-off-by: Mikulas Patocka Reviewed-by: Ville Syrjälä Cc: stable@vger.kernel.org Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/aty/mach64_accel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index 2541a0e0de76..7c53a2380cc8 100644 --- a/drivers/video/fbdev/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -345,7 +345,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) * since Rage 3D IIc we have DP_HOST_TRIPLE_EN bit * this hwaccelerated triple has an issue with not aligned data */ - if (M64_HAS(HW_TRIPLE) && image->width % 8 == 0) + if (image->depth == 1 && M64_HAS(HW_TRIPLE) && image->width % 8 == 0) pix_width |= DP_HOST_TRIPLE_EN; } @@ -382,7 +382,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) src_bytes = (((image->width * image->depth) + 7) / 8) * image->height; /* manual triple each pixel */ - if (info->var.bits_per_pixel == 24 && !(pix_width & DP_HOST_TRIPLE_EN)) { + if (image->depth == 1 && info->var.bits_per_pixel == 24 && !(pix_width & DP_HOST_TRIPLE_EN)) { int inbit, outbit, mult24, byte_id_in_dword, width; u8 *pbitmapin = (u8*)image->data, *pbitmapout; u32 hostdword; @@ -415,7 +415,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) } } wait_for_fifo(1, par); - aty_st_le32(HOST_DATA0, hostdword, par); + aty_st_le32(HOST_DATA0, le32_to_cpu(hostdword), par); } } else { u32 *pbitmap, dwords = (src_bytes + 3) / 4; From c09bcc91bb94ed91f1391bffcbe294963d605732 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 8 Oct 2018 12:57:35 +0200 Subject: [PATCH 234/836] mach64: fix image corruption due to reading accelerator registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading the registers without waiting for engine idle returns unpredictable values. These unpredictable values result in display corruption - if atyfb_imageblit reads the content of DP_PIX_WIDTH with the bit DP_HOST_TRIPLE_EN set (from previous invocation), the driver would never ever clear the bit, resulting in display corruption. We don't want to wait for idle because it would degrade performance, so this patch modifies the driver so that it never reads accelerator registers. HOST_CNTL doesn't have to be read, we can just write it with HOST_BYTE_ALIGN because no other part of the driver cares if HOST_BYTE_ALIGN is set. DP_PIX_WIDTH is written in the functions atyfb_copyarea and atyfb_fillrect with the default value and in atyfb_imageblit with the value set according to the source image data. Signed-off-by: Mikulas Patocka Reviewed-by: Ville Syrjälä Cc: stable@vger.kernel.org Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/aty/mach64_accel.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/video/fbdev/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index 7c53a2380cc8..3ad46255f990 100644 --- a/drivers/video/fbdev/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -127,7 +127,7 @@ void aty_init_engine(struct atyfb_par *par, struct fb_info *info) /* set host attributes */ wait_for_fifo(13, par); - aty_st_le32(HOST_CNTL, 0, par); + aty_st_le32(HOST_CNTL, HOST_BYTE_ALIGN, par); /* set pattern attributes */ aty_st_le32(PAT_REG0, 0, par); @@ -233,7 +233,8 @@ void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) rotation = rotation24bpp(dx, direction); } - wait_for_fifo(4, par); + wait_for_fifo(5, par); + aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par); aty_st_le32(DP_SRC, FRGD_SRC_BLIT, par); aty_st_le32(SRC_Y_X, (sx << 16) | sy, par); aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | area->height, par); @@ -269,7 +270,8 @@ void atyfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) rotation = rotation24bpp(dx, DST_X_LEFT_TO_RIGHT); } - wait_for_fifo(3, par); + wait_for_fifo(4, par); + aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, par); aty_st_le32(DP_FRGD_CLR, color, par); aty_st_le32(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE, @@ -284,7 +286,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct atyfb_par *par = (struct atyfb_par *) info->par; u32 src_bytes, dx = image->dx, dy = image->dy, width = image->width; - u32 pix_width_save, pix_width, host_cntl, rotation = 0, src, mix; + u32 pix_width, rotation = 0, src, mix; if (par->asleep) return; @@ -296,8 +298,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) return; } - pix_width = pix_width_save = aty_ld_le32(DP_PIX_WIDTH, par); - host_cntl = aty_ld_le32(HOST_CNTL, par) | HOST_BYTE_ALIGN; + pix_width = par->crtc.dp_pix_width; switch (image->depth) { case 1: @@ -370,12 +371,11 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) mix = FRGD_MIX_D_XOR_S | BKGD_MIX_D; } - wait_for_fifo(6, par); - aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, par); + wait_for_fifo(5, par); aty_st_le32(DP_PIX_WIDTH, pix_width, par); aty_st_le32(DP_MIX, mix, par); aty_st_le32(DP_SRC, src, par); - aty_st_le32(HOST_CNTL, host_cntl, par); + aty_st_le32(HOST_CNTL, HOST_BYTE_ALIGN, par); aty_st_le32(DST_CNTL, DST_Y_TOP_TO_BOTTOM | DST_X_LEFT_TO_RIGHT | rotation, par); draw_rect(dx, dy, width, image->height, par); @@ -424,8 +424,4 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image) aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par); } } - - /* restore pix_width */ - wait_for_fifo(1, par); - aty_st_le32(DP_PIX_WIDTH, pix_width_save, par); } From 01c40a17249727472da3f52e2f344cc2cc4138c4 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 8 Oct 2018 12:57:35 +0200 Subject: [PATCH 235/836] mach64: optimize wait_for_fifo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a simple optimization for fifo waiting that improves scrolling performance by 5%. If the queue has more free entries that what we consume, we can skip the costly register read next time. Signed-off-by: Mikulas Patocka Reviewed-by: Ville Syrjälä Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/aty/atyfb.h | 12 ++++++++---- drivers/video/fbdev/aty/mach64_accel.c | 4 +++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h index d09bab3bf224..e5a347c58180 100644 --- a/drivers/video/fbdev/aty/atyfb.h +++ b/drivers/video/fbdev/aty/atyfb.h @@ -147,6 +147,7 @@ struct atyfb_par { u16 pci_id; u32 accel_flags; int blitter_may_be_busy; + unsigned fifo_space; int asleep; int lock_blank; unsigned long res_start; @@ -346,10 +347,13 @@ extern int aty_init_cursor(struct fb_info *info); * Hardware acceleration */ -static inline void wait_for_fifo(u16 entries, const struct atyfb_par *par) +static inline void wait_for_fifo(u16 entries, struct atyfb_par *par) { - while ((aty_ld_le32(FIFO_STAT, par) & 0xffff) > - ((u32) (0x8000 >> entries))); + unsigned fifo_space = par->fifo_space; + while (entries > fifo_space) { + fifo_space = 16 - fls(aty_ld_le32(FIFO_STAT, par) & 0xffff); + } + par->fifo_space = fifo_space - entries; } static inline void wait_for_idle(struct atyfb_par *par) @@ -359,7 +363,7 @@ static inline void wait_for_idle(struct atyfb_par *par) par->blitter_may_be_busy = 0; } -extern void aty_reset_engine(const struct atyfb_par *par); +extern void aty_reset_engine(struct atyfb_par *par); extern void aty_init_engine(struct atyfb_par *par, struct fb_info *info); void atyfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); diff --git a/drivers/video/fbdev/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index 3ad46255f990..e4b2c89baee2 100644 --- a/drivers/video/fbdev/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -37,7 +37,7 @@ static u32 rotation24bpp(u32 dx, u32 direction) return ((rotation << 8) | DST_24_ROTATION_ENABLE); } -void aty_reset_engine(const struct atyfb_par *par) +void aty_reset_engine(struct atyfb_par *par) { /* reset engine */ aty_st_le32(GEN_TEST_CNTL, @@ -50,6 +50,8 @@ void aty_reset_engine(const struct atyfb_par *par) /* HOST errors */ aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, par) | BUS_HOST_ERR_ACK | BUS_FIFO_ERR_ACK, par); + + par->fifo_space = 0; } static void reset_GTC_3D_engine(const struct atyfb_par *par) From ee6fbb20ab76a08c6623dc59a70db996f44b8ff9 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 8 Oct 2018 12:57:35 +0200 Subject: [PATCH 236/836] atyfb: fix debugging printks This patch fixes the debugging printks. Use pr_cont, so that the lines are not broken up. Use printk when starting a new line (a long string of pr_cont's without any printks causes missing characters in the console output on sparc). Signed-off-by: Mikulas Patocka Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/aty/atyfb_base.c | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 05111e90f168..b6fe103df145 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -1480,24 +1480,28 @@ static int atyfb_set_par(struct fb_info *info) base = 0x2000; printk("debug atyfb: Mach64 non-shadow register values:"); for (i = 0; i < 256; i = i+4) { - if (i % 16 == 0) - printk("\ndebug atyfb: 0x%04X: ", base + i); - printk(" %08X", aty_ld_le32(i, par)); + if (i % 16 == 0) { + pr_cont("\n"); + printk("debug atyfb: 0x%04X: ", base + i); + } + pr_cont(" %08X", aty_ld_le32(i, par)); } - printk("\n\n"); + pr_cont("\n\n"); #ifdef CONFIG_FB_ATY_CT /* PLL registers */ base = 0x00; printk("debug atyfb: Mach64 PLL register values:"); for (i = 0; i < 64; i++) { - if (i % 16 == 0) - printk("\ndebug atyfb: 0x%02X: ", base + i); + if (i % 16 == 0) { + pr_cont("\n"); + printk("debug atyfb: 0x%02X: ", base + i); + } if (i % 4 == 0) - printk(" "); - printk("%02X", aty_ld_pll_ct(i, par)); + pr_cont(" "); + pr_cont("%02X", aty_ld_pll_ct(i, par)); } - printk("\n\n"); + pr_cont("\n\n"); #endif /* CONFIG_FB_ATY_CT */ #ifdef CONFIG_FB_ATY_GENERIC_LCD @@ -1509,19 +1513,19 @@ static int atyfb_set_par(struct fb_info *info) for (i = 0; i <= POWER_MANAGEMENT; i++) { if (i == EXT_VERT_STRETCH) continue; - printk("\ndebug atyfb: 0x%04X: ", + pr_cont("\ndebug atyfb: 0x%04X: ", lt_lcd_regs[i]); - printk(" %08X", aty_ld_lcd(i, par)); + pr_cont(" %08X", aty_ld_lcd(i, par)); } } else { for (i = 0; i < 64; i++) { if (i % 4 == 0) - printk("\ndebug atyfb: 0x%02X: ", + pr_cont("\ndebug atyfb: 0x%02X: ", base + i); - printk(" %08X", aty_ld_lcd(i, par)); + pr_cont(" %08X", aty_ld_lcd(i, par)); } } - printk("\n\n"); + pr_cont("\n\n"); } #endif /* CONFIG_FB_ATY_GENERIC_LCD */ } @@ -2597,8 +2601,8 @@ static int aty_init(struct fb_info *info) aty_ld_le32(DSP_ON_OFF, par), aty_ld_le32(CLOCK_CNTL, par)); for (i = 0; i < 40; i++) - printk(" %02x", aty_ld_pll_ct(i, par)); - printk("\n"); + pr_cont(" %02x", aty_ld_pll_ct(i, par)); + pr_cont("\n"); } #endif if (par->pll_ops->init_pll) From 811ab8db890714e6644dae09366ef2820ca11272 Mon Sep 17 00:00:00 2001 From: Mehdi Bounya Date: Mon, 8 Oct 2018 12:57:35 +0200 Subject: [PATCH 237/836] Video: vgastate: fixed a spacing coding style Removed a space between function name and open parant. Signed-off-by: Mehdi Bounya Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/vgastate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index 548c751d2415..122fb3c3ec9d 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c @@ -455,7 +455,7 @@ int save_vga(struct vgastate *state) return 0; } -int restore_vga (struct vgastate *state) +int restore_vga(struct vgastate *state) { if (state->vidstate == NULL) return 1; From 60e5e48dba72c6b59a7a9c7686ba320766913368 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 8 Oct 2018 12:57:35 +0200 Subject: [PATCH 238/836] atmel_lcdfb: support native-mode display-timings When a device tree set a display-timing using native-mode then according to the bindings doc this should: native-mode: The native mode for the display, in case multiple modes are provided. When omitted, assume the first node is the native. The atmel_lcdfb used the last timing subnode and did not respect the timing mode specified with native-mode. Introduce use of of_get_videomode() which allowed a nice simplification of the code while also added support for native-mode. As a nice side-effect this fixes a memory leak where the data used for timings and the display_np was not freed. Signed-off-by: Sam Ravnborg Cc: Nicolas Ferre Cc: Alexandre Belloni Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/video/fbdev/atmel_lcdfb.c | 43 +++++++------------------------ 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 076d24afbd72..4ed55e6bbb84 100644 --- a/drivers/video/fbdev/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -22,6 +22,7 @@ #include #include #include +#include