Module Name:    src
Committed By:   jmcneill
Date:           Sun Apr 16 12:28:21 UTC 2017

Modified Files:
        src/sys/arch/arm/nvidia: tegra124_car.c tegra_ahcisata.c tegra_drm.c
            tegra_hdaudio.c tegra_soctherm.c tegra_timer.c tegra_xusb.c
        src/sys/dev/clk: clk.c clk.h clk_backend.h

Log Message:
Add support for multiple clock domains in clk API.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/nvidia/tegra124_car.c \
    src/sys/arch/arm/nvidia/tegra_ahcisata.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/nvidia/tegra_drm.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/nvidia/tegra_hdaudio.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/nvidia/tegra_soctherm.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/nvidia/tegra_timer.c \
    src/sys/arch/arm/nvidia/tegra_xusb.c
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/clk/clk.c src/sys/dev/clk/clk.h \
    src/sys/dev/clk/clk_backend.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/nvidia/tegra124_car.c
diff -u src/sys/arch/arm/nvidia/tegra124_car.c:1.9 src/sys/arch/arm/nvidia/tegra124_car.c:1.10
--- src/sys/arch/arm/nvidia/tegra124_car.c:1.9	Fri Apr 14 09:50:56 2017
+++ src/sys/arch/arm/nvidia/tegra124_car.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra124_car.c,v 1.9 2017/04/14 09:50:56 jmcneill Exp $ */
+/* $NetBSD: tegra124_car.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.9 2017/04/14 09:50:56 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra124_car.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -626,8 +626,6 @@ static struct tegra_clk tegra124_car_clo
 	CLK_GATE_H("fuse", "clk_m", CAR_DEV_H_FUSE),
 	CLK_GATE_U("soc_therm", "div_soc_therm", CAR_DEV_U_SOC_THERM),
 	CLK_GATE_V("tsensor", "div_tsensor", CAR_DEV_V_TSENSOR),
-	CLK_GATE_SIMPLE("watchdog", "clk_m", CAR_RST_SOURCE_REG,
-		CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN),
 	CLK_GATE_L("host1x", "div_host1x", CAR_DEV_L_HOST1X),
 	CLK_GATE_L("disp1", "mux_disp1", CAR_DEV_L_DISP1),
 	CLK_GATE_L("disp2", "mux_disp2", CAR_DEV_L_DISP2),
@@ -639,6 +637,22 @@ static struct tegra_clk tegra124_car_clo
 	CLK_GATE_X("gpu", "pll_ref", CAR_DEV_X_GPU),
 };
 
+struct tegra124_init_parent {
+	const char *clock;
+	const char *parent;
+} tegra124_init_parents[] = {
+	{ "sata_oob",		"pll_p_out0" },
+	{ "sata",		"pll_p_out0" },
+	{ "hda",		"pll_p_out0" },
+	{ "hda2codec_2x",	"pll_p_out0" },
+	{ "soc_therm",		"pll_p_out0" },
+	{ "tsensor",		"clk_m" },
+	{ "xusb_host_src",	"pll_p_out0" },
+	{ "xusb_falcon_src",	"pll_p_out0" },
+	{ "xusb_ss_src",	"pll_u_480" },
+	{ "xusb_fs_src",	"pll_u_48" },
+};
+
 struct tegra124_car_rst {
 	u_int	set_reg;
 	u_int	clr_reg;
@@ -674,6 +688,8 @@ struct tegra124_car_softc {
 	bus_space_tag_t		sc_bst;
 	bus_space_handle_t	sc_bsh;
 
+	struct clk_domain	sc_clkdom;
+
 	u_int			sc_clock_cells;
 	u_int			sc_reset_cells;
 
@@ -684,6 +700,8 @@ struct tegra124_car_softc {
 static void	tegra124_car_init(struct tegra124_car_softc *);
 static void	tegra124_car_utmip_init(struct tegra124_car_softc *);
 static void	tegra124_car_xusb_init(struct tegra124_car_softc *);
+static void	tegra124_car_watchdog_init(struct tegra124_car_softc *);
+static void	tegra124_car_parent_init(struct tegra124_car_softc *);
 
 static void	tegra124_car_rnd_attach(device_t);
 static void	tegra124_car_rnd_callback(size_t, void *);
@@ -715,7 +733,7 @@ tegra124_car_attach(device_t parent, dev
 	const int phandle = faa->faa_phandle;
 	bus_addr_t addr;
 	bus_size_t size;
-	int error;
+	int error, n;
 
 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
 		aprint_error(": couldn't get registers\n");
@@ -737,7 +755,10 @@ tegra124_car_attach(device_t parent, dev
 	aprint_naive("\n");
 	aprint_normal(": CAR\n");
 
-	clk_backend_register("tegra124", &tegra124_car_clock_funcs, sc);
+	sc->sc_clkdom.funcs = &tegra124_car_clock_funcs;
+	sc->sc_clkdom.priv = sc;
+	for (n = 0; n < __arraycount(tegra124_car_clocks); n++)
+		tegra124_car_clocks[n].base.domain = &sc->sc_clkdom;
 
 	fdtbus_register_clock_controller(self, phandle,
 	    &tegra124_car_fdtclock_funcs);
@@ -752,8 +773,35 @@ tegra124_car_attach(device_t parent, dev
 static void
 tegra124_car_init(struct tegra124_car_softc *sc)
 {
+	tegra124_car_parent_init(sc);
 	tegra124_car_utmip_init(sc);
 	tegra124_car_xusb_init(sc);
+	tegra124_car_watchdog_init(sc);
+}
+
+static void
+tegra124_car_parent_init(struct tegra124_car_softc *sc)
+{
+	struct clk *clk, *clk_parent;
+	int error;
+	u_int n;
+
+	for (n = 0; n < __arraycount(tegra124_init_parents); n++) {
+		clk = clk_get(&sc->sc_clkdom, tegra124_init_parents[n].clock);
+		KASSERT(clk != NULL);
+		clk_parent = clk_get(&sc->sc_clkdom,
+		    tegra124_init_parents[n].parent);
+		KASSERT(clk_parent != NULL);
+
+		error = clk_set_parent(clk, clk_parent);
+		if (error) {
+			aprint_error_dev(sc->sc_dev,
+			    "couldn't set '%s' parent to '%s': %d\n",
+			    clk->name, clk_parent->name, error);
+		}
+		clk_put(clk_parent);
+		clk_put(clk);
+	}
 }
 
 static void
@@ -835,6 +883,17 @@ tegra124_car_xusb_init(struct tegra124_c
 }
 
 static void
+tegra124_car_watchdog_init(struct tegra124_car_softc *sc)
+{
+	const bus_space_tag_t bst = sc->sc_bst;
+	const bus_space_handle_t bsh = sc->sc_bsh;
+
+	/* Enable watchdog timer reset for system */
+	tegra_reg_set_clear(bst, bsh, CAR_RST_SOURCE_REG,
+	    CAR_RST_SOURCE_WDT_EN|CAR_RST_SOURCE_WDT_SYS_RST_EN, 0);
+}
+
+static void
 tegra124_car_rnd_attach(device_t self)
 {
 	struct tegra124_car_softc * const sc = device_private(self);
Index: src/sys/arch/arm/nvidia/tegra_ahcisata.c
diff -u src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.9 src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.10
--- src/sys/arch/arm/nvidia/tegra_ahcisata.c:1.9	Tue Dec 22 22:10:36 2015
+++ src/sys/arch/arm/nvidia/tegra_ahcisata.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_ahcisata.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $ */
+/* $NetBSD: tegra_ahcisata.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.9 2015/12/22 22:10:36 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_ahcisata.c,v 1.10 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -284,26 +284,13 @@ static int
 tegra_ahcisata_init_clocks(struct tegra_ahcisata_softc *sc)
 {
 	device_t self = sc->sc.sc_atac.atac_dev;
-	struct clk *pll_p_out0;
 	int error;
 
-	pll_p_out0 = clk_get("pll_p_out0");
-	if (pll_p_out0 == NULL) {
-		aprint_error_dev(self, "couldn't find pll_p_out0\n");
-		return ENOENT;
-	}
-
 	/* Assert resets */
 	fdtbus_reset_assert(sc->sc_rst_sata);
 	fdtbus_reset_assert(sc->sc_rst_sata_cold);
 
-	/* Set SATA_OOB clock source to PLLP, 204MHz */
-	error = clk_set_parent(sc->sc_clk_sata_oob, pll_p_out0);
-	if (error) {
-		aprint_error_dev(self, "couldn't set sata-oob parent: %d\n",
-		    error);
-		return error;
-	}
+	/* Set SATA_OOB clock source to 204MHz */
 	error = clk_set_rate(sc->sc_clk_sata_oob, 204000000);
 	if (error) {
 		aprint_error_dev(self, "couldn't set sata-oob rate: %d\n",
@@ -311,12 +298,7 @@ tegra_ahcisata_init_clocks(struct tegra_
 		return error;
 	}
 
-	/* Set SATA clock source to PLLP, 102MHz */
-	error = clk_set_parent(sc->sc_clk_sata, pll_p_out0);
-	if (error) {
-		aprint_error_dev(self, "couldn't set sata parent: %d\n", error);
-		return error;
-	}
+	/* Set SATA clock source to 102MHz */
 	error = clk_set_rate(sc->sc_clk_sata, 102000000);
 	if (error) {
 		aprint_error_dev(self, "couldn't set sata rate: %d\n", error);

Index: src/sys/arch/arm/nvidia/tegra_drm.c
diff -u src/sys/arch/arm/nvidia/tegra_drm.c:1.6 src/sys/arch/arm/nvidia/tegra_drm.c:1.7
--- src/sys/arch/arm/nvidia/tegra_drm.c:1.6	Sat Jan 30 00:00:56 2016
+++ src/sys/arch/arm/nvidia/tegra_drm.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_drm.c,v 1.6 2016/01/30 00:00:56 riastradh Exp $ */
+/* $NetBSD: tegra_drm.c,v 1.7 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.6 2016/01/30 00:00:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_drm.c,v 1.7 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -126,7 +126,6 @@ tegra_drm_attach(device_t parent, device
 		"hdmi-supply", "pll-supply", "vdd-supply"
 	};
 	struct fdtbus_regulator *reg;
-	struct clk *pll_p_out0;
 	u_int n, ndc;
 
 	sc->sc_dev = self;
@@ -192,24 +191,7 @@ tegra_drm_attach(device_t parent, device
 		}
 	}
 
-	pll_p_out0 = clk_get("pll_p_out0");
-	if (pll_p_out0 == NULL) {
-		aprint_error_dev(self, "couldn't get clock pll_p_out0\n");
-		return;
-	}
 	fdtbus_reset_assert(sc->sc_rst_host1x);
-	error = clk_set_parent(sc->sc_clk_host1x, pll_p_out0);
-	if (error) {
-		aprint_error_dev(self, "couldn't set host1x clock parent: %d\n",
-		    error);
-		return;
-	}
-	error = clk_set_rate(sc->sc_clk_host1x, 408000000);
-	if (error) {
-		aprint_error_dev(self, "couldn't set host1x frequency: %d\n",
-		    error);
-		return;
-	}
 	error = clk_enable(sc->sc_clk_host1x);
 	if (error) {
 		aprint_error_dev(self, "couldn't enable clock host1x: %d\n",
@@ -217,7 +199,6 @@ tegra_drm_attach(device_t parent, device
 		return;
 	}
 	fdtbus_reset_deassert(sc->sc_rst_host1x);
-	clk_put(pll_p_out0);
 
 	prop_dictionary_get_bool(prop, "force-dvi", &sc->sc_force_dvi);
 

Index: src/sys/arch/arm/nvidia/tegra_hdaudio.c
diff -u src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.7 src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.8
--- src/sys/arch/arm/nvidia/tegra_hdaudio.c:1.7	Wed Dec 23 12:44:06 2015
+++ src/sys/arch/arm/nvidia/tegra_hdaudio.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_hdaudio.c,v 1.7 2015/12/23 12:44:06 jmcneill Exp $ */
+/* $NetBSD: tegra_hdaudio.c,v 1.8 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.7 2015/12/23 12:44:06 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_hdaudio.c,v 1.8 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -183,26 +183,14 @@ static int
 tegra_hdaudio_init_clocks(struct tegra_hdaudio_softc *sc)
 {
 	device_t self = sc->sc.sc_dev;
-	struct clk *pll_p_out0;
 	int error;
 
-	pll_p_out0 = clk_get("pll_p_out0");
-	if (pll_p_out0 == NULL) {
-		aprint_error_dev(self, "couldn't find pll_p_out0\n");
-		return ENOENT;
-	}
-
 	/* Assert resets */
 	fdtbus_reset_assert(sc->sc_rst_hda);
 	fdtbus_reset_assert(sc->sc_rst_hda2hdmi);
 	fdtbus_reset_assert(sc->sc_rst_hda2codec_2x);
 
 	/* Set hda to 48MHz and enable it */
-	error = clk_set_parent(sc->sc_clk_hda, pll_p_out0);
-	if (error) {
-		aprint_error_dev(self, "coulnd't set hda parent: %d\n", error);
-		return error;
-	}
 	error = clk_set_rate(sc->sc_clk_hda, 48000000);
 	if (error) {
 		aprint_error_dev(self, "couldn't set hda frequency: %d\n",
@@ -225,12 +213,6 @@ tegra_hdaudio_init_clocks(struct tegra_h
 	}
 
 	/* Set hda2codec_2x to 48MHz and enable it */
-	error = clk_set_parent(sc->sc_clk_hda2codec_2x, pll_p_out0);
-	if (error) {
-		aprint_error_dev(self, "couldn't set hda2codec_2x parent: %d\n",
-		    error);
-		return error;
-	}
 	error = clk_set_rate(sc->sc_clk_hda2codec_2x, 48000000);
 	if (error) {
 		aprint_error_dev(self,

Index: src/sys/arch/arm/nvidia/tegra_soctherm.c
diff -u src/sys/arch/arm/nvidia/tegra_soctherm.c:1.3 src/sys/arch/arm/nvidia/tegra_soctherm.c:1.4
--- src/sys/arch/arm/nvidia/tegra_soctherm.c:1.3	Tue Dec 22 22:10:36 2015
+++ src/sys/arch/arm/nvidia/tegra_soctherm.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_soctherm.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $ */
+/* $NetBSD: tegra_soctherm.c,v 1.4 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.3 2015/12/22 22:10:36 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_soctherm.c,v 1.4 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -135,7 +135,7 @@ struct tegra_soctherm_softc {
 };
 
 static int	tegra_soctherm_init_clocks(struct tegra_soctherm_softc *);
-static void	tegra_soctherm_init_sensors(struct tegra_soctherm_softc *);
+static void	tegra_soctherm_init_sensors(device_t);
 static void	tegra_soctherm_init_sensor(struct tegra_soctherm_softc *,
 		    struct tegra_soctherm_sensor *);
 static void	tegra_soctherm_refresh(struct sysmon_envsys *, envsys_data_t *);
@@ -220,35 +220,16 @@ tegra_soctherm_attach(device_t parent, d
 	if (tegra_soctherm_init_clocks(sc) != 0)
 		return;
 
-	tegra_soctherm_init_sensors(sc);
+	config_defer(self, tegra_soctherm_init_sensors);
 }
 
 static int
 tegra_soctherm_init_clocks(struct tegra_soctherm_softc *sc)
 {
-	struct clk *pll_p_out0;
-	struct clk *clk_m;
 	int error;
 
-	pll_p_out0 = clk_get("pll_p_out0");
-	if (pll_p_out0 == NULL) {
-		aprint_error_dev(sc->sc_dev, "couldn't find pll_p_out0\n");
-		return ENOENT;
-	}
-	clk_m = clk_get("clk_m");
-	if (clk_m == NULL) {
-		aprint_error_dev(sc->sc_dev, "couldn't find clk_m\n");
-		return ENOENT;
-	}
-
 	fdtbus_reset_assert(sc->sc_rst_soctherm);
 
-	error = clk_set_parent(sc->sc_clk_soctherm, pll_p_out0);
-	if (error) {
-		aprint_error_dev(sc->sc_dev,
-		    "couldn't set soctherm parent: %d\n", error);
-		return error;
-	}
 	error = clk_set_rate(sc->sc_clk_soctherm, 51000000);
 	if (error) {
 		aprint_error_dev(sc->sc_dev,
@@ -256,12 +237,6 @@ tegra_soctherm_init_clocks(struct tegra_
 		return error;
 	}
 
-	error = clk_set_parent(sc->sc_clk_tsensor, clk_m);
-	if (error) {
-		aprint_error_dev(sc->sc_dev,
-		    "couldn't set tsensor parent: %d\n", error);
-		return error;
-	}
 	error = clk_set_rate(sc->sc_clk_tsensor, 400000);
 	if (error) {
 		aprint_error_dev(sc->sc_dev,
@@ -289,8 +264,9 @@ tegra_soctherm_init_clocks(struct tegra_
 }
 
 static void
-tegra_soctherm_init_sensors(struct tegra_soctherm_softc *sc)
+tegra_soctherm_init_sensors(device_t dev)
 {
+	struct tegra_soctherm_softc * const sc = device_private(dev);
 	const struct tegra_soctherm_config *config = sc->sc_config;
 	const u_int nsensors = __arraycount(tegra_soctherm_sensors);
 	const size_t len = sizeof(*sc->sc_sensors) * nsensors;

Index: src/sys/arch/arm/nvidia/tegra_timer.c
diff -u src/sys/arch/arm/nvidia/tegra_timer.c:1.4 src/sys/arch/arm/nvidia/tegra_timer.c:1.5
--- src/sys/arch/arm/nvidia/tegra_timer.c:1.4	Thu Dec 24 12:47:38 2015
+++ src/sys/arch/arm/nvidia/tegra_timer.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_timer.c,v 1.4 2015/12/24 12:47:38 jmcneill Exp $ */
+/* $NetBSD: tegra_timer.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.4 2015/12/24 12:47:38 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_timer.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -54,7 +54,6 @@ struct tegra_timer_softc {
 	device_t		sc_dev;
 	bus_space_tag_t		sc_bst;
 	bus_space_handle_t	sc_bsh;
-	struct clk		*sc_clk_watchdog;
 
 	struct sysmon_wdog	sc_smw;
 };
@@ -94,9 +93,6 @@ tegra_timer_attach(device_t parent, devi
 		aprint_error(": couldn't get registers\n");
 		return;
 	}
-	sc->sc_clk_watchdog = fdtbus_clock_get(faa->faa_phandle, "watchdog");
-	if (sc->sc_clk_watchdog == NULL)
-		sc->sc_clk_watchdog = clk_get("watchdog");
 
 	sc->sc_dev = self;
 	sc->sc_bst = faa->faa_bst;
@@ -109,21 +105,19 @@ tegra_timer_attach(device_t parent, devi
 	aprint_naive("\n");
 	aprint_normal(": Timers\n");
 
-	if (sc->sc_clk_watchdog) {
-		sc->sc_smw.smw_name = device_xname(self);
-		sc->sc_smw.smw_cookie = sc;
-		sc->sc_smw.smw_setmode = tegra_timer_wdt_setmode;
-		sc->sc_smw.smw_tickle = tegra_timer_wdt_tickle;
-		sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT;
-
-		aprint_normal_dev(self,
-		    "default watchdog period is %u seconds\n",
-		    sc->sc_smw.smw_period);
-
-		if (sysmon_wdog_register(&sc->sc_smw) != 0) {
-			aprint_error_dev(self,
-			    "couldn't register with sysmon\n");
-		}
+	sc->sc_smw.smw_name = device_xname(self);
+	sc->sc_smw.smw_cookie = sc;
+	sc->sc_smw.smw_setmode = tegra_timer_wdt_setmode;
+	sc->sc_smw.smw_tickle = tegra_timer_wdt_tickle;
+	sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT;
+
+	aprint_normal_dev(self,
+	    "default watchdog period is %u seconds\n",
+	    sc->sc_smw.smw_period);
+
+	if (sysmon_wdog_register(&sc->sc_smw) != 0) {
+		aprint_error_dev(self,
+		    "couldn't register with sysmon\n");
 	}
 }
 
@@ -134,7 +128,6 @@ tegra_timer_wdt_setmode(struct sysmon_wd
 
 	if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
 		TIMER_SET_CLEAR(sc, TMR1_PTV_REG, 0, TMR_PTV_EN);
-		return clk_disable(sc->sc_clk_watchdog);
 	} else {
 		if (smw->smw_period == WDOG_PERIOD_DEFAULT) {
 			sc->sc_smw.smw_period = TEGRA_TIMER_WDOG_PERIOD_DEFAULT;
@@ -147,8 +140,9 @@ tegra_timer_wdt_setmode(struct sysmon_wd
 		TIMER_WRITE(sc, TMR1_PTV_REG,
 		    TMR_PTV_EN | TMR_PTV_PER | __SHIFTIN(tval, TMR_PTV_VAL));
 		TIMER_WRITE(sc, TMR1_PCR_REG, TMR_PCR_INTR_CLR);
-		return clk_enable(sc->sc_clk_watchdog);
 	}
+
+	return 0;
 }
 
 static int
Index: src/sys/arch/arm/nvidia/tegra_xusb.c
diff -u src/sys/arch/arm/nvidia/tegra_xusb.c:1.4 src/sys/arch/arm/nvidia/tegra_xusb.c:1.5
--- src/sys/arch/arm/nvidia/tegra_xusb.c:1.4	Fri Apr 14 00:19:34 2017
+++ src/sys/arch/arm/nvidia/tegra_xusb.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_xusb.c,v 1.4 2017/04/14 00:19:34 jmcneill Exp $ */
+/* $NetBSD: tegra_xusb.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2016 Jonathan A. Kollasch
@@ -30,7 +30,7 @@
 #include "opt_tegra.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.4 2017/04/14 00:19:34 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_xusb.c,v 1.5 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -201,15 +201,6 @@ tegra_xusb_attach(device_t parent, devic
 	}
 	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
 
-	struct clk * const pll_p_out0 = clk_get("pll_p_out0");
-	KASSERT(pll_p_out0 != NULL);
-
-	struct clk * const pll_u_48 = clk_get("pll_u_48");
-	KASSERT(pll_u_48 != NULL);
-
-	struct clk * const pll_u_480 = clk_get("pll_u_480");
-	KASSERT(pll_u_480 != NULL);
-
 	clk = fdtbus_clock_get(faa->faa_phandle, "pll_e");
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
@@ -217,9 +208,6 @@ tegra_xusb_attach(device_t parent, devic
 	tegra_xusb_attach_check(sc, error, "failed to enable pll_e clock");
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_host_src");
-	error = clk_set_parent(clk, pll_p_out0);
-	tegra_xusb_attach_check(sc, error, "failed to set xusb_host_src clock parent");
-	
 	rate = clk_get_rate(clk);
 	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
 	error = clk_set_rate(clk, 102000000);
@@ -231,9 +219,6 @@ tegra_xusb_attach(device_t parent, devic
 	tegra_xusb_attach_check(sc, error, "failed to enable xusb_host_src clock");
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_falcon_src");
-	error = clk_set_parent(clk, pll_p_out0);
-	tegra_xusb_attach_check(sc, error, "failed to set xusb_falcon_src clock parent");
-
 	rate = clk_get_rate(clk);
 	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);
 	error = clk_set_rate(clk, 204000000);
@@ -258,18 +243,15 @@ tegra_xusb_attach(device_t parent, devic
 	psc->sc_clk_ss_src = fdtbus_clock_get(faa->faa_phandle, "xusb_ss_src");
 	tegra_xusb_attach_check(sc, psc->sc_clk_ss_src == NULL,
 		"failed to get xusb_ss_src clock");
+
 	rate = clk_get_rate(psc->sc_clk_ss_src);
 	device_printf(sc->sc_dev, "xusb_ss_src rate %u\n", rate);
-
 	error = clk_set_rate(psc->sc_clk_ss_src, 2000000);
 	rate = clk_get_rate(psc->sc_clk_ss_src);
 	device_printf(sc->sc_dev, "xusb_ss_src rate %u error %d\n", rate,
 	    error);
 	tegra_xusb_attach_check(sc, error, "failed to get xusb_ss_src clock rate");
 
-	error = clk_set_parent(psc->sc_clk_ss_src, pll_u_480);
-	tegra_xusb_attach_check(sc, error, "failed to set xusb_ss_src clock parent");
-
 	rate = clk_get_rate(psc->sc_clk_ss_src);
 	device_printf(sc->sc_dev, "ss_src rate %u\n", rate);
 	tegra_xusb_attach_check(sc, error, "failed to set xusb_ss_src clock rate");
@@ -291,9 +273,6 @@ tegra_xusb_attach(device_t parent, devic
 #endif
 
 	clk = fdtbus_clock_get(faa->faa_phandle, "xusb_fs_src");
-	error = clk_set_parent(clk, pll_u_48);
-	tegra_xusb_attach_check(sc, error, "failed to set xusb_fs_src clock parent");
-
 	rate = clk_get_rate(clk);
 	error = clk_enable(clk); /* XXX set frequency */
 	device_printf(sc->sc_dev, "rate %u error %d\n", rate, error);

Index: src/sys/dev/clk/clk.c
diff -u src/sys/dev/clk/clk.c:1.1 src/sys/dev/clk/clk.c:1.2
--- src/sys/dev/clk/clk.c:1.1	Sat Dec  5 13:31:07 2015
+++ src/sys/dev/clk/clk.c	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: clk.c,v 1.1 2015/12/05 13:31:07 jmcneill Exp $ */
+/* $NetBSD: clk.c,v 1.2 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,47 +27,29 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clk.c,v 1.1 2015/12/05 13:31:07 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clk.c,v 1.2 2017/04/16 12:28:21 jmcneill Exp $");
 
 #include <sys/param.h>
 
 #include <dev/clk/clk.h>
 #include <dev/clk/clk_backend.h>
 
-static const char *clk_backend = NULL;
-static const struct clk_funcs *clk_funcs = NULL;
-static void *clk_priv = NULL;
-
-int
-clk_backend_register(const char *name, const struct clk_funcs *funcs, void *priv)
-{
-	KASSERT(clk_funcs == NULL);
-
-	clk_backend = name;
-	clk_funcs = funcs;
-	clk_priv = priv;
-
-	return 0;
-}
-
 struct clk *
-clk_get(const char *name)
+clk_get(struct clk_domain *domain, const char *name)
 {
-	if (clk_funcs == NULL)
-		return NULL;
-	return clk_funcs->get(clk_priv, name);
+	return domain->funcs->get(domain->priv, name);
 }
 
 void
 clk_put(struct clk *clk)
 {
-	return clk_funcs->put(clk_priv, clk);
+	return clk->domain->funcs->put(clk->domain->priv, clk);
 }
 
 u_int
 clk_get_rate(struct clk *clk)
 {
-	return clk_funcs->get_rate(clk_priv, clk);
+	return clk->domain->funcs->get_rate(clk->domain->priv, clk);
 }
 
 int
@@ -75,31 +57,44 @@ clk_set_rate(struct clk *clk, u_int rate
 {
 	if (clk->flags & CLK_SET_RATE_PARENT) {
 		return clk_set_rate(clk_get_parent(clk), rate);
+	} else if (clk->domain->funcs->set_rate) {
+		return clk->domain->funcs->set_rate(clk->domain->priv,
+		    clk, rate);
 	} else {
-		return clk_funcs->set_rate(clk_priv, clk, rate);
+		return EINVAL;
 	}
 }
 
 int
 clk_enable(struct clk *clk)
 {
-	return clk_funcs->enable(clk_priv, clk);
+	if (clk->domain->funcs->enable)
+		return clk->domain->funcs->enable(clk->domain->priv, clk);
+	else
+		return 0;
 }
 
 int
 clk_disable(struct clk *clk)
 {
-	return clk_funcs->disable(clk_priv, clk);
+	if (clk->domain->funcs->disable)
+		return clk->domain->funcs->disable(clk->domain->priv, clk);
+	else
+		return EINVAL;
 }
 
 int
 clk_set_parent(struct clk *clk, struct clk *parent_clk)
 {
-	return clk_funcs->set_parent(clk_priv, clk, parent_clk);
+	if (clk->domain->funcs->set_parent)
+		return clk->domain->funcs->set_parent(clk->domain->priv,
+		    clk, parent_clk);
+	else
+		return EINVAL;
 }
 
 struct clk *
 clk_get_parent(struct clk *clk)
 {
-	return clk_funcs->get_parent(clk_priv, clk);
+	return clk->domain->funcs->get_parent(clk->domain->priv, clk);
 }
Index: src/sys/dev/clk/clk.h
diff -u src/sys/dev/clk/clk.h:1.1 src/sys/dev/clk/clk.h:1.2
--- src/sys/dev/clk/clk.h:1.1	Sat Dec  5 13:31:07 2015
+++ src/sys/dev/clk/clk.h	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: clk.h,v 1.1 2015/12/05 13:31:07 jmcneill Exp $ */
+/* $NetBSD: clk.h,v 1.2 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -29,9 +29,10 @@
 #ifndef _DEV_CLK_CLK_H
 #define _DEV_CLK_CLK_H
 
+struct clk_domain;
 struct clk;
 
-struct clk *	clk_get(const char *);
+struct clk *	clk_get(struct clk_domain *, const char *);
 void		clk_put(struct clk *);
 u_int		clk_get_rate(struct clk *);
 int		clk_set_rate(struct clk *, u_int);
Index: src/sys/dev/clk/clk_backend.h
diff -u src/sys/dev/clk/clk_backend.h:1.1 src/sys/dev/clk/clk_backend.h:1.2
--- src/sys/dev/clk/clk_backend.h:1.1	Sat Dec  5 13:31:07 2015
+++ src/sys/dev/clk/clk_backend.h	Sun Apr 16 12:28:21 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: clk_backend.h,v 1.1 2015/12/05 13:31:07 jmcneill Exp $ */
+/* $NetBSD: clk_backend.h,v 1.2 2017/04/16 12:28:21 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -31,7 +31,13 @@
 
 #include <dev/clk/clk.h>
 
+struct clk_domain {
+	const struct clk_funcs *funcs;
+	void *priv;
+};
+
 struct clk {
+	struct clk_domain *domain;
         const char *name;
         u_int flags;
 #define CLK_SET_RATE_PARENT     0x01
@@ -49,6 +55,4 @@ struct clk_funcs {
 	struct clk *(*get_parent)(void *, struct clk *);
 };
 
-int	clk_backend_register(const char *, const struct clk_funcs *, void *);
-
 #endif /* _DEV_CLK_CLK_BACKEND_H */

Reply via email to