sparc: Annotate of_device_id arrays with const or __initdata.
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / sparc64 / kernel / time.c
index abdeead4e5b99ae2a0b158e39a2a0472b0b2b325..209e7d28c3a548d21640d39ca2cd9829ea77ed03 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,113 +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);
-}
-
-/* davem suggests we keep this within the 4M locked kernel image */
-static u32 starfire_get_time(void)
-{
-       static char obp_gettod[32];
-       static u32 unix_tod;
-
-       sprintf(obp_gettod, "h# %08x unix-gettod",
-               (unsigned int) (long) &unix_tod);
-       prom_feval(obp_gettod);
-
-       return unix_tod;
-}
-
-static int starfire_set_time(u32 val)
-{
-       /* Do nothing, time is set using the service processor
-        * console on this platform.
-        */
-       return 0;
-}
-
-static u32 hypervisor_get_time(void)
-{
-       unsigned long ret, time;
-       int retries = 10000;
-
-retry:
-       ret = sun4v_tod_get(&time);
-       if (ret == HV_EOK)
-               return time;
-       if (ret == HV_EWOULDBLOCK) {
-               if (--retries > 0) {
-                       udelay(100);
-                       goto retry;
-               }
-               printk(KERN_WARNING "SUN4V: tod_get() timed out.\n");
-               return 0;
-       }
-       printk(KERN_WARNING "SUN4V: tod_get() not supported.\n");
-       return 0;
-}
-
-static int hypervisor_set_time(u32 secs)
-{
-       unsigned long ret;
-       int retries = 10000;
-
-retry:
-       ret = sun4v_tod_set(secs);
-       if (ret == HV_EOK)
-               return 0;
-       if (ret == HV_EWOULDBLOCK) {
-               if (--retries > 0) {
-                       udelay(100);
-                       goto retry;
-               }
-               printk(KERN_WARNING "SUN4V: tod_set() timed out.\n");
-               return -EAGAIN;
-       }
-       printk(KERN_WARNING "SUN4V: tod_set() not supported.\n");
-       return -EOPNOTSUPP;
+       return -1;
 }
 
 unsigned long cmos_regs;
@@ -547,7 +438,7 @@ static int __devinit rtc_probe(struct of_device *op, const struct of_device_id *
        return platform_device_register(&rtc_cmos_device);
 }
 
