sparc64: Use generic BQ4802 RTC driver.
authorDavid S. Miller <davem@davemloft.net>
Fri, 29 Aug 2008 04:54:34 +0000 (21:54 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 29 Aug 2008 21:16:50 +0000 (14:16 -0700)
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc64/Kconfig
arch/sparc64/kernel/time.c

index e0d783bbae0942f49571bf81ec447311e29d7ae8..a4ec899faa42ea319280c73d08bf37d3349463e2 100644 (file)
@@ -22,6 +22,7 @@ config SPARC64
        select RTC_CLASS
        select RTC_DRV_M48T59
        select RTC_DRV_CMOS
+       select RTC_DRV_BQ4802
 
 config GENERIC_TIME
        bool
index abdeead4e5b99ae2a0b158e39a2a0472b0b2b325..5e199a0e43786d18bbf49565898dc6b38cec8337 100644 (file)
@@ -52,9 +52,6 @@
 #include "entry.h"
 
 DEFINE_SPINLOCK(rtc_lock);
-static void __iomem *bq4802_regs;
-
-static int set_rtc_mmss(unsigned long);
 
 #define TICK_PRIV_BIT  (1UL << 63)
 #define TICKCMP_IRQ_BIT        (1UL << 63)
@@ -403,50 +400,7 @@ int update_persistent_clock(struct timespec now)
        if (rtc)
                return rtc_set_mmss(rtc, now.tv_sec);
 
-       return set_rtc_mmss(now.tv_sec);
-}
-
-/* Probe for the real time clock chip. */
-static void __init set_system_time(void)
-{
-       unsigned int year, mon, day, hour, min, sec;
-       void __iomem *bregs = bq4802_regs;
-       unsigned char val = readb(bregs + 0x0e);
-       unsigned int century;
-
-       if (!bregs) {
-               prom_printf("Something wrong, clock regs not mapped yet.\n");
-               prom_halt();
-       }               
-
-       /* BQ4802 RTC chip. */
-
-       writeb(val | 0x08, bregs + 0x0e);
-
-       sec  = readb(bregs + 0x00);
-       min  = readb(bregs + 0x02);
-       hour = readb(bregs + 0x04);
-       day  = readb(bregs + 0x06);
-       mon  = readb(bregs + 0x09);
-       year = readb(bregs + 0x0a);
-       century = readb(bregs + 0x0f);
-
-       writeb(val, bregs + 0x0e);
-
-       BCD_TO_BIN(sec);
-       BCD_TO_BIN(min);
-       BCD_TO_BIN(hour);
-       BCD_TO_BIN(day);
-       BCD_TO_BIN(mon);
-       BCD_TO_BIN(year);
-       BCD_TO_BIN(century);
-
-       year += (century * 100);
-
-       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-       xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-       set_normalized_timespec(&wall_to_monotonic,
-                               -xtime.tv_sec, -xtime.tv_nsec);
+       return -1;
 }
 
 /* davem suggests we keep this within the 4M locked kernel image */
@@ -575,24 +529,20 @@ static struct of_platform_driver rtc_driver = {
        },
 };
 
+static struct platform_device rtc_bq4802_device = {
+       .name           = "rtc-bq4802",
+       .id             = -1,
+       .num_resources  = 1,
+};
+
 static int __devinit bq4802_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct device_node *dp = op->node;
-       unsigned long flags;
-
-       bq4802_regs = of_ioremap(&op->resource[0], 0, resource_size(&op->resource[0]), "bq4802");
-       if (!bq4802_regs)
-               return -ENOMEM;
-
-       printk(KERN_INFO "%s: Clock regs at %p\n", dp->full_name, bq4802_regs);
 
-       local_irq_save(flags);
-
-       set_system_time();
-       
-       local_irq_restore(flags);
+       printk(KERN_INFO "%s: BQ4802 regs at 0x%lx\n",
+              op->node->full_name, op->resource[0].start);
 
-       return 0;
+       rtc_bq4802_device.resource = &op->resource[0];
+       return platform_device_register(&rtc_bq4802_device);
 }
 
 static struct of_device_id bq4802_match[] = {
@@ -984,56 +934,6 @@ unsigned long long sched_clock(void)
                >> SPARC64_NSEC_PER_CYC_SHIFT;
 }
 
