Merge tag 'renesas-clk-for-v6.9-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas

Pull Renesas clk driver updates from Geert Uytterhoeven:

 - Ignore all clocks which are assigned to a non-Linux system
 - Add watchdog clock on RZ/G3S
 - Add camera (CRU) clock and reset on RZ/G2UL
 - Add support for the R-Car V4M (R8A779H0) SoC
 - Miscellaneous fixes and improvements

* tag 'renesas-clk-for-v6.9-tag1' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers:
  clk: renesas: r8a779h0: Add I2C clocks
  clk: renesas: r8a779h0: Add watchdog clock
  clk: renesas: r8a779h0: Add PFC/GPIO clocks
  clk: renesas: r8a779g0: Fix PCIe clock name
  clk: renesas: cpg-mssr: Add support for R-Car V4M
  clk: renesas: rcar-gen4: Add support for FRQCRC1
  clk: renesas: r9a07g043: Add clock and reset entries for CRU
  clk: renesas: r9a08g045: Add clock and reset support for watchdog
  dt-bindings: clock: Add R8A779H0 V4M CPG Core Clock Definitions
  dt-bindings: clock: renesas,cpg-mssr: Document R-Car V4M support
  dt-bindings: power: Add r8a779h0 SYSC power domain definitions
  dt-bindings: power: renesas,rcar-sysc: Document R-Car V4M support
  clk: renesas: mstp: Remove obsolete clkdev registration
  clk: renesas: cpg-mssr: Ignore all clocks assigned to non-Linux system
  of: Add for_each_reserved_child_of_node()
  of: Add of_get_next_status_child() and makes more generic of_get_next
  of: Add __of_device_is_status() and makes more generic status check
This commit is contained in:
Stephen Boyd
2024-02-19 11:16:32 -08:00
16 changed files with 657 additions and 59 deletions

View File

@@ -50,6 +50,7 @@ properties:
- renesas,r8a779a0-cpg-mssr # R-Car V3U
- renesas,r8a779f0-cpg-mssr # R-Car S4-8
- renesas,r8a779g0-cpg-mssr # R-Car V4H
- renesas,r8a779h0-cpg-mssr # R-Car V4M
reg:
maxItems: 1

View File

@@ -45,6 +45,7 @@ properties:
- renesas,r8a779a0-sysc # R-Car V3U
- renesas,r8a779f0-sysc # R-Car S4-8
- renesas,r8a779g0-sysc # R-Car V4H
- renesas,r8a779h0-sysc # R-Car V4M
reg:
maxItems: 1

View File

@@ -33,6 +33,7 @@ config CLK_RENESAS
select CLK_R8A779A0 if ARCH_R8A779A0
select CLK_R8A779F0 if ARCH_R8A779F0
select CLK_R8A779G0 if ARCH_R8A779G0
select CLK_R8A779H0 if ARCH_R8A779H0
select CLK_R9A06G032 if ARCH_R9A06G032
select CLK_R9A07G043 if ARCH_R9A07G043
select CLK_R9A07G044 if ARCH_R9A07G044
@@ -165,6 +166,10 @@ config CLK_R8A779G0
bool "R-Car V4H clock support" if COMPILE_TEST
select CLK_RCAR_GEN4_CPG
config CLK_R8A779H0
bool "R-Car V4M clock support" if COMPILE_TEST
select CLK_RCAR_GEN4_CPG
config CLK_R9A06G032
bool "RZ/N1D clock support" if COMPILE_TEST

View File

@@ -30,6 +30,7 @@ obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o
obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o
obj-$(CONFIG_CLK_R8A779F0) += r8a779f0-cpg-mssr.o
obj-$(CONFIG_CLK_R8A779G0) += r8a779g0-cpg-mssr.o
obj-$(CONFIG_CLK_R8A779H0) += r8a779h0-cpg-mssr.o
obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o
obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o

View File

@@ -10,7 +10,6 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/clk/renesas.h>
#include <linux/device.h>
#include <linux/io.h>
@@ -19,6 +18,7 @@
#include <linux/of_address.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
/*
@@ -237,22 +237,12 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
clks[clkidx] = cpg_mstp_clock_register(name, parent_name,
clkidx, group);
if (!IS_ERR(clks[clkidx])) {
if (!IS_ERR(clks[clkidx]))
group->data.clk_num = max(group->data.clk_num,
clkidx + 1);
/*
* Register a clkdev to let board code retrieve the
* clock by name and register aliases for non-DT
* devices.
*
* FIXME: Remove this when all devices that require a
* clock will be instantiated from DT.
*/
clk_register_clkdev(clks[clkidx], name, NULL);
} else {
else
pr_err("%s: failed to register %pOFn %s clock (%ld)\n",
__func__, np, name, PTR_ERR(clks[clkidx]));
}
}
of_clk_add_provider(np, of_clk_src_onecell_get, &group->data);

View File

@@ -193,7 +193,7 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
DEF_MOD("msi4", 622, R8A779G0_CLK_MSO),
DEF_MOD("msi5", 623, R8A779G0_CLK_MSO),
DEF_MOD("pciec0", 624, R8A779G0_CLK_S0D2_HSC),
DEF_MOD("pscie1", 625, R8A779G0_CLK_S0D2_HSC),
DEF_MOD("pciec1", 625, R8A779G0_CLK_S0D2_HSC),
DEF_MOD("pwm", 628, R8A779G0_CLK_SASYNCPERD4),
DEF_MOD("rpc-if", 629, R8A779G0_CLK_RPCD2),
DEF_MOD("scif0", 702, R8A779G0_CLK_SASYNCPERD4),

View File

