[U-Boot] [RFC PATCH 3/4 v1] mvrtc: add fdt support.
Jason
u-boot at lakedaemon.net
Thu Sep 15 22:01:31 CEST 2011
On Thu, Sep 15, 2011 at 12:23:52PM -0700, Simon Glass wrote:
> On Thu, Sep 15, 2011 at 6:54 AM, Jason Cooper <u-boot at lakedaemon.net> wrote:
> >
> > Signed-off-by: Jason Cooper <u-boot at lakedaemon.net>
> > ---
> > common/fdt_decode.c | 1 +
> > drivers/rtc/mvrtc.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--
> > drivers/rtc/mvrtc.h | 7 +++++
> > include/fdt_decode.h | 1 +
> > 4 files changed, 68 insertions(+), 3 deletions(-)
> >
> > diff --git a/common/fdt_decode.c b/common/fdt_decode.c
> > index 0f13089..1a0dcf4 100644
> > --- a/common/fdt_decode.c
> > +++ b/common/fdt_decode.c
> > @@ -34,6 +34,7 @@
> > */
> > #define COMPAT(id, name) name
> > const char *compat_names[COMPAT_COUNT] = {
> > + COMPAT(MARVELL_KIRKWOOD_RTC, "marvell,kirkwood-rtc"),
> > };
> >
> > /**
> > diff --git a/drivers/rtc/mvrtc.c b/drivers/rtc/mvrtc.c
> > index ccc573a..ce2dc3d 100644
> > --- a/drivers/rtc/mvrtc.c
> > +++ b/drivers/rtc/mvrtc.c
> > @@ -28,18 +28,62 @@
> > #include <common.h>
> > #include <command.h>
> > #include <rtc.h>
> > +#ifdef CONFIG_OF_CONTROL
> > +#include <fdt_decode.h>
> > +#endif
> > #include "mvrtc.h"
> >
> > +DECLARE_GLOBAL_DATA_PTR;
> > +
> > /* This RTC does not support century, so we assume 20 */
> > #define CENTURY 20
> >
> > +#ifndef CONFIG_OF_CONTROL
>
> Perhaps #ifdef and put the fdt code first?
Sure. For larger drivers, I'd prefer to see a separate file. eg:
mvgbe.c
mvgbe-dt.c
with mvgbe.h selecting _init() or _init_fdt() on CONFIG_OF_CONTROL. Not
sure, gotta think about it more.
> > +struct mvrtc_registers *mvrtc_get_config(void) {
> > + return (struct mvrtc_registers *)KW_RTC_BASE;
> > +}
> > +
> > +#else
> > +int fdt_decode_rtc(const void *blob, int node, struct fdt_rtc *config)
> > +{
> > + config->reg = get_addr(blob, node, "reg");
> > + config->enabled = get_is_enabled(blob, node, 0);
> > +
> > + return 0;
> > +}
> > +
> > +struct mvrtc_registers *mvrtc_get_config(void) {
> > + const void *blob = gd->blob;
> > + struct fdt_rtc config;
> > + int node;
> > + int index=0;
> > +
> > + node = fdt_decode_next_alias(blob, "rtc",
> > + COMPAT_MARVELL_KIRKWOOD_RTC, &index);
> > +
> > + if (node < 0)
> > + return NULL;
> > +
> > + if (fdt_decode_rtc(blob, node, &config))
> > + return NULL;
> > +
> > + return config.enabled ? (struct mvrtc_registers *)config.reg : NULL;
> > +}
> > +#endif
> > +
> > int rtc_get(struct rtc_time *t)
> > {
> > u32 time;
> > u32 date;
> > struct mvrtc_registers *mvrtc_regs;
> >
> > - mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
> > + mvrtc_regs = mvrtc_get_config();
> > +#ifdef CONFIG_OF_CONTROL
> > + if (mvrtc_regs == NULL) {
> > + printf("Error decoding fdt for mvrtc.\n");
> > + return -1;
> > + }
> > +#endif
> >
> > /* read the time register */
> > time = readl(&mvrtc_regs->time);
> > @@ -79,7 +123,13 @@ int rtc_set(struct rtc_time *t)
> > u32 date = 0;
> > struct mvrtc_registers *mvrtc_regs;
> >
> > - mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
> > + mvrtc_regs = mvrtc_get_config();
> > +#ifdef CONFIG_OF_CONTROL
> > + if (mvrtc_regs == NULL) {
> > + printf("Error decoding fdt for mvrtc.\n");
> > + return -1;
> > + }
> > +#endif
> >
> > /* check that this code isn't 80+ years old ;-) */
> > if ((t->tm_year / 100) != CENTURY)
> > @@ -111,7 +161,13 @@ void rtc_reset(void)
> > u32 sec;
> > struct mvrtc_registers *mvrtc_regs;
> >
> > - mvrtc_regs = (struct mvrtc_registers *)KW_RTC_BASE;
> > + mvrtc_regs = mvrtc_get_config();
> > +#ifdef CONFIG_OF_CONTROL
> > + if (mvrtc_regs == NULL) {
> > + printf("Error decoding fdt for mvrtc.\n");
> > + return;
> > + }
> > +#endif
> >
> > /* no init routine for this RTC needed, just check that it's working */
>
> Hmm I think it would be better to decode the fdt once in init, and
> store it in your structure. It seems like you are doing it each time
> the driver is called.
Yes, it's a stupid/simple driver. There is definitely room for
optimization.
> > time = readl(&mvrtc_regs->time);
> > diff --git a/drivers/rtc/mvrtc.h b/drivers/rtc/mvrtc.h
> > index b9d5c6f..56b09f2 100644
> > --- a/drivers/rtc/mvrtc.h
> > +++ b/drivers/rtc/mvrtc.h
> > @@ -37,6 +37,13 @@ struct mvrtc_registers {
> > u32 date;
> > };
> >
> > +#ifdef CONFIG_OF_CONTROL
> > +struct fdt_rtc {
> > + addr_t reg; /* address of the registers */
> > + int enabled; /* 1 if enabled, 0 if disabled */
> > +};
>
> It seems to be that this structure should generally only be needed in
> the C file, so should perhaps go there.
true.
> > +#endif
> > +
> > /* time register */
> > #define MVRTC_SEC_SFT 0
> > #define MVRTC_SEC_MSK 0x7f
> > diff --git a/include/fdt_decode.h b/include/fdt_decode.h
> > index 4264e3b..f236643 100644
> > --- a/include/fdt_decode.h
> > +++ b/include/fdt_decode.h
> > @@ -54,6 +54,7 @@ struct fdt_memory {
> > */
> > enum fdt_compat_id {
> > COMPAT_UNKNOWN,
> > + COMPAT_MARVELL_KIRKWOOD_RTC,
>
> My cunning plan is that this can be some sort of driver ID and could
> serve as a lead in to a unified device model (it provides a simple
> enumeration of available drivers).
That's on the list of words that scare me. ;-) Right up there with
perfect, minimized, maximized, secure, and user-friendly.
> However, perhaps we should discuss this separately.
Definitely.
thx,
Jason.
More information about the U-Boot
mailing list