-static int set_rtc_mmss(unsigned long nowtime)
-{
-       int real_seconds, real_minutes, chip_minutes;
-       void __iomem *bregs = bq4802_regs;
-       unsigned long flags;
-       unsigned char val;
-       int retval = 0;
-
-       /* 
-        * Not having a register set can lead to trouble.
-        * Also starfire doesn't have a tod clock.
-        */
-       if (!bregs)
-               return -1;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-
-       val = readb(bregs + 0x0e);
-
-       /* BQ4802 RTC chip. */
-
-       writeb(val | 0x08, bregs + 0x0e);
-
-       chip_minutes = readb(bregs + 0x02);
-       BCD_TO_BIN(chip_minutes);
-       real_seconds = nowtime % 60;
-       real_minutes = nowtime / 60;
-       if (((abs(real_minutes - chip_minutes) + 15)/30) & 1)
-               real_minutes += 30;
-       real_minutes %= 60;
-
-       if (abs(real_minutes - chip_minutes) < 30) {
-               BIN_TO_BCD(real_seconds);
-               BIN_TO_BCD(real_minutes);
-               writeb(real_seconds, bregs + 0x00);
-               writeb(real_minutes, bregs + 0x02);
-       } else {
-               printk(KERN_WARNING
-                      "set_rtc_mmss: can't update from %d to %d\n",
-                      chip_minutes, real_minutes);
-               retval = -1;
-       }
-
-       writeb(val, bregs + 0x0e);
-
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return retval;
-}
-
 #define RTC_IS_OPEN            0x01    /* means /dev/rtc is in use     */
 static unsigned char mini_rtc_status;  /* bitmapped status byte.       */
 
@@ -1155,78 +1055,6 @@ static int hypervisor_set_rtc_time(struct rtc_time *time)
        return hypervisor_set_time(seconds);
 }
 
-static void bq4802_get_rtc_time(struct rtc_time *time)
-{
-       unsigned char val = readb(bq4802_regs + 0x0e);
-       unsigned int century;
-
-       writeb(val | 0x08, bq4802_regs + 0x0e);
-
-       time->tm_sec = readb(bq4802_regs + 0x00);
-       time->tm_min = readb(bq4802_regs + 0x02);
-       time->tm_hour = readb(bq4802_regs + 0x04);
-       time->tm_mday = readb(bq4802_regs + 0x06);
-       time->tm_mon = readb(bq4802_regs + 0x09);
-       time->tm_year = readb(bq4802_regs + 0x0a);
-       time->tm_wday = readb(bq4802_regs + 0x08);
-       century = readb(bq4802_regs + 0x0f);
-
-       writeb(val, bq4802_regs + 0x0e);
-
-       BCD_TO_BIN(time->tm_sec);
-       BCD_TO_BIN(time->tm_min);
-       BCD_TO_BIN(time->tm_hour);
-       BCD_TO_BIN(time->tm_mday);
-       BCD_TO_BIN(time->tm_mon);
-       BCD_TO_BIN(time->tm_year);
-       BCD_TO_BIN(time->tm_wday);
-       BCD_TO_BIN(century);
-
-       time->tm_year += (century * 100);
-       time->tm_year -= 1900;
-
-       time->tm_mon--;
-}
-
-static int bq4802_set_rtc_time(struct rtc_time *time)
-{
-       unsigned char val = readb(bq4802_regs + 0x0e);
-       unsigned char sec, min, hrs, day, mon, yrs, century;
-       unsigned int year;
-
-       year = time->tm_year + 1900;
-       century = year / 100;
-       yrs = year % 100;
-
-       mon = time->tm_mon + 1;   /* tm_mon starts at zero */
-       day = time->tm_mday;
-       hrs = time->tm_hour;
-       min = time->tm_min;
-       sec = time->tm_sec;
-
-       BIN_TO_BCD(sec);
-       BIN_TO_BCD(min);
-       BIN_TO_BCD(hrs);
-       BIN_TO_BCD(day);
-       BIN_TO_BCD(mon);
-       BIN_TO_BCD(yrs);
-       BIN_TO_BCD(century);
-
-       writeb(val | 0x08, bq4802_regs + 0x0e);
-
-       writeb(sec, bq4802_regs + 0x00);
-       writeb(min, bq4802_regs + 0x02);
-       writeb(hrs, bq4802_regs + 0x04);
-       writeb(day, bq4802_regs + 0x06);
-       writeb(mon, bq4802_regs + 0x09);
-       writeb(yrs, bq4802_regs + 0x0a);
-       writeb(century, bq4802_regs + 0x0f);
-
-       writeb(val, bq4802_regs + 0x0e);
-
-       return 0;
-}
-
 struct mini_rtc_ops {
        void (*get_rtc_time)(struct rtc_time *);
        int (*set_rtc_time)(struct rtc_time *);
@@ -1242,11 +1070,6 @@ static struct mini_rtc_ops hypervisor_rtc_ops = {
        .set_rtc_time = hypervisor_set_rtc_time,
 };
 
-static struct mini_rtc_ops bq4802_rtc_ops = {
-       .get_rtc_time = bq4802_get_rtc_time,
-       .set_rtc_time = bq4802_set_rtc_time,
-};
-
 static struct mini_rtc_ops *mini_rtc_ops;
 
 static inline void mini_get_rtc_time(struct rtc_time *time)
@@ -1373,8 +1196,6 @@ static int __init rtc_mini_init(void)
                mini_rtc_ops = &hypervisor_rtc_ops;
        else if (this_is_starfire)
                mini_rtc_ops = &starfire_rtc_ops;
-       else if (bq4802_regs)
-               mini_rtc_ops = &bq4802_rtc_ops;
        else
                return -ENODEV;