@@ -0,0 +1,249 @@
// SPDX-License-Identifier: GPL-2.0
/*
* r8a779h0 Clock Pulse Generator / Module Standby and Software Reset
*
* Copyright (C) 2023 Renesas Electronics Corp.
*
* Based on r8a779g0-cpg-mssr.c
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/soc/renesas/rcar-rst.h>
#include <dt-bindings/clock/renesas,r8a779h0-cpg-mssr.h>
#include "renesas-cpg-mssr.h"
#include "rcar-gen4-cpg.h"
enum clk_ids {
/* Core Clock Outputs exported to DT */
LAST_DT_CORE_CLK = R8A779H0_CLK_R,
/* External Input Clocks */
CLK_EXTAL,
CLK_EXTALR,
/* Internal Core Clocks */
CLK_MAIN,
CLK_PLL1,
CLK_PLL2,
CLK_PLL3,
CLK_PLL4,
CLK_PLL5,
CLK_PLL6,
CLK_PLL1_DIV2,
CLK_PLL2_DIV2,
CLK_PLL3_DIV2,
CLK_PLL4_DIV2,
CLK_PLL4_DIV5,
CLK_PLL5_DIV2,
CLK_PLL5_DIV4,
CLK_PLL6_DIV2,
CLK_S0,
CLK_S0_VIO,
CLK_S0_VC,
CLK_S0_HSC,
CLK_SASYNCPER,
CLK_SV_VIP,
CLK_SV_IR,
CLK_IMPASRC,
CLK_IMPBSRC,
CLK_VIOSRC,
CLK_VCSRC,
CLK_SDSRC,
CLK_RPCSRC,
CLK_OCO,
/* Module Clocks */
MOD_CLK_BASE
};
static const struct cpg_core_clk r8a779h0_core_clks[] = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
DEF_INPUT("extalr", CLK_EXTALR),
/* Internal Core Clocks */
DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN4_MAIN, CLK_EXTAL),
DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN4_PLL1, CLK_MAIN),
DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN4_PLL2, CLK_MAIN),
DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN4_PLL3, CLK_MAIN),
DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN4_PLL4, CLK_MAIN),
DEF_BASE(".pll5", CLK_PLL5, CLK_TYPE_GEN4_PLL5, CLK_MAIN),
DEF_BASE(".pll6", CLK_PLL6, CLK_TYPE_GEN4_PLL6, CLK_MAIN),
DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 2, 1),
DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 2, 1),
DEF_FIXED(".pll4_div2", CLK_PLL4_DIV2, CLK_PLL4, 2, 1),
DEF_FIXED(".pll4_div5", CLK_PLL4_DIV5, CLK_PLL4, 5, 1),
DEF_FIXED(".pll5_div2", CLK_PLL5_DIV2, CLK_PLL5, 2, 1),
DEF_FIXED(".pll5_div4", CLK_PLL5_DIV4, CLK_PLL5_DIV2, 2, 1),
DEF_FIXED(".pll6_div2", CLK_PLL6_DIV2, CLK_PLL6, 2, 1),
DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1),
DEF_FIXED(".s0_vio", CLK_S0_VIO, CLK_PLL1_DIV2, 2, 1),
DEF_FIXED(".s0_vc", CLK_S0_VC, CLK_PLL1_DIV2, 2, 1),
DEF_FIXED(".s0_hsc", CLK_S0_HSC, CLK_PLL1_DIV2, 2, 1),
DEF_FIXED(".sasyncper", CLK_SASYNCPER, CLK_PLL5_DIV4, 3, 1),
DEF_FIXED(".sv_vip", CLK_SV_VIP, CLK_PLL1, 5, 1),
DEF_FIXED(".sv_ir", CLK_SV_IR, CLK_PLL1, 5, 1),
DEF_FIXED(".impasrc", CLK_IMPASRC, CLK_PLL1_DIV2, 2, 1),
DEF_FIXED(".impbsrc", CLK_IMPBSRC, CLK_PLL1, 4, 1),
DEF_FIXED(".viosrc", CLK_VIOSRC, CLK_PLL1, 6, 1),
DEF_FIXED(".vcsrc", CLK_VCSRC, CLK_PLL1, 6, 1),
DEF_BASE(".sdsrc", CLK_SDSRC, CLK_TYPE_GEN4_SDSRC, CLK_PLL5),
DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN4_RPCSRC, CLK_PLL5),
DEF_RATE(".oco", CLK_OCO, 32768),
/* Core Clock Outputs */
DEF_GEN4_Z("zc0", R8A779H0_CLK_ZC0, CLK_TYPE_GEN4_Z, CLK_PLL2_DIV2, 2, 0),
DEF_GEN4_Z("zc1", R8A779H0_CLK_ZC1, CLK_TYPE_GEN4_Z, CLK_PLL2_DIV2, 2, 8),
DEF_GEN4_Z("zc2", R8A779H0_CLK_ZC2, CLK_TYPE_GEN4_Z, CLK_PLL2_DIV2, 2, 32),
DEF_GEN4_Z("zc3", R8A779H0_CLK_ZC3, CLK_TYPE_GEN4_Z, CLK_PLL2_DIV2, 2, 40),
DEF_FIXED("s0d2", R8A779H0_CLK_S0D2, CLK_S0, 2, 1),
DEF_FIXED("s0d3", R8A779H0_CLK_S0D3, CLK_S0, 3, 1),
DEF_FIXED("s0d4", R8A779H0_CLK_S0D4, CLK_S0, 4, 1),
DEF_FIXED("cl16m", R8A779H0_CLK_CL16M, CLK_S0, 48, 1),
DEF_FIXED("s0d2_rt", R8A779H0_CLK_S0D2_RT, CLK_S0, 2, 1),
DEF_FIXED("s0d3_rt", R8A779H0_CLK_S0D3_RT, CLK_S0, 3, 1),
DEF_FIXED("s0d4_rt", R8A779H0_CLK_S0D4_RT, CLK_S0, 4, 1),
DEF_FIXED("s0d6_rt", R8A779H0_CLK_S0D6_RT, CLK_S0, 6, 1),
DEF_FIXED("cl16m_rt", R8A779H0_CLK_CL16M_RT, CLK_S0, 48, 1),
DEF_FIXED("s0d2_per", R8A779H0_CLK_S0D2_PER, CLK_S0, 2, 1),
DEF_FIXED("s0d3_per", R8A779H0_CLK_S0D3_PER, CLK_S0, 3, 1),
DEF_FIXED("s0d4_per", R8A779H0_CLK_S0D4_PER, CLK_S0, 4, 1),
DEF_FIXED("s0d6_per", R8A779H0_CLK_S0D6_PER, CLK_S0, 6, 1),
DEF_FIXED("s0d12_per", R8A779H0_CLK_S0D12_PER, CLK_S0, 12, 1),
DEF_FIXED("s0d24_per", R8A779H0_CLK_S0D24_PER, CLK_S0, 24, 1),
DEF_FIXED("cl16m_per", R8A779H0_CLK_CL16M_PER, CLK_S0, 48, 1),
DEF_FIXED("s0d2_mm", R8A779H0_CLK_S0D2_MM, CLK_S0, 2, 1),
DEF_FIXED("s0d4_mm", R8A779H0_CLK_S0D4_MM, CLK_S0, 4, 1),
DEF_FIXED("cl16m_mm", R8A779H0_CLK_CL16M_MM, CLK_S0, 48, 1),
DEF_FIXED("s0d2_u3dg", R8A779H0_CLK_S0D2_U3DG, CLK_S0, 2, 1),
DEF_FIXED("s0d4_u3dg", R8A779H0_CLK_S0D4_U3DG, CLK_S0, 4, 1),
DEF_FIXED("s0d1_vio", R8A779H0_CLK_S0D1_VIO, CLK_S0_VIO, 1, 1),
DEF_FIXED("s0d2_vio", R8A779H0_CLK_S0D2_VIO, CLK_S0_VIO, 2, 1),
DEF_FIXED("s0d4_vio", R8A779H0_CLK_S0D4_VIO, CLK_S0_VIO, 4, 1),
DEF_FIXED("s0d8_vio", R8A779H0_CLK_S0D8_VIO, CLK_S0_VIO, 8, 1),
DEF_FIXED("s0d1_vc", R8A779H0_CLK_S0D1_VC, CLK_S0_VC, 1, 1),
DEF_FIXED("s0d2_vc", R8A779H0_CLK_S0D2_VC, CLK_S0_VC, 2, 1),
DEF_FIXED("s0d4_vc", R8A779H0_CLK_S0D4_VC, CLK_S0_VC, 4, 1),
DEF_FIXED("s0d1_hsc", R8A779H0_CLK_S0D1_HSC, CLK_S0_HSC, 1, 1),
DEF_FIXED("s0d2_hsc", R8A779H0_CLK_S0D2_HSC, CLK_S0_HSC, 2, 1),
DEF_FIXED("s0d4_hsc", R8A779H0_CLK_S0D4_HSC, CLK_S0_HSC, 4, 1),
DEF_FIXED("s0d8_hsc", R8A779H0_CLK_S0D8_HSC, CLK_S0_HSC, 8, 1),
DEF_FIXED("cl16m_hsc", R8A779H0_CLK_CL16M_HSC, CLK_S0_HSC, 48, 1),
DEF_FIXED("sasyncrt", R8A779H0_CLK_SASYNCRT, CLK_PLL5_DIV4, 48, 1),
DEF_FIXED("sasyncperd1", R8A779H0_CLK_SASYNCPERD1, CLK_SASYNCPER, 1, 1),
DEF_FIXED("sasyncperd2", R8A779H0_CLK_SASYNCPERD2, CLK_SASYNCPER, 2, 1),
DEF_FIXED("sasyncperd4", R8A779H0_CLK_SASYNCPERD4, CLK_SASYNCPER, 4, 1),
DEF_FIXED("svd1_vip", R8A779H0_CLK_SVD1_VIP, CLK_SV_VIP, 1, 1),
DEF_FIXED("svd2_vip", R8A779H0_CLK_SVD2_VIP, CLK_SV_VIP, 2, 1),
DEF_FIXED("svd1_ir", R8A779H0_CLK_SVD1_IR, CLK_SV_IR, 1, 1),
DEF_FIXED("svd2_ir", R8A779H0_CLK_SVD2_IR, CLK_SV_IR, 2, 1),
DEF_FIXED("cbfusa", R8A779H0_CLK_CBFUSA, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A779H0_CLK_CPEX, CLK_EXTAL, 2, 1),
DEF_FIXED("cp", R8A779H0_CLK_CP, CLK_EXTAL, 2, 1),
DEF_FIXED("impad1", R8A779H0_CLK_IMPAD1, CLK_IMPASRC, 1, 1),
DEF_FIXED("impad4", R8A779H0_CLK_IMPAD4, CLK_IMPASRC, 4, 1),
DEF_FIXED("impb", R8A779H0_CLK_IMPB, CLK_IMPBSRC, 1, 1),
DEF_FIXED("viobusd1", R8A779H0_CLK_VIOBUSD1, CLK_VIOSRC, 1, 1),
DEF_FIXED("viobusd2", R8A779H0_CLK_VIOBUSD2, CLK_VIOSRC, 2, 1),
DEF_FIXED("vcbusd1", R8A779H0_CLK_VCBUSD1, CLK_VCSRC, 1, 1),
DEF_FIXED("vcbusd2", R8A779H0_CLK_VCBUSD2, CLK_VCSRC, 2, 1),
DEF_DIV6P1("canfd", R8A779H0_CLK_CANFD, CLK_PLL5_DIV4, 0x878),
DEF_DIV6P1("csi", R8A779H0_CLK_CSI, CLK_PLL5_DIV4, 0x880),
DEF_FIXED("dsiref", R8A779H0_CLK_DSIREF, CLK_PLL5_DIV4, 48, 1),
DEF_DIV6P1("dsiext", R8A779H0_CLK_DSIEXT, CLK_PLL5_DIV4, 0x884),
DEF_DIV6P1("mso", R8A779H0_CLK_MSO, CLK_PLL5_DIV4, 0x87c),
DEF_GEN4_SDH("sd0h", R8A779H0_CLK_SD0H, CLK_SDSRC, 0x870),
DEF_GEN4_SD("sd0", R8A779H0_CLK_SD0, R8A779H0_CLK_SD0H, 0x870),
DEF_BASE("rpc", R8A779H0_CLK_RPC, CLK_TYPE_GEN4_RPC, CLK_RPCSRC),
DEF_BASE("rpcd2", R8A779H0_CLK_RPCD2, CLK_TYPE_GEN4_RPCD2, R8A779H0_CLK_RPC),
DEF_GEN4_OSC("osc", R8A779H0_CLK_OSC, CLK_EXTAL, 8),
DEF_GEN4_MDSEL("r", R8A779H0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
};
static const struct mssr_mod_clk r8a779h0_mod_clks[] = {
DEF_MOD("hscif0", 514, R8A779H0_CLK_SASYNCPERD1),
DEF_MOD("hscif1", 515, R8A779H0_CLK_SASYNCPERD1),
DEF_MOD("hscif2", 516, R8A779H0_CLK_SASYNCPERD1),
DEF_MOD("hscif3", 517, R8A779H0_CLK_SASYNCPERD1),
DEF_MOD("i2c0", 518, R8A779H0_CLK_S0D6_PER),
DEF_MOD("i2c1", 519, R8A779H0_CLK_S0D6_PER),
DEF_MOD("i2c2", 520, R8A779H0_CLK_S0D6_PER),
DEF_MOD("i2c3", 521, R8A779H0_CLK_S0D6_PER),
DEF_MOD("wdt1:wdt0", 907, R8A779H0_CLK_R),
DEF_MOD("pfc0", 915, R8A779H0_CLK_CP),
DEF_MOD("pfc1", 916, R8A779H0_CLK_CP),
DEF_MOD("pfc2", 917, R8A779H0_CLK_CP),
};
/*
* CPG Clock Data
*/
/*
* MD EXTAL PLL1 PLL2 PLL3 PLL4 PLL5 PLL6 OSC
* 14 13 (MHz)
* ------------------------------------------------------------------------
* 0 0 16.66 / 1 x192 x204 x192 x144 x192 x168 /16
* 0 1 20 / 1 x160 x170 x160 x120 x160 x140 /19
* 1 0 Prohibited setting
* 1 1 33.33 / 2 x192 x204 x192 x144 x192 x168 /32
*/
#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 13) | \
(((md) & BIT(13)) >> 13))
static const struct rcar_gen4_cpg_pll_config cpg_pll_configs[4] = {
/* EXTAL div PLL1 mult/div PLL2 mult/div PLL3 mult/div PLL4 mult/div PLL5 mult/div PLL6 mult/div OSC prediv */
{ 1, 192, 1, 240, 1, 192, 1, 240, 1, 192, 1, 168, 1, 16, },
{ 1, 160, 1, 200, 1, 160, 1, 200, 1, 160, 1, 140, 1, 19, },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 2, 192, 1, 240, 1, 192, 1, 240, 1, 192, 1, 168, 1, 32, },
};
static int __init r8a779h0_cpg_mssr_init(struct device *dev)
{
const struct rcar_gen4_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_gen4_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode);
}
const struct cpg_mssr_info r8a779h0_cpg_mssr_info __initconst = {
/* Core Clocks */
.core_clks = r8a779h0_core_clks,
.num_core_clks = ARRAY_SIZE(r8a779h0_core_clks),
.last_dt_core_clk = LAST_DT_CORE_CLK,
.num_total_core_clks = MOD_CLK_BASE,
/* Module Clocks */
.mod_clks = r8a779h0_mod_clks,
.num_mod_clks = ARRAY_SIZE(r8a779h0_mod_clks),
.num_hw_mod_clks = 30 * 32,
/* Callbacks */
.init = r8a779h0_cpg_mssr_init,
.cpg_clk_register = rcar_gen4_cpg_clk_register,
.reg_layout = CLK_REG_LAYOUT_RCAR_GEN4,
};

