Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Mar 2009 16:48:53 GMT
From:      Ulf Lilleengen <lulf@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 159389 for review
Message-ID:  <200903181648.n2IGmrFi066538@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=159389

Change 159389 by lulf@lulf_carrot on 2009/03/18 16:48:38

	- Firsly, use KOBJ_FIELDS; in the devclk structure, so we avoid going
	  via the methods, as it is not really any point in it.
	- Use ints instead of uint8_t for now.
	- Re-work the devclk interface a bit. Previously, one would have to go
	  via the bus to get the mapping from a device to its clocks. However,
	  this made the interface a bit ugly, as parts of it was used by the bus
	  and parts by the clocks. Instead, register these mappings with the
	  devclk manager. The tradeoff (for now a least), is that lookups
	  involve looping over the maps and enable all clocks registered on a
	  device. It could be made more efficient by just storing the mapping in
	  the device itself, but it will have to do for now.

Affected files ...

.. //depot/projects/avr32/src/sys/avr32/avr32/at32.c#8 edit
.. //depot/projects/avr32/src/sys/avr32/avr32/at32_pm.c#4 edit
.. //depot/projects/avr32/src/sys/kern/devclk_if.m#3 edit
.. //depot/projects/avr32/src/sys/kern/subr_devclk.c#3 edit
.. //depot/projects/avr32/src/sys/sys/devclk.h#3 edit

Differences ...

==== //depot/projects/avr32/src/sys/avr32/avr32/at32.c#8 (text+ko) ====

@@ -80,9 +80,8 @@
 };
 struct at32_ivar {
 	struct resource_list	resources;
-	char			clk_name[32];
-	int			clk_index;
 };
+
 static device_method_t at32_methods[] = {
 	DEVMETHOD(device_probe,			at32_probe),
 	DEVMETHOD(device_attach,		at32_attach),
@@ -100,10 +99,11 @@
 	DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
 	DEVMETHOD(bus_release_resource,		at32_release_resource),
 
+/*
 	DEVMETHOD(devclk_get_rate,		at32_clk_get_rate),
 	DEVMETHOD(devclk_set_rate,		at32_clk_set_rate),
 	DEVMETHOD(devclk_enable,		at32_clk_enable),
-	DEVMETHOD(devclk_disable,		at32_clk_disable),
+	DEVMETHOD(devclk_disable,		at32_clk_disable),*/
 	{0, 0},
 };
 
@@ -189,12 +189,10 @@
 static void
 at32_hinted_child(device_t bus, const char *dname, int dunit)
 {
-	/* XXX: Fetch ivar and set variables. */
 	device_t child;
 	long maddr;
-	int msize, irq, result;
+	int msize, irq, result, clk_index;
 	const char *resval;
-	struct at32_ivar *ivar;
 	
 
 	child = BUS_ADD_CHILD(bus, 0, dname, dunit);
@@ -218,14 +216,12 @@
 				"warning: bus_set_resource() failed\n");
 		}
 	}
-	ivar = device_get_ivars(child);
 	if (resource_string_value(dname, dunit, "clk", &resval) == 0) {
 		if (resource_int_value(dname, dunit, "clk_index",
-		    &ivar->clk_index) != 0)
-			ivar->clk_index = 0; /* Default */
-		strlcpy(ivar->clk_name, resval, sizeof(ivar->clk_name));
+		    &clk_index) != 0)
+			clk_index = 0; /* Default */
+		devclk_register_map(child, resval, clk_index);
 	}
-
 }
 
 static struct resource *
@@ -359,7 +355,7 @@
 	ivar = device_get_ivars(child);
 	return (&(ivar->resources));
 }
-
+#if 0
 static uint64_t
 at32_clk_get_rate(device_t dev, device_t child)
 {
@@ -393,3 +389,4 @@
 	if (strcmp(ivar->clk_name, "") != 0)
 		devclk_deactivate(ivar->clk_name, ivar->clk_index);
 }
+#endif

==== //depot/projects/avr32/src/sys/avr32/avr32/at32_pm.c#4 (text+ko) ====

@@ -65,12 +65,12 @@
 static int at32_pm_activate(device_t);
 static void at32_pm_deactivate(device_t);
 
