1 /* 2 * PS3 RTC Driver 3 * 4 * Copyright 2009 Sony Corporation 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. 17 * If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/platform_device.h> 23 #include <linux/rtc.h> 24 25 #include <asm/lv1call.h> 26 #include <asm/ps3.h> 27 28 29 static u64 read_rtc(void) 30 { 31 int result; 32 u64 rtc_val; 33 u64 tb_val; 34 35 result = lv1_get_rtc(&rtc_val, &tb_val); 36 BUG_ON(result); 37 38 return rtc_val; 39 } 40 41 static int ps3_get_time(struct device *dev, struct rtc_time *tm) 42 { 43 rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm); 44 return rtc_valid_tm(tm); 45 } 46 47 static int ps3_set_time(struct device *dev, struct rtc_time *tm) 48 { 49 unsigned long now; 50 51 rtc_tm_to_time(tm, &now); 52 ps3_os_area_set_rtc_diff(now - read_rtc()); 53 return 0; 54 } 55 56 static const struct rtc_class_ops ps3_rtc_ops = { 57 .read_time = ps3_get_time, 58 .set_time = ps3_set_time, 59 }; 60 61 static int __init ps3_rtc_probe(struct platform_device *dev) 62 { 63 struct rtc_device *rtc; 64 65 rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops, 66 THIS_MODULE); 67 if (IS_ERR(rtc)) 68 return PTR_ERR(rtc); 69 70 platform_set_drvdata(dev, rtc); 71 return 0; 72 } 73 74 static int __exit ps3_rtc_remove(struct platform_device *dev) 75 { 76 rtc_device_unregister(platform_get_drvdata(dev)); 77 return 0; 78 } 79 80 static struct platform_driver ps3_rtc_driver = { 81 .driver = { 82 .name = "rtc-ps3", 83 .owner = THIS_MODULE, 84 }, 85 .remove = __exit_p(ps3_rtc_remove), 86 }; 87 88 static int __init ps3_rtc_init(void) 89 { 90 return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe); 91 } 92 93 static void __exit ps3_rtc_fini(void) 94 { 95 platform_driver_unregister(&ps3_rtc_driver); 96 } 97 98 module_init(ps3_rtc_init); 99 module_exit(ps3_rtc_fini); 100 101 MODULE_AUTHOR("Sony Corporation"); 102 MODULE_LICENSE("GPL"); 103 MODULE_DESCRIPTION("ps3 RTC driver"); 104 MODULE_ALIAS("platform:rtc-ps3"); 105