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>