Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.3 122 lines 2.5 kB view raw
1/* rtc-sun4v.c: Hypervisor based RTC for SUN4V systems. 2 * 3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net> 4 */ 5 6#include <linux/kernel.h> 7#include <linux/module.h> 8#include <linux/delay.h> 9#include <linux/init.h> 10#include <linux/rtc.h> 11#include <linux/platform_device.h> 12 13#include <asm/hypervisor.h> 14 15static unsigned long hypervisor_get_time(void) 16{ 17 unsigned long ret, time; 18 int retries = 10000; 19 20retry: 21 ret = sun4v_tod_get(&time); 22 if (ret == HV_EOK) 23 return time; 24 if (ret == HV_EWOULDBLOCK) { 25 if (--retries > 0) { 26 udelay(100); 27 goto retry; 28 } 29 printk(KERN_WARNING "SUN4V: tod_get() timed out.\n"); 30 return 0; 31 } 32 printk(KERN_WARNING "SUN4V: tod_get() not supported.\n"); 33 return 0; 34} 35 36static int sun4v_read_time(struct device *dev, struct rtc_time *tm) 37{ 38 rtc_time_to_tm(hypervisor_get_time(), tm); 39 return 0; 40} 41 42static int hypervisor_set_time(unsigned long secs) 43{ 44 unsigned long ret; 45 int retries = 10000; 46 47retry: 48 ret = sun4v_tod_set(secs); 49 if (ret == HV_EOK) 50 return 0; 51 if (ret == HV_EWOULDBLOCK) { 52 if (--retries > 0) { 53 udelay(100); 54 goto retry; 55 } 56 printk(KERN_WARNING "SUN4V: tod_set() timed out.\n"); 57 return -EAGAIN; 58 } 59 printk(KERN_WARNING "SUN4V: tod_set() not supported.\n"); 60 return -EOPNOTSUPP; 61} 62 63static int sun4v_set_time(struct device *dev, struct rtc_time *tm) 64{ 65 unsigned long secs; 66 int err; 67 68 err = rtc_tm_to_time(tm, &secs); 69 if (err) 70 return err; 71 72 return hypervisor_set_time(secs); 73} 74 75static const struct rtc_class_ops sun4v_rtc_ops = { 76 .read_time = sun4v_read_time, 77 .set_time = sun4v_set_time, 78}; 79 80static int __init sun4v_rtc_probe(struct platform_device *pdev) 81{ 82 struct rtc_device *rtc = rtc_device_register("sun4v", &pdev->dev, 83 &sun4v_rtc_ops, THIS_MODULE); 84 if (IS_ERR(rtc)) 85 return PTR_ERR(rtc); 86 87 platform_set_drvdata(pdev, rtc); 88 return 0; 89} 90 91static int __exit sun4v_rtc_remove(struct platform_device *pdev) 92{ 93 struct rtc_device *rtc = platform_get_drvdata(pdev); 94 95 rtc_device_unregister(rtc); 96 return 0; 97} 98 99static struct platform_driver sun4v_rtc_driver = { 100 .driver = { 101 .name = "rtc-sun4v", 102 .owner = THIS_MODULE, 103 }, 104 .remove = __exit_p(sun4v_rtc_remove), 105}; 106 107static int __init sun4v_rtc_init(void) 108{ 109 return platform_driver_probe(&sun4v_rtc_driver, sun4v_rtc_probe); 110} 111 112static void __exit sun4v_rtc_exit(void) 113{ 114 platform_driver_unregister(&sun4v_rtc_driver); 115} 116 117module_init(sun4v_rtc_init); 118module_exit(sun4v_rtc_exit); 119 120MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 121MODULE_DESCRIPTION("SUN4V RTC driver"); 122MODULE_LICENSE("GPL");