11.1Sskrll/* $NetBSD: omap4_prcm.c,v 1.1 2025/12/16 12:20:22 skrll Exp $ */ 21.1Sskrll 31.1Sskrll/*- 41.1Sskrll * Copyright (c) 2025 Rui-Xiang Guo 51.1Sskrll * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 61.1Sskrll * All rights reserved. 71.1Sskrll * 81.1Sskrll * Redistribution and use in source and binary forms, with or without 91.1Sskrll * modification, are permitted provided that the following conditions 101.1Sskrll * are met: 111.1Sskrll * 1. Redistributions of source code must retain the above copyright 121.1Sskrll * notice, this list of conditions and the following disclaimer. 131.1Sskrll * 2. Redistributions in binary form must reproduce the above copyright 141.1Sskrll * notice, this list of conditions and the following disclaimer in the 151.1Sskrll * documentation and/or other materials provided with the distribution. 161.1Sskrll * 171.1Sskrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 181.1Sskrll * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 191.1Sskrll * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201.1Sskrll * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 211.1Sskrll * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 221.1Sskrll * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 231.1Sskrll * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 241.1Sskrll * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 251.1Sskrll * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261.1Sskrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271.1Sskrll * SUCH DAMAGE. 281.1Sskrll */ 291.1Sskrll 301.1Sskrll#include <sys/cdefs.h> 311.1Sskrll 321.1Sskrll__KERNEL_RCSID(1, "$NetBSD: omap4_prcm.c,v 1.1 2025/12/16 12:20:22 skrll Exp $"); 331.1Sskrll 341.1Sskrll#include <sys/param.h> 351.1Sskrll#include <sys/bus.h> 361.1Sskrll#include <sys/device.h> 371.1Sskrll#include <sys/systm.h> 381.1Sskrll 391.1Sskrll#include <dev/fdt/fdtvar.h> 401.1Sskrll 411.1Sskrll#define TI_PRCM_PRIVATE 421.1Sskrll#include <arm/ti/ti_prcm.h> 431.1Sskrll 441.1Sskrll#define CM1_ABE 0x0500 451.1Sskrll 461.1Sskrll#define CM2_CORE 0x0700 471.1Sskrll#define CM2_L3INIT 0x1300 481.1Sskrll#define CM2_L4PER 0x1400 491.1Sskrll 501.1Sskrll#define CM_WKUP 0x1800 511.1Sskrll 521.1Sskrll#define CLKCTRL_MODULEMODE __BITS(1,0) 531.1Sskrll#define CLKCTRL_MODULEMODE_DISABLE 0x0 541.1Sskrll#define CLKCTRL_MODULEMODE_AUTO 0x1 551.1Sskrll#define CLKCTRL_MODULEMODE_ENABLE 0x2 561.1Sskrll 571.1Sskrll#define CLKCTRL_IDLEST __BITS(17,16) 581.1Sskrll#define CLKCTRL_IDLEST_ENABLE 0x0 591.1Sskrll#define CLKCTRL_IDLEST_BUSY 0x1 601.1Sskrll#define CLKCTRL_IDLEST_IDLE 0x2 611.1Sskrll#define CLKCTRL_IDLEST_DISABLE 0x3 621.1Sskrll 631.1Sskrllenum omap4_prcm_inst { 641.1Sskrll PRCM_CM1 = 1, 651.1Sskrll PRCM_CM2, 661.1Sskrll PRCM_PRM, 671.1Sskrll}; 681.1Sskrll 691.1Sskrllstruct omap4_prcm_softc { 701.1Sskrll struct ti_prcm_softc sc_prcm; /* must be first */ 711.1Sskrll bus_addr_t sc_regbase; 721.1Sskrll enum omap4_prcm_inst sc_inst; 731.1Sskrll}; 741.1Sskrll 751.1Sskrllstatic int omap4_prcm_match(device_t, cfdata_t, void *); 761.1Sskrllstatic void omap4_prcm_attach(device_t, device_t, void *); 771.1Sskrll 781.1Sskrllstatic int 791.1Sskrllomap4_prcm_hwmod_enable(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enable) 801.1Sskrll{ 811.1Sskrll uint32_t val; 821.1Sskrll int retry; 831.1Sskrll 841.1Sskrll val = PRCM_READ(sc, tc->u.hwmod.reg); 851.1Sskrll val &= ~CLKCTRL_MODULEMODE; 861.1Sskrll if (enable) { 871.1Sskrll val |= __SHIFTIN(CLKCTRL_MODULEMODE_ENABLE, 881.1Sskrll CLKCTRL_MODULEMODE); 891.1Sskrll } else 901.1Sskrll val |= __SHIFTIN(CLKCTRL_MODULEMODE_DISABLE, 911.1Sskrll CLKCTRL_MODULEMODE); 921.1Sskrll PRCM_WRITE(sc, tc->u.hwmod.reg, val); 931.1Sskrll 941.1Sskrll for (retry = 100; retry > 0; retry--) { 951.1Sskrll val = PRCM_READ(sc, tc->u.hwmod.reg); 961.1Sskrll if ((val & CLKCTRL_IDLEST) == CLKCTRL_IDLEST_ENABLE) 971.1Sskrll break; 981.1Sskrll delay(10); 991.1Sskrll } 1001.1Sskrll 1011.1Sskrll return (retry >= 0) ? 0 : ETIMEDOUT; 1021.1Sskrll} 1031.1Sskrll 1041.1Sskrllstatic int 1051.1Sskrllomap4_prcm_hwmod_enable_auto(struct ti_prcm_softc *sc, struct ti_prcm_clk *tc, int enable) 1061.1Sskrll{ 1071.1Sskrll uint32_t val; 1081.1Sskrll int retry; 1091.1Sskrll 1101.1Sskrll val = PRCM_READ(sc, tc->u.hwmod.reg); 1111.1Sskrll val &= ~CLKCTRL_MODULEMODE; 1121.1Sskrll if (enable) { 1131.1Sskrll val |= __SHIFTIN(CLKCTRL_MODULEMODE_AUTO, 1141.1Sskrll CLKCTRL_MODULEMODE); 1151.1Sskrll } else 1161.1Sskrll val |= __SHIFTIN(CLKCTRL_MODULEMODE_DISABLE, 1171.1Sskrll CLKCTRL_MODULEMODE); 1181.1Sskrll PRCM_WRITE(sc, tc->u.hwmod.reg, val); 1191.1Sskrll 1201.1Sskrll for (retry = 100; retry > 0; retry--) { 1211.1Sskrll val = PRCM_READ(sc, tc->u.hwmod.reg); 1221.1Sskrll if ((val & CLKCTRL_IDLEST) == CLKCTRL_IDLEST_ENABLE) 1231.1Sskrll break; 1241.1Sskrll delay(10); 1251.1Sskrll } 1261.1Sskrll 1271.1Sskrll return (retry >= 0) ? 0 : ETIMEDOUT; 1281.1Sskrll} 1291.1Sskrll 1301.1Sskrll#define OMAP4_PRCM_HWMOD_CM1_ABE(_name, _reg, _parent) \ 1311.1Sskrll TI_PRCM_HWMOD((_name), CM1_ABE + (_reg), (_parent), omap4_prcm_hwmod_enable) 1321.1Sskrll#define OMAP4_PRCM_HWMOD_CM2_L3INIT(_name, _reg, _parent) \ 1331.1Sskrll TI_PRCM_HWMOD((_name), CM2_L3INIT + (_reg), (_parent), omap4_prcm_hwmod_enable) 1341.1Sskrll#define OMAP4_PRCM_HWMOD_CM2_L3INIT_AUTO(_name, _reg, _parent) \ 1351.1Sskrll TI_PRCM_HWMOD((_name), CM2_L3INIT + (_reg), (_parent), omap4_prcm_hwmod_enable_auto) 1361.1Sskrll#define OMAP4_PRCM_HWMOD_CM2_L4PER(_name, _reg, _parent) \ 1371.1Sskrll TI_PRCM_HWMOD((_name), CM2_L4PER + (_reg), (_parent), omap4_prcm_hwmod_enable) 1381.1Sskrll#define OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO(_name, _reg, _parent) \ 1391.1Sskrll TI_PRCM_HWMOD((_name), CM2_L4PER + (_reg), (_parent), omap4_prcm_hwmod_enable_auto) 1401.1Sskrll#define OMAP4_PRCM_HWMOD_CM_WKUP(_name, _reg, _parent) \ 1411.1Sskrll TI_PRCM_HWMOD((_name), CM_WKUP + (_reg), (_parent), omap4_prcm_hwmod_enable) 1421.1Sskrll#define OMAP4_PRCM_HWMOD_CM_WKUP_AUTO(_name, _reg, _parent) \ 1431.1Sskrll TI_PRCM_HWMOD((_name), CM_WKUP + (_reg), (_parent), omap4_prcm_hwmod_enable_auto) 1441.1Sskrll 1451.1Sskrllstatic const struct device_compatible_entry compat_data[] = { 1461.1Sskrll { .compat = "ti,omap4-cm1", .value = PRCM_CM1 }, 1471.1Sskrll { .compat = "ti,omap4-cm2", .value = PRCM_CM2 }, 1481.1Sskrll { .compat = "ti,omap4-prm", .value = PRCM_PRM }, 1491.1Sskrll { .compat = "ti,omap4-scrm", .value = PRCM_PRM }, 1501.1Sskrll DEVICE_COMPAT_EOL 1511.1Sskrll}; 1521.1Sskrll 1531.1Sskrllstatic const struct device_compatible_entry cm_compat_data[] = { 1541.1Sskrll { .compat = "ti,omap4-cm" }, 1551.1Sskrll DEVICE_COMPAT_EOL 1561.1Sskrll}; 1571.1Sskrll 1581.1Sskrllstatic const struct device_compatible_entry clkctrl_compat_data[] = { 1591.1Sskrll { .compat = "ti,clkctrl" }, 1601.1Sskrll DEVICE_COMPAT_EOL 1611.1Sskrll}; 1621.1Sskrll 1631.1SskrllCFATTACH_DECL_NEW(omap4_prcm, sizeof(struct omap4_prcm_softc), 1641.1Sskrll omap4_prcm_match, omap4_prcm_attach, NULL, NULL); 1651.1Sskrll 1661.1Sskrllstatic struct ti_prcm_clk omap4_cm1_clks[] = { 1671.1Sskrll /* XXX until we get a proper clock tree */ 1681.1Sskrll TI_PRCM_FIXED("FIXED_32K", 32768), 1691.1Sskrll TI_PRCM_FIXED("FIXED_24MHZ", 24000000), 1701.1Sskrll 1711.1Sskrll OMAP4_PRCM_HWMOD_CM1_ABE("timer5", 0x68, "FIXED_24MHZ"), 1721.1Sskrll OMAP4_PRCM_HWMOD_CM1_ABE("timer6", 0x70, "FIXED_24MHZ"), 1731.1Sskrll OMAP4_PRCM_HWMOD_CM1_ABE("timer7", 0x78, "FIXED_24MHZ"), 1741.1Sskrll OMAP4_PRCM_HWMOD_CM1_ABE("timer8", 0x80, "FIXED_24MHZ"), 1751.1Sskrll// OMAP4_PRCM_HWMOD_CM1_ABE("wd_timer3", 0x88, "FIXED_32K"), 1761.1Sskrll}; 1771.1Sskrll 1781.1Sskrllstatic struct ti_prcm_clk omap4_cm2_clks[] = { 1791.1Sskrll /* XXX until we get a proper clock tree */ 1801.1Sskrll TI_PRCM_FIXED("FIXED_32K", 32768), 1811.1Sskrll TI_PRCM_FIXED("FIXED_24MHZ", 24000000), 1821.1Sskrll TI_PRCM_FIXED("FIXED_48MHZ", 48000000), 1831.1Sskrll TI_PRCM_FIXED("FIXED_96MHZ", 96000000), 1841.1Sskrll TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "FIXED_48MHZ"), 1851.1Sskrll TI_PRCM_FIXED_FACTOR("MMC_CLK", 1, 1, "FIXED_96MHZ"), 1861.1Sskrll 1871.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("uart1", 0x140, "PERIPH_CLK"), 1881.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("uart2", 0x148, "PERIPH_CLK"), 1891.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("uart3", 0x150, "PERIPH_CLK"), 1901.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("uart4", 0x158, "PERIPH_CLK"), 1911.1Sskrll 1921.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("i2c1", 0xa0, "PERIPH_CLK"), 1931.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("i2c2", 0xa8, "PERIPH_CLK"), 1941.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("i2c3", 0xb0, "PERIPH_CLK"), 1951.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("i2c4", 0xb8, "PERIPH_CLK"), 1961.1Sskrll 1971.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO("gpio2", 0x60, "PERIPH_CLK"), 1981.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO("gpio3", 0x68, "PERIPH_CLK"), 1991.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO("gpio4", 0x70, "PERIPH_CLK"), 2001.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO("gpio5", 0x78, "PERIPH_CLK"), 2011.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO("gpio6", 0x80, "PERIPH_CLK"), 2021.1Sskrll 2031.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("timer2", 0x38, "FIXED_24MHZ"), 2041.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("timer3", 0x40, "FIXED_24MHZ"), 2051.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("timer4", 0x48, "FIXED_24MHZ"), 2061.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("timer9", 0x50, "FIXED_24MHZ"), 2071.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("timer10", 0x28, "FIXED_24MHZ"), 2081.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("timer11", 0x30, "FIXED_24MHZ"), 2091.1Sskrll 2101.1Sskrll OMAP4_PRCM_HWMOD_CM2_L3INIT("mmc1", 0x28, "MMC_CLK"), 2111.1Sskrll OMAP4_PRCM_HWMOD_CM2_L3INIT("mmc2", 0x30, "MMC_CLK"), 2121.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("mmc3", 0x120, "PERIPH_CLK"), 2131.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("mmc4", 0x128, "PERIPH_CLK"), 2141.1Sskrll OMAP4_PRCM_HWMOD_CM2_L4PER("mmc5", 0x160, "PERIPH_CLK"), 2151.1Sskrll 2161.1Sskrll OMAP4_PRCM_HWMOD_CM2_L3INIT("usb_host_hs", 0x58, "PERIPH_CLK"), 2171.1Sskrll OMAP4_PRCM_HWMOD_CM2_L3INIT_AUTO("usb_otg_hs", 0x60, "PERIPH_CLK"), 2181.1Sskrll OMAP4_PRCM_HWMOD_CM2_L3INIT_AUTO("usb_tll_hs", 0x68, "PERIPH_CLK"), 2191.1Sskrll 2201.1Sskrll// OMAP4_PRCM_HWMOD_CM2_L4PER_AUTO("rng", 0x1c0, "PERIPH_CLK"), 2211.1Sskrll}; 2221.1Sskrll 2231.1Sskrllstatic struct ti_prcm_clk omap4_prm_clks[] = { 2241.1Sskrll /* XXX until we get a proper clock tree */ 2251.1Sskrll TI_PRCM_FIXED("FIXED_32K", 32768), 2261.1Sskrll TI_PRCM_FIXED("FIXED_48MHZ", 48000000), 2271.1Sskrll TI_PRCM_FIXED_FACTOR("PERIPH_CLK", 1, 1, "FIXED_48MHZ"), 2281.1Sskrll 2291.1Sskrll OMAP4_PRCM_HWMOD_CM_WKUP_AUTO("gpio1", 0x38, "PERIPH_CLK"), 2301.1Sskrll OMAP4_PRCM_HWMOD_CM_WKUP("timer1", 0x40, "FIXED_32K"), 2311.1Sskrll OMAP4_PRCM_HWMOD_CM_WKUP("wd_timer2", 0x30, "FIXED_32K"), 2321.1Sskrll}; 2331.1Sskrll 2341.1Sskrllstatic struct clk * 2351.1Sskrllomap4_prcm_clock_decode(device_t dev, int cc_phandle, const void *data, size_t len) 2361.1Sskrll{ 2371.1Sskrll struct omap4_prcm_softc * const sc = device_private(dev); 2381.1Sskrll const u_int *cells = data; 2391.1Sskrll bus_addr_t regbase; 2401.1Sskrll u_int n; 2411.1Sskrll 2421.1Sskrll if (len != 8) 2431.1Sskrll return NULL; 2441.1Sskrll 2451.1Sskrll bus_size_t regoff = be32toh(cells[0]); 2461.1Sskrll const u_int clock_index = be32toh(cells[1]); 2471.1Sskrll 2481.1Sskrll /* XXX not sure how to handle this yet */ 2491.1Sskrll if (clock_index != 0) 2501.1Sskrll return NULL; 2511.1Sskrll 2521.1Sskrll /* 2531.1Sskrll * Register offset in specifier is relative to base address of the 2541.1Sskrll * clock node. Translate this to an address relative to the start 2551.1Sskrll * of PRCM space. 2561.1Sskrll */ 2571.1Sskrll if (fdtbus_get_reg(cc_phandle, 0, ®base, NULL) != 0) 2581.1Sskrll return NULL; 2591.1Sskrll regoff += (regbase - sc->sc_regbase); 2601.1Sskrll 2611.1Sskrll /* 2621.1Sskrll * Look for a matching hwmod. 2631.1Sskrll */ 2641.1Sskrll for (n = 0; n < sc->sc_prcm.sc_nclks; n++) { 2651.1Sskrll struct ti_prcm_clk *tclk = &sc->sc_prcm.sc_clks[n]; 2661.1Sskrll if (tclk->type != TI_PRCM_HWMOD) 2671.1Sskrll continue; 2681.1Sskrll 2691.1Sskrll if (tclk->u.hwmod.reg == regoff) 2701.1Sskrll return &tclk->base; 2711.1Sskrll } 2721.1Sskrll 2731.1Sskrll /* Not found */ 2741.1Sskrll return NULL; 2751.1Sskrll} 2761.1Sskrll 2771.1Sskrllstatic const struct fdtbus_clock_controller_func omap4_prcm_clock_fdt_funcs = { 2781.1Sskrll .decode = omap4_prcm_clock_decode 2791.1Sskrll}; 2801.1Sskrll 2811.1Sskrllstatic int 2821.1Sskrllomap4_prcm_match(device_t parent, cfdata_t cf, void *aux) 2831.1Sskrll{ 2841.1Sskrll struct fdt_attach_args * const faa = aux; 2851.1Sskrll 2861.1Sskrll return of_compatible_match(faa->faa_phandle, compat_data); 2871.1Sskrll} 2881.1Sskrll 2891.1Sskrllstatic void 2901.1Sskrllomap4_prcm_attach(device_t parent, device_t self, void *aux) 2911.1Sskrll{ 2921.1Sskrll struct omap4_prcm_softc * const sc = device_private(self); 2931.1Sskrll struct fdt_attach_args * const faa = aux; 2941.1Sskrll const int phandle = faa->faa_phandle; 2951.1Sskrll int clocks, child, cm_child; 2961.1Sskrll char iname[5]; 2971.1Sskrll 2981.1Sskrll if (fdtbus_get_reg(phandle, 0, &sc->sc_regbase, NULL) != 0) { 2991.1Sskrll aprint_error(": couldn't get registers\n"); 3001.1Sskrll return; 3011.1Sskrll } 3021.1Sskrll 3031.1Sskrll sc->sc_prcm.sc_dev = self; 3041.1Sskrll sc->sc_prcm.sc_phandle = phandle; 3051.1Sskrll sc->sc_prcm.sc_bst = faa->faa_bst; 3061.1Sskrll sc->sc_inst = of_compatible_lookup(phandle, compat_data)->value; 3071.1Sskrll 3081.1Sskrll switch (sc->sc_inst) { 3091.1Sskrll case PRCM_CM1: 3101.1Sskrll sc->sc_prcm.sc_clks = omap4_cm1_clks; 3111.1Sskrll sc->sc_prcm.sc_nclks = __arraycount(omap4_cm1_clks); 3121.1Sskrll strcpy(iname, "CM1"); 3131.1Sskrll break; 3141.1Sskrll case PRCM_CM2: 3151.1Sskrll sc->sc_prcm.sc_clks = omap4_cm2_clks; 3161.1Sskrll sc->sc_prcm.sc_nclks = __arraycount(omap4_cm2_clks); 3171.1Sskrll strcpy(iname, "CM2"); 3181.1Sskrll break; 3191.1Sskrll case PRCM_PRM: 3201.1Sskrll sc->sc_prcm.sc_clks = omap4_prm_clks; 3211.1Sskrll sc->sc_prcm.sc_nclks = __arraycount(omap4_prm_clks); 3221.1Sskrll strcpy(iname, "PRM"); 3231.1Sskrll break; 3241.1Sskrll default: 3251.1Sskrll aprint_error(": unsupported instance\n"); 3261.1Sskrll return; 3271.1Sskrll } 3281.1Sskrll 3291.1Sskrll if (ti_prcm_attach(&sc->sc_prcm) != 0) 3301.1Sskrll return; 3311.1Sskrll 3321.1Sskrll aprint_naive("\n"); 3331.1Sskrll aprint_normal(": OMAP44xx PRCM (%s)\n", iname); 3341.1Sskrll 3351.1Sskrll for (child = OF_child(phandle); child; child = OF_peer(child)) { 3361.1Sskrll if (of_compatible_match(child, cm_compat_data) == 0) 3371.1Sskrll continue; 3381.1Sskrll 3391.1Sskrll for (cm_child = OF_child(child); cm_child; 3401.1Sskrll cm_child = OF_peer(cm_child)) { 3411.1Sskrll if (of_compatible_match(cm_child, 3421.1Sskrll clkctrl_compat_data) == 0) 3431.1Sskrll continue; 3441.1Sskrll 3451.1Sskrll aprint_debug_dev(self, "clkctrl: %s\n", fdtbus_get_string(cm_child, "name")); 3461.1Sskrll fdtbus_register_clock_controller(self, cm_child, 3471.1Sskrll &omap4_prcm_clock_fdt_funcs); 3481.1Sskrll } 3491.1Sskrll } 3501.1Sskrll 3511.1Sskrll clocks = of_find_firstchild_byname(phandle, "clocks"); 3521.1Sskrll if (clocks > 0) 3531.1Sskrll fdt_add_bus(self, clocks, faa); 3541.1Sskrll} 355