Blame view
drivers/rtc/rtc-pl030.c
3.49 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
a190901c6 [RTC] rtc-pl030: ... |
2 3 4 5 |
/* * linux/drivers/rtc/rtc-pl030.c * * Copyright (C) 2000-2001 Deep Blue Solutions Ltd. |
a190901c6 [RTC] rtc-pl030: ... |
6 7 8 9 10 11 12 |
*/ #include <linux/module.h> #include <linux/rtc.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/amba/bus.h> #include <linux/io.h> |
5a0e3ad6a include cleanup: ... |
13 |
#include <linux/slab.h> |
a190901c6 [RTC] rtc-pl030: ... |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#define RTC_DR (0) #define RTC_MR (4) #define RTC_STAT (8) #define RTC_EOI (8) #define RTC_LR (12) #define RTC_CR (16) #define RTC_CR_MIE (1 << 0) struct pl030_rtc { struct rtc_device *rtc; void __iomem *base; }; static irqreturn_t pl030_interrupt(int irq, void *dev_id) { struct pl030_rtc *rtc = dev_id; writel(0, rtc->base + RTC_EOI); return IRQ_HANDLED; } |
a190901c6 [RTC] rtc-pl030: ... |
34 35 36 |
static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); |
c33c4713c rtc: pl030: switc... |
37 |
rtc_time64_to_tm(readl(rtc->base + RTC_MR), &alrm->time); |
a190901c6 [RTC] rtc-pl030: ... |
38 39 40 41 42 43 |
return 0; } static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); |
a190901c6 [RTC] rtc-pl030: ... |
44 |
|
c33c4713c rtc: pl030: switc... |
45 46 47 |
writel(rtc_tm_to_time64(&alrm->time), rtc->base + RTC_MR); return 0; |
a190901c6 [RTC] rtc-pl030: ... |
48 49 50 51 52 |
} static int pl030_read_time(struct device *dev, struct rtc_time *tm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); |
c33c4713c rtc: pl030: switc... |
53 |
rtc_time64_to_tm(readl(rtc->base + RTC_DR), tm); |
a190901c6 [RTC] rtc-pl030: ... |
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
return 0; } /* * Set the RTC time. Unfortunately, we can't accurately set * the point at which the counter updates. * * Also, since RTC_LR is transferred to RTC_CR on next rising * edge of the 1Hz clock, we must write the time one second * in advance. */ static int pl030_set_time(struct device *dev, struct rtc_time *tm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); |
a190901c6 [RTC] rtc-pl030: ... |
69 |
|
c33c4713c rtc: pl030: switc... |
70 |
writel(rtc_tm_to_time64(tm) + 1, rtc->base + RTC_LR); |
a190901c6 [RTC] rtc-pl030: ... |
71 |
|
c33c4713c rtc: pl030: switc... |
72 |
return 0; |
a190901c6 [RTC] rtc-pl030: ... |
73 74 75 |
} static const struct rtc_class_ops pl030_ops = { |
a190901c6 [RTC] rtc-pl030: ... |
76 77 78 79 80 |
.read_time = pl030_read_time, .set_time = pl030_set_time, .read_alarm = pl030_read_alarm, .set_alarm = pl030_set_alarm, }; |
aa25afad2 ARM: amba: make p... |
81 |
static int pl030_probe(struct amba_device *dev, const struct amba_id *id) |
a190901c6 [RTC] rtc-pl030: ... |
82 83 84 85 86 87 88 |
{ struct pl030_rtc *rtc; int ret; ret = amba_request_regions(dev, NULL); if (ret) goto err_req; |
58c181c82 drivers/rtc/rtc-p... |
89 |
rtc = devm_kzalloc(&dev->dev, sizeof(*rtc), GFP_KERNEL); |
a190901c6 [RTC] rtc-pl030: ... |
90 91 92 93 |
if (!rtc) { ret = -ENOMEM; goto err_rtc; } |
c778ec858 rtc: pl030: fix p... |
94 95 96 97 98 99 100 |
rtc->rtc = devm_rtc_allocate_device(&dev->dev); if (IS_ERR(rtc->rtc)) { ret = PTR_ERR(rtc->rtc); goto err_rtc; } rtc->rtc->ops = &pl030_ops; |
9896169a1 rtc: pl030: set r... |
101 |
rtc->rtc->range_max = U32_MAX; |
dc890c2dc [ARM] 5544/1: Tru... |
102 |
rtc->base = ioremap(dev->res.start, resource_size(&dev->res)); |
a190901c6 [RTC] rtc-pl030: ... |
103 104 |
if (!rtc->base) { ret = -ENOMEM; |
58c181c82 drivers/rtc/rtc-p... |
105 |
goto err_rtc; |
a190901c6 [RTC] rtc-pl030: ... |
106 107 108 109 110 111 |
} __raw_writel(0, rtc->base + RTC_CR); __raw_writel(0, rtc->base + RTC_EOI); amba_set_drvdata(dev, rtc); |
2f6e5f945 drivers/rtc: remo... |
112 |
ret = request_irq(dev->irq[0], pl030_interrupt, 0, |
a190901c6 [RTC] rtc-pl030: ... |
113 114 115 |
"rtc-pl030", rtc); if (ret) goto err_irq; |
c778ec858 rtc: pl030: fix p... |
116 117 |
ret = rtc_register_device(rtc->rtc); if (ret) |
a190901c6 [RTC] rtc-pl030: ... |
118 |
goto err_reg; |
a190901c6 [RTC] rtc-pl030: ... |
119 120 121 122 123 124 125 |
return 0; err_reg: free_irq(dev->irq[0], rtc); err_irq: iounmap(rtc->base); |
a190901c6 [RTC] rtc-pl030: ... |
126 127 128 129 130 131 132 133 134 |
err_rtc: amba_release_regions(dev); err_req: return ret; } static int pl030_remove(struct amba_device *dev) { struct pl030_rtc *rtc = amba_get_drvdata(dev); |
a190901c6 [RTC] rtc-pl030: ... |
135 136 137 |
writel(0, rtc->base + RTC_CR); free_irq(dev->irq[0], rtc); |
a190901c6 [RTC] rtc-pl030: ... |
138 |
iounmap(rtc->base); |
a190901c6 [RTC] rtc-pl030: ... |
139 140 141 142 143 144 145 146 147 148 149 150 |
amba_release_regions(dev); return 0; } static struct amba_id pl030_ids[] = { { .id = 0x00041030, .mask = 0x000fffff, }, { 0, 0 }, }; |
66bce5916 rtc: pl030: Enabl... |
151 |
MODULE_DEVICE_TABLE(amba, pl030_ids); |
a190901c6 [RTC] rtc-pl030: ... |
152 153 154 155 156 157 158 159 |
static struct amba_driver pl030_driver = { .drv = { .name = "rtc-pl030", }, .probe = pl030_probe, .remove = pl030_remove, .id_table = pl030_ids, }; |
9e5ed094c ARM: 7362/1: AMBA... |
160 |
module_amba_driver(pl030_driver); |
a190901c6 [RTC] rtc-pl030: ... |
161 162 163 164 |
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); MODULE_DESCRIPTION("ARM AMBA PL030 RTC Driver"); MODULE_LICENSE("GPL"); |