PERFORCE change 159389 for review
Ulf Lilleengen
lulf at FreeBSD.org
Wed Mar 18 09:48:55 PDT 2009
http://perforce.freebsd.org/chv.cgi?CH=159389
Change 159389 by lulf at 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_ */
More information about the p4-projects
mailing list