static int clk_fixed_attach(device_t dev) { struct clk_fixed_softc *sc; intptr_t clk_type; phandle_t node; struct clk_fixed_def def; int rv; sc = device_get_softc(dev); sc->dev = dev; node = ofw_bus_get_node(dev); clk_type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; bzero(&def, sizeof(def)); if (clk_type == CLK_TYPE_FIXED) rv = clk_fixed_init_fixed(sc, node, &def); else if (clk_type == CLK_TYPE_FIXED_FACTOR) rv = clk_fixed_init_fixed_factor(sc, node, &def); else rv = ENXIO; if (rv != 0) { device_printf(sc->dev, "Cannot FDT parameters.\n"); goto fail; } rv = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name); if (rv != 0) { device_printf(sc->dev, "Cannot parse clock name.\n"); goto fail; } sc->clkdom = clkdom_create(dev); KASSERT(sc->clkdom != NULL, ("Clock domain is NULL")); rv = clknode_fixed_register(sc->clkdom, &def); if (rv != 0) { device_printf(sc->dev, "Cannot register fixed clock.\n"); rv = ENXIO; goto fail; } rv = clkdom_finit(sc->clkdom); if (rv != 0) { device_printf(sc->dev, "Clk domain finit fails.\n"); rv = ENXIO; goto fail; } #ifdef CLK_DEBUG clkdom_dump(sc->clkdom); #endif OF_prop_free(__DECONST(char *, def.clkdef.name)); OF_prop_free(def.clkdef.parent_names); return (bus_generic_attach(dev)); fail: OF_prop_free(__DECONST(char *, def.clkdef.name)); OF_prop_free(def.clkdef.parent_names); return (rv); }
static int aw_oscclk_attach(device_t dev) { struct clk_fixed_def def; struct clkdom *clkdom; phandle_t node; uint32_t freq; int error; node = ofw_bus_get_node(dev); if (OF_getencprop(node, "clock-frequency", &freq, sizeof(freq)) <= 0) { device_printf(dev, "missing clock-frequency property\n"); error = ENXIO; goto fail; } clkdom = clkdom_create(dev); memset(&def, 0, sizeof(def)); def.clkdef.id = 1; def.freq = freq; error = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name); if (error != 0) { device_printf(dev, "cannot parse clock name\n"); error = ENXIO; goto fail; } error = clknode_fixed_register(clkdom, &def); if (error != 0) { device_printf(dev, "cannot register fixed clock\n"); error = ENXIO; goto fail; } if (clkdom_finit(clkdom) != 0) { device_printf(dev, "cannot finalize clkdom initialization\n"); error = ENXIO; goto fail; } if (bootverbose) clkdom_dump(clkdom); free(__DECONST(char *, def.clkdef.name), M_OFWPROP); return (0); fail: free(__DECONST(char *, def.clkdef.name), M_OFWPROP); return (error); }
static int aw_cpuclk_attach(device_t dev) { struct clk_mux_def def; struct clkdom *clkdom; bus_addr_t paddr; bus_size_t psize; phandle_t node; int error, ncells, i; clk_t clk; node = ofw_bus_get_node(dev); if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) { device_printf(dev, "cannot parse 'reg' property\n"); return (ENXIO); } error = ofw_bus_parse_xref_list_get_length(node, "clocks", "#clock-cells", &ncells); if (error != 0) { device_printf(dev, "cannot get clock count\n"); return (error); } clkdom = clkdom_create(dev); memset(&def, 0, sizeof(def)); def.clkdef.id = 1; def.clkdef.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK); for (i = 0; i < ncells; i++) { error = clk_get_by_ofw_index(dev, 0, i, &clk); if (error != 0) { device_printf(dev, "cannot get clock %d\n", i); goto fail; } def.clkdef.parent_names[i] = clk_get_name(clk); clk_release(clk); } def.clkdef.parent_cnt = ncells; def.offset = paddr; def.shift = CPU_CLK_SRC_SEL_SHIFT; def.width = CPU_CLK_SRC_SEL_WIDTH; error = clk_parse_ofw_clk_name(dev, node, &def.clkdef.name); if (error != 0) { device_printf(dev, "cannot parse clock name\n"); error = ENXIO; goto fail; } error = clknode_mux_register(clkdom, &def); if (error != 0) { device_printf(dev, "cannot register mux clock\n"); error = ENXIO; goto fail; } if (clkdom_finit(clkdom) != 0) { device_printf(dev, "cannot finalize clkdom initialization\n"); error = ENXIO; goto fail; } OF_prop_free(__DECONST(char *, def.clkdef.parent_names)); OF_prop_free(__DECONST(char *, def.clkdef.name)); if (bootverbose) clkdom_dump(clkdom); return (0); fail: OF_prop_free(__DECONST(char *, def.clkdef.name)); return (error); }