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-armada38x.c (15820B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * RTC driver for the Armada 38x Marvell SoCs
      4 *
      5 * Copyright (C) 2015 Marvell
      6 *
      7 * Gregory Clement <gregory.clement@free-electrons.com>
      8 */
      9
     10#include <linux/delay.h>
     11#include <linux/io.h>
     12#include <linux/module.h>
     13#include <linux/of.h>
     14#include <linux/of_device.h>
     15#include <linux/platform_device.h>
     16#include <linux/rtc.h>
     17
     18#define RTC_STATUS	    0x0
     19#define RTC_STATUS_ALARM1	    BIT(0)
     20#define RTC_STATUS_ALARM2	    BIT(1)
     21#define RTC_IRQ1_CONF	    0x4
     22#define RTC_IRQ2_CONF	    0x8
     23#define RTC_IRQ_AL_EN		    BIT(0)
     24#define RTC_IRQ_FREQ_EN		    BIT(1)
     25#define RTC_IRQ_FREQ_1HZ	    BIT(2)
     26#define RTC_CCR		    0x18
     27#define RTC_CCR_MODE		    BIT(15)
     28#define RTC_CONF_TEST	    0x1C
     29#define RTC_NOMINAL_TIMING	    BIT(13)
     30
     31#define RTC_TIME	    0xC
     32#define RTC_ALARM1	    0x10
     33#define RTC_ALARM2	    0x14
     34
     35/* Armada38x SoC registers  */
     36#define RTC_38X_BRIDGE_TIMING_CTL   0x0
     37#define RTC_38X_PERIOD_OFFS		0
     38#define RTC_38X_PERIOD_MASK		(0x3FF << RTC_38X_PERIOD_OFFS)
     39#define RTC_38X_READ_DELAY_OFFS		26
     40#define RTC_38X_READ_DELAY_MASK		(0x1F << RTC_38X_READ_DELAY_OFFS)
     41
     42/* Armada 7K/8K registers  */
     43#define RTC_8K_BRIDGE_TIMING_CTL0    0x0
     44#define RTC_8K_WRCLK_PERIOD_OFFS	0
     45#define RTC_8K_WRCLK_PERIOD_MASK	(0xFFFF << RTC_8K_WRCLK_PERIOD_OFFS)
     46#define RTC_8K_WRCLK_SETUP_OFFS		16
     47#define RTC_8K_WRCLK_SETUP_MASK		(0xFFFF << RTC_8K_WRCLK_SETUP_OFFS)
     48#define RTC_8K_BRIDGE_TIMING_CTL1   0x4
     49#define RTC_8K_READ_DELAY_OFFS		0
     50#define RTC_8K_READ_DELAY_MASK		(0xFFFF << RTC_8K_READ_DELAY_OFFS)
     51
     52#define RTC_8K_ISR		    0x10
     53#define RTC_8K_IMR		    0x14
     54#define RTC_8K_ALARM2			BIT(0)
     55
     56#define SOC_RTC_INTERRUPT	    0x8
     57#define SOC_RTC_ALARM1			BIT(0)
     58#define SOC_RTC_ALARM2			BIT(1)
     59#define SOC_RTC_ALARM1_MASK		BIT(2)
     60#define SOC_RTC_ALARM2_MASK		BIT(3)
     61
     62#define SAMPLE_NR 100
     63
     64struct value_to_freq {
     65	u32 value;
     66	u8 freq;
     67};
     68
     69struct armada38x_rtc {
     70	struct rtc_device   *rtc_dev;
     71	void __iomem	    *regs;
     72	void __iomem	    *regs_soc;
     73	spinlock_t	    lock;
     74	int		    irq;
     75	bool		    initialized;
     76	struct value_to_freq *val_to_freq;
     77	const struct armada38x_rtc_data *data;
     78};
     79
     80#define ALARM1	0
     81#define ALARM2	1
     82
     83#define ALARM_REG(base, alarm)	 ((base) + (alarm) * sizeof(u32))
     84
     85struct armada38x_rtc_data {
     86	/* Initialize the RTC-MBUS bridge timing */
     87	void (*update_mbus_timing)(struct armada38x_rtc *rtc);
     88	u32 (*read_rtc_reg)(struct armada38x_rtc *rtc, u8 rtc_reg);
     89	void (*clear_isr)(struct armada38x_rtc *rtc);
     90	void (*unmask_interrupt)(struct armada38x_rtc *rtc);
     91	u32 alarm;
     92};
     93
     94/*
     95 * According to the datasheet, the OS should wait 5us after every
     96 * register write to the RTC hard macro so that the required update
     97 * can occur without holding off the system bus
     98 * According to errata RES-3124064, Write to any RTC register
     99 * may fail. As a workaround, before writing to RTC
    100 * register, issue a dummy write of 0x0 twice to RTC Status
    101 * register.
    102 */
    103
    104static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset)
    105{
    106	writel(0, rtc->regs + RTC_STATUS);
    107	writel(0, rtc->regs + RTC_STATUS);
    108	writel(val, rtc->regs + offset);
    109	udelay(5);
    110}
    111
    112/* Update RTC-MBUS bridge timing parameters */
    113static void rtc_update_38x_mbus_timing_params(struct armada38x_rtc *rtc)
    114{
    115	u32 reg;
    116
    117	reg = readl(rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL);
    118	reg &= ~RTC_38X_PERIOD_MASK;
    119	reg |= 0x3FF << RTC_38X_PERIOD_OFFS; /* Maximum value */
    120	reg &= ~RTC_38X_READ_DELAY_MASK;
    121	reg |= 0x1F << RTC_38X_READ_DELAY_OFFS; /* Maximum value */
    122	writel(reg, rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL);
    123}
    124
    125static void rtc_update_8k_mbus_timing_params(struct armada38x_rtc *rtc)
    126{
    127	u32 reg;
    128
    129	reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0);
    130	reg &= ~RTC_8K_WRCLK_PERIOD_MASK;
    131	reg |= 0x3FF << RTC_8K_WRCLK_PERIOD_OFFS;
    132	reg &= ~RTC_8K_WRCLK_SETUP_MASK;
    133	reg |= 0x29 << RTC_8K_WRCLK_SETUP_OFFS;
    134	writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0);
    135
    136	reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1);
    137	reg &= ~RTC_8K_READ_DELAY_MASK;
    138	reg |= 0x3F << RTC_8K_READ_DELAY_OFFS;
    139	writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1);
    140}
    141
    142static u32 read_rtc_register(struct armada38x_rtc *rtc, u8 rtc_reg)
    143{
    144	return readl(rtc->regs + rtc_reg);
    145}
    146
    147static u32 read_rtc_register_38x_wa(struct armada38x_rtc *rtc, u8 rtc_reg)
    148{
    149	int i, index_max = 0, max = 0;
    150
    151	for (i = 0; i < SAMPLE_NR; i++) {
    152		rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg);
    153		rtc->val_to_freq[i].freq = 0;
    154	}
    155
    156	for (i = 0; i < SAMPLE_NR; i++) {
    157		int j = 0;
    158		u32 value = rtc->val_to_freq[i].value;
    159
    160		while (rtc->val_to_freq[j].freq) {
    161			if (rtc->val_to_freq[j].value == value) {
    162				rtc->val_to_freq[j].freq++;
    163				break;
    164			}
    165			j++;
    166		}
    167
    168		if (!rtc->val_to_freq[j].freq) {
    169			rtc->val_to_freq[j].value = value;
    170			rtc->val_to_freq[j].freq = 1;
    171		}
    172
    173		if (rtc->val_to_freq[j].freq > max) {
    174			index_max = j;
    175			max = rtc->val_to_freq[j].freq;
    176		}
    177
    178		/*
    179		 * If a value already has half of the sample this is the most
    180		 * frequent one and we can stop the research right now
    181		 */
    182		if (max > SAMPLE_NR / 2)
    183			break;
    184	}
    185
    186	return rtc->val_to_freq[index_max].value;
    187}
    188
    189static void armada38x_clear_isr(struct armada38x_rtc *rtc)
    190{
    191	u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
    192
    193	writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT);
    194}
    195
    196static void armada38x_unmask_interrupt(struct armada38x_rtc *rtc)
    197{
    198	u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT);
    199
    200	writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT);
    201}
    202
    203static void armada8k_clear_isr(struct armada38x_rtc *rtc)
    204{
    205	writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR);
    206}
    207
    208static void armada8k_unmask_interrupt(struct armada38x_rtc *rtc)
    209{
    210	writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_IMR);
    211}
    212
    213static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm)
    214{
    215	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    216	unsigned long time, flags;
    217
    218	spin_lock_irqsave(&rtc->lock, flags);
    219	time = rtc->data->read_rtc_reg(rtc, RTC_TIME);
    220	spin_unlock_irqrestore(&rtc->lock, flags);
    221
    222	rtc_time64_to_tm(time, tm);
    223
    224	return 0;
    225}
    226
    227static void armada38x_rtc_reset(struct armada38x_rtc *rtc)
    228{
    229	u32 reg;
    230
    231	reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST);
    232	/* If bits [7:0] are non-zero, assume RTC was uninitialized */
    233	if (reg & 0xff) {
    234		rtc_delayed_write(0, rtc, RTC_CONF_TEST);
    235		msleep(500); /* Oscillator startup time */
    236		rtc_delayed_write(0, rtc, RTC_TIME);
    237		rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc,
    238				  RTC_STATUS);
    239		rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR);
    240	}
    241	rtc->initialized = true;
    242}
    243
    244static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm)
    245{
    246	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    247	unsigned long time, flags;
    248
    249	time = rtc_tm_to_time64(tm);
    250
    251	if (!rtc->initialized)
    252		armada38x_rtc_reset(rtc);
    253
    254	spin_lock_irqsave(&rtc->lock, flags);
    255	rtc_delayed_write(time, rtc, RTC_TIME);
    256	spin_unlock_irqrestore(&rtc->lock, flags);
    257
    258	return 0;
    259}
    260
    261static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
    262{
    263	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    264	unsigned long time, flags;
    265	u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
    266	u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
    267	u32 val;
    268
    269	spin_lock_irqsave(&rtc->lock, flags);
    270
    271	time = rtc->data->read_rtc_reg(rtc, reg);
    272	val = rtc->data->read_rtc_reg(rtc, reg_irq) & RTC_IRQ_AL_EN;
    273
    274	spin_unlock_irqrestore(&rtc->lock, flags);
    275
    276	alrm->enabled = val ? 1 : 0;
    277	rtc_time64_to_tm(time,  &alrm->time);
    278
    279	return 0;
    280}
    281
    282static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
    283{
    284	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    285	u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm);
    286	u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
    287	unsigned long time, flags;
    288
    289	time = rtc_tm_to_time64(&alrm->time);
    290
    291	spin_lock_irqsave(&rtc->lock, flags);
    292
    293	rtc_delayed_write(time, rtc, reg);
    294
    295	if (alrm->enabled) {
    296		rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq);
    297		rtc->data->unmask_interrupt(rtc);
    298	}
    299
    300	spin_unlock_irqrestore(&rtc->lock, flags);
    301
    302	return 0;
    303}
    304
    305static int armada38x_rtc_alarm_irq_enable(struct device *dev,
    306					 unsigned int enabled)
    307{
    308	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    309	u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
    310	unsigned long flags;
    311
    312	spin_lock_irqsave(&rtc->lock, flags);
    313
    314	if (enabled)
    315		rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq);
    316	else
    317		rtc_delayed_write(0, rtc, reg_irq);
    318
    319	spin_unlock_irqrestore(&rtc->lock, flags);
    320
    321	return 0;
    322}
    323
    324static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data)
    325{
    326	struct armada38x_rtc *rtc = data;
    327	u32 val;
    328	int event = RTC_IRQF | RTC_AF;
    329	u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm);
    330
    331	dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq);
    332
    333	spin_lock(&rtc->lock);
    334
    335	rtc->data->clear_isr(rtc);
    336	val = rtc->data->read_rtc_reg(rtc, reg_irq);
    337	/* disable all the interrupts for alarm*/
    338	rtc_delayed_write(0, rtc, reg_irq);
    339	/* Ack the event */
    340	rtc_delayed_write(1 << rtc->data->alarm, rtc, RTC_STATUS);
    341
    342	spin_unlock(&rtc->lock);
    343
    344	if (val & RTC_IRQ_FREQ_EN) {
    345		if (val & RTC_IRQ_FREQ_1HZ)
    346			event |= RTC_UF;
    347		else
    348			event |= RTC_PF;
    349	}
    350
    351	rtc_update_irq(rtc->rtc_dev, 1, event);
    352
    353	return IRQ_HANDLED;
    354}
    355
    356/*
    357 * The information given in the Armada 388 functional spec is complex.
    358 * They give two different formulas for calculating the offset value,
    359 * but when considering "Offset" as an 8-bit signed integer, they both
    360 * reduce down to (we shall rename "Offset" as "val" here):
    361 *
    362 *   val = (f_ideal / f_measured - 1) / resolution   where f_ideal = 32768
    363 *
    364 * Converting to time, f = 1/t:
    365 *   val = (t_measured / t_ideal - 1) / resolution   where t_ideal = 1/32768
    366 *
    367 *   =>  t_measured / t_ideal = val * resolution + 1
    368 *
    369 * "offset" in the RTC interface is defined as:
    370 *   t = t0 * (1 + offset * 1e-9)
    371 * where t is the desired period, t0 is the measured period with a zero
    372 * offset, which is t_measured above. With t0 = t_measured and t = t_ideal,
    373 *   offset = (t_ideal / t_measured - 1) / 1e-9
    374 *
    375 *   => t_ideal / t_measured = offset * 1e-9 + 1
    376 *
    377 * so:
    378 *
    379 *   offset * 1e-9 + 1 = 1 / (val * resolution + 1)
    380 *
    381 * We want "resolution" to be an integer, so resolution = R * 1e-9, giving
    382 *   offset = 1e18 / (val * R + 1e9) - 1e9
    383 *   val = (1e18 / (offset + 1e9) - 1e9) / R
    384 * with a common transformation:
    385 *   f(x) = 1e18 / (x + 1e9) - 1e9
    386 *   offset = f(val * R)
    387 *   val = f(offset) / R
    388 *
    389 * Armada 38x supports two modes, fine mode (954ppb) and coarse mode (3815ppb).
    390 */
    391static long armada38x_ppb_convert(long ppb)
    392{
    393	long div = ppb + 1000000000L;
    394
    395	return div_s64(1000000000000000000LL + div / 2, div) - 1000000000L;
    396}
    397
    398static int armada38x_rtc_read_offset(struct device *dev, long *offset)
    399{
    400	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    401	unsigned long ccr, flags;
    402	long ppb_cor;
    403
    404	spin_lock_irqsave(&rtc->lock, flags);
    405	ccr = rtc->data->read_rtc_reg(rtc, RTC_CCR);
    406	spin_unlock_irqrestore(&rtc->lock, flags);
    407
    408	ppb_cor = (ccr & RTC_CCR_MODE ? 3815 : 954) * (s8)ccr;
    409	/* ppb_cor + 1000000000L can never be zero */
    410	*offset = armada38x_ppb_convert(ppb_cor);
    411
    412	return 0;
    413}
    414
    415static int armada38x_rtc_set_offset(struct device *dev, long offset)
    416{
    417	struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    418	unsigned long ccr = 0;
    419	long ppb_cor, off;
    420
    421	/*
    422	 * The maximum ppb_cor is -128 * 3815 .. 127 * 3815, but we
    423	 * need to clamp the input.  This equates to -484270 .. 488558.
    424	 * Not only is this to stop out of range "off" but also to
    425	 * avoid the division by zero in armada38x_ppb_convert().
    426	 */
    427	offset = clamp(offset, -484270L, 488558L);
    428
    429	ppb_cor = armada38x_ppb_convert(offset);
    430
    431	/*
    432	 * Use low update mode where possible, which gives a better
    433	 * resolution of correction.
    434	 */
    435	off = DIV_ROUND_CLOSEST(ppb_cor, 954);
    436	if (off > 127 || off < -128) {
    437		ccr = RTC_CCR_MODE;
    438		off = DIV_ROUND_CLOSEST(ppb_cor, 3815);
    439	}
    440
    441	/*
    442	 * Armada 388 requires a bit pattern in bits 14..8 depending on
    443	 * the sign bit: { 0, ~S, S, S, S, S, S }
    444	 */
    445	ccr |= (off & 0x3fff) ^ 0x2000;
    446	rtc_delayed_write(ccr, rtc, RTC_CCR);
    447
    448	return 0;
    449}
    450
    451static const struct rtc_class_ops armada38x_rtc_ops = {
    452	.read_time = armada38x_rtc_read_time,
    453	.set_time = armada38x_rtc_set_time,
    454	.read_alarm = armada38x_rtc_read_alarm,
    455	.set_alarm = armada38x_rtc_set_alarm,
    456	.alarm_irq_enable = armada38x_rtc_alarm_irq_enable,
    457	.read_offset = armada38x_rtc_read_offset,
    458	.set_offset = armada38x_rtc_set_offset,
    459};
    460
    461static const struct armada38x_rtc_data armada38x_data = {
    462	.update_mbus_timing = rtc_update_38x_mbus_timing_params,
    463	.read_rtc_reg = read_rtc_register_38x_wa,
    464	.clear_isr = armada38x_clear_isr,
    465	.unmask_interrupt = armada38x_unmask_interrupt,
    466	.alarm = ALARM1,
    467};
    468
    469static const struct armada38x_rtc_data armada8k_data = {
    470	.update_mbus_timing = rtc_update_8k_mbus_timing_params,
    471	.read_rtc_reg = read_rtc_register,
    472	.clear_isr = armada8k_clear_isr,
    473	.unmask_interrupt = armada8k_unmask_interrupt,
    474	.alarm = ALARM2,
    475};
    476
    477#ifdef CONFIG_OF
    478static const struct of_device_id armada38x_rtc_of_match_table[] = {
    479	{
    480		.compatible = "marvell,armada-380-rtc",
    481		.data = &armada38x_data,
    482	},
    483	{
    484		.compatible = "marvell,armada-8k-rtc",
    485		.data = &armada8k_data,
    486	},
    487	{}
    488};
    489MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table);
    490#endif
    491
    492static __init int armada38x_rtc_probe(struct platform_device *pdev)
    493{
    494	struct resource *res;
    495	struct armada38x_rtc *rtc;
    496
    497	rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc),
    498			    GFP_KERNEL);
    499	if (!rtc)
    500		return -ENOMEM;
    501
    502	rtc->data = of_device_get_match_data(&pdev->dev);
    503
    504	rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR,
    505				sizeof(struct value_to_freq), GFP_KERNEL);
    506	if (!rtc->val_to_freq)
    507		return -ENOMEM;
    508
    509	spin_lock_init(&rtc->lock);
    510
    511	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc");
    512	rtc->regs = devm_ioremap_resource(&pdev->dev, res);
    513	if (IS_ERR(rtc->regs))
    514		return PTR_ERR(rtc->regs);
    515	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc-soc");
    516	rtc->regs_soc = devm_ioremap_resource(&pdev->dev, res);
    517	if (IS_ERR(rtc->regs_soc))
    518		return PTR_ERR(rtc->regs_soc);
    519
    520	rtc->irq = platform_get_irq(pdev, 0);
    521	if (rtc->irq < 0)
    522		return rtc->irq;
    523
    524	rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
    525	if (IS_ERR(rtc->rtc_dev))
    526		return PTR_ERR(rtc->rtc_dev);
    527
    528	if (devm_request_irq(&pdev->dev, rtc->irq, armada38x_rtc_alarm_irq,
    529				0, pdev->name, rtc) < 0) {
    530		dev_warn(&pdev->dev, "Interrupt not available.\n");
    531		rtc->irq = -1;
    532	}
    533	platform_set_drvdata(pdev, rtc);
    534
    535	if (rtc->irq != -1)
    536		device_init_wakeup(&pdev->dev, 1);
    537	else
    538		clear_bit(RTC_FEATURE_ALARM, rtc->rtc_dev->features);
    539
    540	/* Update RTC-MBUS bridge timing parameters */
    541	rtc->data->update_mbus_timing(rtc);
    542
    543	rtc->rtc_dev->ops = &armada38x_rtc_ops;
    544	rtc->rtc_dev->range_max = U32_MAX;
    545
    546	return devm_rtc_register_device(rtc->rtc_dev);
    547}
    548
    549#ifdef CONFIG_PM_SLEEP
    550static int armada38x_rtc_suspend(struct device *dev)
    551{
    552	if (device_may_wakeup(dev)) {
    553		struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    554
    555		return enable_irq_wake(rtc->irq);
    556	}
    557
    558	return 0;
    559}
    560
    561static int armada38x_rtc_resume(struct device *dev)
    562{
    563	if (device_may_wakeup(dev)) {
    564		struct armada38x_rtc *rtc = dev_get_drvdata(dev);
    565
    566		/* Update RTC-MBUS bridge timing parameters */
    567		rtc->data->update_mbus_timing(rtc);
    568
    569		return disable_irq_wake(rtc->irq);
    570	}
    571
    572	return 0;
    573}
    574#endif
    575
    576static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops,
    577			 armada38x_rtc_suspend, armada38x_rtc_resume);
    578
    579static struct platform_driver armada38x_rtc_driver = {
    580	.driver		= {
    581		.name	= "armada38x-rtc",
    582		.pm	= &armada38x_rtc_pm_ops,
    583		.of_match_table = of_match_ptr(armada38x_rtc_of_match_table),
    584	},
    585};
    586
    587module_platform_driver_probe(armada38x_rtc_driver, armada38x_rtc_probe);
    588
    589MODULE_DESCRIPTION("Marvell Armada 38x RTC driver");
    590MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
    591MODULE_LICENSE("GPL");