linux/drivers/rtc/rtc-tile.c
<<
>>
Prefs
   1/*
   2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
   3 *
   4 *   This program is free software; you can redistribute it and/or
   5 *   modify it under the terms of the GNU General Public License
   6 *   as published by the Free Software Foundation, version 2.
   7 *
   8 *   This program is distributed in the hope that it will be useful, but
   9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11 *   NON INFRINGEMENT.  See the GNU General Public License for
  12 *   more details.
  13 *
  14 * Tilera-specific RTC driver.
  15 */
  16
  17#include <linux/module.h>
  18#include <linux/device.h>
  19#include <linux/rtc.h>
  20#include <linux/platform_device.h>
  21
  22/* Platform device pointer. */
  23static struct platform_device *tile_rtc_platform_device;
  24
  25/*
  26 * RTC read routine.  Gets time info from RTC chip via hypervisor syscall.
  27 */
  28static int read_rtc_time(struct device *dev, struct rtc_time *tm)
  29{
  30        HV_RTCTime hvtm = hv_get_rtc();
  31
  32        tm->tm_sec = hvtm.tm_sec;
  33        tm->tm_min = hvtm.tm_min;
  34        tm->tm_hour = hvtm.tm_hour;
  35        tm->tm_mday = hvtm.tm_mday;
  36        tm->tm_mon = hvtm.tm_mon;
  37        tm->tm_year = hvtm.tm_year;
  38        tm->tm_wday = 0;
  39        tm->tm_yday = 0;
  40        tm->tm_isdst = 0;
  41
  42        if (rtc_valid_tm(tm) < 0)
  43                dev_warn(dev, "Read invalid date/time from RTC\n");
  44
  45        return 0;
  46}
  47
  48/*
  49 * RTC write routine.  Sends time info to hypervisor via syscall, to be
  50 * written to RTC chip.
  51 */
  52static int set_rtc_time(struct device *dev, struct rtc_time *tm)
  53{
  54        HV_RTCTime hvtm;
  55
  56        hvtm.tm_sec = tm->tm_sec;
  57        hvtm.tm_min = tm->tm_min;
  58        hvtm.tm_hour = tm->tm_hour;
  59        hvtm.tm_mday = tm->tm_mday;
  60        hvtm.tm_mon = tm->tm_mon;
  61        hvtm.tm_year = tm->tm_year;
  62
  63        hv_set_rtc(hvtm);
  64
  65        return 0;
  66}
  67
  68/*
  69 * RTC read/write ops.
  70 */
  71static const struct rtc_class_ops tile_rtc_ops = {
  72        .read_time      = read_rtc_time,
  73        .set_time       = set_rtc_time,
  74};
  75
  76/*
  77 * Device probe routine.
  78 */
  79static int tile_rtc_probe(struct platform_device *dev)
  80{
  81        struct rtc_device *rtc;
  82
  83        rtc = devm_rtc_device_register(&dev->dev, "tile",
  84                                &tile_rtc_ops, THIS_MODULE);
  85
  86        if (IS_ERR(rtc))
  87                return PTR_ERR(rtc);
  88
  89        platform_set_drvdata(dev, rtc);
  90
  91        return 0;
  92}
  93
  94static struct platform_driver tile_rtc_platform_driver = {
  95        .driver         = {
  96                .name   = "rtc-tile",
  97        },
  98        .probe          = tile_rtc_probe,
  99};
 100
 101/*
 102 * Driver init routine.
 103 */
 104static int __init tile_rtc_driver_init(void)
 105{
 106        int err;
 107
 108        err = platform_driver_register(&tile_rtc_platform_driver);
 109        if (err)
 110                return err;
 111
 112        tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0);
 113        if (tile_rtc_platform_device == NULL) {
 114                err = -ENOMEM;
 115                goto exit_driver_unregister;
 116        }
 117
 118        err = platform_device_add(tile_rtc_platform_device);
 119        if (err)
 120                goto exit_device_put;
 121
 122        return 0;
 123
 124exit_device_put:
 125        platform_device_put(tile_rtc_platform_device);
 126
 127exit_driver_unregister:
 128        platform_driver_unregister(&tile_rtc_platform_driver);
 129        return err;
 130}
 131
 132/*
 133 * Driver cleanup routine.
 134 */
 135static void __exit tile_rtc_driver_exit(void)
 136{
 137        platform_device_unregister(tile_rtc_platform_device);
 138        platform_driver_unregister(&tile_rtc_platform_driver);
 139}
 140
 141module_init(tile_rtc_driver_init);
 142module_exit(tile_rtc_driver_exit);
 143
 144MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver");
 145MODULE_LICENSE("GPL");
 146MODULE_ALIAS("platform:rtc-tile");
 147