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-88pm80x.c (9450B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Real Time Clock driver for Marvell 88PM80x PMIC
      4 *
      5 * Copyright (c) 2012 Marvell International Ltd.
      6 *  Wenzeng Chen<wzch@marvell.com>
      7 *  Qiao Zhou <zhouqiao@marvell.com>
      8 */
      9
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/slab.h>
     13#include <linux/regmap.h>
     14#include <linux/mfd/core.h>
     15#include <linux/mfd/88pm80x.h>
     16#include <linux/rtc.h>
     17
     18#define PM800_RTC_COUNTER1		(0xD1)
     19#define PM800_RTC_COUNTER2		(0xD2)
     20#define PM800_RTC_COUNTER3		(0xD3)
     21#define PM800_RTC_COUNTER4		(0xD4)
     22#define PM800_RTC_EXPIRE1_1		(0xD5)
     23#define PM800_RTC_EXPIRE1_2		(0xD6)
     24#define PM800_RTC_EXPIRE1_3		(0xD7)
     25#define PM800_RTC_EXPIRE1_4		(0xD8)
     26#define PM800_RTC_TRIM1			(0xD9)
     27#define PM800_RTC_TRIM2			(0xDA)
     28#define PM800_RTC_TRIM3			(0xDB)
     29#define PM800_RTC_TRIM4			(0xDC)
     30#define PM800_RTC_EXPIRE2_1		(0xDD)
     31#define PM800_RTC_EXPIRE2_2		(0xDE)
     32#define PM800_RTC_EXPIRE2_3		(0xDF)
     33#define PM800_RTC_EXPIRE2_4		(0xE0)
     34
     35#define PM800_POWER_DOWN_LOG1	(0xE5)
     36#define PM800_POWER_DOWN_LOG2	(0xE6)
     37
     38struct pm80x_rtc_info {
     39	struct pm80x_chip *chip;
     40	struct regmap *map;
     41	struct rtc_device *rtc_dev;
     42	struct device *dev;
     43
     44	int irq;
     45};
     46
     47static irqreturn_t rtc_update_handler(int irq, void *data)
     48{
     49	struct pm80x_rtc_info *info = (struct pm80x_rtc_info *)data;
     50	int mask;
     51
     52	mask = PM800_ALARM | PM800_ALARM_WAKEUP;
     53	regmap_update_bits(info->map, PM800_RTC_CONTROL, mask | PM800_ALARM1_EN,
     54			   mask);
     55	rtc_update_irq(info->rtc_dev, 1, RTC_AF);
     56	return IRQ_HANDLED;
     57}
     58
     59static int pm80x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
     60{
     61	struct pm80x_rtc_info *info = dev_get_drvdata(dev);
     62
     63	if (enabled)
     64		regmap_update_bits(info->map, PM800_RTC_CONTROL,
     65				   PM800_ALARM1_EN, PM800_ALARM1_EN);
     66	else
     67		regmap_update_bits(info->map, PM800_RTC_CONTROL,
     68				   PM800_ALARM1_EN, 0);
     69	return 0;
     70}
     71
     72/*
     73 * Calculate the next alarm time given the requested alarm time mask
     74 * and the current time.
     75 */
     76static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
     77				struct rtc_time *alrm)
     78{
     79	unsigned long next_time;
     80	unsigned long now_time;
     81
     82	next->tm_year = now->tm_year;
     83	next->tm_mon = now->tm_mon;
     84	next->tm_mday = now->tm_mday;
     85	next->tm_hour = alrm->tm_hour;
     86	next->tm_min = alrm->tm_min;
     87	next->tm_sec = alrm->tm_sec;
     88
     89	now_time = rtc_tm_to_time64(now);
     90	next_time = rtc_tm_to_time64(next);
     91
     92	if (next_time < now_time) {
     93		/* Advance one day */
     94		next_time += 60 * 60 * 24;
     95		rtc_time64_to_tm(next_time, next);
     96	}
     97}
     98
     99static int pm80x_rtc_read_time(struct device *dev, struct rtc_time *tm)
    100{
    101	struct pm80x_rtc_info *info = dev_get_drvdata(dev);
    102	unsigned char buf[4];
    103	unsigned long ticks, base, data;
    104	regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
    105	base = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    106		(buf[1] << 8) | buf[0];
    107	dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
    108
    109	/* load 32-bit read-only counter */
    110	regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
    111	data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    112		(buf[1] << 8) | buf[0];
    113	ticks = base + data;
    114	dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
    115		base, data, ticks);
    116	rtc_time64_to_tm(ticks, tm);
    117	return 0;
    118}
    119
    120static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm)
    121{
    122	struct pm80x_rtc_info *info = dev_get_drvdata(dev);
    123	unsigned char buf[4];
    124	unsigned long ticks, base, data;
    125
    126	ticks = rtc_tm_to_time64(tm);
    127
    128	/* load 32-bit read-only counter */
    129	regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
    130	data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    131		(buf[1] << 8) | buf[0];
    132	base = ticks - data;
    133	dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
    134		base, data, ticks);
    135	buf[0] = base & 0xFF;
    136	buf[1] = (base >> 8) & 0xFF;
    137	buf[2] = (base >> 16) & 0xFF;
    138	buf[3] = (base >> 24) & 0xFF;
    139	regmap_raw_write(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
    140
    141	return 0;
    142}
    143
    144static int pm80x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
    145{
    146	struct pm80x_rtc_info *info = dev_get_drvdata(dev);
    147	unsigned char buf[4];
    148	unsigned long ticks, base, data;
    149	int ret;
    150
    151	regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
    152	base = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    153		(buf[1] << 8) | buf[0];
    154	dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
    155
    156	regmap_raw_read(info->map, PM800_RTC_EXPIRE1_1, buf, 4);
    157	data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    158		(buf[1] << 8) | buf[0];
    159	ticks = base + data;
    160	dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
    161		base, data, ticks);
    162
    163	rtc_time64_to_tm(ticks, &alrm->time);
    164	regmap_read(info->map, PM800_RTC_CONTROL, &ret);
    165	alrm->enabled = (ret & PM800_ALARM1_EN) ? 1 : 0;
    166	alrm->pending = (ret & (PM800_ALARM | PM800_ALARM_WAKEUP)) ? 1 : 0;
    167	return 0;
    168}
    169
    170static int pm80x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
    171{
    172	struct pm80x_rtc_info *info = dev_get_drvdata(dev);
    173	struct rtc_time now_tm, alarm_tm;
    174	unsigned long ticks, base, data;
    175	unsigned char buf[4];
    176	int mask;
    177
    178	regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_ALARM1_EN, 0);
    179
    180	regmap_raw_read(info->map, PM800_RTC_EXPIRE2_1, buf, 4);
    181	base = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    182		(buf[1] << 8) | buf[0];
    183	dev_dbg(info->dev, "%x-%x-%x-%x\n", buf[0], buf[1], buf[2], buf[3]);
    184
    185	/* load 32-bit read-only counter */
    186	regmap_raw_read(info->map, PM800_RTC_COUNTER1, buf, 4);
    187	data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) |
    188		(buf[1] << 8) | buf[0];
    189	ticks = base + data;
    190	dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
    191		base, data, ticks);
    192
    193	rtc_time64_to_tm(ticks, &now_tm);
    194	dev_dbg(info->dev, "%s, now time : %lu\n", __func__, ticks);
    195	rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
    196	/* get new ticks for alarm in 24 hours */
    197	ticks = rtc_tm_to_time64(&alarm_tm);
    198	dev_dbg(info->dev, "%s, alarm time: %lu\n", __func__, ticks);
    199	data = ticks - base;
    200
    201	buf[0] = data & 0xff;
    202	buf[1] = (data >> 8) & 0xff;
    203	buf[2] = (data >> 16) & 0xff;
    204	buf[3] = (data >> 24) & 0xff;
    205	regmap_raw_write(info->map, PM800_RTC_EXPIRE1_1, buf, 4);
    206	if (alrm->enabled) {
    207		mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN;
    208		regmap_update_bits(info->map, PM800_RTC_CONTROL, mask, mask);
    209	} else {
    210		mask = PM800_ALARM | PM800_ALARM_WAKEUP | PM800_ALARM1_EN;
    211		regmap_update_bits(info->map, PM800_RTC_CONTROL, mask,
    212				   PM800_ALARM | PM800_ALARM_WAKEUP);
    213	}
    214	return 0;
    215}
    216
    217static const struct rtc_class_ops pm80x_rtc_ops = {
    218	.read_time = pm80x_rtc_read_time,
    219	.set_time = pm80x_rtc_set_time,
    220	.read_alarm = pm80x_rtc_read_alarm,
    221	.set_alarm = pm80x_rtc_set_alarm,
    222	.alarm_irq_enable = pm80x_rtc_alarm_irq_enable,
    223};
    224
    225#ifdef CONFIG_PM_SLEEP
    226static int pm80x_rtc_suspend(struct device *dev)
    227{
    228	return pm80x_dev_suspend(dev);
    229}
    230
    231static int pm80x_rtc_resume(struct device *dev)
    232{
    233	return pm80x_dev_resume(dev);
    234}
    235#endif
    236
    237static SIMPLE_DEV_PM_OPS(pm80x_rtc_pm_ops, pm80x_rtc_suspend, pm80x_rtc_resume);
    238
    239static int pm80x_rtc_probe(struct platform_device *pdev)
    240{
    241	struct pm80x_chip *chip = dev_get_drvdata(pdev->dev.parent);
    242	struct pm80x_rtc_pdata *pdata = dev_get_platdata(&pdev->dev);
    243	struct pm80x_rtc_info *info;
    244	struct device_node *node = pdev->dev.of_node;
    245	int ret;
    246
    247	if (!pdata && !node) {
    248		dev_err(&pdev->dev,
    249			"pm80x-rtc requires platform data or of_node\n");
    250		return -EINVAL;
    251	}
    252
    253	if (!pdata) {
    254		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
    255		if (!pdata) {
    256			dev_err(&pdev->dev, "failed to allocate memory\n");
    257			return -ENOMEM;
    258		}
    259	}
    260
    261	info =
    262	    devm_kzalloc(&pdev->dev, sizeof(struct pm80x_rtc_info), GFP_KERNEL);
    263	if (!info)
    264		return -ENOMEM;
    265	info->irq = platform_get_irq(pdev, 0);
    266	if (info->irq < 0) {
    267		ret = -EINVAL;
    268		goto out;
    269	}
    270
    271	info->chip = chip;
    272	info->map = chip->regmap;
    273	if (!info->map) {
    274		dev_err(&pdev->dev, "no regmap!\n");
    275		ret = -EINVAL;
    276		goto out;
    277	}
    278
    279	info->dev = &pdev->dev;
    280	dev_set_drvdata(&pdev->dev, info);
    281
    282	info->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
    283	if (IS_ERR(info->rtc_dev))
    284		return PTR_ERR(info->rtc_dev);
    285
    286	ret = pm80x_request_irq(chip, info->irq, rtc_update_handler,
    287				IRQF_ONESHOT, "rtc", info);
    288	if (ret < 0) {
    289		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
    290			info->irq, ret);
    291		goto out;
    292	}
    293
    294	info->rtc_dev->ops = &pm80x_rtc_ops;
    295	info->rtc_dev->range_max = U32_MAX;
    296
    297	ret = devm_rtc_register_device(info->rtc_dev);
    298	if (ret)
    299		goto out_rtc;
    300
    301	/*
    302	 * enable internal XO instead of internal 3.25MHz clock since it can
    303	 * free running in PMIC power-down state.
    304	 */
    305	regmap_update_bits(info->map, PM800_RTC_CONTROL, PM800_RTC1_USE_XO,
    306			   PM800_RTC1_USE_XO);
    307
    308	/* remember whether this power up is caused by PMIC RTC or not */
    309	info->rtc_dev->dev.platform_data = &pdata->rtc_wakeup;
    310
    311	device_init_wakeup(&pdev->dev, 1);
    312
    313	return 0;
    314out_rtc:
    315	pm80x_free_irq(chip, info->irq, info);
    316out:
    317	return ret;
    318}
    319
    320static int pm80x_rtc_remove(struct platform_device *pdev)
    321{
    322	struct pm80x_rtc_info *info = platform_get_drvdata(pdev);
    323	pm80x_free_irq(info->chip, info->irq, info);
    324	return 0;
    325}
    326
    327static struct platform_driver pm80x_rtc_driver = {
    328	.driver = {
    329		   .name = "88pm80x-rtc",
    330		   .pm = &pm80x_rtc_pm_ops,
    331		   },
    332	.probe = pm80x_rtc_probe,
    333	.remove = pm80x_rtc_remove,
    334};
    335
    336module_platform_driver(pm80x_rtc_driver);
    337
    338MODULE_LICENSE("GPL");
    339MODULE_DESCRIPTION("Marvell 88PM80x RTC driver");
    340MODULE_AUTHOR("Qiao Zhou <zhouqiao@marvell.com>");
    341MODULE_ALIAS("platform:88pm80x-rtc");