0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/clk.h>
0014 #include <linux/delay.h>
0015 #include <linux/init.h>
0016 #include <linux/io.h>
0017 #include <linux/irq.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/of.h>
0021 #include <linux/of_irq.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/rtc.h>
0024
0025 #include <dt-bindings/mfd/st-lpc.h>
0026
0027
0028 #define LPC_LPT_LSB_OFF 0x400
0029 #define LPC_LPT_MSB_OFF 0x404
0030 #define LPC_LPT_START_OFF 0x408
0031
0032
0033 #define LPC_LPA_LSB_OFF 0x410
0034 #define LPC_LPA_MSB_OFF 0x414
0035 #define LPC_LPA_START_OFF 0x418
0036
0037
0038 #define LPC_WDT_OFF 0x510
0039 #define LPC_WDT_FLAG_OFF 0x514
0040
0041 struct st_rtc {
0042 struct rtc_device *rtc_dev;
0043 struct rtc_wkalrm alarm;
0044 struct clk *clk;
0045 unsigned long clkrate;
0046 void __iomem *ioaddr;
0047 bool irq_enabled:1;
0048 spinlock_t lock;
0049 short irq;
0050 };
0051
0052 static void st_rtc_set_hw_alarm(struct st_rtc *rtc,
0053 unsigned long msb, unsigned long lsb)
0054 {
0055 unsigned long flags;
0056
0057 spin_lock_irqsave(&rtc->lock, flags);
0058
0059 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF);
0060
0061 writel_relaxed(msb, rtc->ioaddr + LPC_LPA_MSB_OFF);
0062 writel_relaxed(lsb, rtc->ioaddr + LPC_LPA_LSB_OFF);
0063 writel_relaxed(1, rtc->ioaddr + LPC_LPA_START_OFF);
0064
0065 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF);
0066
0067 spin_unlock_irqrestore(&rtc->lock, flags);
0068 }
0069
0070 static irqreturn_t st_rtc_handler(int this_irq, void *data)
0071 {
0072 struct st_rtc *rtc = (struct st_rtc *)data;
0073
0074 rtc_update_irq(rtc->rtc_dev, 1, RTC_AF);
0075
0076 return IRQ_HANDLED;
0077 }
0078
0079 static int st_rtc_read_time(struct device *dev, struct rtc_time *tm)
0080 {
0081 struct st_rtc *rtc = dev_get_drvdata(dev);
0082 unsigned long lpt_lsb, lpt_msb;
0083 unsigned long long lpt;
0084 unsigned long flags;
0085
0086 spin_lock_irqsave(&rtc->lock, flags);
0087
0088 do {
0089 lpt_msb = readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF);
0090 lpt_lsb = readl_relaxed(rtc->ioaddr + LPC_LPT_LSB_OFF);
0091 } while (readl_relaxed(rtc->ioaddr + LPC_LPT_MSB_OFF) != lpt_msb);
0092
0093 spin_unlock_irqrestore(&rtc->lock, flags);
0094
0095 lpt = ((unsigned long long)lpt_msb << 32) | lpt_lsb;
0096 do_div(lpt, rtc->clkrate);
0097 rtc_time64_to_tm(lpt, tm);
0098
0099 return 0;
0100 }
0101
0102 static int st_rtc_set_time(struct device *dev, struct rtc_time *tm)
0103 {
0104 struct st_rtc *rtc = dev_get_drvdata(dev);
0105 unsigned long long lpt, secs;
0106 unsigned long flags;
0107
0108 secs = rtc_tm_to_time64(tm);
0109
0110 lpt = (unsigned long long)secs * rtc->clkrate;
0111
0112 spin_lock_irqsave(&rtc->lock, flags);
0113
0114 writel_relaxed(lpt >> 32, rtc->ioaddr + LPC_LPT_MSB_OFF);
0115 writel_relaxed(lpt, rtc->ioaddr + LPC_LPT_LSB_OFF);
0116 writel_relaxed(1, rtc->ioaddr + LPC_LPT_START_OFF);
0117
0118 spin_unlock_irqrestore(&rtc->lock, flags);
0119
0120 return 0;
0121 }
0122
0123 static int st_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
0124 {
0125 struct st_rtc *rtc = dev_get_drvdata(dev);
0126 unsigned long flags;
0127
0128 spin_lock_irqsave(&rtc->lock, flags);
0129
0130 memcpy(wkalrm, &rtc->alarm, sizeof(struct rtc_wkalrm));
0131
0132 spin_unlock_irqrestore(&rtc->lock, flags);
0133
0134 return 0;
0135 }
0136
0137 static int st_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
0138 {
0139 struct st_rtc *rtc = dev_get_drvdata(dev);
0140
0141 if (enabled && !rtc->irq_enabled) {
0142 enable_irq(rtc->irq);
0143 rtc->irq_enabled = true;
0144 } else if (!enabled && rtc->irq_enabled) {
0145 disable_irq(rtc->irq);
0146 rtc->irq_enabled = false;
0147 }
0148
0149 return 0;
0150 }
0151
0152 static int st_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
0153 {
0154 struct st_rtc *rtc = dev_get_drvdata(dev);
0155 struct rtc_time now;
0156 unsigned long long now_secs;
0157 unsigned long long alarm_secs;
0158 unsigned long long lpa;
0159
0160 st_rtc_read_time(dev, &now);
0161 now_secs = rtc_tm_to_time64(&now);
0162 alarm_secs = rtc_tm_to_time64(&t->time);
0163
0164 memcpy(&rtc->alarm, t, sizeof(struct rtc_wkalrm));
0165
0166
0167 alarm_secs -= now_secs;
0168 lpa = (unsigned long long)alarm_secs * rtc->clkrate;
0169
0170 st_rtc_set_hw_alarm(rtc, lpa >> 32, lpa);
0171 st_rtc_alarm_irq_enable(dev, t->enabled);
0172
0173 return 0;
0174 }
0175
0176 static const struct rtc_class_ops st_rtc_ops = {
0177 .read_time = st_rtc_read_time,
0178 .set_time = st_rtc_set_time,
0179 .read_alarm = st_rtc_read_alarm,
0180 .set_alarm = st_rtc_set_alarm,
0181 .alarm_irq_enable = st_rtc_alarm_irq_enable,
0182 };
0183
0184 static int st_rtc_probe(struct platform_device *pdev)
0185 {
0186 struct device_node *np = pdev->dev.of_node;
0187 struct st_rtc *rtc;
0188 uint32_t mode;
0189 int ret = 0;
0190
0191 ret = of_property_read_u32(np, "st,lpc-mode", &mode);
0192 if (ret) {
0193 dev_err(&pdev->dev, "An LPC mode must be provided\n");
0194 return -EINVAL;
0195 }
0196
0197
0198 if (mode != ST_LPC_MODE_RTC)
0199 return -ENODEV;
0200
0201 rtc = devm_kzalloc(&pdev->dev, sizeof(struct st_rtc), GFP_KERNEL);
0202 if (!rtc)
0203 return -ENOMEM;
0204
0205 rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
0206 if (IS_ERR(rtc->rtc_dev))
0207 return PTR_ERR(rtc->rtc_dev);
0208
0209 spin_lock_init(&rtc->lock);
0210
0211 rtc->ioaddr = devm_platform_ioremap_resource(pdev, 0);
0212 if (IS_ERR(rtc->ioaddr))
0213 return PTR_ERR(rtc->ioaddr);
0214
0215 rtc->irq = irq_of_parse_and_map(np, 0);
0216 if (!rtc->irq) {
0217 dev_err(&pdev->dev, "IRQ missing or invalid\n");
0218 return -EINVAL;
0219 }
0220
0221 ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, 0,
0222 pdev->name, rtc);
0223 if (ret) {
0224 dev_err(&pdev->dev, "Failed to request irq %i\n", rtc->irq);
0225 return ret;
0226 }
0227
0228 enable_irq_wake(rtc->irq);
0229 disable_irq(rtc->irq);
0230
0231 rtc->clk = clk_get(&pdev->dev, NULL);
0232 if (IS_ERR(rtc->clk)) {
0233 dev_err(&pdev->dev, "Unable to request clock\n");
0234 return PTR_ERR(rtc->clk);
0235 }
0236
0237 clk_prepare_enable(rtc->clk);
0238
0239 rtc->clkrate = clk_get_rate(rtc->clk);
0240 if (!rtc->clkrate) {
0241 dev_err(&pdev->dev, "Unable to fetch clock rate\n");
0242 return -EINVAL;
0243 }
0244
0245 device_set_wakeup_capable(&pdev->dev, 1);
0246
0247 platform_set_drvdata(pdev, rtc);
0248
0249 rtc->rtc_dev->ops = &st_rtc_ops;
0250 rtc->rtc_dev->range_max = U64_MAX;
0251 do_div(rtc->rtc_dev->range_max, rtc->clkrate);
0252
0253 ret = devm_rtc_register_device(rtc->rtc_dev);
0254 if (ret) {
0255 clk_disable_unprepare(rtc->clk);
0256 return ret;
0257 }
0258
0259 return 0;
0260 }
0261
0262 #ifdef CONFIG_PM_SLEEP
0263 static int st_rtc_suspend(struct device *dev)
0264 {
0265 struct st_rtc *rtc = dev_get_drvdata(dev);
0266
0267 if (device_may_wakeup(dev))
0268 return 0;
0269
0270 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF);
0271 writel_relaxed(0, rtc->ioaddr + LPC_LPA_START_OFF);
0272 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF);
0273
0274 return 0;
0275 }
0276
0277 static int st_rtc_resume(struct device *dev)
0278 {
0279 struct st_rtc *rtc = dev_get_drvdata(dev);
0280
0281 rtc_alarm_irq_enable(rtc->rtc_dev, 0);
0282
0283
0284
0285
0286
0287 memset(&rtc->alarm, 0, sizeof(struct rtc_wkalrm));
0288
0289 writel_relaxed(0, rtc->ioaddr + LPC_LPA_MSB_OFF);
0290 writel_relaxed(0, rtc->ioaddr + LPC_LPA_LSB_OFF);
0291 writel_relaxed(1, rtc->ioaddr + LPC_WDT_OFF);
0292 writel_relaxed(1, rtc->ioaddr + LPC_LPA_START_OFF);
0293 writel_relaxed(0, rtc->ioaddr + LPC_WDT_OFF);
0294
0295 return 0;
0296 }
0297 #endif
0298
0299 static SIMPLE_DEV_PM_OPS(st_rtc_pm_ops, st_rtc_suspend, st_rtc_resume);
0300
0301 static const struct of_device_id st_rtc_match[] = {
0302 { .compatible = "st,stih407-lpc" },
0303 {}
0304 };
0305 MODULE_DEVICE_TABLE(of, st_rtc_match);
0306
0307 static struct platform_driver st_rtc_platform_driver = {
0308 .driver = {
0309 .name = "st-lpc-rtc",
0310 .pm = &st_rtc_pm_ops,
0311 .of_match_table = st_rtc_match,
0312 },
0313 .probe = st_rtc_probe,
0314 };
0315
0316 module_platform_driver(st_rtc_platform_driver);
0317
0318 MODULE_DESCRIPTION("STMicroelectronics LPC RTC driver");
0319 MODULE_AUTHOR("David Paris <david.paris@st.com>");
0320 MODULE_LICENSE("GPL");