-static struct of_device_id rtc_match[] = {
+static struct of_device_id __initdata rtc_match[] = {
        {
                .name = "rtc",
                .compatible = "m5819",
@@ -575,27 +466,23 @@ 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[] = {
+static struct of_device_id __initdata bq4802_match[] = {
        {
                .name = "rtc",
                .compatible = "bq4802",
@@ -679,7 +566,7 @@ static int __devinit mostek_probe(struct of_device *op, const struct of_device_i
        return platform_device_register(&m48t59_rtc);
 }
 
-static struct of_device_id mostek_match[] = {
+static struct of_device_id __initdata mostek_match[] = {
        {
                .name = "eeprom",
        },
@@ -694,22 +581,23 @@ static struct of_platform_driver mostek_driver = {
        },
 };
 
+static struct platform_device rtc_sun4v_device = {
+       .name           = "rtc-sun4v",
+       .id             = -1,
+};
+
+static struct platform_device rtc_starfire_device = {
+       .name           = "rtc-starfire",
+       .id             = -1,
+};
+
 static int __init clock_init(void)
 {
-       if (this_is_starfire) {
-               xtime.tv_sec = starfire_get_time();
-               xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-               set_normalized_timespec(&wall_to_monotonic,
-                                       -xtime.tv_sec, -xtime.tv_nsec);
-               return 0;
-       }
-       if (tlb_type == hypervisor) {
-               xtime.tv_sec = hypervisor_get_time();
-               xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-               set_normalized_timespec(&wall_to_monotonic,
-                                       -xtime.tv_sec, -xtime.tv_nsec);
-               return 0;
-       }
+       if (this_is_starfire)
+               return platform_device_register(&rtc_starfire_device);
+
+       if (tlb_type == hypervisor)
+               return platform_device_register(&rtc_sun4v_device);
 
        (void) of_register_driver(&rtc_driver, &of_platform_bus_type);
        (void) of_register_driver(&mostek_driver, &of_platform_bus_type);
@@ -984,419 +872,8 @@ 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.       */
-
-#define FEBRUARY       2
-#define        STARTOFTIME     1970
-#define SECDAY         86400L
-#define SECYR          (SECDAY * 365)
-#define        leapyear(year)          ((year) % 4 == 0 && \
-                                ((year) % 100 != 0 || (year) % 400 == 0))
-#define        days_in_year(a)         (leapyear(a) ? 366 : 365)
-#define        days_in_month(a)        (month_days[(a) - 1])
-
-static int month_days[12] = {
-       31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/*
- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
- */
-static void GregorianDay(struct rtc_time * tm)
-{
-       int leapsToDate;
-       int lastYear;
-       int day;
-       int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-
-       lastYear = tm->tm_year - 1;
-
-       /*
-        * Number of leap corrections to apply up to end of last year
-        */
-       leapsToDate = lastYear / 4 - lastYear / 100 + lastYear / 400;
-
-       /*
-        * This year is a leap year if it is divisible by 4 except when it is
-        * divisible by 100 unless it is divisible by 400
-        *
-        * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 was
-        */
-       day = tm->tm_mon > 2 && leapyear(tm->tm_year);
-
-       day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
-                  tm->tm_mday;
-
-       tm->tm_wday = day % 7;
-}
-
-static void to_tm(int tim, struct rtc_time *tm)
-{
-       register int    i;
-       register long   hms, day;
-
-       day = tim / SECDAY;
-       hms = tim % SECDAY;
-
-       /* Hours, minutes, seconds are easy */
-       tm->tm_hour = hms / 3600;
-       tm->tm_min = (hms % 3600) / 60;
-       tm->tm_sec = (hms % 3600) % 60;
-
-       /* Number of years in days */
-       for (i = STARTOFTIME; day >= days_in_year(i); i++)
-               day -= days_in_year(i);
-       tm->tm_year = i;
-
-       /* Number of months in days left */
-       if (leapyear(tm->tm_year))
-               days_in_month(FEBRUARY) = 29;
-       for (i = 1; day >= days_in_month(i); i++)
-               day -= days_in_month(i);
-       days_in_month(FEBRUARY) = 28;
-       tm->tm_mon = i;
-
-       /* Days are what is left over (+1) from all that. */
-       tm->tm_mday = day + 1;
-
-       /*
-        * Determine the day of week
-        */
-       GregorianDay(tm);
-}
-
-/* Both Starfire and SUN4V give us seconds since Jan 1st, 1970,
- * aka Unix time.  So we have to convert to/from rtc_time.
- */
-static void starfire_get_rtc_time(struct rtc_time *time)
-{
-       u32 seconds = starfire_get_time();
-
-       to_tm(seconds, time);
-       time->tm_year -= 1900;
-       time->tm_mon -= 1;
-}
-
-static int starfire_set_rtc_time(struct rtc_time *time)
-{
-       u32 seconds = mktime(time->tm_year + 1900, time->tm_mon + 1,
-                            time->tm_mday, time->tm_hour,
-                            time->tm_min, time->tm_sec);
-
-       return starfire_set_time(seconds);
-}
-
-static void hypervisor_get_rtc_time(struct rtc_time *time)
-{
-       u32 seconds = hypervisor_get_time();
-
-       to_tm(seconds, time);
-       time->tm_year -= 1900;
-       time->tm_mon -= 1;
-}
-
-static int hypervisor_set_rtc_time(struct rtc_time *time)
-{
-       u32 seconds = mktime(time->tm_year + 1900, time->tm_mon + 1,
-                            time->tm_mday, time->tm_hour,
-                            time->tm_min, time->tm_sec);
-
-       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 *);
-};
-
-static struct mini_rtc_ops starfire_rtc_ops = {
-       .get_rtc_time = starfire_get_rtc_time,
-       .set_rtc_time = starfire_set_rtc_time,
-};
-
-static struct mini_rtc_ops hypervisor_rtc_ops = {
-       .get_rtc_time = hypervisor_get_rtc_time,
-       .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)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       mini_rtc_ops->get_rtc_time(time);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-}
-
-static inline int mini_set_rtc_time(struct rtc_time *time)
-{
-       unsigned long flags;
-       int err;
-
-       spin_lock_irqsave(&rtc_lock, flags);
-       err = mini_rtc_ops->set_rtc_time(time);
-       spin_unlock_irqrestore(&rtc_lock, flags);
-
-       return err;
-}
-
-static int mini_rtc_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, unsigned long arg)
-{
-       struct rtc_time wtime;
-       void __user *argp = (void __user *)arg;
-
-       switch (cmd) {
-
-       case RTC_PLL_GET:
-               return -EINVAL;
-
-       case RTC_PLL_SET:
-               return -EINVAL;
-
-       case RTC_UIE_OFF:       /* disable ints from RTC updates.       */
-               return 0;
-
-       case RTC_UIE_ON:        /* enable ints for RTC updates. */
-               return -EINVAL;
-
-       case RTC_RD_TIME:       /* Read the time/date from RTC  */
-               /* this doesn't get week-day, who cares */
-               memset(&wtime, 0, sizeof(wtime));
-               mini_get_rtc_time(&wtime);
-
-               return copy_to_user(argp, &wtime, sizeof(wtime)) ? -EFAULT : 0;
-
-       case RTC_SET_TIME:      /* Set the RTC */
-           {
-               int year, days;
-
-               if (!capable(CAP_SYS_TIME))
-                       return -EACCES;
-
-               if (copy_from_user(&wtime, argp, sizeof(wtime)))
-                       return -EFAULT;
-
-               year = wtime.tm_year + 1900;
-               days = month_days[wtime.tm_mon] +
-                      ((wtime.tm_mon == 1) && leapyear(year));
-
-               if ((wtime.tm_mon < 0 || wtime.tm_mon > 11) ||
-                   (wtime.tm_mday < 1))
-                       return -EINVAL;
-
-               if (wtime.tm_mday < 0 || wtime.tm_mday > days)
-                       return -EINVAL;
-
-               if (wtime.tm_hour < 0 || wtime.tm_hour >= 24 ||
-                   wtime.tm_min < 0 || wtime.tm_min >= 60 ||
-                   wtime.tm_sec < 0 || wtime.tm_sec >= 60)
-                       return -EINVAL;
-
-               return mini_set_rtc_time(&wtime);
-           }
-       }
-
-       return -EINVAL;
-}
-
-static int mini_rtc_open(struct inode *inode, struct file *file)
-{
-       lock_kernel();
-       if (mini_rtc_status & RTC_IS_OPEN) {
-               unlock_kernel();
-               return -EBUSY;
-       }
-
-       mini_rtc_status |= RTC_IS_OPEN;
-       unlock_kernel();
-
-       return 0;
-}
-
-static int mini_rtc_release(struct inode *inode, struct file *file)
-{
-       mini_rtc_status &= ~RTC_IS_OPEN;
-       return 0;
-}
-
-
-static const struct file_operations mini_rtc_fops = {
-       .owner          = THIS_MODULE,
-       .ioctl          = mini_rtc_ioctl,
-       .open           = mini_rtc_open,
-       .release        = mini_rtc_release,
-};
-
-static struct miscdevice rtc_mini_dev =
-{
-       .minor          = RTC_MINOR,
-       .name           = "rtc",
-       .fops           = &mini_rtc_fops,
-};
-
-static int __init rtc_mini_init(void)
-{
-       int retval;
-
-       if (tlb_type == hypervisor)
-               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;
-
-       printk(KERN_INFO "Mini RTC Driver\n");
-
-       retval = misc_register(&rtc_mini_dev);
-       if (retval < 0)
-               return retval;
-
-       return 0;
-}
-
-static void __exit rtc_mini_exit(void)
-{
-       misc_deregister(&rtc_mini_dev);
-}
-
 int __devinit read_current_timer(unsigned long *timer_val)
 {
        *timer_val = tick_ops->get_tick();
        return 0;
 }
-
-module_init(rtc_mini_init);
-module_exit(rtc_mini_exit);