View File

@@ -48,6 +48,7 @@ enum clk_ids {
CLK_SEL_PLL3_3,
CLK_DIV_PLL3_C,
#ifdef CONFIG_ARM64
CLK_M2_DIV2,
CLK_PLL5,
CLK_PLL5_500,
CLK_PLL5_250,
@@ -142,6 +143,10 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
#ifdef CONFIG_ARM64
DEF_FIXED("M2", R9A07G043_CLK_M2, CLK_PLL3_533, 1, 2),
DEF_FIXED("M2_DIV2", CLK_M2_DIV2, R9A07G043_CLK_M2, 1, 2),
#endif
};
static struct rzg2l_mod_clk r9a07g043_mod_clks[] = {
@@ -195,6 +200,16 @@ static struct rzg2l_mod_clk r9a07g043_mod_clks[] = {
0x554, 6),
DEF_MOD("sdhi1_aclk", R9A07G043_SDHI1_ACLK, R9A07G043_CLK_P1,
0x554, 7),
#ifdef CONFIG_ARM64
DEF_MOD("cru_sysclk", R9A07G043_CRU_SYSCLK, CLK_M2_DIV2,
0x564, 0),
DEF_MOD("cru_vclk", R9A07G043_CRU_VCLK, R9A07G043_CLK_M2,
0x564, 1),
DEF_MOD("cru_pclk", R9A07G043_CRU_PCLK, R9A07G043_CLK_ZT,
0x564, 2),
DEF_MOD("cru_aclk", R9A07G043_CRU_ACLK, R9A07G043_CLK_M0,
0x564, 3),
#endif
DEF_MOD("ssi0_pclk", R9A07G043_SSI0_PCLK2, R9A07G043_CLK_P0,
0x570, 0),
DEF_MOD("ssi0_sfr", R9A07G043_SSI0_PCLK_SFR, R9A07G043_CLK_P0,
@@ -286,6 +301,11 @@ static struct rzg2l_reset r9a07g043_resets[] = {
DEF_RST(R9A07G043_SPI_RST, 0x850, 0),
DEF_RST(R9A07G043_SDHI0_IXRST, 0x854, 0),
DEF_RST(R9A07G043_SDHI1_IXRST, 0x854, 1),
#ifdef CONFIG_ARM64
DEF_RST(R9A07G043_CRU_CMN_RSTB, 0x864, 0),
DEF_RST(R9A07G043_CRU_PRESETN, 0x864, 1),
DEF_RST(R9A07G043_CRU_ARESETN, 0x864, 2),
#endif
DEF_RST(R9A07G043_SSI0_RST_M2_REG, 0x870, 0),
DEF_RST(R9A07G043_SSI1_RST_M2_REG, 0x870, 1),
DEF_RST(R9A07G043_SSI2_RST_M2_REG, 0x870, 2),
@@ -331,6 +351,13 @@ static const unsigned int r9a07g043_crit_mod_clks[] __initconst = {
MOD_CLK_BASE + R9A07G043_DMAC_ACLK,
};
#ifdef CONFIG_ARM64
static const unsigned int r9a07g043_no_pm_mod_clks[] = {
MOD_CLK_BASE + R9A07G043_CRU_SYSCLK,
MOD_CLK_BASE + R9A07G043_CRU_VCLK,
};
#endif
const struct rzg2l_cpg_info r9a07g043_cpg_info = {
/* Core Clocks */
.core_clks = r9a07g043_core_clks,
@@ -347,6 +374,10 @@ const struct rzg2l_cpg_info r9a07g043_cpg_info = {
.num_mod_clks = ARRAY_SIZE(r9a07g043_mod_clks),
#ifdef CONFIG_ARM64
.num_hw_mod_clks = R9A07G043_TSU_PCLK + 1,
/* No PM Module Clocks */
.no_pm_mod_clks = r9a07g043_no_pm_mod_clks,
.num_no_pm_mod_clks = ARRAY_SIZE(r9a07g043_no_pm_mod_clks),
#endif
#ifdef CONFIG_RISCV
.num_hw_mod_clks = R9A07G043_IAX45_PCLK + 1,

View File

@@ -193,6 +193,8 @@ static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = {
DEF_MOD("ia55_pclk", R9A08G045_IA55_PCLK, R9A08G045_CLK_P2, 0x518, 0),
DEF_MOD("ia55_clk", R9A08G045_IA55_CLK, R9A08G045_CLK_P1, 0x518, 1),
DEF_MOD("dmac_aclk", R9A08G045_DMAC_ACLK, R9A08G045_CLK_P3, 0x52c, 0),
DEF_MOD("wdt0_pclk", R9A08G045_WDT0_PCLK, R9A08G045_CLK_P0, 0x548, 0),
DEF_MOD("wdt0_clk", R9A08G045_WDT0_CLK, R9A08G045_OSCCLK, 0x548, 1),
DEF_MOD("sdhi0_imclk", R9A08G045_SDHI0_IMCLK, CLK_SD0_DIV4, 0x554, 0),
DEF_MOD("sdhi0_imclk2", R9A08G045_SDHI0_IMCLK2, CLK_SD0_DIV4, 0x554, 1),
DEF_MOD("sdhi0_clk_hs", R9A08G045_SDHI0_CLK_HS, R9A08G045_CLK_SD0, 0x554, 2),
@@ -219,6 +221,7 @@ static const struct rzg2l_reset r9a08g045_resets[] = {
DEF_RST(R9A08G045_GIC600_GICRESET_N, 0x814, 0),
DEF_RST(R9A08G045_GIC600_DBG_GICRESET_N, 0x814, 1),
DEF_RST(R9A08G045_IA55_RESETN, 0x818, 0),
DEF_RST(R9A08G045_WDT0_PRESETN, 0x848, 0),
DEF_RST(R9A08G045_SDHI0_IXRST, 0x854, 0),
DEF_RST(R9A08G045_SDHI1_IXRST, 0x854, 1),
DEF_RST(R9A08G045_SDHI2_IXRST, 0x854, 2),

View File

@@ -179,7 +179,8 @@ static struct clk * __init cpg_pll_clk_register(const char *name,
*/
#define CPG_FRQCRB 0x00000804
#define CPG_FRQCRB_KICK BIT(31)
#define CPG_FRQCRC 0x00000808
#define CPG_FRQCRC0 0x00000808
#define CPG_FRQCRC1 0x000008e0
struct cpg_z_clk {
struct clk_hw hw;
@@ -304,7 +305,12 @@ static struct clk * __init cpg_z_clk_register(const char *name,
init.parent_names = &parent_name;
init.num_parents = 1;
zclk->reg = reg + CPG_FRQCRC;
if (offset < 32) {
zclk->reg = reg + CPG_FRQCRC0;
} else {
zclk->reg = reg + CPG_FRQCRC1;
offset -= 32;
}
zclk->kick_reg = reg + CPG_FRQCRB;
zclk->hw.init = &init;
zclk->mask = GENMASK(offset + 4, offset);

View File

@@ -142,6 +142,8 @@ static const u16 srstclr_for_gen4[] = {
* @reset_clear_regs: Pointer to reset clearing registers array
* @smstpcr_saved: [].mask: Mask of SMSTPCR[] bits under our control
* [].val: Saved values of SMSTPCR[]
* @reserved_ids: Temporary used, reserved id list
* @num_reserved_ids: Temporary used, number of reserved id list
* @clks: Array containing all Core and Module Clocks
*/
struct cpg_mssr_priv {
@@ -168,6 +170,9 @@ struct cpg_mssr_priv {
u32 val;
} smstpcr_saved[ARRAY_SIZE(mstpsr_for_gen4)];
unsigned int *reserved_ids;
unsigned int num_reserved_ids;
struct clk *clks[];
};
@@ -453,6 +458,19 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
break;
}
/*
* Ignore reserved device.
* see
* cpg_mssr_reserved_init()
*/
for (i = 0; i < priv->num_reserved_ids; i++) {
if (id == priv->reserved_ids[i]) {
dev_info(dev, "Ignore Linux non-assigned mod (%s)\n", mod->name);
init.flags |= CLK_IGNORE_UNUSED;
break;
}
}
clk = clk_register(NULL, &clock->hw);
if (IS_ERR(clk))
goto fail;
@@ -853,6 +871,12 @@ static const struct of_device_id cpg_mssr_match[] = {
.compatible = "renesas,r8a779g0-cpg-mssr",
.data = &r8a779g0_cpg_mssr_info,
},
#endif
#ifdef CONFIG_CLK_R8A779H0
{
.compatible = "renesas,r8a779h0-cpg-mssr",
.data = &r8a779h0_cpg_mssr_info,
},
#endif
{ /* sentinel */ }
};
@@ -949,6 +973,78 @@ static const struct dev_pm_ops cpg_mssr_pm = {
#define DEV_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */
static void __init cpg_mssr_reserved_exit(struct cpg_mssr_priv *priv)
{
kfree(priv->reserved_ids);
}
static int __init cpg_mssr_reserved_init(struct cpg_mssr_priv *priv,
const struct cpg_mssr_info *info)
{
struct device_node *soc = of_find_node_by_path("/soc");
struct device_node *node;
uint32_t args[MAX_PHANDLE_ARGS];
unsigned int *ids = NULL;
unsigned int num = 0;
/*
* Because clk_disable_unused() will disable all unused clocks, the device which is assigned
* to a non-Linux system will be disabled when Linux is booted.
*
* To avoid such situation, renesas-cpg-mssr assumes the device which has
* status = "reserved" is assigned to a non-Linux system, and adds CLK_IGNORE_UNUSED flag
* to its CPG_MOD clocks.
* see also
* cpg_mssr_register_mod_clk()
*
* scif5: serial@e6f30000 {
* ...
* => clocks = <&cpg CPG_MOD 202>,
* <&cpg CPG_CORE R8A7795_CLK_S3D1>,
* <&scif_clk>;
* ...
* status = "reserved";
* };
*/
for_each_reserved_child_of_node(soc, node) {
struct of_phandle_iterator it;
int rc;
of_for_each_phandle(&it, rc, node, "clocks", "#clock-cells", -1) {
int idx;
if (it.node != priv->np)
continue;
if (of_phandle_iterator_args(&it, args, MAX_PHANDLE_ARGS) != 2)
continue;
if (args[0] != CPG_MOD)
continue;
ids = krealloc_array(ids, (num + 1), sizeof(*ids), GFP_KERNEL);
if (!ids) {
of_node_put(it.node);
return -ENOMEM;
}
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
idx = MOD_CLK_PACK_10(args[1]); /* for DEF_MOD_STB() */
else
idx = MOD_CLK_PACK(args[1]); /* for DEF_MOD() */
ids[num] = info->num_total_core_clks + idx;
num++;
}
}
priv->num_reserved_ids = num;
priv->reserved_ids = ids;
return 0;
}
static int __init cpg_mssr_common_init(struct device *dev,
struct device_node *np,
const struct cpg_mssr_info *info)
@@ -1003,14 +1099,20 @@ static int __init cpg_mssr_common_init(struct device *dev,
for (i = 0; i < nclks; i++)
priv->clks[i] = ERR_PTR(-ENOENT);
error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
error = cpg_mssr_reserved_init(priv, info);
if (error)
goto out_err;
error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
if (error)
goto reserve_err;
cpg_mssr_priv = priv;
return 0;
reserve_err:
cpg_mssr_reserved_exit(priv);
out_err:
if (priv->base)
iounmap(priv->base);
@@ -1070,22 +1172,23 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
cpg_mssr_del_clk_provider,
np);
if (error)
return error;
goto reserve_exit;
error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks,
info->num_core_pm_clks);
if (error)
return error;
goto reserve_exit;
/* Reset Controller not supported for Standby Control SoCs */
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
return 0;
goto reserve_exit;
error = cpg_mssr_reset_controller_register(priv);
if (error)
return error;
return 0;
reserve_exit:
cpg_mssr_reserved_exit(priv);
return error;
}
static struct platform_driver cpg_mssr_driver = {

View File

@@ -180,6 +180,7 @@ extern const struct cpg_mssr_info r8a77995_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779a0_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779f0_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779g0_cpg_mssr_info;
extern const struct cpg_mssr_info r8a779h0_cpg_mssr_info;
void __init cpg_mssr_early_init(struct device_node *np,
const struct cpg_mssr_info *info);

View File

@@ -415,6 +415,37 @@ int of_machine_is_compatible(const char *compat)
}
EXPORT_SYMBOL(of_machine_is_compatible);
static bool __of_device_is_status(const struct device_node *device,
const char * const*strings)
{
const char *status;
int statlen;
if (!device)
return false;
status = __of_get_property(device, "status", &statlen);
if (status == NULL)
return false;
if (statlen > 0) {
while (*strings) {
unsigned int len = strlen(*strings);
if ((*strings)[len - 1] == '-') {
if (!strncmp(status, *strings, len))
return true;
} else {
if (!strcmp(status, *strings))
return true;
}
strings++;
}
}
return false;
}
/**
* __of_device_is_available - check if a device is available for use
*
@@ -425,22 +456,27 @@ EXPORT_SYMBOL(of_machine_is_compatible);
*/
static bool __of_device_is_available(const struct device_node *device)
{
const char *status;
int statlen;
static const char * const ok[] = {"okay", "ok", NULL};
if (!device)
return false;
status = __of_get_property(device, "status", &statlen);
if (status == NULL)
return true;
return !__of_get_property(device, "status", NULL) ||
__of_device_is_status(device, ok);
}
if (statlen > 0) {
if (!strcmp(status, "okay") || !strcmp(status, "ok"))
return true;
}
/**
* __of_device_is_reserved - check if a device is reserved
*
* @device: Node to check for availability, with locks already held
*
* Return: True if the status property is set to "reserved", false otherwise
*/
static bool __of_device_is_reserved(const struct device_node *device)
{
static const char * const reserved[] = {"reserved", NULL};
return false;
return __of_device_is_status(device, reserved);
}
/**
@@ -474,16 +510,9 @@ EXPORT_SYMBOL(of_device_is_available);
*/
static bool __of_device_is_fail(const struct device_node *device)
{
const char *status;
static const char * const fail[] = {"fail", "fail-", NULL};
if (!device)
return false;
status = __of_get_property(device, "status", NULL);
if (status == NULL)
return false;
return !strcmp(status, "fail") || !strncmp(status, "fail-", 5);
return __of_device_is_status(device, fail);
}
/**
@@ -597,6 +626,29 @@ struct device_node *of_get_next_child(const struct device_node *node,
}
EXPORT_SYMBOL(of_get_next_child);
static struct device_node *of_get_next_status_child(const struct device_node *node,
struct device_node *prev,
bool (*checker)(const struct device_node *))
{
struct device_node *next;
unsigned long flags;
if (!node)
return NULL;
raw_spin_lock_irqsave(&devtree_lock, flags);
next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling) {
if (!checker(next))
continue;
if (of_node_get(next))
break;
}
of_node_put(prev);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return next;
}
/**
* of_get_next_available_child - Find the next available child node
* @node: parent node
@@ -608,26 +660,25 @@ EXPORT_SYMBOL(of_get_next_child);
struct device_node *of_get_next_available_child(const struct device_node *node,
struct device_node *prev)
{
struct device_node *next;
unsigned long flags;
if (!node)
return NULL;
raw_spin_lock_irqsave(&devtree_lock, flags);
next = prev ? prev->sibling : node->child;
for (; next; next = next->sibling) {
if (!__of_device_is_available(next))
continue;
if (of_node_get(next))
break;
}
of_node_put(prev);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return next;
return of_get_next_status_child(node, prev, __of_device_is_available);
}
EXPORT_SYMBOL(of_get_next_available_child);
/**
* of_get_next_reserved_child - Find the next reserved child node
* @node: parent node
* @prev: previous child of the parent node, or NULL to get first
*
* This function is like of_get_next_child(), except that it
* automatically skips any disabled nodes (i.e. status = "disabled").
*/
struct device_node *of_get_next_reserved_child(const struct device_node *node,
struct device_node *prev)
{
return of_get_next_status_child(node, prev, __of_device_is_reserved);
}
EXPORT_SYMBOL(of_get_next_reserved_child);
/**
* of_get_next_cpu_node - Iterate on cpu nodes
* @prev: previous child of the /cpus node, or NULL to get first

View File

@@ -0,0 +1,96 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (C) 2023 Renesas Electronics Corp.
*/
#ifndef __DT_BINDINGS_CLOCK_RENESAS_R8A779H0_CPG_MSSR_H__
#define __DT_BINDINGS_CLOCK_RENESAS_R8A779H0_CPG_MSSR_H__
#include <dt-bindings/clock/renesas-cpg-mssr.h>
/* r8a779h0 CPG Core Clocks */
#define R8A779H0_CLK_ZX 0
#define R8A779H0_CLK_ZD 1
#define R8A779H0_CLK_ZS 2
#define R8A779H0_CLK_ZT 3
#define R8A779H0_CLK_ZTR 4
#define R8A779H0_CLK_S0D2 5
#define R8A779H0_CLK_S0D3 6
#define R8A779H0_CLK_S0D4 7
#define R8A779H0_CLK_S0D1_VIO 8
#define R8A779H0_CLK_S0D2_VIO 9
#define R8A779H0_CLK_S0D4_VIO 10
#define R8A779H0_CLK_S0D8_VIO 11
#define R8A779H0_CLK_VIOBUSD1 12
#define R8A779H0_CLK_VIOBUSD2 13
#define R8A779H0_CLK_S0D1_VC 14
#define R8A779H0_CLK_S0D2_VC 15
#define R8A779H0_CLK_S0D4_VC 16
#define R8A779H0_CLK_VCBUSD1 17
#define R8A779H0_CLK_VCBUSD2 18
#define R8A779H0_CLK_S0D2_MM 19
#define R8A779H0_CLK_S0D4_MM 20
#define R8A779H0_CLK_S0D2_U3DG 21
#define R8A779H0_CLK_S0D4_U3DG 22
#define R8A779H0_CLK_S0D2_RT 23
#define R8A779H0_CLK_S0D3_RT 24
#define R8A779H0_CLK_S0D4_RT 25
#define R8A779H0_CLK_S0D6_RT 26
#define R8A779H0_CLK_S0D2_PER 27
#define R8A779H0_CLK_S0D3_PER 28
#define R8A779H0_CLK_S0D4_PER 29
#define R8A779H0_CLK_S0D6_PER 30
#define R8A779H0_CLK_S0D12_PER 31
#define R8A779H0_CLK_S0D24_PER 32
#define R8A779H0_CLK_S0D1_HSC 33
#define R8A779H0_CLK_S0D2_HSC 34
#define R8A779H0_CLK_S0D4_HSC 35
#define R8A779H0_CLK_S0D8_HSC 36
#define R8A779H0_CLK_SVD1_IR 37
#define R8A779H0_CLK_SVD2_IR 38
#define R8A779H0_CLK_IMPAD1 39
#define R8A779H0_CLK_IMPAD4 40
#define R8A779H0_CLK_IMPB 41
#define R8A779H0_CLK_SVD1_VIP 42
#define R8A779H0_CLK_SVD2_VIP 43
#define R8A779H0_CLK_CL 44
#define R8A779H0_CLK_CL16M 45
#define R8A779H0_CLK_CL16M_MM 46
#define R8A779H0_CLK_CL16M_RT 47
#define R8A779H0_CLK_CL16M_PER 48
#define R8A779H0_CLK_CL16M_HSC 49
#define R8A779H0_CLK_ZC0 50
#define R8A779H0_CLK_ZC1 51
#define R8A779H0_CLK_ZC2 52
#define R8A779H0_CLK_ZC3 53
#define R8A779H0_CLK_ZB3 54
#define R8A779H0_CLK_ZB3D2 55
#define R8A779H0_CLK_ZB3D4 56
#define R8A779H0_CLK_ZG 57
#define R8A779H0_CLK_SD0H 58
#define R8A779H0_CLK_SD0 59
#define R8A779H0_CLK_RPC 60
#define R8A779H0_CLK_RPCD2 61
#define R8A779H0_CLK_MSO 62
#define R8A779H0_CLK_CANFD 63
#define R8A779H0_CLK_CSI 64
#define R8A779H0_CLK_FRAY 65
#define R8A779H0_CLK_IPC 66
#define R8A779H0_CLK_SASYNCRT 67
#define R8A779H0_CLK_SASYNCPERD1 68
#define R8A779H0_CLK_SASYNCPERD2 69
#define R8A779H0_CLK_SASYNCPERD4 70
#define R8A779H0_CLK_DSIEXT 71
#define R8A779H0_CLK_DSIREF 72
#define R8A779H0_CLK_ADGH 73
#define R8A779H0_CLK_OSC 74
#define R8A779H0_CLK_ZR0 75
#define R8A779H0_CLK_ZR1 76
#define R8A779H0_CLK_ZR2 77
#define R8A779H0_CLK_RGMII 78
#define R8A779H0_CLK_CPEX 79
#define R8A779H0_CLK_CP 80
#define R8A779H0_CLK_CBFUSA 81
#define R8A779H0_CLK_R 82
#endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A779H0_CPG_MSSR_H__ */

View File

@@ -0,0 +1,49 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/*
* Copyright (C) 2023 Renesas Electronics Corp.
*/
#ifndef __DT_BINDINGS_POWER_RENESAS_R8A779H0_SYSC_H__
#define __DT_BINDINGS_POWER_RENESAS_R8A779H0_SYSC_H__
/*
* These power domain indices match the Power Domain Register Numbers (PDR)
*/
#define R8A779H0_PD_A1E0D0C0 0
#define R8A779H0_PD_A1E0D0C1 1
#define R8A779H0_PD_A1E0D0C2 2
#define R8A779H0_PD_A1E0D0C3 3
#define R8A779H0_PD_A2E0D0 16
#define R8A779H0_PD_A3CR0 21
#define R8A779H0_PD_A3CR1 22
#define R8A779H0_PD_A3CR2 23
#define R8A779H0_PD_A33DGA 24
#define R8A779H0_PD_A23DGB 25
#define R8A779H0_PD_C4 31
#define R8A779H0_PD_A1DSP0 33
#define R8A779H0_PD_A2IMP01 34
#define R8A779H0_PD_A2PSC 35
#define R8A779H0_PD_A2CV0 36
#define R8A779H0_PD_A2CV1 37
#define R8A779H0_PD_A3IMR0 38
#define R8A779H0_PD_A3IMR1 39
#define R8A779H0_PD_A3VC 40
#define R8A779H0_PD_A2CN0 42
#define R8A779H0_PD_A1CN0 44
#define R8A779H0_PD_A1DSP1 45
#define R8A779H0_PD_A2DMA 47
#define R8A779H0_PD_A2CV2 48
#define R8A779H0_PD_A2CV3 49
#define R8A779H0_PD_A3IMR2 50
#define R8A779H0_PD_A3IMR3 51
#define R8A779H0_PD_A3PCI 52
#define R8A779H0_PD_A2PCIPHY 53
#define R8A779H0_PD_A3VIP0 56
#define R8A779H0_PD_A3VIP2 58
#define R8A779H0_PD_A3ISP0 60
#define R8A779H0_PD_A3DUL 62
/* Always-on power area */
#define R8A779H0_PD_ALWAYS_ON 64
#endif /* __DT_BINDINGS_POWER_RENESAS_R8A779H0_SYSC_H__ */

View File

@@ -294,6 +294,8 @@ extern struct device_node *of_get_next_child(const struct device_node *node,
struct device_node *prev);
extern struct device_node *of_get_next_available_child(
const struct device_node *node, struct device_node *prev);
extern struct device_node *of_get_next_reserved_child(
const struct device_node *node, struct device_node *prev);
extern struct device_node *of_get_compatible_child(const struct device_node *parent,
const char *compatible);
@@ -541,6 +543,12 @@ static inline struct device_node *of_get_next_available_child(
return NULL;
}
static inline struct device_node *of_get_next_reserved_child(
const struct device_node *node, struct device_node *prev)
{
return NULL;
}
static inline struct device_node *of_find_node_with_property(
struct device_node *from, const char *prop_name)
{
@@ -1431,6 +1439,9 @@ static inline int of_property_read_s32(const struct device_node *np,
#define for_each_available_child_of_node(parent, child) \
for (child = of_get_next_available_child(parent, NULL); child != NULL; \
child = of_get_next_available_child(parent, child))
#define for_each_reserved_child_of_node(parent, child) \
for (child = of_get_next_reserved_child(parent, NULL); child != NULL; \
child = of_get_next_reserved_child(parent, child))
#define for_each_of_cpu_node(cpu) \
for (cpu = of_get_next_cpu_node(NULL); cpu != NULL; \