1 /* 2 * APM X-Gene SoC Real Time Clock Driver 3 * 4 * Copyright (c) 2014, Applied Micro Circuits Corporation 5 * Author: Rameshwar Prasad Sahu <rsahu@apm.com> 6 * Loc Ho <lho@apm.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 * 21 */ 22 23 #include <linux/init.h> 24 #include <linux/module.h> 25 #include <linux/of.h> 26 #include <linux/platform_device.h> 27 #include <linux/io.h> 28 #include <linux/slab.h> 29 #include <linux/clk.h> 30 #include <linux/delay.h> 31 #include <linux/rtc.h> 32 33 /* RTC CSR Registers */ 34 #define RTC_CCVR 0x00 35 #define RTC_CMR 0x04 36 #define RTC_CLR 0x08 37 #define RTC_CCR 0x0C 38 #define RTC_CCR_IE BIT(0) 39 #define RTC_CCR_MASK BIT(1) 40 #define RTC_CCR_EN BIT(2) 41 #define RTC_CCR_WEN BIT(3) 42 #define RTC_STAT 0x10 43 #define RTC_STAT_BIT BIT(0) 44 #define RTC_RSTAT 0x14 45 #define RTC_EOI 0x18 46 #define RTC_VER 0x1C 47 48 struct xgene_rtc_dev { 49 struct rtc_device *rtc; 50 struct device *dev; 51 unsigned long alarm_time; 52 void __iomem *csr_base; 53 struct clk *clk; 54 unsigned int irq_wake; 55 }; 56 57 static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm) 58 { 59 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); 60 61 rtc_time_to_tm(readl(pdata->csr_base + RTC_CCVR), tm); 62 return rtc_valid_tm(tm); 63 } 64 65 static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs) 66 { 67 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); 68 69 /* 70 * NOTE: After the following write, the RTC_CCVR is only reflected 71 * after the update cycle of 1 seconds. 72 */ 73 writel((u32) secs, pdata->csr_base + RTC_CLR); 74 readl(pdata->csr_base + RTC_CLR); /* Force a barrier */ 75 76 return 0; 77 } 78 79 static int xgene_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 80 { 81 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); 82 83 rtc_time_to_tm(pdata->alarm_time, &alrm->time); 84 alrm->enabled = readl(pdata->csr_base + RTC_CCR) & RTC_CCR_IE; 85 86 return 0; 87 } 88 89 static int xgene_rtc_alarm_irq_enable(struct device *dev, u32 enabled) 90 { 91 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); 92 u32 ccr; 93 94 ccr = readl(pdata->csr_base + RTC_CCR); 95 if (enabled) { 96 ccr &= ~RTC_CCR_MASK; 97 ccr |= RTC_CCR_IE; 98 } else { 99 ccr &= ~RTC_CCR_IE; 100 ccr |= RTC_CCR_MASK; 101 } 102 writel(ccr, pdata->csr_base + RTC_CCR); 103 104 return 0; 105 } 106 107 static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 108 { 109 struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); 110 unsigned long rtc_time; 111 unsigned long alarm_time; 112 113 rtc_time = readl(pdata->csr_base + RTC_CCVR); 114 rtc_tm_to_time(&alrm->time, &alarm_time); 115 116 pdata->alarm_time = alarm_time; 117 writel((u32) pdata->alarm_time, pdata->csr_base + RTC_CMR); 118 119 xgene_rtc_alarm_irq_enable(dev, alrm->enabled); 120 121 return 0; 122 } 123 124 static const struct rtc_class_ops xgene_rtc_ops = { 125 .read_time = xgene_rtc_read_time, 126 .set_mmss = xgene_rtc_set_mmss, 127 .read_alarm = xgene_rtc_read_alarm, 128 .set_alarm = xgene_rtc_set_alarm, 129 .alarm_irq_enable = xgene_rtc_alarm_irq_enable, 130 }; 131 132 static irqreturn_t xgene_rtc_interrupt(int irq, void *id) 133 { 134 struct xgene_rtc_dev *pdata = (struct xgene_rtc_dev *) id; 135 136 /* Check if interrupt asserted */ 137 if (!(readl(pdata->csr_base + RTC_STAT) & RTC_STAT_BIT)) 138 return IRQ_NONE; 139 140 /* Clear interrupt */ 141 readl(pdata->csr_base + RTC_EOI); 142 143 rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF); 144 145 return IRQ_HANDLED; 146 } 147 148 static int xgene_rtc_probe(struct platform_device *pdev) 149 { 150 struct xgene_rtc_dev *pdata; 151 struct resource *res; 152 int ret; 153 int irq; 154 155 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 156 if (!pdata) 157 return -ENOMEM; 158 platform_set_drvdata(pdev, pdata); 159 pdata->dev = &pdev->dev; 160 161 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 162 pdata->csr_base = devm_ioremap_resource(&pdev->dev, res); 163 if (IS_ERR(pdata->csr_base)) 164 return PTR_ERR(pdata->csr_base); 165 166 irq = platform_get_irq(pdev, 0); 167 if (irq < 0) { 168 dev_err(&pdev->dev, "No IRQ resource\n"); 169 return irq; 170 } 171 ret = devm_request_irq(&pdev->dev, irq, xgene_rtc_interrupt, 0, 172 dev_name(&pdev->dev), pdata); 173 if (ret) { 174 dev_err(&pdev->dev, "Could not request IRQ\n"); 175 return ret; 176 } 177 178 pdata->clk = devm_clk_get(&pdev->dev, NULL); 179 if (IS_ERR(pdata->clk)) { 180 dev_err(&pdev->dev, "Couldn't get the clock for RTC\n"); 181 return -ENODEV; 182 } 183 clk_prepare_enable(pdata->clk); 184 185 /* Turn on the clock and the crystal */ 186 writel(RTC_CCR_EN, pdata->csr_base + RTC_CCR); 187 188 device_init_wakeup(&pdev->dev, 1); 189 190 pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 191 &xgene_rtc_ops, THIS_MODULE); 192 if (IS_ERR(pdata->rtc)) { 193 clk_disable_unprepare(pdata->clk); 194 return PTR_ERR(pdata->rtc); 195 } 196 197 /* HW does not support update faster than 1 seconds */ 198 pdata->rtc->uie_unsupported = 1; 199 200 return 0; 201 } 202 203 static int xgene_rtc_remove(struct platform_device *pdev) 204 { 205 struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); 206 207 xgene_rtc_alarm_irq_enable(&pdev->dev, 0); 208 device_init_wakeup(&pdev->dev, 0); 209 clk_disable_unprepare(pdata->clk); 210 return 0; 211 } 212 213 #ifdef CONFIG_PM_SLEEP 214 static int xgene_rtc_suspend(struct device *dev) 215 { 216 struct platform_device *pdev = to_platform_device(dev); 217 struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); 218 int irq; 219 220 irq = platform_get_irq(pdev, 0); 221 if (device_may_wakeup(&pdev->dev)) { 222 if (!enable_irq_wake(irq)) 223 pdata->irq_wake = 1; 224 } else { 225 xgene_rtc_alarm_irq_enable(dev, 0); 226 clk_disable(pdata->clk); 227 } 228 229 return 0; 230 } 231 232 static int xgene_rtc_resume(struct device *dev) 233 { 234 struct platform_device *pdev = to_platform_device(dev); 235 struct xgene_rtc_dev *pdata = platform_get_drvdata(pdev); 236 int irq; 237 238 irq = platform_get_irq(pdev, 0); 239 if (device_may_wakeup(&pdev->dev)) { 240 if (pdata->irq_wake) { 241 disable_irq_wake(irq); 242 pdata->irq_wake = 0; 243 } 244 } else { 245 clk_enable(pdata->clk); 246 xgene_rtc_alarm_irq_enable(dev, 1); 247 } 248 249 return 0; 250 } 251 #endif 252 253 static SIMPLE_DEV_PM_OPS(xgene_rtc_pm_ops, xgene_rtc_suspend, xgene_rtc_resume); 254 255 #ifdef CONFIG_OF 256 static const struct of_device_id xgene_rtc_of_match[] = { 257 {.compatible = "apm,xgene-rtc" }, 258 { } 259 }; 260 MODULE_DEVICE_TABLE(of, xgene_rtc_of_match); 261 #endif 262 263 static struct platform_driver xgene_rtc_driver = { 264 .probe = xgene_rtc_probe, 265 .remove = xgene_rtc_remove, 266 .driver = { 267 .name = "xgene-rtc", 268 .pm = &xgene_rtc_pm_ops, 269 .of_match_table = of_match_ptr(xgene_rtc_of_match), 270 }, 271 }; 272 273 module_platform_driver(xgene_rtc_driver); 274 275 MODULE_DESCRIPTION("APM X-Gene SoC RTC driver"); 276 MODULE_AUTHOR("Rameshwar Sahu <rsahu@apm.com>"); 277 MODULE_LICENSE("GPL"); 278