xref: /openbmc/linux/drivers/rtc/rtc-palmas.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
11d9539edSNobuhiro Iwamatsu // SPDX-License-Identifier: GPL-2.0-only
20101e53cSLaxman Dewangan /*
30101e53cSLaxman Dewangan  * rtc-palmas.c -- Palmas Real Time Clock driver.
40101e53cSLaxman Dewangan 
50101e53cSLaxman Dewangan  * RTC driver for TI Palma series devices like TPS65913,
60101e53cSLaxman Dewangan  * TPS65914 power management IC.
70101e53cSLaxman Dewangan  *
80101e53cSLaxman Dewangan  * Copyright (c) 2012, NVIDIA Corporation.
90101e53cSLaxman Dewangan  *
100101e53cSLaxman Dewangan  * Author: Laxman Dewangan <ldewangan@nvidia.com>
110101e53cSLaxman Dewangan  */
120101e53cSLaxman Dewangan 
130101e53cSLaxman Dewangan #include <linux/bcd.h>
140101e53cSLaxman Dewangan #include <linux/errno.h>
150101e53cSLaxman Dewangan #include <linux/init.h>
160101e53cSLaxman Dewangan #include <linux/interrupt.h>
170101e53cSLaxman Dewangan #include <linux/kernel.h>
180101e53cSLaxman Dewangan #include <linux/mfd/palmas.h>
190101e53cSLaxman Dewangan #include <linux/module.h>
200288d2e3SLaxman Dewangan #include <linux/of.h>
210101e53cSLaxman Dewangan #include <linux/rtc.h>
220101e53cSLaxman Dewangan #include <linux/types.h>
230101e53cSLaxman Dewangan #include <linux/platform_device.h>
240101e53cSLaxman Dewangan #include <linux/pm.h>
250101e53cSLaxman Dewangan 
260101e53cSLaxman Dewangan struct palmas_rtc {
270101e53cSLaxman Dewangan 	struct rtc_device	*rtc;
280101e53cSLaxman Dewangan 	struct device		*dev;
290101e53cSLaxman Dewangan 	unsigned int		irq;
300101e53cSLaxman Dewangan };
310101e53cSLaxman Dewangan 
320101e53cSLaxman Dewangan /* Total number of RTC registers needed to set time*/
330101e53cSLaxman Dewangan #define PALMAS_NUM_TIME_REGS	(PALMAS_YEARS_REG - PALMAS_SECONDS_REG + 1)
340101e53cSLaxman Dewangan 
palmas_rtc_read_time(struct device * dev,struct rtc_time * tm)350101e53cSLaxman Dewangan static int palmas_rtc_read_time(struct device *dev, struct rtc_time *tm)
360101e53cSLaxman Dewangan {
370101e53cSLaxman Dewangan 	unsigned char rtc_data[PALMAS_NUM_TIME_REGS];
380101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(dev->parent);
390101e53cSLaxman Dewangan 	int ret;
400101e53cSLaxman Dewangan 
410101e53cSLaxman Dewangan 	/* Copy RTC counting registers to static registers or latches */
420101e53cSLaxman Dewangan 	ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
430101e53cSLaxman Dewangan 		PALMAS_RTC_CTRL_REG_GET_TIME, PALMAS_RTC_CTRL_REG_GET_TIME);
440101e53cSLaxman Dewangan 	if (ret < 0) {
450101e53cSLaxman Dewangan 		dev_err(dev, "RTC CTRL reg update failed, err: %d\n", ret);
460101e53cSLaxman Dewangan 		return ret;
470101e53cSLaxman Dewangan 	}
480101e53cSLaxman Dewangan 
490101e53cSLaxman Dewangan 	ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG,
500101e53cSLaxman Dewangan 			rtc_data, PALMAS_NUM_TIME_REGS);
510101e53cSLaxman Dewangan 	if (ret < 0) {
520101e53cSLaxman Dewangan 		dev_err(dev, "RTC_SECONDS reg read failed, err = %d\n", ret);
530101e53cSLaxman Dewangan 		return ret;
540101e53cSLaxman Dewangan 	}
550101e53cSLaxman Dewangan 
560101e53cSLaxman Dewangan 	tm->tm_sec = bcd2bin(rtc_data[0]);
570101e53cSLaxman Dewangan 	tm->tm_min = bcd2bin(rtc_data[1]);
580101e53cSLaxman Dewangan 	tm->tm_hour = bcd2bin(rtc_data[2]);
590101e53cSLaxman Dewangan 	tm->tm_mday = bcd2bin(rtc_data[3]);
600101e53cSLaxman Dewangan 	tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
610101e53cSLaxman Dewangan 	tm->tm_year = bcd2bin(rtc_data[5]) + 100;
620101e53cSLaxman Dewangan 
630101e53cSLaxman Dewangan 	return ret;
640101e53cSLaxman Dewangan }
650101e53cSLaxman Dewangan 
palmas_rtc_set_time(struct device * dev,struct rtc_time * tm)660101e53cSLaxman Dewangan static int palmas_rtc_set_time(struct device *dev, struct rtc_time *tm)
670101e53cSLaxman Dewangan {
680101e53cSLaxman Dewangan 	unsigned char rtc_data[PALMAS_NUM_TIME_REGS];
690101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(dev->parent);
700101e53cSLaxman Dewangan 	int ret;
710101e53cSLaxman Dewangan 
720101e53cSLaxman Dewangan 	rtc_data[0] = bin2bcd(tm->tm_sec);
730101e53cSLaxman Dewangan 	rtc_data[1] = bin2bcd(tm->tm_min);
740101e53cSLaxman Dewangan 	rtc_data[2] = bin2bcd(tm->tm_hour);
750101e53cSLaxman Dewangan 	rtc_data[3] = bin2bcd(tm->tm_mday);
760101e53cSLaxman Dewangan 	rtc_data[4] = bin2bcd(tm->tm_mon + 1);
770101e53cSLaxman Dewangan 	rtc_data[5] = bin2bcd(tm->tm_year - 100);
780101e53cSLaxman Dewangan 
790101e53cSLaxman Dewangan 	/* Stop RTC while updating the RTC time registers */
800101e53cSLaxman Dewangan 	ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
810101e53cSLaxman Dewangan 		PALMAS_RTC_CTRL_REG_STOP_RTC, 0);
820101e53cSLaxman Dewangan 	if (ret < 0) {
830101e53cSLaxman Dewangan 		dev_err(dev, "RTC stop failed, err = %d\n", ret);
840101e53cSLaxman Dewangan 		return ret;
850101e53cSLaxman Dewangan 	}
860101e53cSLaxman Dewangan 
870101e53cSLaxman Dewangan 	ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG,
880101e53cSLaxman Dewangan 		rtc_data, PALMAS_NUM_TIME_REGS);
890101e53cSLaxman Dewangan 	if (ret < 0) {
900101e53cSLaxman Dewangan 		dev_err(dev, "RTC_SECONDS reg write failed, err = %d\n", ret);
910101e53cSLaxman Dewangan 		return ret;
920101e53cSLaxman Dewangan 	}
930101e53cSLaxman Dewangan 
940101e53cSLaxman Dewangan 	/* Start back RTC */
950101e53cSLaxman Dewangan 	ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
960101e53cSLaxman Dewangan 		PALMAS_RTC_CTRL_REG_STOP_RTC, PALMAS_RTC_CTRL_REG_STOP_RTC);
970101e53cSLaxman Dewangan 	if (ret < 0)
980101e53cSLaxman Dewangan 		dev_err(dev, "RTC start failed, err = %d\n", ret);
990101e53cSLaxman Dewangan 	return ret;
1000101e53cSLaxman Dewangan }
1010101e53cSLaxman Dewangan 
palmas_rtc_alarm_irq_enable(struct device * dev,unsigned enabled)1020101e53cSLaxman Dewangan static int palmas_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
1030101e53cSLaxman Dewangan {
1040101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(dev->parent);
1050101e53cSLaxman Dewangan 	u8 val;
1060101e53cSLaxman Dewangan 
1070101e53cSLaxman Dewangan 	val = enabled ? PALMAS_RTC_INTERRUPTS_REG_IT_ALARM : 0;
1080101e53cSLaxman Dewangan 	return palmas_write(palmas, PALMAS_RTC_BASE,
1090101e53cSLaxman Dewangan 		PALMAS_RTC_INTERRUPTS_REG, val);
1100101e53cSLaxman Dewangan }
1110101e53cSLaxman Dewangan 
palmas_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alm)1120101e53cSLaxman Dewangan static int palmas_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
1130101e53cSLaxman Dewangan {
1140101e53cSLaxman Dewangan 	unsigned char alarm_data[PALMAS_NUM_TIME_REGS];
1150101e53cSLaxman Dewangan 	u32 int_val;
1160101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(dev->parent);
1170101e53cSLaxman Dewangan 	int ret;
1180101e53cSLaxman Dewangan 
1190101e53cSLaxman Dewangan 	ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE,
1200101e53cSLaxman Dewangan 			PALMAS_ALARM_SECONDS_REG,
1210101e53cSLaxman Dewangan 			alarm_data, PALMAS_NUM_TIME_REGS);
1220101e53cSLaxman Dewangan 	if (ret < 0) {
1230101e53cSLaxman Dewangan 		dev_err(dev, "RTC_ALARM_SECONDS read failed, err = %d\n", ret);
1240101e53cSLaxman Dewangan 		return ret;
1250101e53cSLaxman Dewangan 	}
1260101e53cSLaxman Dewangan 
1270101e53cSLaxman Dewangan 	alm->time.tm_sec = bcd2bin(alarm_data[0]);
1280101e53cSLaxman Dewangan 	alm->time.tm_min = bcd2bin(alarm_data[1]);
1290101e53cSLaxman Dewangan 	alm->time.tm_hour = bcd2bin(alarm_data[2]);
1300101e53cSLaxman Dewangan 	alm->time.tm_mday = bcd2bin(alarm_data[3]);
1310101e53cSLaxman Dewangan 	alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1;
1320101e53cSLaxman Dewangan 	alm->time.tm_year = bcd2bin(alarm_data[5]) + 100;
1330101e53cSLaxman Dewangan 
1340101e53cSLaxman Dewangan 	ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_INTERRUPTS_REG,
1350101e53cSLaxman Dewangan 			&int_val);
1360101e53cSLaxman Dewangan 	if (ret < 0) {
1370101e53cSLaxman Dewangan 		dev_err(dev, "RTC_INTERRUPTS reg read failed, err = %d\n", ret);
1380101e53cSLaxman Dewangan 		return ret;
1390101e53cSLaxman Dewangan 	}
1400101e53cSLaxman Dewangan 
1410101e53cSLaxman Dewangan 	if (int_val & PALMAS_RTC_INTERRUPTS_REG_IT_ALARM)
1420101e53cSLaxman Dewangan 		alm->enabled = 1;
1430101e53cSLaxman Dewangan 	return ret;
1440101e53cSLaxman Dewangan }
1450101e53cSLaxman Dewangan 
palmas_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alm)1460101e53cSLaxman Dewangan static int palmas_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
1470101e53cSLaxman Dewangan {
1480101e53cSLaxman Dewangan 	unsigned char alarm_data[PALMAS_NUM_TIME_REGS];
1490101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(dev->parent);
1500101e53cSLaxman Dewangan 	int ret;
1510101e53cSLaxman Dewangan 
1520101e53cSLaxman Dewangan 	ret = palmas_rtc_alarm_irq_enable(dev, 0);
1530101e53cSLaxman Dewangan 	if (ret < 0) {
1540101e53cSLaxman Dewangan 		dev_err(dev, "Disable RTC alarm failed\n");
1550101e53cSLaxman Dewangan 		return ret;
1560101e53cSLaxman Dewangan 	}
1570101e53cSLaxman Dewangan 
1580101e53cSLaxman Dewangan 	alarm_data[0] = bin2bcd(alm->time.tm_sec);
1590101e53cSLaxman Dewangan 	alarm_data[1] = bin2bcd(alm->time.tm_min);
1600101e53cSLaxman Dewangan 	alarm_data[2] = bin2bcd(alm->time.tm_hour);
1610101e53cSLaxman Dewangan 	alarm_data[3] = bin2bcd(alm->time.tm_mday);
1620101e53cSLaxman Dewangan 	alarm_data[4] = bin2bcd(alm->time.tm_mon + 1);
1630101e53cSLaxman Dewangan 	alarm_data[5] = bin2bcd(alm->time.tm_year - 100);
1640101e53cSLaxman Dewangan 
1650101e53cSLaxman Dewangan 	ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE,
1660101e53cSLaxman Dewangan 		PALMAS_ALARM_SECONDS_REG, alarm_data, PALMAS_NUM_TIME_REGS);
1670101e53cSLaxman Dewangan 	if (ret < 0) {
1680101e53cSLaxman Dewangan 		dev_err(dev, "ALARM_SECONDS_REG write failed, err = %d\n", ret);
1690101e53cSLaxman Dewangan 		return ret;
1700101e53cSLaxman Dewangan 	}
1710101e53cSLaxman Dewangan 
1720101e53cSLaxman Dewangan 	if (alm->enabled)
1730101e53cSLaxman Dewangan 		ret = palmas_rtc_alarm_irq_enable(dev, 1);
1740101e53cSLaxman Dewangan 	return ret;
1750101e53cSLaxman Dewangan }
1760101e53cSLaxman Dewangan 
palmas_clear_interrupts(struct device * dev)1770101e53cSLaxman Dewangan static int palmas_clear_interrupts(struct device *dev)
1780101e53cSLaxman Dewangan {
1790101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(dev->parent);
1800101e53cSLaxman Dewangan 	unsigned int rtc_reg;
1810101e53cSLaxman Dewangan 	int ret;
1820101e53cSLaxman Dewangan 
1830101e53cSLaxman Dewangan 	ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
1840101e53cSLaxman Dewangan 				&rtc_reg);
1850101e53cSLaxman Dewangan 	if (ret < 0) {
1860101e53cSLaxman Dewangan 		dev_err(dev, "RTC_STATUS read failed, err = %d\n", ret);
1870101e53cSLaxman Dewangan 		return ret;
1880101e53cSLaxman Dewangan 	}
1890101e53cSLaxman Dewangan 
1900101e53cSLaxman Dewangan 	ret = palmas_write(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
1910101e53cSLaxman Dewangan 			rtc_reg);
1920101e53cSLaxman Dewangan 	if (ret < 0) {
1930101e53cSLaxman Dewangan 		dev_err(dev, "RTC_STATUS write failed, err = %d\n", ret);
1940101e53cSLaxman Dewangan 		return ret;
1950101e53cSLaxman Dewangan 	}
1960101e53cSLaxman Dewangan 	return 0;
1970101e53cSLaxman Dewangan }
1980101e53cSLaxman Dewangan 
palmas_rtc_interrupt(int irq,void * context)1990101e53cSLaxman Dewangan static irqreturn_t palmas_rtc_interrupt(int irq, void *context)
2000101e53cSLaxman Dewangan {
2010101e53cSLaxman Dewangan 	struct palmas_rtc *palmas_rtc = context;
2020101e53cSLaxman Dewangan 	struct device *dev = palmas_rtc->dev;
2030101e53cSLaxman Dewangan 	int ret;
2040101e53cSLaxman Dewangan 
2050101e53cSLaxman Dewangan 	ret = palmas_clear_interrupts(dev);
2060101e53cSLaxman Dewangan 	if (ret < 0) {
2070101e53cSLaxman Dewangan 		dev_err(dev, "RTC interrupt clear failed, err = %d\n", ret);
2080101e53cSLaxman Dewangan 		return IRQ_NONE;
2090101e53cSLaxman Dewangan 	}
2100101e53cSLaxman Dewangan 
2110101e53cSLaxman Dewangan 	rtc_update_irq(palmas_rtc->rtc, 1, RTC_IRQF | RTC_AF);
2120101e53cSLaxman Dewangan 	return IRQ_HANDLED;
2130101e53cSLaxman Dewangan }
2140101e53cSLaxman Dewangan 
21534c7b3acSJulia Lawall static const struct rtc_class_ops palmas_rtc_ops = {
2160101e53cSLaxman Dewangan 	.read_time	= palmas_rtc_read_time,
2170101e53cSLaxman Dewangan 	.set_time	= palmas_rtc_set_time,
2180101e53cSLaxman Dewangan 	.read_alarm	= palmas_rtc_read_alarm,
2190101e53cSLaxman Dewangan 	.set_alarm	= palmas_rtc_set_alarm,
2200101e53cSLaxman Dewangan 	.alarm_irq_enable = palmas_rtc_alarm_irq_enable,
2210101e53cSLaxman Dewangan };
2220101e53cSLaxman Dewangan 
palmas_rtc_probe(struct platform_device * pdev)2230101e53cSLaxman Dewangan static int palmas_rtc_probe(struct platform_device *pdev)
2240101e53cSLaxman Dewangan {
2250101e53cSLaxman Dewangan 	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
2260101e53cSLaxman Dewangan 	struct palmas_rtc *palmas_rtc = NULL;
2270101e53cSLaxman Dewangan 	int ret;
228666a584dSLaxman Dewangan 	bool enable_bb_charging = false;
229d200c79bSLaxman Dewangan 	bool high_bb_charging = false;
230666a584dSLaxman Dewangan 
231666a584dSLaxman Dewangan 	if (pdev->dev.of_node) {
232666a584dSLaxman Dewangan 		enable_bb_charging = of_property_read_bool(pdev->dev.of_node,
233666a584dSLaxman Dewangan 					"ti,backup-battery-chargeable");
234666a584dSLaxman Dewangan 		high_bb_charging = of_property_read_bool(pdev->dev.of_node,
235666a584dSLaxman Dewangan 					"ti,backup-battery-charge-high-current");
236666a584dSLaxman Dewangan 	}
2370101e53cSLaxman Dewangan 
2380101e53cSLaxman Dewangan 	palmas_rtc = devm_kzalloc(&pdev->dev, sizeof(struct palmas_rtc),
2390101e53cSLaxman Dewangan 			GFP_KERNEL);
2400101e53cSLaxman Dewangan 	if (!palmas_rtc)
2410101e53cSLaxman Dewangan 		return -ENOMEM;
2420101e53cSLaxman Dewangan 
2430101e53cSLaxman Dewangan 	/* Clear pending interrupts */
2440101e53cSLaxman Dewangan 	ret = palmas_clear_interrupts(&pdev->dev);
2450101e53cSLaxman Dewangan 	if (ret < 0) {
2460101e53cSLaxman Dewangan 		dev_err(&pdev->dev, "clear RTC int failed, err = %d\n", ret);
2470101e53cSLaxman Dewangan 		return ret;
2480101e53cSLaxman Dewangan 	}
2490101e53cSLaxman Dewangan 
2500101e53cSLaxman Dewangan 	palmas_rtc->dev = &pdev->dev;
2510101e53cSLaxman Dewangan 	platform_set_drvdata(pdev, palmas_rtc);
2520101e53cSLaxman Dewangan 
253666a584dSLaxman Dewangan 	if (enable_bb_charging) {
254666a584dSLaxman Dewangan 		unsigned reg = PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG;
255666a584dSLaxman Dewangan 
256666a584dSLaxman Dewangan 		if (high_bb_charging)
257666a584dSLaxman Dewangan 			reg = 0;
258666a584dSLaxman Dewangan 
259666a584dSLaxman Dewangan 		ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
260666a584dSLaxman Dewangan 			PALMAS_BACKUP_BATTERY_CTRL,
261666a584dSLaxman Dewangan 			PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG, reg);
262666a584dSLaxman Dewangan 		if (ret < 0) {
263666a584dSLaxman Dewangan 			dev_err(&pdev->dev,
264666a584dSLaxman Dewangan 				"BACKUP_BATTERY_CTRL update failed, %d\n", ret);
265666a584dSLaxman Dewangan 			return ret;
266666a584dSLaxman Dewangan 		}
267666a584dSLaxman Dewangan 
268666a584dSLaxman Dewangan 		ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
269666a584dSLaxman Dewangan 			PALMAS_BACKUP_BATTERY_CTRL,
270666a584dSLaxman Dewangan 			PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN,
271666a584dSLaxman Dewangan 			PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN);
272666a584dSLaxman Dewangan 		if (ret < 0) {
273666a584dSLaxman Dewangan 			dev_err(&pdev->dev,
274666a584dSLaxman Dewangan 				"BACKUP_BATTERY_CTRL update failed, %d\n", ret);
275666a584dSLaxman Dewangan 			return ret;
276666a584dSLaxman Dewangan 		}
277666a584dSLaxman Dewangan 	}
278666a584dSLaxman Dewangan 
2790101e53cSLaxman Dewangan 	/* Start RTC */
2800101e53cSLaxman Dewangan 	ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
2810101e53cSLaxman Dewangan 			PALMAS_RTC_CTRL_REG_STOP_RTC,
2820101e53cSLaxman Dewangan 			PALMAS_RTC_CTRL_REG_STOP_RTC);
2830101e53cSLaxman Dewangan 	if (ret < 0) {
2840101e53cSLaxman Dewangan 		dev_err(&pdev->dev, "RTC_CTRL write failed, err = %d\n", ret);
2850101e53cSLaxman Dewangan 		return ret;
2860101e53cSLaxman Dewangan 	}
2870101e53cSLaxman Dewangan 
2880101e53cSLaxman Dewangan 	palmas_rtc->irq = platform_get_irq(pdev, 0);
2890101e53cSLaxman Dewangan 
2902c5a5b30SWei Ni 	device_init_wakeup(&pdev->dev, 1);
29127971335SJingoo Han 	palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
2920101e53cSLaxman Dewangan 				&palmas_rtc_ops, THIS_MODULE);
2930101e53cSLaxman Dewangan 	if (IS_ERR(palmas_rtc->rtc)) {
2940101e53cSLaxman Dewangan 		ret = PTR_ERR(palmas_rtc->rtc);
2950101e53cSLaxman Dewangan 		dev_err(&pdev->dev, "RTC register failed, err = %d\n", ret);
2960101e53cSLaxman Dewangan 		return ret;
2970101e53cSLaxman Dewangan 	}
2980101e53cSLaxman Dewangan 
29927971335SJingoo Han 	ret = devm_request_threaded_irq(&pdev->dev, palmas_rtc->irq, NULL,
3000101e53cSLaxman Dewangan 			palmas_rtc_interrupt,
301b3be3f6aSGrygorii Strashko 			IRQF_TRIGGER_LOW | IRQF_ONESHOT,
3020101e53cSLaxman Dewangan 			dev_name(&pdev->dev), palmas_rtc);
3030101e53cSLaxman Dewangan 	if (ret < 0) {
3040101e53cSLaxman Dewangan 		dev_err(&pdev->dev, "IRQ request failed, err = %d\n", ret);
3050101e53cSLaxman Dewangan 		return ret;
3060101e53cSLaxman Dewangan 	}
3070101e53cSLaxman Dewangan 
3080101e53cSLaxman Dewangan 	return 0;
3090101e53cSLaxman Dewangan }
3100101e53cSLaxman Dewangan 
palmas_rtc_remove(struct platform_device * pdev)311*a7f9864eSUwe Kleine-König static void palmas_rtc_remove(struct platform_device *pdev)
3120101e53cSLaxman Dewangan {
3130101e53cSLaxman Dewangan 	palmas_rtc_alarm_irq_enable(&pdev->dev, 0);
3140101e53cSLaxman Dewangan }
3150101e53cSLaxman Dewangan 
3160101e53cSLaxman Dewangan #ifdef CONFIG_PM_SLEEP
palmas_rtc_suspend(struct device * dev)3170101e53cSLaxman Dewangan static int palmas_rtc_suspend(struct device *dev)
3180101e53cSLaxman Dewangan {
3190101e53cSLaxman Dewangan 	struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev);
3200101e53cSLaxman Dewangan 
3210101e53cSLaxman Dewangan 	if (device_may_wakeup(dev))
3220101e53cSLaxman Dewangan 		enable_irq_wake(palmas_rtc->irq);
3230101e53cSLaxman Dewangan 	return 0;
3240101e53cSLaxman Dewangan }
3250101e53cSLaxman Dewangan 
palmas_rtc_resume(struct device * dev)3260101e53cSLaxman Dewangan static int palmas_rtc_resume(struct device *dev)
3270101e53cSLaxman Dewangan {
3280101e53cSLaxman Dewangan 	struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev);
3290101e53cSLaxman Dewangan 
3300101e53cSLaxman Dewangan 	if (device_may_wakeup(dev))
3310101e53cSLaxman Dewangan 		disable_irq_wake(palmas_rtc->irq);
3320101e53cSLaxman Dewangan 	return 0;
3330101e53cSLaxman Dewangan }
3340101e53cSLaxman Dewangan #endif
3350101e53cSLaxman Dewangan 
3363f93822dSJingoo Han static SIMPLE_DEV_PM_OPS(palmas_rtc_pm_ops, palmas_rtc_suspend,
3373f93822dSJingoo Han 			 palmas_rtc_resume);
3380101e53cSLaxman Dewangan 
3390288d2e3SLaxman Dewangan #ifdef CONFIG_OF
3407abe3f54SJingoo Han static const struct of_device_id of_palmas_rtc_match[] = {
3410288d2e3SLaxman Dewangan 	{ .compatible = "ti,palmas-rtc"},
3420288d2e3SLaxman Dewangan 	{ },
3430288d2e3SLaxman Dewangan };
3440288d2e3SLaxman Dewangan MODULE_DEVICE_TABLE(of, of_palmas_rtc_match);
3450288d2e3SLaxman Dewangan #endif
3460288d2e3SLaxman Dewangan 
3470101e53cSLaxman Dewangan static struct platform_driver palmas_rtc_driver = {
3480101e53cSLaxman Dewangan 	.probe		= palmas_rtc_probe,
349*a7f9864eSUwe Kleine-König 	.remove_new	= palmas_rtc_remove,
3500101e53cSLaxman Dewangan 	.driver		= {
3510101e53cSLaxman Dewangan 		.name	= "palmas-rtc",
3520101e53cSLaxman Dewangan 		.pm	= &palmas_rtc_pm_ops,
3530288d2e3SLaxman Dewangan 		.of_match_table = of_match_ptr(of_palmas_rtc_match),
3540101e53cSLaxman Dewangan 	},
3550101e53cSLaxman Dewangan };
3560101e53cSLaxman Dewangan 
3570101e53cSLaxman Dewangan module_platform_driver(palmas_rtc_driver);
3580101e53cSLaxman Dewangan 
3590101e53cSLaxman Dewangan MODULE_ALIAS("platform:palmas_rtc");
3600101e53cSLaxman Dewangan MODULE_DESCRIPTION("TI PALMAS series RTC driver");
3610101e53cSLaxman Dewangan MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
3620101e53cSLaxman Dewangan MODULE_LICENSE("GPL v2");
363