0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/delay.h>
0012 #include <linux/init.h>
0013 #include <linux/io.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/rtc.h>
0018 #include <linux/slab.h>
0019
0020
0021 #define RTC_CCVR 0x00
0022 #define RTC_CMR 0x04
0023 #define RTC_CLR 0x08
0024 #define RTC_CCR 0x0C
0025 #define RTC_CCR_IE BIT(0)
0026 #define RTC_CCR_MASK BIT(1)
0027 #define RTC_CCR_EN BIT(2)
0028 #define RTC_CCR_WEN BIT(3)
0029 #define RTC_STAT 0x10
0030 #define RTC_STAT_BIT BIT(0)
0031 #define RTC_RSTAT 0x14
0032 #define RTC_EOI 0x18
0033 #define RTC_VER 0x1C
0034
0035 struct xgene_rtc_dev {
0036 struct rtc_device *rtc;
0037 void __iomem *csr_base;
0038 struct clk *clk;
0039 unsigned int irq_wake;
0040 unsigned int irq_enabled;
0041 };
0042
0043 static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm)
0044 {
0045 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
0046
0047 rtc_time64_to_tm(readl(pdata->csr_base + RTC_CCVR), tm);
0048 return 0;
0049 }
0050
0051 static int xgene_rtc_set_time(struct device *dev, struct rtc_time *tm)
0052 {
0053 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
0054
0055
0056
0057
0058
0059 writel((u32)rtc_tm_to_time64(tm), pdata->csr_base + RTC_CLR);
0060 readl(pdata->csr_base + RTC_CLR);
0061
0062 return 0;
0063 }
0064
0065 static int xgene_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0066 {
0067 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
0068
0069
0070 rtc_time64_to_tm(0, &alrm->time);
0071 alrm->enabled = readl(pdata->csr_base + RTC_CCR) & RTC_CCR_IE;
0072
0073 return 0;
0074 }
0075
0076 static int xgene_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
0077 {
0078 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
0079 u32 ccr;
0080
0081 ccr = readl(pdata->csr_base + RTC_CCR);
0082 if (enabled) {
0083 ccr &= ~RTC_CCR_MASK;
0084 ccr |= RTC_CCR_IE;
0085 } else {
0086 ccr &= ~RTC_CCR_IE;
0087 ccr |= RTC_CCR_MASK;
0088 }
0089 writel(ccr, pdata->csr_base + RTC_CCR);
0090
0091 return 0;
0092 }
0093
0094 static int xgene_rtc_alarm_irq_enabled(struct device *dev)
0095 {
0096 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
0097
0098 return readl(pdata->csr_base + RTC_CCR) & RTC_CCR_IE ? 1 : 0;
0099 }
0100
0101 static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
0102 {
0103 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev);
0104
0105 writel((u32)rtc_tm_to_time64(&alrm->time), pdata->csr_base + RTC_CMR);
0106
0107 xgene_rtc_alarm_irq_enable(dev, alrm->enabled);
0108
0109 return 0;
0110 }
0111
0112 static const struct rtc_class_ops xgene_rtc_ops = {
0113 .read_time = xgene_rtc_read_time,
0114 .set_time = xgene_rtc_set_time,
0115 .read_alarm = xgene_rtc_read_alarm,
0116 .set_alarm = xgene_rtc_set_alarm,
0117 .alarm_irq_enable = xgene_rtc_alarm_irq_enable,
0118 };
0119
0120 static irqreturn_t xgene_rtc_interrupt(int irq, void *id)
0121 {
0122 struct xgene_rtc_dev *pdata = id;
0123
0124
0125 if (!(readl(pdata->csr_base + RTC_STAT) & RTC_STAT_BIT))
0126 return IRQ_NONE;
0127
0128
0129 readl(pdata->csr_base + RTC_EOI);
0130
0131 rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF);
0132
0133 return IRQ_HANDLED;
0134 }
0135
0136 static int xgene_rtc_probe(struct platform_device *pdev)
0137 {
0138 struct xgene_rtc_dev *pdata;
0139 int ret;
0140 int irq;
0141
0142 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0143 if (!pdata)
0144 return -ENOMEM;
0145 platform_set_drvdata(pdev, pdata);
0146
0147 pdata->csr_base = devm_platform_ioremap_resource(pdev, 0);
0148 if (IS_ERR(pdata->csr_base))
0149 return PTR_ERR(pdata->csr_base);
0150
0151 pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
0152 if (IS_ERR(pdata->rtc))
0153 return PTR_ERR(pdata->rtc);
0154
0155 irq = platform_get_irq(pdev, 0);
0156 if (irq < 0)
0157 return irq;
0158 ret = devm_request_irq(&pdev->dev, irq, xgene_rtc_interrupt, 0,
0159 dev_name(&pdev->dev), pdata);
0160 if (ret) {
0161 dev_err(&pdev->dev, "Could not request IRQ\n");
0162 return ret;
0163 }
0164
0165 pdata->clk = devm_clk_get(&pdev->dev, NULL);
0166 if (IS_ERR(pdata->clk)) {
0167 dev_err(&pdev->dev, "Couldn't get the clock for RTC\n");
0168 return -ENODEV;
0169 }
0170 ret = clk_prepare_enable(pdata->clk);
0171 if (ret)
0172 return ret;
0173
0174
0175 writel(RTC_CCR_EN, pdata->csr_base + RTC_CCR);
0176
0177 ret = device_init_wakeup(&pdev->dev, 1);
0178 if (ret) {
0179 clk_disable_unprepare(pdata->clk);
0180 return ret;
0181 }
0182
0183 pdata->rtc->ops = &xgene_rtc_ops;
0184 pdata->rtc->range_max = U32_MAX;
0185
0186 ret = devm_rtc_register_device(pdata->rtc);
0187 if (ret) {
0188 clk_disable_unprepare(pdata->clk);
0189 return ret;
0190 }
0191
0192 return 0;
0193 }
0194
0195 static int xgene_rtc_remove(struct platform_device *pdev)
0196 {
0197 struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
0198
0199 xgene_rtc_alarm_irq_enable(&pdev->dev, 0);
0200 device_init_wakeup(&pdev->dev, 0);
0201 clk_disable_unprepare(pdata->clk);
0202 return 0;
0203 }
0204
0205 static int __maybe_unused xgene_rtc_suspend(struct device *dev)
0206 {
0207 struct platform_device *pdev = to_platform_device(dev);
0208 struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
0209 int irq;
0210
0211 irq = platform_get_irq(pdev, 0);
0212
0213
0214
0215
0216
0217
0218 if (device_may_wakeup(&pdev->dev)) {
0219 if (!enable_irq_wake(irq))
0220 pdata->irq_wake = 1;
0221 } else {
0222 pdata->irq_enabled = xgene_rtc_alarm_irq_enabled(dev);
0223 xgene_rtc_alarm_irq_enable(dev, 0);
0224 clk_disable_unprepare(pdata->clk);
0225 }
0226 return 0;
0227 }
0228
0229 static int __maybe_unused xgene_rtc_resume(struct device *dev)
0230 {
0231 struct platform_device *pdev = to_platform_device(dev);
0232 struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev);
0233 int irq;
0234 int rc;
0235
0236 irq = platform_get_irq(pdev, 0);
0237
0238 if (device_may_wakeup(&pdev->dev)) {
0239 if (pdata->irq_wake) {
0240 disable_irq_wake(irq);
0241 pdata->irq_wake = 0;
0242 }
0243 } else {
0244 rc = clk_prepare_enable(pdata->clk);
0245 if (rc) {
0246 dev_err(dev, "Unable to enable clock error %d\n", rc);
0247 return rc;
0248 }
0249 xgene_rtc_alarm_irq_enable(dev, pdata->irq_enabled);
0250 }
0251
0252 return 0;
0253 }
0254
0255 static SIMPLE_DEV_PM_OPS(xgene_rtc_pm_ops, xgene_rtc_suspend, xgene_rtc_resume);
0256
0257 #ifdef CONFIG_OF
0258 static const struct of_device_id xgene_rtc_of_match[] = {
0259 {.compatible = "apm,xgene-rtc" },
0260 { }
0261 };
0262 MODULE_DEVICE_TABLE(of, xgene_rtc_of_match);
0263 #endif
0264
0265 static struct platform_driver xgene_rtc_driver = {
0266 .probe = xgene_rtc_probe,
0267 .remove = xgene_rtc_remove,
0268 .driver = {
0269 .name = "xgene-rtc",
0270 .pm = &xgene_rtc_pm_ops,
0271 .of_match_table = of_match_ptr(xgene_rtc_of_match),
0272 },
0273 };
0274
0275 module_platform_driver(xgene_rtc_driver);
0276
0277 MODULE_DESCRIPTION("APM X-Gene SoC RTC driver");
0278 MODULE_AUTHOR("Rameshwar Sahu <rsahu@apm.com>");
0279 MODULE_LICENSE("GPL");