-static void at32_pbb_start(devclk_t, uint8_t);
-static void at32_pbb_stop(devclk_t, uint8_t);
-static void at32_pll_start(devclk_t, uint8_t);
-static void at32_pll_stop(devclk_t, uint8_t);
-static void at32_osc_start(devclk_t, uint8_t);
-static void at32_osc_stop(devclk_t, uint8_t);
+static void at32_pbb_enable(devclk_t, int);
+static void at32_pbb_disable(devclk_t, int);
+static void at32_pll_enable(devclk_t, int);
+static void at32_pll_disable(devclk_t, int);
+static void at32_osc_enable(devclk_t, int);
+static void at32_osc_disable(devclk_t, int);
 
 /* Driver variables and private data */
 struct at32_pm_softc {
@@ -99,8 +99,8 @@
 
 /* Class defining our oscilliator. */
 static kobj_method_t at32_osc_methods[] = {
-	KOBJMETHOD(devclk_start,	at32_osc_start),
-	KOBJMETHOD(devclk_stop,		at32_osc_stop),
+	KOBJMETHOD(devclk_enable,	at32_osc_enable),
+	KOBJMETHOD(devclk_disable,	at32_osc_disable),
 /*	KOBJMETHOD(devclk_set_rate,	at32_osc_set_rate),
 	KOBJMETHOD(devclk_get_rate,	at32_osc_get_rate),*/
 	{0, 0},
@@ -109,8 +109,8 @@
 
 /* Class defining our PLLs. */
 static kobj_method_t at32_pll_methods[] = {
-	KOBJMETHOD(devclk_start,	at32_pll_start),
-	KOBJMETHOD(devclk_stop,		at32_pll_stop),
+	KOBJMETHOD(devclk_enable,	at32_pll_enable),
+	KOBJMETHOD(devclk_disable,	at32_pll_disable),
 /*	KOBJMETHOD(devclk_set_rate,	at32_pll_set_rate),
 	KOBJMETHOD(devclk_get_rate,	at32_pll_get_rate),*/
 	{0, 0},
@@ -119,8 +119,8 @@
 
 /* Class defining the PBB clock mask. */
 static kobj_method_t at32_pbb_methods[] = {
-	KOBJMETHOD(devclk_start,	at32_pbb_start),
-	KOBJMETHOD(devclk_stop,		at32_pbb_stop),
+	KOBJMETHOD(devclk_enable,	at32_pbb_enable),
+	KOBJMETHOD(devclk_disable,	at32_pbb_disable),
 /*	KOBJMETHOD(devclk_set_rate,	at32_pbb_set_rate),
 	KOBJMETHOD(devclk_get_rate,	at32_pbb_get_rate),*/
 	{0, 0},
@@ -212,7 +212,7 @@
 }
 
 static void
-at32_pbb_start(devclk_t clk, uint8_t index)
+at32_pbb_enable(devclk_t clk, int index)
 {
 	struct at32_pm_softc *sc;
 	uint32_t reg;
@@ -225,7 +225,7 @@
 }
 
 static void
-at32_pbb_stop(devclk_t clk, uint8_t index)
+at32_pbb_disable(devclk_t clk, int index)
 {
 	struct at32_pm_softc *sc;
 	uint32_t reg;
@@ -238,7 +238,7 @@
 }
 
 static void
-at32_osc_start(devclk_t clk, uint8_t index)
+at32_osc_enable(devclk_t clk, int index)
 {
 	/* In this case, index means which oscilliator. */
 	switch (index) {
@@ -252,7 +252,7 @@
 } 
 
 static void
-at32_osc_stop(devclk_t clk, uint8_t index)
+at32_osc_disable(devclk_t clk, int index)
 {
 	/* In this case, index means which oscilliator. */
 	switch (index) {
@@ -266,7 +266,7 @@
 }
 
 static void
-at32_pll_start(devclk_t clk, uint8_t index)
+at32_pll_enable(devclk_t clk, int index)
 {
 	/* Here, index means which pll. */
 	switch (index) {
@@ -278,7 +278,7 @@
 } 
 
 static void
-at32_pll_stop(devclk_t clk, uint8_t index)
+at32_pll_disable(devclk_t clk, int index)
 {
 	/* Here, index means which pll. */
 	switch (index) {

==== //depot/projects/avr32/src/sys/kern/devclk_if.m#3 (text+ko) ====

@@ -43,26 +43,14 @@
 	uint64_t	_rate;
 };
 
-# Enable device clock
+# Enable a device clock
 METHOD void enable {
-	device_t	_dev;
-	device_t	_child;
+	devclk_t	_clk;
+	int		_index;
 };
 
-# Disable device clock
+# Disable a device clock
 METHOD void disable {
-	device_t	_dev;
-	device_t	_child;
-};
-
-# Enable a devclk
-METHOD void start {
 	devclk_t	_clk;
-	uint8_t		_index;
-};
-
-# Disable a devclk
-METHOD void stop {
-	devclk_t	_clk;
-	uint8_t		_index;
+	int		_index;
 };

==== //depot/projects/avr32/src/sys/kern/subr_devclk.c#3 (text+ko) ====

@@ -39,7 +39,19 @@
 
 #include "devclk_if.h"
 
+/* TODO:
+ - Maybe a bit inefficient.
+ */
+
+struct devclk_map {
+	device_t dev;
+	char clk_name[32];
+	int clk_index;
+	STAILQ_ENTRY(devclk_map) link;
+};
+
 static devclk_list_t devclks;
+static STAILQ_HEAD(, devclk_map) devclk_maps;
 
 static devclk_t devclk_find_clock(const char *);
 
@@ -47,43 +59,69 @@
 devclk_init(void)
 {
 	STAILQ_INIT(&devclks);
+	STAILQ_INIT(&devclk_maps);
 }
 
 uint64_t
 devclk_get_rate(device_t dev)
 {
+#if 0
 	device_t parent = device_get_parent(dev);
 	if (parent) {
 		return (DEVCLK_GET_RATE(parent, dev));
 	}
+#endif
 	return (0);
 }
 
 int
 devclk_set_rate(device_t dev, uint64_t rate)
 {
+#if 0
 	device_t parent = device_get_parent(dev);
 	if (parent) {
 		return (DEVCLK_SET_RATE(parent, dev, rate));
 	}
+#endif
 	return (EINVAL);
 }
 
 void
 devclk_enable(device_t dev)
 {
-	device_t parent = device_get_parent(dev);
-	if (parent) {
-		DEVCLK_ENABLE(parent, dev);
+	struct devclk_map *map;
+	devclk_t clk;
+
+	/* Enable all clocks this device is mapped to. */
+	/*
+	 * XXX: This looks a bit silly right now, and this information should
+	 * perhaps be retrieved from the device somehow, but that makes it
+	 * machine dependant.
+	 */
+	STAILQ_FOREACH(map, &devclk_maps, link) {
+		if (map->dev != dev)
+			continue;
+		clk = devclk_find_clock(map->clk_name);
+		if (clk == NULL)
+			continue;
+		/* XXX: Enable parent too ? */
+		DEVCLK_ENABLE(clk, map->clk_index);
 	}
 }
 
 void
 devclk_disable(device_t dev)
 {
-	device_t parent = device_get_parent(dev);
-	if (parent) {
-		DEVCLK_DISABLE(parent, dev);
+	struct devclk_map *map;
+	devclk_t clk;
+
+	/* Enable all clocks this device is mapped to. */
+	STAILQ_FOREACH(map, &devclk_maps, link) {
+		clk = devclk_find_clock(map->clk_name);
+		if (clk == NULL)
+			continue;
+		/* XXX: Enable parent too ? */
+		DEVCLK_DISABLE(clk, map->clk_index);
 	}
 }
 
@@ -96,8 +134,7 @@
 {
 	devclk_t clk;
 	
-	clk = malloc(sizeof(*clk), M_DEVBUF, M_WAITOK | M_ZERO);
-	clk->methods = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO);
+	clk = kobj_create(cls, M_DEVBUF, M_WAITOK | M_ZERO);
 	clk->dev = dev;
 	strlcpy(clk->name, name, sizeof(clk->name));
 	clk->parent = ((parent == NULL) ? NULL : devclk_find_clock(parent));
@@ -106,6 +143,23 @@
 	STAILQ_INSERT_HEAD(&devclks, clk, link);
 }
 
+/*
+ * Register a mapping between a clock and a device.
+ */
+void
+devclk_register_map(device_t dev, const char *clk, int index)
+{
+	struct devclk_map *map;
+
+	map = malloc(sizeof(*clk), M_DEVBUF, M_WAITOK | M_ZERO);
+	map->dev = dev;
+	strlcpy(map->clk_name, clk, sizeof(map->clk_name));
+	map->clk_index = index;
+
+	/* Insert into map. */
+	STAILQ_INSERT_HEAD(&devclk_maps, map, link);
+}
+
 static devclk_t
 devclk_find_clock(const char *name)
 {
@@ -118,28 +172,3 @@
 	}
 	return (NULL);
 }
-
-/* Start device clock name by activating index index. */
-void
-devclk_activate(const char *name, uint8_t index)
-{
-	devclk_t clk;
-
-	clk = devclk_find_clock(name);
-	if (clk == NULL)
-		return;
-	/* XXX: Enable parent too ? */
-	DEVCLK_START(clk->methods, index);
-}
-
-/* Stop device clock name by deactivating index index. */
-void
-devclk_deactivate(const char *name, uint8_t index)
-{
-	devclk_t clk;
-
-	clk = devclk_find_clock(name);
-	if (clk == NULL)
-		return;
-	DEVCLK_STOP(clk->methods, index);
-}

==== //depot/projects/avr32/src/sys/sys/devclk.h#3 (text+ko) ====

@@ -5,7 +5,7 @@
 
 #include  <sys/kobj.h>
 struct devclk {
-	kobj_t methods;
+	KOBJ_FIELDS;
 	device_t dev;		/* Device responsible for clock. */
 	char name[32];		/* Clock name.			 */
 	struct devclk *parent;	/* Clock we originate from.	 */
@@ -39,14 +39,15 @@
  */
 void devclk_disable(device_t);
 
-void devclk_activate(const char *, uint8_t);
-void devclk_deactivate(const char *, uint8_t);
-
 /**
  * Add a clock to the devclk manager.
  */
 void	devclk_register_clock(device_t, kobj_class_t, const char *, const char *);
 
+/**
+ * Register a mapping from device to clock
+ */
+void	devclk_register_map(device_t, const char *, int);
 
 #endif /* _KERNEL */
 #endif /* !_SYS_DEVCLK_H_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903181648.n2IGmrFi066538>