cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtc-vr41xx.c (8181B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Driver for NEC VR4100 series Real Time Clock unit.
      4 *
      5 *  Copyright (C) 2003-2008  Yoichi Yuasa <yuasa@linux-mips.org>
      6 */
      7#include <linux/compat.h>
      8#include <linux/err.h>
      9#include <linux/fs.h>
     10#include <linux/init.h>
     11#include <linux/io.h>
     12#include <linux/ioport.h>
     13#include <linux/interrupt.h>
     14#include <linux/module.h>
     15#include <linux/platform_device.h>
     16#include <linux/rtc.h>
     17#include <linux/spinlock.h>
     18#include <linux/types.h>
     19#include <linux/uaccess.h>
     20#include <linux/log2.h>
     21
     22#include <asm/div64.h>
     23
     24MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>");
     25MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
     26MODULE_LICENSE("GPL v2");
     27
     28/* RTC 1 registers */
     29#define ETIMELREG		0x00
     30#define ETIMEMREG		0x02
     31#define ETIMEHREG		0x04
     32/* RFU */
     33#define ECMPLREG		0x08
     34#define ECMPMREG		0x0a
     35#define ECMPHREG		0x0c
     36/* RFU */
     37#define RTCL1LREG		0x10
     38#define RTCL1HREG		0x12
     39#define RTCL1CNTLREG		0x14
     40#define RTCL1CNTHREG		0x16
     41#define RTCL2LREG		0x18
     42#define RTCL2HREG		0x1a
     43#define RTCL2CNTLREG		0x1c
     44#define RTCL2CNTHREG		0x1e
     45
     46/* RTC 2 registers */
     47#define TCLKLREG		0x00
     48#define TCLKHREG		0x02
     49#define TCLKCNTLREG		0x04
     50#define TCLKCNTHREG		0x06
     51/* RFU */
     52#define RTCINTREG		0x1e
     53 #define TCLOCK_INT		0x08
     54 #define RTCLONG2_INT		0x04
     55 #define RTCLONG1_INT		0x02
     56 #define ELAPSEDTIME_INT	0x01
     57
     58#define RTC_FREQUENCY		32768
     59#define MAX_PERIODIC_RATE	6553
     60
     61static void __iomem *rtc1_base;
     62static void __iomem *rtc2_base;
     63
     64#define rtc1_read(offset)		readw(rtc1_base + (offset))
     65#define rtc1_write(offset, value)	writew((value), rtc1_base + (offset))
     66
     67#define rtc2_read(offset)		readw(rtc2_base + (offset))
     68#define rtc2_write(offset, value)	writew((value), rtc2_base + (offset))
     69
     70/* 32-bit compat for ioctls that nobody else uses */
     71#define RTC_EPOCH_READ32	_IOR('p', 0x0d, __u32)
     72
     73static unsigned long epoch = 1970;	/* Jan 1 1970 00:00:00 */
     74
     75static DEFINE_SPINLOCK(rtc_lock);
     76static char rtc_name[] = "RTC";
     77static unsigned long periodic_count;
     78static unsigned int alarm_enabled;
     79static int aie_irq;
     80static int pie_irq;
     81
     82static inline time64_t read_elapsed_second(void)
     83{
     84
     85	unsigned long first_low, first_mid, first_high;
     86
     87	unsigned long second_low, second_mid, second_high;
     88
     89	do {
     90		first_low = rtc1_read(ETIMELREG);
     91		first_mid = rtc1_read(ETIMEMREG);
     92		first_high = rtc1_read(ETIMEHREG);
     93		second_low = rtc1_read(ETIMELREG);
     94		second_mid = rtc1_read(ETIMEMREG);
     95		second_high = rtc1_read(ETIMEHREG);
     96	} while (first_low != second_low || first_mid != second_mid ||
     97		 first_high != second_high);
     98
     99	return ((u64)first_high << 17) | (first_mid << 1) | (first_low >> 15);
    100}
    101
    102static inline void write_elapsed_second(time64_t sec)
    103{
    104	spin_lock_irq(&rtc_lock);
    105
    106	rtc1_write(ETIMELREG, (uint16_t)(sec << 15));
    107	rtc1_write(ETIMEMREG, (uint16_t)(sec >> 1));
    108	rtc1_write(ETIMEHREG, (uint16_t)(sec >> 17));
    109
    110	spin_unlock_irq(&rtc_lock);
    111}
    112
    113static int vr41xx_rtc_read_time(struct device *dev, struct rtc_time *time)
    114{
    115	time64_t epoch_sec, elapsed_sec;
    116
    117	epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
    118	elapsed_sec = read_elapsed_second();
    119
    120	rtc_time64_to_tm(epoch_sec + elapsed_sec, time);
    121
    122	return 0;
    123}
    124
    125static int vr41xx_rtc_set_time(struct device *dev, struct rtc_time *time)
    126{
    127	time64_t epoch_sec, current_sec;
    128
    129	epoch_sec = mktime64(epoch, 1, 1, 0, 0, 0);
    130	current_sec = rtc_tm_to_time64(time);
    131
    132	write_elapsed_second(current_sec - epoch_sec);
    133
    134	return 0;
    135}
    136
    137static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
    138{
    139	unsigned long low, mid, high;
    140	struct rtc_time *time = &wkalrm->time;
    141
    142	spin_lock_irq(&rtc_lock);
    143
    144	low = rtc1_read(ECMPLREG);
    145	mid = rtc1_read(ECMPMREG);
    146	high = rtc1_read(ECMPHREG);
    147	wkalrm->enabled = alarm_enabled;
    148
    149	spin_unlock_irq(&rtc_lock);
    150
    151	rtc_time64_to_tm((high << 17) | (mid << 1) | (low >> 15), time);
    152
    153	return 0;
    154}
    155
    156static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
    157{
    158	time64_t alarm_sec;
    159
    160	alarm_sec = rtc_tm_to_time64(&wkalrm->time);
    161
    162	spin_lock_irq(&rtc_lock);
    163
    164	if (alarm_enabled)
    165		disable_irq(aie_irq);
    166
    167	rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
    168	rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
    169	rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
    170
    171	if (wkalrm->enabled)
    172		enable_irq(aie_irq);
    173
    174	alarm_enabled = wkalrm->enabled;
    175
    176	spin_unlock_irq(&rtc_lock);
    177
    178	return 0;
    179}
    180
    181static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
    182{
    183	switch (cmd) {
    184	case RTC_EPOCH_READ:
    185		return put_user(epoch, (unsigned long __user *)arg);
    186#ifdef CONFIG_64BIT
    187	case RTC_EPOCH_READ32:
    188		return put_user(epoch, (unsigned int __user *)arg);
    189#endif
    190	case RTC_EPOCH_SET:
    191		/* Doesn't support before 1900 */
    192		if (arg < 1900)
    193			return -EINVAL;
    194		epoch = arg;
    195		break;
    196	default:
    197		return -ENOIOCTLCMD;
    198	}
    199
    200	return 0;
    201}
    202
    203static int vr41xx_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
    204{
    205	spin_lock_irq(&rtc_lock);
    206	if (enabled) {
    207		if (!alarm_enabled) {
    208			enable_irq(aie_irq);
    209			alarm_enabled = 1;
    210		}
    211	} else {
    212		if (alarm_enabled) {
    213			disable_irq(aie_irq);
    214			alarm_enabled = 0;
    215		}
    216	}
    217	spin_unlock_irq(&rtc_lock);
    218	return 0;
    219}
    220
    221static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
    222{
    223	struct platform_device *pdev = (struct platform_device *)dev_id;
    224	struct rtc_device *rtc = platform_get_drvdata(pdev);
    225
    226	rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
    227
    228	rtc_update_irq(rtc, 1, RTC_AF);
    229
    230	return IRQ_HANDLED;
    231}
    232
    233static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
    234{
    235	struct platform_device *pdev = (struct platform_device *)dev_id;
    236	struct rtc_device *rtc = platform_get_drvdata(pdev);
    237	unsigned long count = periodic_count;
    238
    239	rtc2_write(RTCINTREG, RTCLONG1_INT);
    240
    241	rtc1_write(RTCL1LREG, count);
    242	rtc1_write(RTCL1HREG, count >> 16);
    243
    244	rtc_update_irq(rtc, 1, RTC_PF);
    245
    246	return IRQ_HANDLED;
    247}
    248
    249static const struct rtc_class_ops vr41xx_rtc_ops = {
    250	.ioctl			= vr41xx_rtc_ioctl,
    251	.read_time		= vr41xx_rtc_read_time,
    252	.set_time		= vr41xx_rtc_set_time,
    253	.read_alarm		= vr41xx_rtc_read_alarm,
    254	.set_alarm		= vr41xx_rtc_set_alarm,
    255	.alarm_irq_enable	= vr41xx_rtc_alarm_irq_enable,
    256};
    257
    258static int rtc_probe(struct platform_device *pdev)
    259{
    260	struct resource *res;
    261	struct rtc_device *rtc;
    262	int retval;
    263
    264	if (pdev->num_resources != 4)
    265		return -EBUSY;
    266
    267	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    268	if (!res)
    269		return -EBUSY;
    270
    271	rtc1_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
    272	if (!rtc1_base)
    273		return -EBUSY;
    274
    275	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
    276	if (!res) {
    277		retval = -EBUSY;
    278		goto err_rtc1_iounmap;
    279	}
    280
    281	rtc2_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
    282	if (!rtc2_base) {
    283		retval = -EBUSY;
    284		goto err_rtc1_iounmap;
    285	}
    286
    287	rtc = devm_rtc_allocate_device(&pdev->dev);
    288	if (IS_ERR(rtc)) {
    289		retval = PTR_ERR(rtc);
    290		goto err_iounmap_all;
    291	}
    292
    293	rtc->ops = &vr41xx_rtc_ops;
    294
    295	/* 48-bit counter at 32.768 kHz */
    296	rtc->range_max = (1ULL << 33) - 1;
    297	rtc->max_user_freq = MAX_PERIODIC_RATE;
    298
    299	spin_lock_irq(&rtc_lock);
    300
    301	rtc1_write(ECMPLREG, 0);
    302	rtc1_write(ECMPMREG, 0);
    303	rtc1_write(ECMPHREG, 0);
    304	rtc1_write(RTCL1LREG, 0);
    305	rtc1_write(RTCL1HREG, 0);
    306
    307	spin_unlock_irq(&rtc_lock);
    308
    309	aie_irq = platform_get_irq(pdev, 0);
    310	if (aie_irq <= 0) {
    311		retval = -EBUSY;
    312		goto err_iounmap_all;
    313	}
    314
    315	retval = devm_request_irq(&pdev->dev, aie_irq, elapsedtime_interrupt, 0,
    316				"elapsed_time", pdev);
    317	if (retval < 0)
    318		goto err_iounmap_all;
    319
    320	pie_irq = platform_get_irq(pdev, 1);
    321	if (pie_irq <= 0) {
    322		retval = -EBUSY;
    323		goto err_iounmap_all;
    324	}
    325
    326	retval = devm_request_irq(&pdev->dev, pie_irq, rtclong1_interrupt, 0,
    327				"rtclong1", pdev);
    328	if (retval < 0)
    329		goto err_iounmap_all;
    330
    331	platform_set_drvdata(pdev, rtc);
    332
    333	disable_irq(aie_irq);
    334	disable_irq(pie_irq);
    335
    336	dev_info(&pdev->dev, "Real Time Clock of NEC VR4100 series\n");
    337
    338	retval = devm_rtc_register_device(rtc);
    339	if (retval)
    340		goto err_iounmap_all;
    341
    342	return 0;
    343
    344err_iounmap_all:
    345	rtc2_base = NULL;
    346
    347err_rtc1_iounmap:
    348	rtc1_base = NULL;
    349
    350	return retval;
    351}
    352
    353/* work with hotplug and coldplug */
    354MODULE_ALIAS("platform:RTC");
    355
    356static struct platform_driver rtc_platform_driver = {
    357	.probe		= rtc_probe,
    358	.driver		= {
    359		.name	= rtc_name,
    360	},
    361};
    362
    363module_platform_driver(rtc_platform_driver);